Refactorizar de forma segura el código existente de la biblioteca en Python
sorted, las comprensiones y next de Python pueden expresar la intención con claridad, pero
tienen distintas semánticas de copia y mutación. Conserva el comportamiento del que dependen los usuarios.
Resumen del laboratorio

Ilustración conceptual original (SVG)
| De un vistazo | Tu ruta |
|---|---|
| Nivel y tiempo | 300; 60 minutos (estimación de facilitación) |
| Acción inicial | Prueba duplicados, empates y mutación antes de simplificar la iteración. |
| Materiales del aprendiz | Descarga 05-python.zip |
| Espacio de trabajo | Abre la raíz del kit extraído; ejecuta la baseline desde library relativa a esa raíz |
| Comprobación inicial esperada | Las pruebas unittest existentes se descubren y pasan. |
| Ayuda de configuración | Descarga, extrae, Git local y GitHub opcional |
[!NOTE] sorted and list.sort no son contratos intercambiables.
Conceptos · Primera tarea · Lista de evidencias · Restablecer
Objetivos de aprendizaje
- Identifica qué devuelven y modifican realmente el filtrado y la ordenación.
- Conserva la semántica de mayúsculas y de resultados ausentes.
- Usa caracterización antes de sustituir bucles.
Antes de empezar
Prepara 05-python usando la guía de configuración.
Ejecuta los comandos desde library en el
fixture de refactorización de Python incluido.
Conceptos y casos de uso
| Código existente | Trampa semántica |
|---|---|
La búsqueda de subcadenas de usuarios usa lower() |
Cambiar a una comprobación de pertenencia sensible a mayúsculas altera los resultados |
| Una ordenación de burbuja ordena los nombres coincidentes | Sustituirla por un conjunto pierde duplicados y orden |
sort_loans_by_due_date modifica la lista de préstamos |
sorted(...) devuelve en cambio una lista nueva |
La búsqueda devuelve None para un ID ausente |
next(...) sin valor predeterminado lanza una excepción |
| Las entidades devueltas son objetos compartidos | Una copia profunda puede cambiar las suposiciones de quienes llaman |
Escenario del ejercicio
Simplifica un método de búsqueda de usuarios u ordenación de préstamos sin cambiar el contrato observable. El análisis de rendimiento es un ejercicio separado; no prometas aceleraciones.
Tarea 1 - Establecer las pruebas y el comportamiento actual
python -m unittest discover -s tests -p "test_*.py" -v
- Lee los métodos del repositorio y quienes los llaman.
- Caracteriza la entrada vacía, los IDs ausentes, los nombres con mayúsculas y minúsculas mezcladas, los nombres visibles duplicados, las fechas iguales y la mutación de la lista original.
- Registra las suposiciones sobre fecha y hora. Usa fechas de prueba controladas.
- Deja el comportamiento de lectura y escritura JSON fuera de la primera refactorización, salvo que se pruebe explícitamente.
Tarea 2 - Comparar alternativas con Ask
Compare the existing manual search/sort with comprehension, sorted, list.sort,
and next alternatives. Explain which returns a new list, which mutates, how ties
are handled, and what missing-result behavior must be preserved. Do not edit.
No presupongas que una expresión de una línea sea más clara ni que el comportamiento del repositorio de otro lenguaje se aplique aquí.
Tarea 3 - Planificar e implementar una parte
- En Plan, elige un método y enumera la semántica preservada y las pruebas.
- Pide a Agent que implemente únicamente esa parte.
- Inspecciona el tipo de retorno, la identidad, el orden y la mutación.
- Ejecuta las pruebas específicas y la batería existente.
- Introduce una diferencia deliberada, como sustituir la ordenación en el mismo objeto por una copia ordenada devuelta. Confirma que falle la prueba de caracterización correspondiente.
- Restaura la refactorización correcta y registra las limitaciones.
Compruébate
Reemplazaste la ordenación in situ de sort_loans_by_due_date por return sorted(loans, ...) y todas las pruebas existentes siguen pasando. ¿Qué le falta comprobar a tu evidencia?
Elige una respuesta para ver por qué se sostiene o falla.
- Si la lista del llamador se sigue reordenando in situ, ya que sorted deja intacta la original. sorted devuelve una lista nueva, así que una prueba que solo compara el orden devuelto pasa mientras el contrato in situ desaparece.
- Nada más; sorted es estable, las fechas de vencimiento iguales conservan su orden y todo se preserva. La estabilidad existe, pero solo cubre la secuencia devuelta; no dice nada sobre si la lista del llamador se ordenó in situ.
- Si la copia ordenada se clona en profundidad antes, para que nadie mute los objetos de préstamo compartidos. El laboratorio advierte que el deep copy puede cambiar las suposiciones de quien llama, y la lista original sigue sin ordenar.
Verifica tu trabajo
- El comportamiento ante IDs ausentes no cambia.
- La normalización y el orden de búsqueda siguen siendo los mismos.
- Se prueban explícitamente los resultados en el mismo objeto frente a los copiados.
- No se pierden accidentalmente el orden de claves iguales ni los duplicados.
- La mutación negativa falla y el comportamiento no relacionado sigue pasando.
Solución de problemas
Si solo se comparan instantáneas, puede pasar inadvertida la mutación de objetos. Si la refactorización cambia
la gestión de errores, clasifícala como una corrección separada. Si fallan las importaciones, ejecuta desde library
en lugar de añadir modificaciones improvisadas de sys.path.
Práctica independiente
Refactoriza una operación de actualización preservando exactamente cuándo se invocan save_loans y
load_data. Prueba el comportamiento ante registros ausentes sin inventar una nueva política.
Restablecimiento
Guarda la evidencia, restaura únicamente el método y las pruebas seleccionados en la copia desechable y cierra la sesión de aprendizaje. Mantén intactos los intérpretes compartidos y los datos fuente.