Skip to content
This page has been auto-translated and may contain errors.View in English

Casa de bichos

Felicitaciones. Eres el Jefe de Tecnología en Crooked Orbit, una pequeña y un tanto caótica empresa de logística espacial dirigida por una tripulación de astronautas cuestionables con código aún más cuestionable.

La paga es decente. La base de código no...

Tu trabajo es revisar los problemas: bugs, funciones rotas, cosas que técnicamente corren pero que realmente no deberían.

#1: Formateador de nombres

Pip Hola, escribí este formateador de nombres y simplemente... ¿no hace nada? 😭 O sea corre bien, sin errores, pero los nombres siguen todos en minúsculas. Estoy llamando a .capitalize() en cada uno, lo puedo ver ahí en el bucle. No entiendo. ¿Puedes echarle un vistazo, por favor?
python
def format_name(full_name):
    parts = full_name.split()
    for part in parts:
        part = part.capitalize()
    return " ".join(parts)

print(format_name("sofia van den berg"))

Esperado: Sofia Van Den Berg

Obtenido: sofia van den berg

¿Qué está fallando y cómo lo arreglas?

Pista

Piensa en lo que realmente sucede cuando reasignas una variable dentro de un bucle for. ¿Cambiar part afecta a la lista de la que vino?

Una forma de arreglarlo

Cuando escribes for part in parts, Python te da cada elemento de la lista uno a la vez. part es solo una variable temporal que contiene el elemento actual. No es una conexión directa con la lista en sí.

Entonces, cuando escribes part = part.capitalize(), estás reemplazando aquello a lo que apunta part. Pero parts todavía contiene las cadenas originales. Nunca cambiaste realmente la lista.

Aquí hay una forma de verlo claramente:

python
parts = ["sofia", "van", "den", "berg"]

for part in parts:
    part = part.capitalize()

print(parts)
# ['sofia', 'van', 'den', 'berg']  # nada cambió

Para arreglarlo, necesitas construir una nueva lista con los valores capitalizados. Una comprensión de lista hace esto de forma limpia:

python
def format_name(full_name):
    parts = full_name.split()
    return " ".join(part.capitalize() for part in parts)

print(format_name("sofia van den berg"))
# Sofia Van Den Berg

part.capitalize() for part in parts recorre cada nombre, lo capitaliza y recoge los resultados en una nueva lista. Luego .join() los une de nuevo con espacios.

#2: Puntuación máxima

Zee Bien, esto es vergonzoso pero tengo esta función que se supone que debe encontrar la puntuación más alta en una lista y simplemente... ¿imprime None? Cada vez. He revisado el bucle como cinco veces, la lógica me parece bien. Las puntuaciones definitivamente están ahí. No sé qué está pasando 😅
python
def highest_score(scores):
    best = 0
    for score in scores:
        if score > best:
            best = score

results = [45, 92, 78, 88, 65]
print(f"Top score: {highest_score(results)}")

Esperado: Top score: 92

Obtenido: Top score: None

¿Qué está fallando y cómo lo arreglas?

Pista

¿Qué devuelve una función si nunca escribes una declaración return?

Una forma de arreglarlo

El bucle está bien. La lógica está bien. El problema es que highest_score nunca devuelve nada. Encuentra la mejor puntuación y luego no hace nada con ella.

En Python, si una función no tiene una declaración return, devuelve None automáticamente. Eso es lo que estás imprimiendo.

El arreglo es una línea al final:

python
def highest_score(scores):
    best = 0
    for score in scores:
        if score > best:
            best = score
    return best

results = [45, 92, 78, 88, 65]
print(f"Top score: {highest_score(results)}")
# Top score: 92

Esto sucede mucho. La función parece completa porque la lógica está toda ahí, pero sin return, el resultado simplemente desaparece cuando la función termina.

#3: Verificación de presupuesto

Orla Bien, estoy construyendo este pequeño rastreador de presupuesto y se cae cada vez que ingreso un número. Como que ni siquiera hace nada con él, simplemente explota inmediatamente con un TypeError. Revisé la lógica y me parece bien. El umbral es un float, la entrada es un número... ¿de qué se queja...? ayuda por favor
python
def check_budget(threshold):
    spent = input("How much have you spent? ")
    if spent >= threshold:
        print("Over budget!")
    else:
        print("You're within budget.")

check_budget(500.0)

Error:

TypeError: '>=' not supported between instances of 'str' and 'float'

¿Qué está fallando y cómo lo arreglas?

Pista

¿Qué tipo devuelve siempre input(), sin importar lo que el usuario escriba?

Una forma de arreglarlo

input() siempre devuelve una cadena. No importa que el usuario haya escrito un número. Python no sabe eso. Simplemente devuelve lo que se haya escrito como texto.

Entonces, cuando el código intenta comparar spent >= threshold, está comparando una cadena con un float, y Python se niega a hacer eso. Ese es el TypeError.

El arreglo es convertir la entrada a un número antes de compararla. Usa float() para manejar valores decimales:

python
def check_budget(threshold):
    spent = float(input("How much have you spent? "))
    if spent >= threshold:
        print("Over budget!")
    else:
        print("You're within budget.")

check_budget(500.0)
# How much have you spent? 620
# Over budget!

Envolver input() en float() convierte la cadena en un número de inmediato, así que la comparación funciona como se espera.

Esta es una de las fuentes más comunes de confusión en Python: input() parece que está leyendo un número, pero siempre te da una cadena. Tienes que convertirla tú mismo.

#4: Etiqueta de carga

Dex Estoy generando etiquetas de carga para el manifiesto y sigue cayéndose en esta línea. El nombre del artículo es una cadena, el peso es un número, ¿me parece bien? Pero Python está haciendo un escándalo por la concatenación 😩
python
def cargo_label(item, weight):
    label = "Item: " + item + " | Weight: " + weight + "kg"
    return label

print(cargo_label("Moon rocks", 42))

Error:

TypeError: can only concatenate str (not "int") to str

¿Qué está fallando y cómo lo arreglas?

Pista

El operador + de Python no convierte automáticamente los números en cadenas. ¿Qué necesitas hacer antes de poder unirlos?

Una forma de arreglarlo

Cuando usas + para unir cadenas en Python, cada valor tiene que ser una cadena. weight es un entero, así que Python no sabe cómo adjuntarlo al texto que lo rodea. Se niega en lugar de adivinar.

El arreglo es convertir weight a una cadena con str():

python
def cargo_label(item, weight):
    label = "Item: " + item + " | Weight: " + str(weight) + "kg"
    return label

print(cargo_label("Moon rocks", 42))
# Item: Moon rocks | Weight: 42kg

Una f-string suele ser más limpia para este tipo de cosas, ya que maneja la conversión por ti:

python
def cargo_label(item, weight):
    return f"Item: {item} | Weight: {weight}kg"

print(cargo_label("Moon rocks", 42))
# Item: Moon rocks | Weight: 42kg

Dentro de {}, Python convierte automáticamente el valor a su representación de cadena, así que no necesitas str() para nada.

#5: Manifiesto de pasajeros

Cass Algo muy raro está pasando. Tengo esta función que construye una lista de pasajeros para cada vuelo, y el primer vuelo se ve bien. ¿Pero para el tercero el manifiesto tiene a todos los de los vuelos anteriores también? No estoy compartiendo ningún dato entre llamadas, cada una es completamente independiente. Sinceramente no tengo idea de qué está pasando 😰
python
def build_manifest(name, passengers=[]):
    passengers.append(name)
    return passengers

flight_1 = build_manifest("Sofía")
flight_2 = build_manifest("Mateo")
flight_3 = build_manifest("Valentina")

print(flight_1)
print(flight_2)
print(flight_3)

Esperado:

['Sofía']
['Mateo']
['Valentina']

Obtenido:

['Sofía']
['Sofía', 'Mateo']
['Sofía', 'Mateo', 'Valentina']

¿Qué está fallando y cómo lo arreglas?

Pista

Los valores de los argumentos por defecto en Python se evalúan una vez, cuando se define la función. No cada vez que se llama a la función. ¿Qué significa eso para un objeto mutable como una lista?

Una forma de arreglarlo

Esta es una de las sorpresas más conocidas de Python. Cuando escribes passengers=[] como argumento por defecto, Python crea esa lista una sola vez cuando se define la función. Cada llamada que use el valor por defecto está compartiendo exactamente el mismo objeto lista. Así que agregar a ella en una llamada afecta a todas las llamadas futuras.

El arreglo estándar es usar None como valor por defecto y crear una nueva lista dentro de la función:

python
def build_manifest(name, passengers=None):
    if passengers is None:
        passengers = []
    passengers.append(name)
    return passengers

flight_1 = build_manifest("Sofía")
flight_2 = build_manifest("Mateo")
flight_3 = build_manifest("Valentina")

print(flight_1)  # ['Sofía']
print(flight_2)  # ['Mateo']
print(flight_3)  # ['Valentina']

Ahora cada llamada que no pase una lista obtiene una completamente nueva.

Esto se aplica a cualquier valor por defecto mutable: listas, dicts, sets. Si quieres uno nuevo cada vez, no lo pongas en la firma. Usa None y créalo dentro.