Skip to content

Python de Cero a Pro - Cap.5 Operadores y Condiciones Práctica Resuelta

¡QuéPasaLinux! En este capítulo, realizaremos la práctica de los fundamentos de los operadores y las estructuras de control en Python. Es una forma práctica de aplicar los conceptos teóricos aprendidos en el capítulo anterior.

Volver a Página Principal

Ver Codigo en GitLab

✅ Hoja de Respuestas: Ejercicios de Capacitación

Section titled “✅ Hoja de Respuestas: Ejercicios de Capacitación”

A continuación se presentan las soluciones técnicas a los retos planteados en la Documentación.

1. Límites de Seguridad (Módulo calculos.py)

Section titled “1. Límites de Seguridad (Módulo calculos.py)”

Objetivo: Evitar que la calculadora maneje números excesivamente grandes.

  • Modificación: Añadir una validación antes de retornar el valor.
def ejecutar_operacion(simbolo, valor_actual, nuevo_valor):
try:
# ... (lógica anterior de if/elif) ...
resultado = # (aquí se guarda el cálculo)
# Nueva validación de seguridad
if isinstance(resultado, (int, float)) and resultado > 1000000:
raise ValueError("Límite superado: El resultado es mayor a 1,000,000")
return resultado
except Exception as e:
raise e

2. Contador de Operaciones (Módulo calculadora.py)

Section titled “2. Contador de Operaciones (Módulo calculadora.py)”

Objetivo: Mostrar cuántas veces se ha operado en la sesión actual.

  • Modificación: Usar len(historial) dentro de mostrar_interfaz.
# Dentro de mostrar_interfaz, modificar la línea de información:
elif i == 2:
# Usamos len() para contar los elementos de la lista historial
txt_control = f"OPERACIONES REALIZADAS: {len(historial)}"

3. Formato de Historial (Módulo calculadora.py)

Section titled “3. Formato de Historial (Módulo calculadora.py)”

Objetivo: Cambiar la narrativa del historial de operaciones.

  • Modificación: Cambiar el diccionario de nombres y el append.
# En iniciar_calculadora, crear un mapeo de nombres:
nombres_ops = {'+': 'SUMA', '-': 'RESTA', '*': 'MULT', '/': 'DIV', '**': 'POT'}
# Al hacer el append:
nombre = nombres_ops.get(op, "OP")
historial.append(f"[{nombre}] {num}")

4. Confirmación de Salida (Módulo calculadora.py)

Section titled “4. Confirmación de Salida (Módulo calculadora.py)”

Objetivo: Implementar una validación de usuario antes de cerrar el programa.

  • Modificación: Añadir un input de confirmación en el bloque de exit.
if entrada == 'exit':
confirmar = input("¿Está seguro que desea salir? (s/n): ").lower()
if confirmar == 's':
print("Finalizando capacitación...")
break
else:
continue # Regresa al inicio del bucle

Este código final incluye todas las mejoras de la hoja de respuestas: límites de seguridad, contador de operaciones, historial formateado y confirmación de salida.

import os
# --- CAPA DE LÓGICA (Equivalente a calculos.py) ---
def ejecutar_operacion(simbolo, valor_actual, nuevo_valor):
"""Ejecuta la aritmética y valida límites de seguridad."""
try:
operaciones = {
'+': lambda a, b: a + b,
'-': lambda a, b: a - b,
'*': lambda a, b: a * b,
'/': lambda a, b: a / b,
'//': lambda a, b: a // b,
'%': lambda a, b: a % b,
'**': lambda a, b: a ** b
}
if simbolo in ['/', '//'] and nuevo_valor == 0:
raise ZeroDivisionError("No es posible dividir entre cero.")
resultado = operaciones[simbolo](valor_actual, nuevo_valor)
# Ejercicio 1: Límite de seguridad
if isinstance(resultado, (int, float)) and resultado > 1000000:
raise ValueError("Límite superado (> 1,000,000)")
return resultado
except KeyError:
raise ValueError(f"Operador '{simbolo}' no soportado.")
except Exception as e:
raise e
def validar_entrada(entrada):
"""Convierte la entrada a número de forma segura."""
try:
return float(entrada) if '.' in entrada else int(entrada)
except ValueError:
raise ValueError("Entrada no válida. Use números.")
# --- CAPA DE INTERFAZ (Equivalente a main.py) ---
def limpiar_pantalla():
# Uso de os.name para compatibilidad entre Windows (nt) y Unix (posix)
os.system('cls' if os.name == 'nt' else 'clear')
def mostrar_interfaz(acumulado, historial, mensaje=""):
limpiar_pantalla()
col1, col2 = 45, 35
filas_interfaz = 10
print("=" * (col1 + col2 + 3))
print(f"{' HISTORIAL (LOG)':^{col1}} | {' DASHBOARD DE CONTROL':^{col2}}")
print("-" * (col1 + col2 + 3))
# Obtenemos las últimas líneas del historial
items_visibles = historial[-(filas_interfaz-1):] if historial else ["Esperando datos..."]
for i in range(filas_interfaz):
txt_h = items_visibles[i] if i < len(items_visibles) else ""
txt_c = ""
# Mapeo de información en el panel derecho (Ejercicio 2)
if i == 0: txt_c = f"OP. REALIZADAS: {len(historial)}"
elif i == 1: txt_c = "COMANDOS: clear, exit"
elif i == 2: txt_c = "MODOS: +, -, *, /, //, %, **"
elif i == filas_interfaz - 1:
txt_c = f"TOTAL: {acumulado}"
print(f" {txt_h:<{col1-1}} | {txt_c}")
print("-" * (col1 + col2 + 3))
if mensaje: print(f" [AVISO]: {mensaje}")
else: print("")
def iniciar_calculadora():
acumulado, historial, error = 0, [], ""
# Mapeo para nombres de historial (Ejercicio 3)
nombres_ops = {'+': 'SUMA', '-': 'RESTA', '*': 'MULT', '/': 'DIV', '**': 'POT', '%': 'MOD', '//': 'DIV_E'}
while True:
mostrar_interfaz(acumulado, historial, error)
error = ""
entrada = input(" DIGITE OPERACIÓN >> ").strip().lower()
# Ejercicio 4: Confirmación de salida
if entrada == 'exit':
if input(" ¿Cerrar aplicación? (s/n): ").lower() == 's':
break
continue
if entrada == 'clear':
acumulado, historial = 0, []
continue
try:
op = ""
if entrada.startswith(('**', '//')):
op, num_str = entrada[:2], entrada[2:]
elif entrada[:1] in "+-*/%":
op, num_str = entrada[0], entrada[1:]
else:
# Caso: primer número de la sesión
num = validar_entrada(entrada)
if not historial:
acumulado = num
historial.append(f"[INICIO] {num}")
else: error = "Falta operador (ej: +5)"
continue
num = validar_entrada(num_str)
nuevo_total = ejecutar_operacion(op, acumulado, num)
# Formateo de historial (Ejercicio 3)
nombre_op = nombres_ops.get(op, "OP")
historial.append(f"[{nombre_op}] {num} -> {nuevo_total}")
acumulado = nuevo_total
except Exception as e:
error = str(e)
if __name__ == "__main__":
iniciar_calculadora()
  1. Refactorización: Cómo una función simple evoluciona para manejar casos de negocio (límites de 1M).
  2. UX (Experiencia de Usuario): Por qué es importante pedir confirmación antes de cerrar un programa.
  3. Análisis de Datos: Cómo transformar un símbolo técnico (+) en algo legible para un reporte ([SUMA]).
  4. Optimización: El uso de diccionarios (nombres_ops) para evitar múltiples bloques if/else.

🎓 Arquitectura y Conceptos Avanzados en Python

Section titled “🎓 Arquitectura y Conceptos Avanzados en Python”

1. El Módulo os: Interacción con el Sistema

Section titled “1. El Módulo os: Interacción con el Sistema”
  • os.name: Propiedad que detecta el sistema operativo ('nt' para Windows, 'posix' para Linux/macOS). Permite que el código sea multiplataforma.
  • os.system(): Ejecuta comandos de la terminal desde el script. Lo usamos para limpiar la pantalla (cls o clear) y crear una interfaz estática.
  • Control de Tipos: Se utiliza para verificar si una variable pertenece a un tipo específico (ej: isinstance(resultado, (int, float))).
  • Seguridad: En nuestra calculadora, asegura que solo apliquemos reglas de negocio (como el límite de 1,000,000) a valores numéricos, evitando errores al comparar cadenas o valores nulos.
  • ZeroDivisionError: Excepción estándar de Python que capturamos para evitar que el programa se detenga si el usuario intenta dividir por cero.
  • raise: Palabra clave para “lanzar” una excepción manualmente. Es útil cuando el código es técnicamente correcto pero rompe una regla lógica (como el límite de seguridad).
  • try...except: Estructura que “atrapa” los errores. Permite que la calculadora siga funcionando y muestre un aviso amigable en lugar de cerrarse con un error crítico.
  • startswith(): Método de strings para detectar prefijos. Clave para distinguir operadores de 1 carácter (+) de los de 2 caracteres (**, //).
  • append(): Método de listas para acumular el historial. Permite que la interfaz “recuerde” y muestre el progreso del usuario.
  • Diccionarios para Mapeo: Usamos nombres_ops = {'+': 'SUMA'} para transformar símbolos técnicos en nombres legibles, haciendo el código más limpio que usar múltiples if/elif.
  • F-Strings y Alineación: El uso de modificadores de formato (ej: {:<45}) garantiza que las columnas y el separador | se mantengan rectos, creando un “Dashboard” profesional en la terminal.