From 677cde4aec0433744197c985447d0d8ebc819af2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iv=C3=A1n=20Calero?= Date: Sun, 26 Oct 2025 19:05:17 +0100 Subject: [PATCH 1/8] =?UTF-8?q?Completados=20ejercicios=2001=20de=20introd?= =?UTF-8?q?ucci=C3=B3n=20a=20Python?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ejercicios_Calero/01/bigotes_felices.py | 8 ++++++++ ejercicios_Calero/01/conversor.py | 7 +++++++ ejercicios_Calero/01/eco.py | 2 ++ ejercicios_Calero/01/primer_script.py | 4 ++++ ejercicios_Calero/01/saludo_input.py | 6 ++++++ ejercicios_Calero/01/tres_prints.py | 3 +++ ejercicios_Calero/01/variables_basicas.py | 4 ++++ ejercicios_Calero/02/operaciones.py | 0 8 files changed, 34 insertions(+) create mode 100644 ejercicios_Calero/01/bigotes_felices.py create mode 100644 ejercicios_Calero/01/conversor.py create mode 100644 ejercicios_Calero/01/eco.py create mode 100644 ejercicios_Calero/01/primer_script.py create mode 100644 ejercicios_Calero/01/saludo_input.py create mode 100644 ejercicios_Calero/01/tres_prints.py create mode 100644 ejercicios_Calero/01/variables_basicas.py create mode 100644 ejercicios_Calero/02/operaciones.py diff --git a/ejercicios_Calero/01/bigotes_felices.py b/ejercicios_Calero/01/bigotes_felices.py new file mode 100644 index 0000000..aa81d0f --- /dev/null +++ b/ejercicios_Calero/01/bigotes_felices.py @@ -0,0 +1,8 @@ +nombre = input("Nombre del michi: ").strip() +edad_input = input("Edad del michi: ").strip() + +try: + edad = float(edad_input) + print(f"Gato: {nombre} (edad: {edad})") +except ValueError: + print("Edad no válida") \ No newline at end of file diff --git a/ejercicios_Calero/01/conversor.py b/ejercicios_Calero/01/conversor.py new file mode 100644 index 0000000..2c031b8 --- /dev/null +++ b/ejercicios_Calero/01/conversor.py @@ -0,0 +1,7 @@ +entrada = input("Introduce un numero: ") + +try: + numero = float(entrada) + print(f"Has introducido el numero {numero}") +except ValueError: + print("Eso no parece un nuemero válido.") \ No newline at end of file diff --git a/ejercicios_Calero/01/eco.py b/ejercicios_Calero/01/eco.py new file mode 100644 index 0000000..b3d642e --- /dev/null +++ b/ejercicios_Calero/01/eco.py @@ -0,0 +1,2 @@ +mensaje = input("Escribe algo y lo repetiré: ") +print(mensaje) \ No newline at end of file diff --git a/ejercicios_Calero/01/primer_script.py b/ejercicios_Calero/01/primer_script.py new file mode 100644 index 0000000..c72db54 --- /dev/null +++ b/ejercicios_Calero/01/primer_script.py @@ -0,0 +1,4 @@ +nombre = "Ana" + +print("Hola, Python") +print(f"Hola, {nombre}") diff --git a/ejercicios_Calero/01/saludo_input.py b/ejercicios_Calero/01/saludo_input.py new file mode 100644 index 0000000..ae2799c --- /dev/null +++ b/ejercicios_Calero/01/saludo_input.py @@ -0,0 +1,6 @@ +nombre = input("¿Cómo te llamas? ").strip() + +if nombre == "": + print("Nombre no válido") +else: + print(f"Hola, {nombre}") diff --git a/ejercicios_Calero/01/tres_prints.py b/ejercicios_Calero/01/tres_prints.py new file mode 100644 index 0000000..934a196 --- /dev/null +++ b/ejercicios_Calero/01/tres_prints.py @@ -0,0 +1,3 @@ +print("Me llamo Ana") +print("Vivo en Lima") +print("Me gusta programar en Python") \ No newline at end of file diff --git a/ejercicios_Calero/01/variables_basicas.py b/ejercicios_Calero/01/variables_basicas.py new file mode 100644 index 0000000..8d82a30 --- /dev/null +++ b/ejercicios_Calero/01/variables_basicas.py @@ -0,0 +1,4 @@ +nombre = "Ana" +ciudad = "Lima" +mensaje = f"{nombre} vive en {ciudad}" +print(mensaje) \ No newline at end of file diff --git a/ejercicios_Calero/02/operaciones.py b/ejercicios_Calero/02/operaciones.py new file mode 100644 index 0000000..e69de29 From 3b7cacff9fbd0a9809a2c522f2fc1452142e5078 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iv=C3=A1n=20Calero?= Date: Sun, 26 Oct 2025 19:33:03 +0100 Subject: [PATCH 2/8] Completados ejercicios de Python del bloque 02: Estructuras --- ejercicios_Calero/02/booleans.py | 4 ++++ ejercicios_Calero/02/casting.py | 6 ++++++ ejercicios_Calero/02/operaciones.py | 12 ++++++++++++ ejercicios_Calero/02/pesaje_bigotes_felices | 18 ++++++++++++++++++ ejercicios_Calero/02/porcentajes.py | 4 ++++ ejercicios_Calero/02/redondeo.py | 3 +++ ejercicios_Calero/02/strings.py | 4 ++++ 7 files changed, 51 insertions(+) create mode 100644 ejercicios_Calero/02/booleans.py create mode 100644 ejercicios_Calero/02/casting.py create mode 100644 ejercicios_Calero/02/pesaje_bigotes_felices create mode 100644 ejercicios_Calero/02/porcentajes.py create mode 100644 ejercicios_Calero/02/redondeo.py create mode 100644 ejercicios_Calero/02/strings.py diff --git a/ejercicios_Calero/02/booleans.py b/ejercicios_Calero/02/booleans.py new file mode 100644 index 0000000..035c308 --- /dev/null +++ b/ejercicios_Calero/02/booleans.py @@ -0,0 +1,4 @@ +a = 10 +b = 3 +print(a >= b) +print(a == b) \ No newline at end of file diff --git a/ejercicios_Calero/02/casting.py b/ejercicios_Calero/02/casting.py new file mode 100644 index 0000000..f5e90dc --- /dev/null +++ b/ejercicios_Calero/02/casting.py @@ -0,0 +1,6 @@ +entrada = input("Introduce un número entero: ").strip() +try: + numero = int(entrada) + print(f"Número válido: {numero}") +except ValueError: + print("Entrada no válida") \ No newline at end of file diff --git a/ejercicios_Calero/02/operaciones.py b/ejercicios_Calero/02/operaciones.py index e69de29..89aa1ca 100644 --- a/ejercicios_Calero/02/operaciones.py +++ b/ejercicios_Calero/02/operaciones.py @@ -0,0 +1,12 @@ +a = 10 +b = 3 + +suma = a + b +resta = a - b +multiplicacion = a * b +division = round(a / b, 2) + +print(f"Suma: {suma}") +print(f"Resta: {resta}") +print(f"Multplicacion: {multiplicacion}") +print(f"Division = {division}") \ No newline at end of file diff --git a/ejercicios_Calero/02/pesaje_bigotes_felices b/ejercicios_Calero/02/pesaje_bigotes_felices new file mode 100644 index 0000000..28fda2b --- /dev/null +++ b/ejercicios_Calero/02/pesaje_bigotes_felices @@ -0,0 +1,18 @@ +def leer_peso(gato_num): + entrada = input(f"Peso del michi {gato_num} (kg): ").strip().replace(",", ".") + try: + peso = float(entrada) + return peso + except ValueError: + print("¡Pon un valor válido para el peso del michi!") + return None + +pesos = [] +for i in range (1, 4): + peso_valido = None + while peso_valido is None: + peso_valido = leer_peso(i) + pesos.append(peso_valido) + +promedio = round(sum(pesos) / len(pesos), 2) +print(f"Peso promedio de los gatos: {promedio} kg") \ No newline at end of file diff --git a/ejercicios_Calero/02/porcentajes.py b/ejercicios_Calero/02/porcentajes.py new file mode 100644 index 0000000..e64157e --- /dev/null +++ b/ejercicios_Calero/02/porcentajes.py @@ -0,0 +1,4 @@ +cantidad = 200 +porcentaje = 0.15 +resultado = cantidad * porcentaje +print(f"El 15% de {cantidad} es {resultado}") \ No newline at end of file diff --git a/ejercicios_Calero/02/redondeo.py b/ejercicios_Calero/02/redondeo.py new file mode 100644 index 0000000..3717675 --- /dev/null +++ b/ejercicios_Calero/02/redondeo.py @@ -0,0 +1,3 @@ +pi = 3.14159 +pi_redondeado = round(pi, 3) +print(pi_redondeado) \ No newline at end of file diff --git a/ejercicios_Calero/02/strings.py b/ejercicios_Calero/02/strings.py new file mode 100644 index 0000000..460279b --- /dev/null +++ b/ejercicios_Calero/02/strings.py @@ -0,0 +1,4 @@ +nombre = "Iván" +apellido = "Calero" +nombre_completo = f"{nombre} {apellido}".title() +print(nombre_completo) \ No newline at end of file From ecf7c2669cd033b041fbd63955f89b362547f542 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iv=C3=A1n=20Calero?= Date: Tue, 28 Oct 2025 13:07:05 +0100 Subject: [PATCH 3/8] feat: ejercicio 03 completado y calculadora v1, v2 y v3 --- 01_intro/ejercicio_guiado/calculadora_v1.py | 11 +++-- .../ejercicio_guiado/calculadora_v2.py | 20 ++++++-- .../ejercicio_guiado/calculadora_v3.py | 46 +++++++++++++++---- ...otes_felices => pesaje_bigotes_felices.py} | 0 ejercicios_Calero/03/clasificador_simple.py | 10 ++++ ejercicios_Calero/03/suma_acumulada.py | 13 ++++++ 6 files changed, 82 insertions(+), 18 deletions(-) rename ejercicios_Calero/02/{pesaje_bigotes_felices => pesaje_bigotes_felices.py} (100%) create mode 100644 ejercicios_Calero/03/clasificador_simple.py create mode 100644 ejercicios_Calero/03/suma_acumulada.py diff --git a/01_intro/ejercicio_guiado/calculadora_v1.py b/01_intro/ejercicio_guiado/calculadora_v1.py index cb19414..7a57ee1 100644 --- a/01_intro/ejercicio_guiado/calculadora_v1.py +++ b/01_intro/ejercicio_guiado/calculadora_v1.py @@ -21,25 +21,26 @@ # TODO 1: Pide el primer número al usuario # Pista: usa input() y guarda el valor en una variable # primer_numero = ... - +num1 = input("¿Cuál es el primer número?: ") # TODO 2: Pide el segundo número al usuario # segundo_numero = ... - +num2 = input("¿Y el segundo número?: ") # TODO 3: Convierte los strings a números decimales # Pista: usa float() para permitir decimales (ej: 3.5) # num1 = float(primer_numero) # num2 = ... - +num1 = float(num1) +num2 = float(num2) # TODO 4: Realiza la suma # resultado = ... - +resultado = num1 + num2 # TODO 5: Muestra el resultado # Pista: print("El resultado es:", resultado) - +print("Resultado:", resultado) # ¡Ya está! Ejecuta el programa y prueba con diferentes números # Ejemplos para probar: diff --git a/02_estructuras/ejercicio_guiado/calculadora_v2.py b/02_estructuras/ejercicio_guiado/calculadora_v2.py index 424d58f..cf73c24 100644 --- a/02_estructuras/ejercicio_guiado/calculadora_v2.py +++ b/02_estructuras/ejercicio_guiado/calculadora_v2.py @@ -20,16 +20,16 @@ # TODO 1: Pide el primer número al usuario y conviértelo a float # num1 = ... - +num1 = float(input("Primer número: ")) # TODO 2: Pide el segundo número al usuario y conviértelo a float # num2 = ... - +num2 = float(input("Segundo número: ")) # TODO 3: Pregunta qué operación desea realizar # Pista: input("¿Qué operación deseas realizar? (+, -, *, /): ") # operacion = ... - +operacion = input("¿Cuál de las operaciones quieres realizar? ¿Sumar, restar, multplicar o dividir?: ") # TODO 4: Realiza la operación correspondiente usando if/elif/else # Pista: Compara la variable 'operacion' con "+", "-", "*", "/" @@ -45,12 +45,24 @@ # else: # print("❌ Operación no válida") +if operacion == "+": + resultado = num1 + num2 +elif operacion == "-": + resultado = num1 - num2 +elif operacion == "*": + resultado = num1 * num2 +elif operacion == "/": + resultado = num1 / num2 +else: + print("No es válida esa operación") + resultado = None # TODO 5: Muestra el resultado usando f-strings # Pista: f"El resultado de {num1} {operacion} {num2} = {resultado:.2f}" # El :.2f muestra solo 2 decimales # print(f"...") - +if resultado is not None: + print(f"El resultado de {num1} {operacion} {num2} = {resultado:.2f}") # ¡Perfecto! Ahora tu calculadora puede hacer las 4 operaciones básicas # diff --git a/03_control_flujo/ejercicio_guiado/calculadora_v3.py b/03_control_flujo/ejercicio_guiado/calculadora_v3.py index 02191bc..b299ebd 100644 --- a/03_control_flujo/ejercicio_guiado/calculadora_v3.py +++ b/03_control_flujo/ejercicio_guiado/calculadora_v3.py @@ -24,7 +24,7 @@ # TODO 1: Crea el bucle principal # while True: # # Todo el código va aquí dentro - +while True: # TODO 2: Muestra el menú # print("\n=== CALCULADORA ===") @@ -33,34 +33,52 @@ # print("3. Multiplicar") # print("4. Dividir") # print("5. Salir") + + + print("\n=== CALCULADORA ===") + print("1. Sumar") + print("2. Restar") + print("3. Multiplicar") + print("4. Dividir") + print("5. Salir") + # TODO 3: Pide la opción al usuario # opcion = input("\nElige una opción: ") - + opcion = input("\nElige una opción: ") # TODO 4: Si elige salir (opción 5), termina el programa # if opcion == "5": # print("¡Hasta pronto! 👋") # break # Sale del bucle while - + if opcion == "5": + print("¡Hasta pronto!") + break # TODO 5: Valida que la opción sea válida (1, 2, 3 o 4) # if opcion not in ["1", "2", "3", "4"]: # print("❌ Opción no válida. Intenta de nuevo.") # continue # Vuelve al inicio del bucle (muestra el menú de nuevo) - + if opcion not in ["1", "2", "3", "4"]: + print("Opción no válida. Intentalo de nuevo.") # TODO 6: Pide los dos números # num1 = float(input("Primer número: ")) # num2 = float(input("Segundo número: ")) - + try: + num1 = float(input("Primer número: ")) + num2 = float(input("Segund número: ")) + except ValueError: + print("Incorrecto.") # TODO 7: Controla la división por cero # if opcion == "4" and num2 == 0: # print("❌ Error: No se puede dividir por cero") # continue # Vuelve al menú sin hacer la operación - + if opcion == "4" and num2 == 0: + print("No se puede dividir por cero.") + continue # TODO 8: Realiza la operación según la opción elegida # if opcion == "1": @@ -75,11 +93,21 @@ # elif opcion == "4": # resultado = num1 / num2 # simbolo = "/" - - + if opcion == "1": + resultado = num1 + num2 + simbolo = "+" + elif opcion == "2": + resultado = num1 - num2 + simbolo = "-" + elif opcion == "3": + resultado = num1 * num2 + simbolo = "*" + elif opcion == "4": + resultado = num1 / num2 + simbolo = "/" # TODO 9: Muestra el resultado con f-string # print(f"✅ {num1} {simbolo} {num2} = {resultado:.2f}") - + print(f"{num1} {simbolo} {num2} = {resultado:.2f}") # ¡Excelente trabajo! Ahora tienes una calculadora interactiva que: # - Se repite hasta que el usuario quiera salir diff --git a/ejercicios_Calero/02/pesaje_bigotes_felices b/ejercicios_Calero/02/pesaje_bigotes_felices.py similarity index 100% rename from ejercicios_Calero/02/pesaje_bigotes_felices rename to ejercicios_Calero/02/pesaje_bigotes_felices.py diff --git a/ejercicios_Calero/03/clasificador_simple.py b/ejercicios_Calero/03/clasificador_simple.py new file mode 100644 index 0000000..1ffa389 --- /dev/null +++ b/ejercicios_Calero/03/clasificador_simple.py @@ -0,0 +1,10 @@ +try: + numero = float(input("¿Qué número eliges?: ")) + if numero > 0: + print("¡El número es positivo!") + elif numero < 0: + print("¡El número es negativo!") + elif numero == 0: + print("¡El número es cero!") +except ValueError: + print("¡Entrada no válida!") \ No newline at end of file diff --git a/ejercicios_Calero/03/suma_acumulada.py b/ejercicios_Calero/03/suma_acumulada.py new file mode 100644 index 0000000..a7112e8 --- /dev/null +++ b/ejercicios_Calero/03/suma_acumulada.py @@ -0,0 +1,13 @@ +suma_total = 0.0 +while True: + entrada = input("¿Número?") + if entrada.lower() == "Acabose": + break + + try: + numero = float(entrada) + suma_total += numero + except ValueError: + print("Hay un error. Escribe un numero.") + +print(f"La suma total es: {suma_total:.2f}") From a032e1dce5bc2024ee67000fbd4bb26ab05858c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iv=C3=A1n=20Calero?= Date: Tue, 28 Oct 2025 16:22:44 +0100 Subject: [PATCH 4/8] feat: ejercicio 04 y calculadora v4 completado --- .../ejercicio_guiado/calculadora_v4.py | 57 ++++++++++++++++--- ejercicios_Calero/04/autonomos.py | 30 ++++++++++ .../04/filtrar_michis_bigotesfelices.py | 4 ++ ejercicios_Calero/04/funcion_saludo.py | 3 + ejercicios_Calero/04/sumar_lista.py | 6 ++ 5 files changed, 92 insertions(+), 8 deletions(-) create mode 100644 ejercicios_Calero/04/autonomos.py create mode 100644 ejercicios_Calero/04/filtrar_michis_bigotesfelices.py create mode 100644 ejercicios_Calero/04/funcion_saludo.py create mode 100644 ejercicios_Calero/04/sumar_lista.py diff --git a/04_funciones/ejercicio_guiado/calculadora_v4.py b/04_funciones/ejercicio_guiado/calculadora_v4.py index de137ba..24a99e8 100644 --- a/04_funciones/ejercicio_guiado/calculadora_v4.py +++ b/04_funciones/ejercicio_guiado/calculadora_v4.py @@ -24,7 +24,7 @@ def sumar(a, b): """Suma dos números. - + Args: a: Primer número b: Segundo número @@ -33,20 +33,21 @@ def sumar(a, b): La suma de a y b """ # return a + b - pass # Borra esto y escribe el return + pass + return a + b def restar(a, b): """Resta dos números.""" # TODO: Implementa la resta pass - + return a - b def multiplicar(a, b): """Multiplica dos números.""" # TODO: Implementa la multiplicación pass - + return a * b def dividir(a, b): """Divide dos números. @@ -60,7 +61,7 @@ def dividir(a, b): """ # TODO: Implementa la división pass - + return a / b # TODO 2: Crea una función para mostrar el menú def mostrar_menu(): @@ -72,6 +73,12 @@ def mostrar_menu(): # print("4. Dividir") # print("5. Salir") pass + print("\n=== CALCULADORA ===") + print("1. Sumar") + print("2. Restar") + print("3. Multiplicar") + print("4. Dividir") + print("5. Salir") # TODO 3: Crea una función para obtener dos números del usuario @@ -85,7 +92,13 @@ def obtener_numeros(): # num2 = float(input("Segundo número: ")) # return num1, num2 pass - + try: + num1 = float(input("Primer número: ")) + num2 = float(input("Segundo: ")) + return num1, num2 + except ValueError: + print("Entrada incorrecta.") + return obtener_numeros() # TODO 4: Crea la función principal que contiene el bucle del programa def main(): @@ -135,13 +148,41 @@ def main(): # print(f"✅ {num1} {simbolo} {num2} = {resultado:.2f}") pass - + while True: + mostrar_menu() + opcion = input("\nElige una opción: ") + if opcion == 5: + print("¡Hasta pronto!") + break + if opcion not in ["1", "2", "3", "4"]: + print("¡Opción no válida!") + continue + num1, num2 = obtener_numeros() + + if opcion == "4" and num2 == 0: + print("No se puede dividir por cero...") + continue + if opcion == "1": + resultado = sumar(num1, num2) + simbolo = "+" + elif opcion == "2": + resultado = restar(num1, num2) + simbolo = "-" + elif opcion == "3": + resultado = multiplicar(num1, num2) + simbolo = "*" + elif opcion == "4": + resultado = dividir(num1, num2) + simbolo = "/" + + print(f"{num1} {simbolo} {num2} = {resultado:.2f}") # TODO 5: Punto de entrada del programa # Este patrón permite que el archivo sea importable sin ejecutarse automáticamente # if __name__ == "__main__": # main() - +if __name__ == "__main__": + main() # ¡Excelente! Has refactorizado tu calculadora con funciones. # diff --git a/ejercicios_Calero/04/autonomos.py b/ejercicios_Calero/04/autonomos.py new file mode 100644 index 0000000..39e1d62 --- /dev/null +++ b/ejercicios_Calero/04/autonomos.py @@ -0,0 +1,30 @@ +# 1. `es_par(n)` -> bool + +def es_par(n): + return n % 2 == 0 + +# 2. `area_rectangulo(a, b)` + +def area_rectangulo(a,b): + return a * b + +# 3. `formatear_gato(nombre, edad)` -> string con f-string + +def formatear_gato(nombre, edad): + return f"El michi se llama {nombre} y tiene {edad} años." + +# 4. `promedio(nums)` con manejo de lista vacía + +def promedio(nums): + if not nums: + return None + return sum(nums) / len(nums) + +# 5. `leer_edad()` pide una edad por `input()`, valida `ValueError` y retorna un entero o `None`. + +def leer_edad(): + try: + edad = int(imput("¿Cuál es tu edad?: ")) + return edad + except ValueError: + return None \ No newline at end of file diff --git a/ejercicios_Calero/04/filtrar_michis_bigotesfelices.py b/ejercicios_Calero/04/filtrar_michis_bigotesfelices.py new file mode 100644 index 0000000..c923ade --- /dev/null +++ b/ejercicios_Calero/04/filtrar_michis_bigotesfelices.py @@ -0,0 +1,4 @@ +def filtrar_michis(gatos): + if not isinstance(gatos, list): + raise TypeError("¡Estaba espreando lista de michis!") + return [gato for gato in gatos if isinstance(gato, dict) and gato.get('edad', 0) > 5] \ No newline at end of file diff --git a/ejercicios_Calero/04/funcion_saludo.py b/ejercicios_Calero/04/funcion_saludo.py new file mode 100644 index 0000000..18390a8 --- /dev/null +++ b/ejercicios_Calero/04/funcion_saludo.py @@ -0,0 +1,3 @@ +def saludar(nombre): + return f"Hola, {nombre}" +print(saludar("Cale")) \ No newline at end of file diff --git a/ejercicios_Calero/04/sumar_lista.py b/ejercicios_Calero/04/sumar_lista.py new file mode 100644 index 0000000..9f32bc0 --- /dev/null +++ b/ejercicios_Calero/04/sumar_lista.py @@ -0,0 +1,6 @@ +def sumar(nums): + if not isinstance(nums, list): + raise TypeError("Debe ser una lista") + return sum(nums) + +print(sumar([1, 2, 3])) \ No newline at end of file From 496e8639cbf54f232fcca5d760f7e18130bc8bb1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iv=C3=A1n=20Calero?= Date: Tue, 28 Oct 2025 17:09:58 +0100 Subject: [PATCH 5/8] feat: ejercicio 05 y calculadora v5 completado --- .../ejercicio_guiado/calculadora_v5.py | 52 +++++++++++++++++-- ejercicios_Calero/05/autonomos.py | 31 +++++++++++ ejercicios_Calero/05/diccionario_simple.py | 8 +++ ejercicios_Calero/05/lista_michis.py | 3 ++ 4 files changed, 91 insertions(+), 3 deletions(-) create mode 100644 ejercicios_Calero/05/autonomos.py create mode 100644 ejercicios_Calero/05/diccionario_simple.py create mode 100644 ejercicios_Calero/05/lista_michis.py diff --git a/05_colecciones/ejercicio_guiado/calculadora_v5.py b/05_colecciones/ejercicio_guiado/calculadora_v5.py index 3caf649..92d74e4 100644 --- a/05_colecciones/ejercicio_guiado/calculadora_v5.py +++ b/05_colecciones/ejercicio_guiado/calculadora_v5.py @@ -66,7 +66,7 @@ def obtener_numeros(): # TODO 1: Crea una lista global para almacenar el historial # (Nota: en programación avanzada evitamos globales, pero aquí es didáctico) # historial = [] - +historial = [] def guardar_operacion(num1, num2, operacion, resultado): """Guarda una operación en el historial. @@ -77,6 +77,7 @@ def guardar_operacion(num1, num2, operacion, resultado): operacion: Símbolo de la operación (+, -, *, /) resultado: Resultado de la operación """ + # TODO 2: Crea un diccionario con los datos de la operación # operacion_dict = { # "num1": num1, @@ -84,11 +85,20 @@ def guardar_operacion(num1, num2, operacion, resultado): # "operacion": operacion, # "resultado": resultado # } + # TODO 3: Añade el diccionario a la lista historial # historial.append(operacion_dict) pass + operacion_dict = { + "num1": num1, + "num2": num2, + "operacion": operacion, + "resultado": resultado + } + historial.append(operacion_dict) + def mostrar_historial(): @@ -108,7 +118,12 @@ def mostrar_historial(): # print(f"{i}. {op['num1']} {op['operacion']} {op['num2']} = {op['resultado']:.2f}") pass - + if not historial: + print("No hay operaciones en el historial") + return + print("\nHistorial de operaciones") + for i, op in enumerate(historial, 1): + print(f"{i}. {op['num1']} {op['operacion']} {op['num2']} = {op['resultado']:.2f}") # ===== FUNCIÓN PRINCIPAL ===== @@ -160,7 +175,38 @@ def main(): # guardar_operacion(num1, num2, simbolo, resultado) pass - + while True: + mostrar_menu() + opcion = input("\nElige una opción: ") + if opcion == "6": + print("¡See you soon!") + break + if opcion == "5": + mostrar_historial() + continue + if opcion not in ["1", "2", "3", "4"]: + print("Opción no válida") + continue + + num1, num2 = obtener_numeros() + + if opcion == "4" and num2 == 0: + print("No se puede dividir entre cero...") + + if opcion == "1": + resultado = sumar(num1, num2) + simbolo = "+" + elif opcion == "2": + resultado = restar(num1, num2) + simbolo = "-" + elif opcion == "3": + resultado = multiplicar(num1, num2) + simbolo = "*" + elif opcion == "4": + resultado = dividir(num1, num2) + simbolo = "/" + + print(f"{num1} {simbolo} {num2} ? {resultado:.2f}") if __name__ == "__main__": main() diff --git a/ejercicios_Calero/05/autonomos.py b/ejercicios_Calero/05/autonomos.py new file mode 100644 index 0000000..3f6704a --- /dev/null +++ b/ejercicios_Calero/05/autonomos.py @@ -0,0 +1,31 @@ +# 1 +vacunas = {"rabia", "leucemia", "panleucopenia"} +print("rabia" in vacunas) #sería verdadero: True. +print("parvovirus" in vacunas) #sería falso: False. + +# 2 +nombres = ["Michifuchi", "Peludo", "Catanga", "Furro"] +edades = [3, 7, 1, 18] +michis = dict(zip(nombres, edades)) +print(michis) + +# 3 +texto = "Soy un michi feliz" +contador = {} +for letra in texto: + if letra != " ": + contador[letra] = contador.get(letra, 0) + 1 +print(contador) + +# 4 +michis = ["Michifuchi", "Fuchimichi", "Pelúo", "Garra mortal"] +ultimos = michis[-3] +print(ultimos) + +michi_Mayus = [nombre.upper() for nombre in michis] +print(michi_Mayus) + +# 5 +michis = {"Michifurri": 14, "Pelúo": 32, "Garra mortal": 2} +for nombre, edad in michis.items(): + print(f"{nombre} tiene {edad} años.") \ No newline at end of file diff --git a/ejercicios_Calero/05/diccionario_simple.py b/ejercicios_Calero/05/diccionario_simple.py new file mode 100644 index 0000000..3a72a63 --- /dev/null +++ b/ejercicios_Calero/05/diccionario_simple.py @@ -0,0 +1,8 @@ +michi = {"nombre": "Michifuchi", "edad": 3} +nombre = michi.get("nombre") +edad = michi.get("edad") +tamaño = michi.get("tamaño") + +print(f"nombre: {nombre}") +print(f"edad: {edad}") +print(f"tamañaco: {tamaño}") \ No newline at end of file diff --git a/ejercicios_Calero/05/lista_michis.py b/ejercicios_Calero/05/lista_michis.py new file mode 100644 index 0000000..e6d3546 --- /dev/null +++ b/ejercicios_Calero/05/lista_michis.py @@ -0,0 +1,3 @@ +michis = ["Peludo", "Bigotes", "Michifuchi"] +for i, nombre in enumerate(michis): + print(f"{i}: {nombre}") \ No newline at end of file From d466dd0805503287b75307513d5d135a1813e798 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iv=C3=A1n=20Calero?= Date: Tue, 28 Oct 2025 17:50:17 +0100 Subject: [PATCH 6/8] feat: ejercicio 06 y calculadura v6 completado --- .../ejercicio_guiado/calculadora_v6.py | 72 +++++++++++++++++-- ejercicios_Calero/05/pesos_bigotes_felices.py | 6 ++ ejercicios_Calero/06/autonomos.py | 32 +++++++++ ejercicios_Calero/06/escribir_archivo.py | 5 ++ ejercicios_Calero/06/leer_archivo.py | 3 + 5 files changed, 112 insertions(+), 6 deletions(-) create mode 100644 ejercicios_Calero/05/pesos_bigotes_felices.py create mode 100644 ejercicios_Calero/06/autonomos.py create mode 100644 ejercicios_Calero/06/escribir_archivo.py create mode 100644 ejercicios_Calero/06/leer_archivo.py diff --git a/06_archivos_y_modulos/ejercicio_guiado/calculadora_v6.py b/06_archivos_y_modulos/ejercicio_guiado/calculadora_v6.py index 27d34ed..f29b8f0 100644 --- a/06_archivos_y_modulos/ejercicio_guiado/calculadora_v6.py +++ b/06_archivos_y_modulos/ejercicio_guiado/calculadora_v6.py @@ -22,7 +22,8 @@ # TODO 1: Importa el módulo json # import json - +import json +import os # Nombre del archivo donde se guardará el historial ARCHIVO_HISTORIAL = "historial_calculadora.json" @@ -122,8 +123,17 @@ def cargar_historial(): # return [] pass - return [] # Borra esto cuando implementes la función - + try: + with open(ARCHIVO_HISTORIAL, "r", enconding="utf-8") as archivo: + datos = json.load(archivo) + print(f"Historial cargado: {len(datos)} operaciones") + return datos + except FileNotFoundError: + print("No hay historial") + return [] + except json.JSONDecodeError: + print("Historial corrupto") + return [] def guardar_historial_archivo(): """Guarda el historial actual en el archivo JSON.""" @@ -138,7 +148,12 @@ def guardar_historial_archivo(): # print(f"❌ Error al guardar el historial: {e}") pass - + try: + with open(ARCHIVO_HISTORIAL, "w", enconding="utf-8") as archivo: + json.dump(historial, archivo, indent=2, ensure_ascii=False) + print("Historial guardado") + except Exception as e: + print(f"Error al guardar historial. {e}") def limpiar_historial(): """Limpia el historial en memoria y elimina el archivo.""" @@ -163,7 +178,10 @@ def limpiar_historial(): # print(f"❌ Error al eliminar el archivo: {e}") pass - + confirmacion = input("¿Quieres borrar historial?") + if confirmacion.lower() != "s": + print("Cancelado") + return # ===== FUNCIÓN PRINCIPAL ===== @@ -224,7 +242,49 @@ def main(): # guardar_operacion(num1, num2, simbolo, resultado) pass - + global historial + print("Cargando historial...") + historial = cargar_historial() + + while True: + mostrar_menu() + opcion = input("\nElige una opción: ") + + if opcion == "7": + print("Guardando historial") + guardar_historial_archivo() + print("See you soon!!") + break + if opcion == "5": + mostrar_historial() + continue + if opcion == "6": + limpiar_historial() + continue + if opcion not in ["1", "2", "3", "4"]: + print("Opción no válida") + continue + + num1, num2 = obtener_numeros() + + if opcion == "4" and num2 == 0: + print("No se puede dividr entre cero") + continue + if opcion == "1": + resultado == sumar(num1, num2) + simbolo = "+" + elif opcion == "2": + resultado = restar(num1, num2) + simbolo = "-" + elif opcion == "3": + resultado == multiplicar(num1, num2) + simbolo = "*" + elif opcion == "4": + resultado == dividir(num1, num2) + simbolo = "/" + + print(f"{num1} {simbolo} {num2} = {resultado:.2f}") + guardar_operacion(num1, num2, simbolo, resultado) if __name__ == "__main__": main() diff --git a/ejercicios_Calero/05/pesos_bigotes_felices.py b/ejercicios_Calero/05/pesos_bigotes_felices.py new file mode 100644 index 0000000..358862b --- /dev/null +++ b/ejercicios_Calero/05/pesos_bigotes_felices.py @@ -0,0 +1,6 @@ +pesos_michis = [3.5, 33.2, 4.0, 6.6, 8.4, 7.6, 1.2] +pesos_ordenados = sorted(pesos_michis, reverse=True) +top3 = pesos_ordenados[:3] +print("Los tres michis mas gordacos son: ") +for i, peso in enumerate(top3, 1): + print(f"{i}. {peso} kg") \ No newline at end of file diff --git a/ejercicios_Calero/06/autonomos.py b/ejercicios_Calero/06/autonomos.py new file mode 100644 index 0000000..610f50b --- /dev/null +++ b/ejercicios_Calero/06/autonomos.py @@ -0,0 +1,32 @@ +# 1 +with open("michis.csv", "w", enconding="utf-8") as archivo: + archivo.write("Nombre,Edad\n") + archivo.write("Michi, 2\n") + archivo.write("Michifurri, 5\n") + archivo.wirte("Furrimichi 12\n") + +# 2 +def leer_lineas(ruta): + with open(ruta, "r", encoding="utf-8") as archivo: + return archivo.areadlines() + +def guardar_lineas(ruta, lineas): + with open(ruta, "w", enconding="utf-8") as archivo: + for linea in lineas: + archivo.write(linea + "\n") + +# 3 +import os +import utiles + +ruta = input("Ruta archivo: ") +if not os.path.exists(ruta): + print("La ruta no es correcta.") +else: + try: + lineas = utiles.leer_lineas(ruta) + print("Contenido del arhcivo: ") + for i, linea in enumerate(lineas, 1): + print(f"{i}. {linea.strip()}") + except FileNotFound: + print("Lo siento compi no se pudo abrir el archivo") \ No newline at end of file diff --git a/ejercicios_Calero/06/escribir_archivo.py b/ejercicios_Calero/06/escribir_archivo.py new file mode 100644 index 0000000..165b4ec --- /dev/null +++ b/ejercicios_Calero/06/escribir_archivo.py @@ -0,0 +1,5 @@ +with open("escribir.txt", "w", enconding="utf-8") as archivo: #el open("escribir.txt", "w" abre archivo en formato escritura (lo crea o lo sobrescribee) + + archivo.write("Primera línea\n") + archivo.write("Segunda línea\n") + archivo.write("Tercera línea\n") \ No newline at end of file diff --git a/ejercicios_Calero/06/leer_archivo.py b/ejercicios_Calero/06/leer_archivo.py new file mode 100644 index 0000000..7bd30ba --- /dev/null +++ b/ejercicios_Calero/06/leer_archivo.py @@ -0,0 +1,3 @@ +with open("escribir.txt", "r", encoding="utf-8") as archivo: #"r" modo lectura.. + for i, linea in enumerate(archivo, 1): + print(f"{i}. {linea.strip()}") \ No newline at end of file From efb4539d3966455bbd6cfcea8574d4fee34cea58 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iv=C3=A1n=20Calero?= Date: Tue, 28 Oct 2025 18:06:05 +0100 Subject: [PATCH 7/8] feat: ejercicio 07 completado --- 07_mini_proyectos/MODULO.md | 2 + ejercicios_Calero/07/log_parser.py | 75 +++++++++++++++++++++++++++++ ejercicios_Calero/07/michi_stats.py | 45 +++++++++++++++++ ejercicios_Calero/07/tickets.py | 75 +++++++++++++++++++++++++++++ 4 files changed, 197 insertions(+) create mode 100644 ejercicios_Calero/07/log_parser.py create mode 100644 ejercicios_Calero/07/michi_stats.py create mode 100644 ejercicios_Calero/07/tickets.py diff --git a/07_mini_proyectos/MODULO.md b/07_mini_proyectos/MODULO.md index fafb47a..bf222fa 100644 --- a/07_mini_proyectos/MODULO.md +++ b/07_mini_proyectos/MODULO.md @@ -1,3 +1,5 @@ # 07_mini_proyectos Aquí integrarás lo aprendido en mini-retos de 60–90 minutos. Revisa `retos.md`. + + diff --git a/ejercicios_Calero/07/log_parser.py b/ejercicios_Calero/07/log_parser.py new file mode 100644 index 0000000..defc58d --- /dev/null +++ b/ejercicios_Calero/07/log_parser.py @@ -0,0 +1,75 @@ +import json +import os + +def cargar_tickets(fichero="tickets.json"): + if os.path.exists(fichero): + with open(fichero, "r", encoding="utf-8") as f: + return json.load(f) + return [] + +def guardar_tickets(tickets, fichero="tickets.json"): + with open(fichero, "w", encoding="utf-8") as f: + json.dump(tickets, f, ensure_ascii=False, indent=2) + +def generar_nuevo_id(tickets): + if not tickets: + return 1 + ids = [t["id"] for t in tickets] + return max(ids) + 1 + +def crear_ticket(tickets): + titulo = input("Título del ticket: ") + nuevo = { + "id": generar_nuevo_id(tickets), + "titulo": titulo, + "estado": "abierto" + } + tickets.append(nuevo) + print(f"✅ Ticket creado con id {nuevo['id']}") + +def listar_tickets(tickets): + if not tickets: + print("No hay tickets.") + return + for t in tickets: + print(f"[{t['id']}] {t['titulo']} - {t['estado']}") + +def cerrar_ticket(tickets): + try: + tid = int(input("ID del ticket a cerrar: ")) + except ValueError: + print("ID inválido.") + return + for t in tickets: + if t["id"] == tid: + t["estado"] = "cerrado" + print(f"🔒 Ticket {tid} cerrado.") + return + print("No existe ese ID.") + +def menu_tickets(): + tickets = cargar_tickets() + + while True: + print("\n=== SISTEMA DE TICKETS ===") + print("1) Crear ticket") + print("2) Listar tickets") + print("3) Cerrar ticket") + print("4) Salir") + opcion = input("> ") + + if opcion == "1": + crear_ticket(tickets) + elif opcion == "2": + listar_tickets(tickets) + elif opcion == "3": + cerrar_ticket(tickets) + elif opcion == "4": + guardar_tickets(tickets) + print("Guardado. ¡Hasta luego!") + break + else: + print("Opción no válida.") + +if __name__ == "__main__": + menu_tickets() diff --git a/ejercicios_Calero/07/michi_stats.py b/ejercicios_Calero/07/michi_stats.py new file mode 100644 index 0000000..ecdb8c3 --- /dev/null +++ b/ejercicios_Calero/07/michi_stats.py @@ -0,0 +1,45 @@ +def calcular_media(valores): + return sum(valores) / len(valores) if valores else 0 + +def calcular_mediana(valores): + if not valores: + return 0 + ordenados = sorted(valores) + n = len(ordenados) + mitad = n // 2 + if n % 2 == 1: + return ordenados[mitad] + else: + return (ordenados[mitad - 1] + ordenados[mitad]) / 2 + +def resumen_refugio(michis, k_top=3, guardar=False, fichero_salida="resumen_refugio.txt"): + pesos = [m["peso"] for m in michis] + edades = [m["edad"] for m in michis] + + total = len(michis) + peso_medio = calcular_media(pesos) + edad_media = calcular_media(edades) + peso_mediano = calcular_mediana(pesos) + + michis_ordenados = sorted(michis, key=lambda m: m["peso"], reverse=True) + top_k = michis_ordenados[:k_top] + + informe = [] + informe.append(f"Total de michis: {total}") + informe.append(f"Peso medio: {peso_medio:.2f} kg") + informe.append(f"Peso mediano: {peso_mediano:.2f} kg") + informe.append(f"Edad media: {edad_media:.2f} años") + informe.append(f"Top {k_top} michis más pesados:") + for michi in top_k: + informe.append(f" - {michi['nombre']}: {michi['peso']} kg ({michi['edad']} años)") + informe_texto = "\n".join(informe) + + print(informe_texto) + + if guardar: + with open(fichero_salida, "w", encoding="utf-8") as f: + f.write(informe_texto) + + +if __name__ == "__main__": + pass diff --git a/ejercicios_Calero/07/tickets.py b/ejercicios_Calero/07/tickets.py new file mode 100644 index 0000000..b7206dc --- /dev/null +++ b/ejercicios_Calero/07/tickets.py @@ -0,0 +1,75 @@ +import json +import os + +def cargar_tickets(fichero="tickets.json"): + if os.path.exists(fichero): + with open(fichero, "r", encoding="utf-8") as f: + return json.load(f) + return [] + +def guardar_tickets(tickets, fichero="tickets.json"): + with open(fichero, "w", encoding="utf-8") as f: + json.dump(tickets, f, ensure_ascii=False, indent=2) + +def generar_nuevo_id(tickets): + if not tickets: + return 1 + ids = [t["id"] for t in tickets] + return max(ids) + 1 + +def crear_ticket(tickets): + titulo = input("Título del ticket: ") + nuevo = { + "id": generar_nuevo_id(tickets), + "titulo": titulo, + "estado": "abierto" + } + tickets.append(nuevo) + print(f"Ticket creado con id {nuevo['id']}") + +def listar_tickets(tickets): + if not tickets: + print("No hay tickets.") + return + for t in tickets: + print(f"[{t['id']}] {t['titulo']} - {t['estado']}") + +def cerrar_ticket(tickets): + try: + tid = int(input("ID del ticket a cerrar: ")) + except ValueError: + print("ID inválido.") + return + for t in tickets: + if t["id"] == tid: + t["estado"] = "cerrado" + print(f"🔒 Ticket {tid} cerrado.") + return + print("No existe ese ID.") + +def menu_tickets(): + tickets = cargar_tickets() + + while True: + print("\n=== TICKETS ===") + print("1) Crear ticket") + print("2) Listar tickets") + print("3) Cerrar ticket") + print("4) Salir") + opcion = input("> ") + + if opcion == "1": + crear_ticket(tickets) + elif opcion == "2": + listar_tickets(tickets) + elif opcion == "3": + cerrar_ticket(tickets) + elif opcion == "4": + guardar_tickets(tickets) + print("Guardado. See you!") + break + else: + print("Opción no válida.") + +if __name__ == "__main__": + menu_tickets() From ab122919b69b551cfeb8ef1f48083923b458786e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iv=C3=A1n=20Calero?= Date: Fri, 7 Nov 2025 09:02:20 +0100 Subject: [PATCH 8/8] Fix: ejercicios operador morsa terminados --- .../ejercicio_guiado/calculadora_v7.py | 86 +++++++++++-------- ejercicios_Calero/08-Operador-Morsa/Reto-1.py | 31 +++++++ ejercicios_Calero/08-Operador-Morsa/Reto-2.py | 35 ++++++++ ejercicios_Calero/08-Operador-Morsa/Reto-3.py | 29 +++++++ ejercicios_Calero/08-Operador-Morsa/Reto-4.py | 61 +++++++++++++ ejercicios_Calero/08-Operador-Morsa/Reto-5.py | 50 +++++++++++ ejercicios_Calero/08-Operador-Morsa/Reto-6.py | 31 +++++++ 7 files changed, 289 insertions(+), 34 deletions(-) create mode 100644 ejercicios_Calero/08-Operador-Morsa/Reto-1.py create mode 100644 ejercicios_Calero/08-Operador-Morsa/Reto-2.py create mode 100644 ejercicios_Calero/08-Operador-Morsa/Reto-3.py create mode 100644 ejercicios_Calero/08-Operador-Morsa/Reto-4.py create mode 100644 ejercicios_Calero/08-Operador-Morsa/Reto-5.py create mode 100644 ejercicios_Calero/08-Operador-Morsa/Reto-6.py diff --git a/07_mini_proyectos/ejercicio_guiado/calculadora_v7.py b/07_mini_proyectos/ejercicio_guiado/calculadora_v7.py index b5e330c..608b562 100644 --- a/07_mini_proyectos/ejercicio_guiado/calculadora_v7.py +++ b/07_mini_proyectos/ejercicio_guiado/calculadora_v7.py @@ -51,43 +51,55 @@ def dividir(a, b): """Divide dos números.""" return a / b +print(s := sumar(67, 32)) +print(r := restar(6, 342)) +print(m := multiplicar(265, 2)) +print(d := dividir(546, 54)) + # ===== FUNCIONES DE INTERFAZ ===== def mostrar_menu(): """Muestra el menú de opciones de la calculadora.""" - print("\n=== CALCULADORA ===") - print("1. Sumar") - print("2. Restar") - print("3. Multiplicar") - print("4. Dividir") - print("5. Ver historial") - print("6. Limpiar historial") - print("7. Salir") + print(t := "\n=== CALCULADORA ===") + print(o1 := "1. Sumar") + print(o2 := "2. Restar") + print(o3 := "3. Multiplicar") + print(o4 := "4. Dividir") + print(o5 := "5. Ver historial") + print(o6 := "6. Limpiar historial") + print(o7 := "7. Salir") + def obtener_numeros(): """Pide dos números al usuario con validación mejorada.""" + while True: + try: + if (a := input("primer número: ")) and (b := input("segnudo número: ")): + return float(a), float(b) + except ValueError: + print("introduce valores numéricos válidos.") + # TODO 1: Refactoriza usando operador morsa # Combina el input y la validación en una sola expresión # Pista: while not (entrada := input(...)).algo(): +def obtener_numeros(): while True: - entrada1 = input("Primer número: ") try: - num1 = float(entrada1) + num1 = float(entrada1 := input("primer número: ")) break except ValueError: - print("❌ Ingresa un número válido") + print("Ingresa un número válido") while True: - entrada2 = input("Segundo número: ") try: - num2 = float(entrada2) + num2 = float(entrada2 := input("segundo número: ")) break except ValueError: - print("❌ Ingresa un número válido") + print("Ingresa un número válido") return num1, num2 @@ -96,24 +108,22 @@ def obtener_numeros(): def guardar_operacion(num1, num2, operacion, resultado): """Guarda una operación en el historial (en memoria).""" - operacion_dict = { + historial.append(operacion_dict := { "num1": num1, "num2": num2, "operacion": operacion, "resultado": resultado - } - historial.append(operacion_dict) - + }) def mostrar_historial(): """Muestra todas las operaciones del historial.""" if not historial: - print("📭 No hay operaciones en el historial") + print(msg := "📭 No hay operaciones en el historial") return - print("\n📜 HISTORIAL DE OPERACIONES:") + print(titulo := "\n📜 HISTORIAL DE OPERACIONES:") for i, op in enumerate(historial, 1): - print(f"{i}. {op['num1']} {op['operacion']} {op['num2']} = {op['resultado']:.2f}") + print(linea := f"{i}. {op['num1']} {op['operacion']} {op['num2']} = {op['resultado']:.2f}") # ===== FUNCIONES DE PERSISTENCIA (archivos JSON) ===== @@ -126,36 +136,43 @@ def cargar_historial(): """ try: with open(ARCHIVO_HISTORIAL, "r", encoding="utf-8") as archivo: - datos = json.load(archivo) - print(f"✅ Historial cargado: {len(datos)} operaciones") + print(f"Historial cargado: {len(datos := json.load(archivo))} operaciones") return datos except FileNotFoundError: - print("📝 No hay historial previo, iniciando uno nuevo") + print(mensaje := "No hay historial previo, iniciando uno nuevo") return [] except json.JSONDecodeError: - print("⚠️ Archivo de historial corrupto, iniciando uno nuevo") + print(mensaje := "Archivo de historial corrupto, iniciando uno nuevo") return [] - def guardar_historial_archivo(): """Guarda el historial actual en el archivo JSON.""" try: with open(ARCHIVO_HISTORIAL, "w", encoding="utf-8") as archivo: json.dump(historial, archivo, indent=2, ensure_ascii=False) - print("✅ Historial guardado correctamente") + print(mensaje := "Historial guardado correctamente") except Exception as e: - print(f"❌ Error al guardar el historial: {e}") - + print(error := f"Error al guardar el historial: {e}") def limpiar_historial(): """Limpia el historial en memoria y elimina el archivo.""" global historial + historial.clear() + if os.path.exists(ARCHIVO_HISTORIAL): + os.remove(ARCHIVO_HISTORIAL) + print(mensaje := "Historial limpiado y archivo eliminado") + else: + print(mensaje := "No había archivo de historial para eliminar") + # TODO 2: Refactoriza la confirmación con operador morsa # Pista: if (confirmacion := input(...).lower()) != "s": - confirmacion = input("⚠️ ¿Estás seguro de que quieres limpiar el historial? (s/n): ") - if confirmacion.lower() != "s": - print("❌ Operación cancelada") +def limpiar_historial(): + """Limpia el historial en memoria y elimina el archivo.""" + global historial + + if (confirmacion := input("¿Estás seguro de que quieres limpiar el historial? (s/n): ").lower()) != "s": + print("Operación cancelada") return historial = [] @@ -163,9 +180,10 @@ def limpiar_historial(): try: if os.path.exists(ARCHIVO_HISTORIAL): os.remove(ARCHIVO_HISTORIAL) - print("🗑️ Historial limpiado correctamente") + print("Historial limpiado correctamente") except Exception as e: - print(f"❌ Error al eliminar el archivo: {e}") + print(f"Error al eliminar el archivo: {e}") + # ===== FUNCIÓN PRINCIPAL ===== diff --git a/ejercicios_Calero/08-Operador-Morsa/Reto-1.py b/ejercicios_Calero/08-Operador-Morsa/Reto-1.py new file mode 100644 index 0000000..2496a30 --- /dev/null +++ b/ejercicios_Calero/08-Operador-Morsa/Reto-1.py @@ -0,0 +1,31 @@ +def reto1(): + while (comando := input("Comando: ").strip().lower()) != "salir": + partes = comando.split() + + if len(partes) != 3: + print("Comando no válido") + continue + + operacion, x_str, y_str = partes + + try: + x, y = float(x_str), float(y_str) + except ValueError: + print("Argumentos no válidos") + continue + + if operacion == "sumar": + print(f"{x} + {y} = {x + y}") + elif operacion == "restar": + print(f"{x} - {y} = {x - y}") + elif operacion == "multiplicar": + print(f"{x} * {y} = {x * y}") + elif operacion == "dividir": + if y == 0: + print("No se puede dividir por cero") + else: + print(f"{x} / {y} = {x / y}") + else: + print("Comando no válido") + + print("Hasta pronto") \ No newline at end of file diff --git a/ejercicios_Calero/08-Operador-Morsa/Reto-2.py b/ejercicios_Calero/08-Operador-Morsa/Reto-2.py new file mode 100644 index 0000000..1464dfe --- /dev/null +++ b/ejercicios_Calero/08-Operador-Morsa/Reto-2.py @@ -0,0 +1,35 @@ +import json + +def reto2(): + while not (nombre := input("Nombre: ")) or len(nombre) < 3: + print("El nombre debe tener al menos 3 caracteres") + + while "@" not in (email := input("Email: ")): + print("El email debe contener @") + + while True: + try: + if not (edad := int(input("Edad: "))) or edad < 18 or edad > 100: + print("La edad debe estar entre 18 y 100") + continue + break + except ValueError: + print("La edad debe ser un número") + + while not (clave := input("Contraseña: ")) or len(clave) < 6: + print("La contraseña debe tener al menos 6 caracteres") + + print("Registro completado:") + print(f"Nombre: {nombre}") + print(f"Email: {email}") + print(f"Edad: {edad}") + + datos = { + "nombre": nombre, + "email": email, + "edad": edad, + "contraseña": clave + } + + with open("registro.json", "w", encoding="utf-8") as archivo: + json.dump(datos, archivo, indent=2, ensure_ascii=False) \ No newline at end of file diff --git a/ejercicios_Calero/08-Operador-Morsa/Reto-3.py b/ejercicios_Calero/08-Operador-Morsa/Reto-3.py new file mode 100644 index 0000000..9c23ea0 --- /dev/null +++ b/ejercicios_Calero/08-Operador-Morsa/Reto-3.py @@ -0,0 +1,29 @@ +def reto3(): + archivo_entrada = input("Archivo a procesar: ").strip() + archivo_salida = "datos_procesados.txt" + + procesadas = 0 + ignoradas = 0 + lineas_validas = [] + + try: + with open(archivo_entrada, "r", encoding="utf-8") as archivo: + while (linea := archivo.readline()): + if (linea_limpia := linea.strip()) and not linea_limpia.startswith("#") and len(linea_limpia) > 10: + lineas_validas.append(linea_limpia) + procesadas += 1 + else: + ignoradas += 1 + + with open(archivo_salida, "w", encoding="utf-8") as salida: + for linea in lineas_validas: + salida.write(linea + "\n") + + print(f"Procesadas: {procesadas} líneas") + print(f"Ignoradas: {ignoradas} líneas") + print(f"Resultado guardado en: {archivo_salida}") + + except FileNotFoundError: + print("El archivo no existe") + except Exception as e: + print(f"Error al procesar el archivo: {e}") \ No newline at end of file diff --git a/ejercicios_Calero/08-Operador-Morsa/Reto-4.py b/ejercicios_Calero/08-Operador-Morsa/Reto-4.py new file mode 100644 index 0000000..76957fa --- /dev/null +++ b/ejercicios_Calero/08-Operador-Morsa/Reto-4.py @@ -0,0 +1,61 @@ +import json + +def reto4(): + archivo = input("Archivo de datos (peso edad por línea): ").strip() + datos = [] + + try: + with open(archivo, "r", encoding="utf-8") as f: + while (linea := f.readline()): + if (partes := linea.strip().split()) and len(partes) == 2: + try: + peso, edad = float(partes[0]), int(partes[1]) + datos.append((peso, edad)) + except ValueError: + continue + + if not datos: + print("No se encontraron datos válidos") + return + + total = len(datos) + pesos = [p for p, _ in datos] + edades = [e for _, e in datos] + + media_peso = sum(pesos) / total + media_edad = sum(edades) / total + + pesos_ordenados = sorted(pesos) + edades_ordenadas = sorted(edades) + + mediana_peso = pesos_ordenados[total // 2] if total % 2 == 1 else (pesos_ordenados[total // 2 - 1] + pesos_ordenados[total // 2]) / 2 + mediana_edad = edades_ordenados[total // 2] if total % 2 == 1 else (edades_ordenados[total // 2 - 1] + edades_ordenados[total // 2]) / 2 + + k = 3 + top_k = sorted(datos, key=lambda x: x[0], reverse=True)[:k] + + print(f"Total de gatos: {total}") + print(f"Peso medio: {media_peso:.2f}") + print(f"Edad media: {media_edad:.2f}") + print(f"Mediana de peso: {mediana_peso:.2f}") + print(f"Mediana de edad: {mediana_edad:.2f}") + print(f"Top {k} más pesados:") + for i, (peso, edad) in enumerate(top_k, 1): + print(f"{i}. Peso: {peso:.2f}, Edad: {edad}") + + guardar = input("¿Guardar resumen en archivo? (s/n): ").strip().lower() + if guardar == "s": + resumen = { + "total": total, + "peso_medio": media_peso, + "edad_medio": media_edad, + "mediana_peso": mediana_peso, + "mediana_edad": mediana_edad, + "top_k_pesados": top_k + } + with open("resumen_gatos.json", "w", encoding="utf-8") as out: + json.dump(resumen, out, indent=2, ensure_ascii=False) + print("Resumen guardado en resumen_gatos.json") + + except FileNotFoundError: + print("Archivo no encontrado") \ No newline at end of file diff --git a/ejercicios_Calero/08-Operador-Morsa/Reto-5.py b/ejercicios_Calero/08-Operador-Morsa/Reto-5.py new file mode 100644 index 0000000..f12c110 --- /dev/null +++ b/ejercicios_Calero/08-Operador-Morsa/Reto-5.py @@ -0,0 +1,50 @@ +import json + +def reto5(): + tickets = [] + siguiente_id = 1 + archivo = "tickets.json" + + try: + with open(archivo, "r", encoding="utf-8") as f: + if (cargados := json.load(f)): + tickets = cargados + siguiente_id = max(t["id"] for t in tickets) + 1 + except (FileNotFoundError, json.JSONDecodeError): + pass + + while (opcion := input("\n[1] Crear [2] Listar [3] Cerrar [4] Salir\nElige: ").strip()) != "4": + if opcion == "1": + if (titulo := input("Título del ticket: ").strip()): + tickets.append({"id": siguiente_id, "titulo": titulo, "estado": "abierto"}) + siguiente_id += 1 + print("Ticket creado") + else: + print("Título no válido") + + elif opcion == "2": + if not tickets: + print("No hay tickets") + else: + for t in tickets: + print(f"[{t['id']}] {t['titulo']} - {t['estado']}") + + elif opcion == "3": + if not (id_str := input("ID del ticket a cerrar: ").strip()).isdigit(): + print("ID no válido") + continue + id_ticket = int(id_str) + for t in tickets: + if t["id"] == id_ticket: + t["estado"] = "cerrado" + print("Ticket cerrado") + break + else: + print("Ticket no encontrado") + + else: + print("Opción no válida") + + with open(archivo, "w", encoding="utf-8") as f: + json.dump(tickets, f, indent=2, ensure_ascii=False) + print("Tickets guardados") \ No newline at end of file diff --git a/ejercicios_Calero/08-Operador-Morsa/Reto-6.py b/ejercicios_Calero/08-Operador-Morsa/Reto-6.py new file mode 100644 index 0000000..2fbc279 --- /dev/null +++ b/ejercicios_Calero/08-Operador-Morsa/Reto-6.py @@ -0,0 +1,31 @@ +from collections import Counter + +def reto6(): + archivo_entrada = input("Archivo de logs: ").strip() + archivo_salida = "resumen.txt" + contador_tipo = Counter() + contador_fecha = Counter() + + try: + with open(archivo_entrada, "r", encoding="utf-8") as f: + while (linea := f.readline()): + if (partes := linea.strip().split()) and len(partes) >= 2: + fecha, tipo = partes[0], partes[1] + contador_fecha[fecha] += 1 + contador_tipo[tipo] += 1 + + with open(archivo_salida, "w", encoding="utf-8") as out: + out.write("Conteo por tipo:\n") + for tipo, cantidad in contador_tipo.items(): + out.write(f"{tipo}: {cantidad}\n") + + out.write("\nConteo por fecha:\n") + for fecha, cantidad in contador_fecha.items(): + out.write(f"{fecha}: {cantidad}\n") + + print("Resumen guardado en resumen.txt") + + except FileNotFoundError: + print("Archivo no encontrado") + except Exception as e: + print(f"Error al procesar el archivo: {e}") \ No newline at end of file