Saltar al contenido

Indice / Practicas / EJ-7.4

EJ-7.4 · CSV europeo y viaje de ida y vuelta

Escribir las ventas en el formato que pide un destino europeo, y demostrar que el archivo está bien volviéndolo a leer. La comprobación de ida y vuelta no es un extra: es el ejercicio.

Qué hay que hacer

A partir de ventas_mensuales.csv, producir dos archivos:

ELI5Explicado facil

Es como traducir un texto y volver a traducirlo al idioma original. Si vuelve igual, la traducción no perdió nada.

El segundo archivo no es el entregable: es la prueba de que el primero está bien. Si la vuelta no coincide, algo se rompió en la ida.

Archivos

La comprobación

Escribís con sep=";" y decimal=",", y leés el mismo archivo declarando lo mismo. Después pd.testing.assert_frame_equal(tabla, vuelta).

Si pasa, el archivo europeo conserva todos los datos. Si falla, te dice qué columna y qué fila - y lo importante: te lo dice antes de mandarle el archivo al destino.

Cómo saber si te salió

python comparar.py mi_ida_vuelta.csv ventas_ida_vuelta.csv

Ese archivo es el que se compara. El europeo se verifica solo: si la vuelta coincide, la ida estaba bien.

Antes de arrancar, mirá los datos

ventas_mensuales.csv (entrada) · 180 filas, se muestran 5
fechavendedorproductounidadesprecio_unitario
2026-03-02Carlos RuizAuriculares157.24
2026-03-26Carlos RuizAuriculares557.73
2026-03-31Beatriz MolinaAuriculares159.37
2026-02-09Lucía VegaWebcam645.42
2026-03-27Carlos RuizLaptop7914.44

El contrato de salida

ventas_es.csv · 180 filas

ColumnaTipoQue lleva
fila_origenenteroPosicion en el archivo de entrada, empezando en 0
fechatextoTal cual viene. Puede quedar vacia
vendedortextoTal cual viene
productotextoTal cual viene
unidadesenteroTal cual viene. Puede quedar vacia
precio_unitariodecimalRedondeado a 2 decimales, con COMA decimal
importedecimalunidades por precio, 2 decimales, con COMA decimal

Orden de las filas: fila_origen ascendente. Es unico por construccion. Indice: no se escribe: to_csv(index=False)

ventas_ida_vuelta.csv · 180 filas

ColumnaTipoQue lleva
fila_origenenteroEl mismo
fechatextoEl mismo
vendedortextoEl mismo
productotextoEl mismo
unidadesenteroEl mismo
precio_unitariodecimalEl mismo, ahora con punto decimal
importedecimalEl mismo, ahora con punto decimal

Orden de las filas: fila_origen ascendente. Indice: no se escribe: to_csv(index=False)

Que hacer con cada defecto

DefectoDondeAccionAdonde va
4 fechas vacias, 1 fecha invalida y 1 en otro formato6 filasNO NO se validan: este ejercicio cambia el formato del archivo, no los datos. La fecha se escribe tal cuallos dos archivos
1 unidad ausente y 2 precios ausentes3 filasel el importe de esas filas queda ausente y se escribe como campo vaciolos dos archivos
la fecha ausente NO se rellena con cadena vacia4 filasen en un CSV una cadena vacia y un ausente se escriben igual, y al releer la diferencia se pierde. Rellenar romperia la comprobacion de ida y vueltalos dos archivos
unidades negativas2 filasNO NO se validan: pasan tal cual y su importe es negativolos dos archivos
Orden de comprobacion

Una fila puede tener mas de un problema. Se informa solo el primero de esta lista:

  1. agregar fila_origen y calcular el importe
  2. redondear precio e importe a 2 decimales
  3. escribir con sep=';' y decimal=','
  4. volver a leer declarando el mismo sep y decimal
  5. assert_frame_equal entre lo que se escribio y lo que se leyo

El assert es el ejercicio: si el archivo europeo esta bien escrito, leerlo con el mismo formato reconstruye la tabla exacta. Si falla, el archivo perdio o deformo algun dato, y la comprobacion lo dice antes de que el destino lo reciba.

Conteos clave

Si estos numeros no te dan, algo se desvio antes de que llegues a comparar los archivos.

filas de entrada180
ventas_es.csv180
ventas_ida_vuelta.csv180
importes ausentes3
fechas ausentes4
por motivo

Invariantes

Comprobaciones que tu resultado tiene que cumplir. Corrilas vos mismo antes de comparar los archivos:

len(europeo_lineas) == 181
len(vuelta) == 180
';' in primera_linea_del_europeo
',' in la_celda_de_precio_del_europeo
vuelta['fila_origen'].is_unique
list(vuelta['fila_origen']) == list(range(180))
int(vuelta['importe'].isna().sum()) == 3
abs(vuelta['importe'].sum() - tabla['importe'].sum()) < 0.01
PISTASSi te trabas, abri esto
  • Sin thousands, un numero con punto de miles no se puede convertir. Aca no hay miles con punto porque lo escribimos nosotros, pero al leer un archivo ajeno hay que declararlo.
  • No rellenes la fecha ausente con cadena vacia: en un CSV los dos se escriben igual y la ida y vuelta deja de cerrar.
  • assert_frame_equal con check_dtype=False alcanza: lo que se comprueba es que los VALORES sobrevivan al formato.
  • Si el assert falla, no cambies el assert: el que esta mal es el archivo.

Así tiene que quedar

ventas_ida_vuelta.csv (objetivo) · 180 filas, se muestran 5
fila_origenfechavendedorproductounidadesprecio_unitarioimporte
02026-03-02Carlos RuizAuriculares157.2457.24
12026-03-26Carlos RuizAuriculares557.73288.65
22026-03-31Beatriz MolinaAuriculares159.3759.37
32026-02-09Lucía VegaWebcam645.42272.52
42026-03-27Carlos RuizLaptop7914.446401.08
No rellenes la fecha ausente con cadena vacía

Es tentador - queda más prolijo - y rompe la ida y vuelta. En un CSV, una cadena vacía y un valor ausente se escriben exactamente igual: dos comas seguidas. Al releer, no hay forma de distinguirlos, y pandas devuelve un ausente.

Así que fillna("") antes de escribir hace que la vuelta nunca coincida con la ida. Es un caso donde la comprobación te enseña algo del formato que no se ve mirando el archivo.

Si el assert falla, el que está mal es el archivo

La tentación es aflojar la comprobación - sacar una columna, bajar la precisión - hasta que pase. Eso convierte una prueba en un adorno.

La comprobación existe justamente para el caso en que falla. Cuando falla, encontró algo.