Saltar a contenido

1.4 · Condicionales

Objetivos. Al terminar este capítulo podrás: escribir ramas if/elif/else, anidar condiciones, usar el operador ternario y combinar condiciones con and/or/not.

Evidencia de logro. Construirás un pequeño sistema (login y calculadora de IMC) que toma una decisión en función de varias condiciones, explicando qué rama se ejecuta y por qué.

Contexto y motivación

Un script puede ejecutar siempre las mismas instrucciones. Los condicionales permiten que el programa elija entre varios caminos según una condición. Por ejemplo: «si el usuario existe y la clave es correcta, permite el acceso; si no, recházalo».

En una aplicación de IA aparecen al validar una entrada antes de llamar a un modelo, elegir una respuesta ante un error o aplicar una regla de negocio. Son necesarios para expresar decisiones en el programa.

Vocabulario

Término Significado
Condición Expresión que devuelve True o False
Rama Bloque de código que se ejecuta si se cumple (o no) la condición
Anidar Poner un condicional dentro de otro
Ternario Expresión condicional en una línea (A if cond else B)
match/case (Avanzado) compara un valor contra varios patrones

Prerrequisitos

1.3 · Operadores y expresiones (comparación y lógicos) y saber escribir variables.

1. if básico

El bloque se ejecuta solo si la condición es True:

edad = 18

if edad >= 18:
    print("Mayor de edad")

Salida esperada:

Mayor de edad

La condición edad >= 18 es una expresión booleana. La línea if ...: no ejecuta nada si es False: simplemente se salta el bloque.

La indentación es obligatoria

El cuerpo del if debe estar indentado (normalmente 4 espacios). Python usa la indentación para saber qué código pertenece a la rama. Si no indentas, obtienes un IndentationError; si indentas mal, la lógica puede cambiar sin que Python dé ningún error. VS Code inserta los 4 espacios al pulsar Tab y al pulsar Intro después de los dos puntos :.

2. if/else y if/elif/else

Con else cubrimos el caso contrario:

temperatura = 25

if temperatura > 20:
    print("Hace calor")
else:
    print("Hace frío")

Salida esperada:

Hace calor

Con elif ("else if") encadenamos más de dos casos:

edad = 65

if edad < 18:
    categoria = "Menor"
elif edad < 65:
    categoria = "Adulto"
else:
    categoria = "Jubilado"

print(categoria)

Salida esperada:

Jubilado

Lee elif como "si no, si...". Python evalúa en orden y se queda con la primera condición que se cumpla; el resto de ramas se ignoran. Por eso la segunda rama no necesita comprobar edad >= 18: si se llega a ella, es que la primera ya fue falsa. Y por eso el orden importa, como verás en el IMC.

3. Condiciones anidadas

Un condicional puede ir dentro de otro:

usuario_ok = True
clave_ok = False

if usuario_ok:
    if clave_ok:
        print("Acceso concedido")
    else:
        print("Contraseña incorrecta")
else:
    print("Usuario desconocido")

Salida esperada:

Contraseña incorrecta

El anidamiento permite distinguir por qué falló algo (¿usuario o clave?). Con este dato puedes dar una respuesta más útil que un simple "acceso denegado".

4. Combinar condiciones: and, or, not

edad = 20
tiene_permiso = True

print(edad >= 18 and tiene_permiso)      # ambas condiciones
print((edad >= 18) and (edad <= 30))     # rango: edad entre 18 y 30

Salida esperada:

True
True

Fíjate en la segunda línea: para comprobar un rango combinamos dos comparaciones con and, y encerramos cada una entre paréntesis. Python permite además escribir un rango como en matemáticas, encadenando comparaciones:

nota = 6
print(5 <= nota <= 10)       # equivale a (5 <= nota) and (nota <= 10)
print(0 <= nota < 5)         # ¿suspenso?

Salida esperada:

True
False

La forma encadenada es la más legible para rangos y la que usaremos a partir de ahora.

Siempre paréntesis alrededor de cada comparación

Al combinar lógicos con comparaciones, encierra cada comparación entre paréntesis: (nota >= 5) and (nota <= 10). Aunque aquí funcione sin ellos (la comparación tiene más precedencia), es un hábito que evita errores cuando la expresión crece.

¿Anidar o combinar?

Cuando solo te importa entrar o no, combina con and en una línea. Cuando quieres dar una respuesta distinta según qué falle, anida (o usa elif):

usuario_ok = True
clave_ok = False

# Combinar: una sola decisión (entra o no)
if usuario_ok and clave_ok:
    print("Acceso")

# Distinguir el fallo (anidado)
if usuario_ok:
    if clave_ok:
        print("Acceso")
    else:
        print("Clave errónea")
else:
    print("Usuario desconocido")

Salida esperada:

Clave errónea

Anidar no es "mejor": es para cuando necesitas un mensaje distinto según el caso. Si solo te importa el resultado final, and es más corto.

5. Operador ternario (A if cond else B)

Cuando la decisión devuelve un valor, el ternario es más compacto que un if/else:

edad = 20
mensaje = "Mayor de edad" if edad >= 18 else "Menor"
print(mensaje)

Salida esperada:

Mayor de edad

Se lee: "devuelve A si la condición es cierta, si no B". Es equivalente a:

if edad >= 18:
    mensaje = "Mayor de edad"
else:
    mensaje = "Menor"

Usa el ternario para asignaciones sencillas; si hay más lógica, un if/else normal es más legible.

6. Comparar cadenas

Las cadenas también se comparan:

nombre = "Ana"
print(nombre == "Ana")           # sensible a mayúsculas/minúsculas
print(nombre.lower() == "ana")   # insensible

Salida esperada:

True
True

"Ana" == "ana" es False porque Python distingue mayúsculas de minúsculas. Para comparar sin importar el caso, normaliza antes con .lower():

entrada = input("Usuario: ").strip().lower()
print(entrada == "ana")   # True, tanto si escribió «Ana» como «ANA»

.strip() recorta los espacios de los extremos y .lower() pasa todo a minúsculas; hacen falta los dos, porque un espacio accidental al final también haría fallar la comparación. Son métodos de las cadenas: operaciones que se escriben detrás del valor con un punto. Los verás a fondo en 1.9 · Cadenas. Normalizar así es un paso habitual al validar entradas de usuario.

7. Aplicación práctica: sistema de login

usuario = "admin"
clave = "1234"

if usuario == "admin" and clave == "1234":
    print("Bienvenido, admin")
elif usuario != "admin":
    print("Usuario no registrado")
else:
    print("Contraseña incorrecta")

Salida esperada:

Bienvenido, admin

Cambia clave = "0000" y verás "Contraseña incorrecta"; cambia usuario = "ana" y verás "Usuario no registrado". Sigue el razonamiento de las ramas: al else solo se llega si las dos primeras condiciones fueron falsas, es decir, si el usuario es admin (falló la segunda) pero la pareja usuario-contraseña no es correcta (falló la primera). Por eso el else puede afirmar que el problema es la contraseña sin volver a comprobarla.

Solo es un ejemplo de lógica

Una aplicación real nunca guarda contraseñas escritas en el código ni las compara en texto plano. Aquí solo interesa el orden de las ramas; la seguridad de las credenciales se trata en la Unidad 2.

8. Aplicación práctica: calculadora de IMC

peso = 70.0
altura = 1.75

imc = peso / altura**2

if imc < 18.5:
    estado = "Bajo peso"
elif imc < 25:
    estado = "Peso normal"
elif imc < 30:
    estado = "Sobrepeso"
else:
    estado = "Obesidad"

print("IMC:", round(imc, 2), "·", estado)

Salida esperada:

IMC: 22.86 · Peso normal

El orden de las ramas

En el IMC, si usamos if imc < 25 antes de if imc < 18.5, nunca alcanzaríamos "Bajo peso" porque todo valor <18.5 también cumple <25. Es el mismo principio: la primera condición que se cumple gana, así que ordena de lo más específico a lo más general.

Ampliación: match/case (Python 3.10+)

Para comparar un valor contra muchos casos "exactos", match es más limpio que una escalera de if:

comando = "listar"

match comando:
    case "listar":
        print("Listando...")
    case "salir":
        print("Saliendo")
    case _:
        print("Comando desconocido")

Salida esperada:

Listando...

El case _ es el "por defecto" (como el else). Usa match cuando compares un valor contra opciones fijas; no lo uses como sustituto general de los condicionales, que siguen siendo más expresivos para rangos y combinaciones.

Errores frecuentes

  • Escribir if x = 5: (falta ==).
  • Olvidar los dos puntos : tras la condición.
  • No indentar el cuerpo (o indentar desigual), provocando IndentationError.
  • Poner las ramas elif en orden incorrecto y que una condición "se coma" a las demás.
  • Confundir and con or (el and exige ambas; el or basta con una).
  • No normalizar cadenas antes de comparar (mayúsculas/minúsculas, espacios).

Práctica de transferencia

  1. Escribe un condicional que devuelva True si edad está entre 18 y 30 (ambos incluidos).
  2. Convierte a ternario: si nota >= 5 la variable resultado vale "Apto", si no "No apto".
  3. Modifica el programa del login para que, cuando usuario sea la cadena vacía "", muestre «Escribe un usuario» antes de comprobar nada más. ¿En qué posición de la cadena de ramas debe ir esa comprobación? ¿Por qué?
  4. Reescribe la calculadora de IMC con rangos encadenados (18.5 <= imc < 25) y comprueba que ahora el orden de las ramas ya no cambia el resultado. Pruébala con tres pesos distintos y explica en una frase qué rama se ejecutó en cada caso.

Qué debes observar: en qué casos el orden de las ramas cambia el resultado y en cuáles no; qué valores exactos están en el límite de cada rango (por ejemplo, imc = 25) y a qué categoría van.

Producto evaluable

Cuaderno 03_decisiones.py con:

  1. El sistema de login y la calculadora de IMC, cada uno en su celda de código con su "Salida esperada".
  2. Una celda Markdown que explique qué rama se ejecuta en cada caso y por qué el orden de los elif importa.
  3. Una celda con tres casos de prueba distintos para el IMC (bajo peso, normal, sobrepeso) y su interpretación.

Formato de entrega: cuaderno marimo ejecutado, con salida esperada, interpretación y conclusión.

Resumen y referencia rápida

Construcción Cuándo usarla Ejemplo
if Una condición if edad >= 18:
if/else Dos casos if ok: ... else: ...
if/elif/else Varios casos excluyentes if x < 5: ... elif x < 10: ...
Anidado Distinguir el fallo if a: if b: ...
Ternario Devolver un valor "Es" if cond else "No"
and/or/not Combinar condiciones (a > 0) and (b < 10)
match/case Comparar contra casos fijos match cmd: case "x": ...

Siguiente: 1.5 · Bucles.