Pensamiento Computacional · Unidad 5 — Entrada, salida y errores
Archivos
Un archivo es la forma de que los datos sobrevivan al programa. Se abre, se usa y se cierra — y lo que se lee siempre es texto.
La explicación
Por qué hacen falta
Las variables viven en memoria y desaparecen cuando el programa termina. Si querés que algo quede, tiene que ir al disco. Eso es un archivo.
Abrir, usar, cerrar
contenido = f.read()
f.close()
El segundo argumento es el modo:
"w" escribir borra todo lo que había
"a" agregar escribe al final, conserva lo anterior
La forma recomendada: with
contenido = f.read()
# acá afuera el archivo ya está cerrado
Cierra solo, incluso si adentro se produce un error. Con open y
close sueltos, un error en el medio deja el archivo abierto. Usá siempre
with.
Tres formas de leer
f.readlines() → una lista con todas las líneas
for linea in f: → de a una, sin cargar todo en memoria
La tercera es la que conviene con archivos grandes: no necesita que todo entre en memoria.
Dos cosas que siempre sorprenden al leer
25, lo que leés es
"25\n". Por eso se usa .strip(), que saca espacios y saltos de los bordes.
Dónde molesta ese salto: en las comparaciones. linea == "25" da
False y linea.strip() == "25" da True. A
int() en cambio no le molesta —int("25\n") devuelve 25 igual—, pero
conviene hacer strip() siempre y no depender de esa tolerancia.2. Todo lo que se lee es texto. Igual que con
input(): si es un número, hay
que convertirlo con int() o float().
for linea in f:
edad = int(linea.strip()) # las dos cosas
Escribir
f.write("primera línea\n")
f.write("segunda línea\n")
write no agrega el salto de línea: si no lo ponés vos, queda todo pegado en
una sola línea. Y sólo escribe strings, así que los números van con str().
Un archivo notas.txt tiene una nota por línea. Escribir una función que devuelva el promedio.
total = 0
cantidad = 0
with open(nombre_archivo, "r") as f:
for linea in f:
total = total + int(linea.strip())
cantidad = cantidad + 1
return total / cantidad
Las tres cosas que hay que notar:
- Los acumuladores van antes del
with. Si los pusieras adentro delforse reiniciarían en cada línea — el mismo error del tema 3.3. .strip()antes deint(). Ojo con lo que se dice de esto:int("7\n")no falla —int()descarta los espacios y los saltos de los bordes y devuelve 7. Lo que sí falla es cualquier otra cosa pegada al número:int(" 7 años "),int("7.0"),int(""). Elstrip()va igual, porque el salto sí rompe cualquier comparación de texto (linea == "7"daFalse,linea.strip() == "7"daTrue) y porque en cuanto el archivo trae algo más que el número limpio, hace falta de verdad.withcierra solo. No hace faltaf.close().
cantidad queda en 0 y
total / cantidad tira ZeroDivisionError. La forma prolija:
return 0 # o None, según qué tenga sentido
return total / cantidad
Control: el promedio tiene que quedar entre la nota más baja y la más alta del archivo. Si te da fuera de ese rango, revisá el acumulador.
Un archivo ventas.txt tiene una venta por línea, con el formato producto,cantidad,precio. Escribir una función que devuelva el total facturado y el producto que más recaudó, ignorando las líneas vacías y los espacios sobrantes.
Un archivo de texto real nunca viene prolijo. Va a tener líneas en blanco al final, espacios de más, y un salto de línea al final de cada renglón. El ejercicio pide justamente eso, así que la limpieza es parte de la respuesta.
El archivo de prueba:
(línea vacía)
cuaderno,3,800
lapicera,5,150
goma,20,50
La función:
total = 0.0
por_producto = {}
with open(ruta, encoding="utf-8") as f:
for linea in f:
linea = linea.strip()
if not linea:
continue
prod, cant, precio = linea.split(",")
monto = int(cant) * float(precio)
total = total + monto
por_producto[prod] = por_producto.get(prod, 0) + monto
mejor = max(por_producto, key=lambda p: por_producto[p])
return (total, mejor, por_producto[mejor])
El with open(...) es la forma correcta de abrir un archivo: lo cierra solo al terminar, aunque el programa falle en el medio. Con open pelado hay que acordarse del close(), y si salta un error el archivo queda abierto.
El encoding="utf-8" evita que el programa se rompa con acentos y eñes. Sin él, el comportamiento depende del sistema operativo: anda en una máquina y falla en otra.
El .strip() hace dos trabajos a la vez: saca el salto de línea final —sin eso, la línea en blanco llega como un salto solo, que no cuenta como vacía, y el if de abajo no la saltea— y saca los espacios de la línea de la goma, que si no quedaría guardada con la clave " goma". Al precio el salto no le molesta: float() lo tolera, igual que int().
El if not linea: continue saltea las líneas vacías. Sin eso, linea.split(",") devuelve una lista de un elemento y el desempaquetado en tres variables tira un error.
Los resultados, con el archivo de prueba:
= 1500 + 2400 + 750 + 1000 = 5650.0
por producto: lapicera 2250, cuaderno 2400, goma 1000
el que más recaudó: cuaderno, con 2400
Fijate el detalle que el ejercicio esconde: la lapicera aparece en dos líneas y hay que sumarlas. Si el diccionario se llenara con por_producto[prod] = monto en vez de sumar, la segunda línea pisaría a la primera y la lapicera quedaría en 750.
Y otro detalle: la lapicera se vendió más veces (15 unidades contra 3), pero el cuaderno recaudó más. La pregunta es cuál recaudó más, no cuál se vendió más — y esas dos respuestas casi nunca coinciden.
El control de la suma: el total tiene que ser igual a la suma de los tres montos por producto: 2250 + 2400 + 1000 = 5650 ✓. Ese control detecta si alguna línea se perdió o se contó dos veces.
Por qué int(cant) y float(precio). Las cantidades son enteras (no se venden 2,5 lapiceras) y los precios pueden tener centavos. Elegir el tipo según lo que representa el dato es parte de escribir bien.
Dónde se pierde el punto: no hacer el strip(). El error que aparece es "not enough values to unpack (expected 3, got 1)" en la línea del split, por la línea en blanco que no se salteó, y señala el desempaquetado, que no es donde está el problema.
Dónde se cae la mayoría
- Abrir en modo "w" cuando se quería agregar: borra todo el archivo al instante.
- Olvidar el .strip() y quedarse con el salto de línea pegado al dato.
- Olvidar el \n al escribir, y que todo salga en una sola línea.
Hasta acá la explicación. La práctica es la otra mitad: 8 ejercicios de este tema, en cuatro niveles, que no te dicen sólo si está bien al final sino que te corrigen en cada paso y te explican por qué. Y uno para escribir el programa vos, que se prueba ejecutándolo en Python ahí mismo, en el navegador. Además trae una animación que muestra la idea en movimiento.
Practicar Archivos →Dónde entra este tema en el parcial
- Segundo parcial — Un .csv leído a mano10 puntos · resuelto paso a paso
- Segundo parcial — El promedio con datos sucios20 puntos · resuelto paso a paso
- Segundo parcial — Encontrar y explicar los errores30 puntos · resuelto paso a paso
Los otros temas de la unidad 5
Entrada, salida y errores