Ejercicios — Programación I
Cada bloque tiene enunciado, una pista y una solución escondida. Probá vos primero. La respuesta se revela tocando "Ver solución".
Los ejercicios están agrupados por capítulo y graduados de fácil a difícil. La pista y la solución están dentro de <details>: hacé clic para abrir.
Cap. 1 — Algoritmos y pseudocódigo
1.1 — Receta a algoritmo (básico)
Escribí en pseudocódigo el algoritmo para preparar pupusas: ingredientes, pasos, criterio de "listo".
💡 Pista
Pensá en inputs (qué necesitás) y outputs (qué obtenés). Los pasos deben ser tan concretos que cualquiera los pueda seguir.
✅ Solución
ENTRADA: harina_maíz, agua, sal, queso, aceite
SALIDA: pupusas listas
mezclar harina_maíz con agua y sal hasta formar masa
PARA cada pupusa:
tomar una porción de masa
aplanar la masa en un disco
rellenar con queso
cerrar y aplanar nuevamente
cocinar en comal con aceite a fuego medio por 3 min cada lado
FIN PARA
DEVOLVER pupusas listas
1.2 — Encontrar el máximo (intermedio)
Dada una lista de números enteros, escribí pseudocódigo para encontrar el máximo sin usar la función max().
💡 Pista
Suponé que el primer elemento es el máximo. Recorrelo y actualizá si encontrás algo mayor.
✅ Solución
ENTRADA: lista de enteros L con |L| ≥ 1
SALIDA: el máximo elemento
máximo ← L[0]
PARA i DESDE 1 HASTA |L| - 1:
SI L[i] > máximo:
máximo ← L[i]
DEVOLVER máximo
Complejidad: . Es óptimo: tenés que mirar cada elemento al menos una vez.
Cap. 2-3 — Primer programa, variables y tipos
2.1 — Conversión de unidades (básico)
Escribí un programa que pida grados Celsius y muestre la conversión a Fahrenheit. Fórmula: .
✅ Solución
celsius = float(input("Temperatura en °C: "))
fahrenheit = celsius * 9/5 + 32
print(f"{celsius}°C = {fahrenheit}°F")
Trampa: si usás int() en lugar de float(), el usuario no puede escribir 36.5.
2.2 — Tipos sospechosos (básico)
¿Qué imprime cada línea? Pensá antes de correr.
print(2 + 3)
print("2" + "3")
print(2 + "3")
print(type(3 / 2))
print(type(3 // 2))
✅ Solución
5 # int + int
23 # concatenación de strings
TypeError # mezclar tipos sin conversión explícita
<class 'float'> # / siempre devuelve float en Python 3
<class 'int'> # // es división entera
Cap. 4 — Operadores
4.1 — Edad en días (básico)
Pedí al usuario su edad en años y mostrá su edad en días, sin considerar bisiestos.
✅ Solución
años = int(input("Edad en años: "))
días = años * 365
print(f"Tenés aproximadamente {días} días.")
4.2 — Operadores lógicos (intermedio)
¿Cuál es el resultado de cada expresión?
print(True and False or True)
print(not (True and False))
print(5 > 3 and 2 > 4)
print((5 > 3) or (2 > 4) and False)
💡 Pista
Recordá precedencia: not > and > or. and se evalúa antes que or.
✅ Solución
True # (True and False) or True = False or True = True
True # not False
False # 5>3 es True, 2>4 es False, True and False = False
True # (5>3) or ((2>4) and False) = True or False = True
Cap. 5 — Condicionales
5.1 — Descuento de pupusas (básico)
Pedí una cantidad de pupusas. Si son menos de 10, costo = cantidad * 0.50. Si son entre 10 y 19, costo = cantidad * 0.45. Si son 20 o más, costo = cantidad * 0.40. Mostrá el costo total.
✅ Solución
cantidad = int(input("¿Cuántas pupusas? "))
if cantidad < 10:
precio = 0.50
elif cantidad < 20:
precio = 0.45
else:
precio = 0.40
total = cantidad * precio
print(f"Total: ${total:.2f}")
5.2 — Año bisiesto (intermedio)
Un año es bisiesto si es divisible por 4, excepto los divisibles por 100, excepto los divisibles por 400.
💡 Pista
2000 es bisiesto. 1900 no. 2024 sí.
✅ Solución
def es_bisiesto(año: int) -> bool:
if año % 400 == 0:
return True
if año % 100 == 0:
return False
return año % 4 == 0
Una sola línea: return año % 400 == 0 or (año % 4 == 0 and año % 100 != 0).
Cap. 6 — Bucles
6.1 — Tabla de multiplicar (básico)
Pedí un número y mostrá su tabla de multiplicar del 1 al 10.
✅ Solución
n = int(input("Número: "))
for i in range(1, 11):
print(f"{n} x {i} = {n * i}")
6.2 — Suma de pares (intermedio)
Calculá la suma de todos los pares entre 1 y , sin usar sum().
✅ Solución
n = int(input("Hasta qué número: "))
suma = 0
for i in range(2, n + 1, 2):
suma += i
print(suma)
Bonus: la fórmula cerrada es para par.
6.3 — FizzBuzz (intermedio)
Para de 1 a 100: si es múltiplo de 3 imprimí "Fizz", si es de 5 imprimí "Buzz", si es de ambos "FizzBuzz", sino el número.
✅ Solución
for i in range(1, 101):
if i % 15 == 0:
print("FizzBuzz")
elif i % 3 == 0:
print("Fizz")
elif i % 5 == 0:
print("Buzz")
else:
print(i)
Trampa: chequear % 15 (o % 3 == 0 and % 5 == 0) primero, no al final, sino la rama de FizzBuzz nunca se alcanza.
Cap. 7 — Funciones
7.1 — Promedio (básico)
Definí una función promedio(lista) que devuelva el promedio de los números de una lista. Manejá el caso de lista vacía.
✅ Solución
def promedio(lista):
if not lista:
return 0
return sum(lista) / len(lista)
Decisión de diseño: ¿devolver 0 o lanzar error en lista vacía? Depende del dominio. Para promedios de notas, error es mejor (un alumno sin notas no tiene promedio 0). Para suavizado, 0 está bien.
7.2 — Factorial recursivo (intermedio)
Implementá recursivamente. Caso base: .
✅ Solución
def factorial(n: int) -> int:
if n < 0:
raise ValueError("factorial no definido para negativos")
if n == 0 or n == 1:
return 1
return n * factorial(n - 1)
Trampa: sin caso base , recursión infinita.
7.3 — Es primo (avanzado)
Función que indique si un número es primo. Optimizala: solo necesitás chequear divisores hasta .
✅ Solución
def es_primo(n: int) -> bool:
if n < 2:
return False
if n < 4:
return True # 2 y 3 son primos
if n % 2 == 0:
return False # pares ≥ 4 no son primos
i = 3
while i * i <= n:
if n % i == 0:
return False
i += 2 # solo impares
return True
Por qué : si con , entonces o . Con uno de los dos alcanza.
Reto integrador
R.1 — Sistema de pedidos de pupusería (proyecto)
Implementá un sistema interactivo:
- Mostrá un menú de 5 productos con precios.
- El usuario elige por número y cantidad.
- Cuando termina (elige opción "salir"), mostrá la cuenta total con IVA del 13 %.
- Aplicá descuento del 10 % si el subtotal supera los $20.
💡 Pista de arquitectura
- Una función por responsabilidad:
mostrar_menu(),pedir_producto(),calcular_total(items, iva, descuento). - Usá diccionarios para el carrito:
{producto: cantidad}. - El
while Trueconbreakes válido para el bucle del menú.
✅ Solución (estructura)
MENU = {
1: ("Pupusa de queso", 0.50),
2: ("Pupusa revuelta", 0.60),
3: ("Curtido", 0.25),
4: ("Refresco de tamarindo", 1.00),
5: ("Frijoles licuados", 0.75),
}
IVA = 0.13
UMBRAL_DESCUENTO = 20.0
DESCUENTO = 0.10
def mostrar_menu():
print("\n--- Menú ---")
for i, (nombre, precio) in MENU.items():
print(f" {i}. {nombre} ........ ${precio:.2f}")
print(" 0. Terminar pedido")
def calcular_total(carrito):
subtotal = sum(MENU[id][1] * cant for id, cant in carrito.items())
descuento = subtotal * DESCUENTO if subtotal > UMBRAL_DESCUENTO else 0
base = subtotal - descuento
iva = base * IVA
return subtotal, descuento, iva, base + iva
def main():
carrito = {}
while True:
mostrar_menu()
op = int(input("Opción: "))
if op == 0:
break
if op not in MENU:
print("Opción inválida.")
continue
cant = int(input("Cantidad: "))
carrito[op] = carrito.get(op, 0) + cant
if not carrito:
print("Carrito vacío.")
return
sub, desc, iva, total = calcular_total(carrito)
print(f"\nSubtotal: ${sub:.2f}")
if desc > 0: print(f"Descuento: -${desc:.2f}")
print(f"IVA (13 %): ${iva:.2f}")
print(f"TOTAL: ${total:.2f}")
main()
Bonus: convertí cada función en testeable con pytest. calcular_total({1: 5}) debería devolver subtotal $2.50, descuento 0, etc.
Si encontrás un ejercicio mal o querés sugerir uno, escribime.