diff --git a/01_intro/autonomos/conversor.py b/01_intro/autonomos/conversor.py new file mode 100644 index 0000000..730435d --- /dev/null +++ b/01_intro/autonomos/conversor.py @@ -0,0 +1,22 @@ +# Programa que pida un número y lo convierta en float, manejando ValueError con un mensaje amable + +# Variable a introducir un dato +numero_conv = input("Introduce un número a convertirlo en float --> ") + +# Imprimir numero introducido y su tipo de dato +print(f"Número introducido: {numero_conv}") +print(f"Tipo de dato: {type(numero_conv)}") + +try: + # Intentamos convertir el dato a float + numero_conv = float(numero_conv) + print(f"Perfecto! Se ha convertido {numero_conv} en un valor float: {type(numero_conv)}") +except ValueError: + # Si sale error de valor (ValueError), suelta el mensaje de error + print(f"Lo siento! '{numero_conv}' no es un número válido. Por favor, vuelva a ejecutar de nuevo el archivo sin ningún carácter.") + +# Conversion valor 45 convertido a float con éxito ✅ + +# Conversion valor 'pepe' convertido a float fallo ❌ +# Razón: ValueError: could not convert string to float: 'pepe' +# Fallo resuelto con try/except \ No newline at end of file diff --git a/01_intro/autonomos/eco.py b/01_intro/autonomos/eco.py new file mode 100644 index 0000000..2019b2c --- /dev/null +++ b/01_intro/autonomos/eco.py @@ -0,0 +1,10 @@ +# Programa que repite lo que el usuario escribe + +# Pedimos al usuario que escriba algo +texto = input("Escribe algo --> ") + +# Se repite lo que escribimos +print(texto) + +# Prueba 'python eco.py' introducido palabra 'pepe' +# Completado con éxito ✅ \ No newline at end of file diff --git a/01_intro/autonomos/tres_prints.py b/01_intro/autonomos/tres_prints.py new file mode 100644 index 0000000..35a525b --- /dev/null +++ b/01_intro/autonomos/tres_prints.py @@ -0,0 +1,10 @@ +# Programa que imprima tres líneas con información personal + +# Imprimir primera línea de dato personal +print("Nombre: David") +# Imprimir segunda línea de dato personal +print("Edad: 27") +# Imprimir tercera línea de dato personal +print("Color favorito: Verde") + +# Prueba 'python tres_prints.py' completado con éxito ✅ \ No newline at end of file diff --git a/01_intro/autonomos/variables_basicas.py b/01_intro/autonomos/variables_basicas.py new file mode 100644 index 0000000..d44a342 --- /dev/null +++ b/01_intro/autonomos/variables_basicas.py @@ -0,0 +1,15 @@ +# Programa que combine nombre y ciudad en un string: 'Ana vive en Lima' + +# Variable nombre +nombre = "Ana" + +# Variable ciudad +ciudad = "Lima" + +# Variable mensaje que combina 'nombre' y 'ciudad' en un string +mensaje = f"{nombre} vive en {ciudad}" + +# Imprimir variable mensaje +print(mensaje) + +# Prueba 'python variables_basicas' Funciona ✅ \ No newline at end of file diff --git a/01_intro/desafio/bigotes_felices.py b/01_intro/desafio/bigotes_felices.py new file mode 100644 index 0000000..bee8c10 --- /dev/null +++ b/01_intro/desafio/bigotes_felices.py @@ -0,0 +1,42 @@ +# Desafio: Bigotes Felices +# En el refugio Bigotes Felices quieren un script que pida el nombre del gato y su edad, +# y muestre: `Gato: (edad: )`. +# Si la edad no es un número, muestra `Edad inválida`. + +# Variable nombre_gato a introducir dato string +nombre_gato = input("Nombre del gato --> ") + +# Variable edad_gato a introducir dato int +edad_gato = input("Edad del gato --> ") + +try: + # Intentamos convertir valor str a int + edad_gato = int(edad_gato) + + # Variable datos a mostrar mensaje de los datos introducidos por el usuario + datos = f"Gato: {nombre_gato} (edad: {edad_gato})" + + # Imprimir mensaje de salida + print(datos) + +except ValueError: + # Muestra mensaje de error si edad_gato es un valor string + print("Edad inválida") + +# Primer test: imprimir datos introducidos de tipo string. +# Prueba: +# Nombre del gato --> pepe +# Edad del gato --> viyuela +# Mensaje de salida: Gato: pepe (edad: viyuela) ✅ + +# Segundo test: imprimir datos de nombre_gato (string: cadena de texto) y de edad_gato (int: numero entero) +# Prueba: +# Nombre del gato --> pepe +# Edad del gato --> julio +# Mensaje de salida: Edad inválida ❌ + +# Tercer test: imprimir los datos validando try/except +# Prueba: +# Nombre del gato --> pepe +# Edad del gato --> 10 +# Mensaje de salida: Gato: pepe (edad: 10) ✅ \ No newline at end of file diff --git a/01_intro/ejercicio_guiado/calculadora_v1.py b/01_intro/ejercicio_guiado/calculadora_v1.py index cb19414..c374864 100644 --- a/01_intro/ejercicio_guiado/calculadora_v1.py +++ b/01_intro/ejercicio_guiado/calculadora_v1.py @@ -21,24 +21,27 @@ # TODO 1: Pide el primer número al usuario # Pista: usa input() y guarda el valor en una variable # primer_numero = ... - +primer_numero = input("Ingrese un número: ") # TODO 2: Pide el segundo número al usuario # segundo_numero = ... +segundo_numero = input("Ingrese otro 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 = ... - +num_float1 = float(primer_numero) +num_float2 = float(segundo_numero) # TODO 4: Realiza la suma # resultado = ... - +resultado = num_float1 + num_float2 # TODO 5: Muestra el resultado # Pista: print("El resultado es:", resultado) +print(f"{num_float1} + {num_float2} = {resultado}") # ¡Ya está! Ejecuta el programa y prueba con diferentes números @@ -46,3 +49,12 @@ # - 5 y 3 → debe dar 8 # - -2 y 7 → debe dar 5 # - 3.5 y 2.5 → debe dar 6.0 +# +# Prueba: +# Comando a ejecutar: 'python calculadora_v1.py' +# Resultado: +# Ingrese un número: 4 +# Ingrese otro número: 9 +# 4.0 + 9.0 = 13.0 +# Éxito ✅ + diff --git a/01_intro/primer_script/primer_script.py b/01_intro/primer_script/primer_script.py new file mode 100644 index 0000000..c7e4e52 --- /dev/null +++ b/01_intro/primer_script/primer_script.py @@ -0,0 +1,10 @@ +# Variable +nombre = 'Ana' + +#Imprimir 'Hola, Python' +print(f"Hola, Python") + +#Imprimir 'Hola, {nombre}' +print(f"Hola, {nombre}") + +#Prueba testing completada \ No newline at end of file diff --git a/01_intro/saludo_input/saludo_input.py b/01_intro/saludo_input/saludo_input.py new file mode 100644 index 0000000..9acb0ed --- /dev/null +++ b/01_intro/saludo_input/saludo_input.py @@ -0,0 +1,7 @@ +# Variable +nombre = input("¿Cómo te llamas? --> ") + +# Imprimir 'Hola, {nombre}' +print(f"Hola, {nombre}") + +# Prueba test pasada \ No newline at end of file diff --git a/02_estructuras/autonomos/booleans.py b/02_estructuras/autonomos/booleans.py new file mode 100644 index 0000000..1ddde8f --- /dev/null +++ b/02_estructuras/autonomos/booleans.py @@ -0,0 +1,48 @@ +# EJERCICIO AUTÓNOMO 1: BOOLEANS +# Enunciado: evalúa condiciones simples (>=, ==) y muestra True/False. + +# Variables de dos números enteros que piden al usuario +num1 = input("Escribe un número: ") +num2 = input("Escribe otro número: ") + +try : + # Intentamos convertir num1 y num2 en enteros + num1 = int(num1) + num2 = int(num2) + + # Declaramos variables de las condiciones simples: + # Condición si el primer número es Mayor o igual que el segundo número + mayorigualque = num1 >= num2 + # Condición si el primer número es Menor o igual que el segundo número + menorigualque = num1 <= num2 + # Condición si el primer número es Igual que el segundo número + igualque = num1 == num2 + # Condición si el primer número es Distinto que el segundo número + distintoque = num1 != num2 + # Condición si el primer número es Mayor que el segundo número + mayorque = num1 > num2 + # Condición si el primer número es Menor que el segundo número + menorque = num1 < num2 + + # Imprimir las condiciones simples en consola + print(f"CONDICIONES SIMPLES:") + print(f"{num1} >= {num2} : {mayorigualque}") + print(f"{num1} <= {num2} : {menorigualque}") + print(f"{num1} == {num2} : {igualque}") + print(f"{num1} != {num2} : {distintoque}") + print(f"{num1} > {num2} : {mayorque}") + print(f"{num1} < {num2} : {menorque}") + +except ValueError: + # Si algun valor introducido no es un numero imprime este error. + print("Inválido. Inténtelo de nuevo.") + +# Cuarto test: introducir '10' como num1 y '5' como num2. +# Resultado: +# 10 >= 5 : True +# 10 <= 5 : False +# 10 == 5 : False +# 10 != 5 : True +# 10 > 5 : True +# 10 < 5 : False +# Éxito ✅ \ No newline at end of file diff --git a/02_estructuras/autonomos/porcentajes.py b/02_estructuras/autonomos/porcentajes.py new file mode 100644 index 0000000..9cfe7a2 --- /dev/null +++ b/02_estructuras/autonomos/porcentajes.py @@ -0,0 +1,31 @@ +# EJERCICIO AUTÓNOMO 4: PORCENTAJES +# Enunciado: calcula el 15% de una cantidad. + +# Variable num al pedir un número entero +num = input("Introduce un número: ") + +# Efecto try/except por si deja convertir la variable num a entero +try: + # Convertir string num a int num + num = int(num) + + # Variable porcentaje a calcular el 15% del numero dado + porcentaje = 0.15 + + # Variable resultado para calcular el resultado del 15% del numero dado + resultado = num * porcentaje + + # Imprimir resultado del ejercicio + print(f"15% de {num} --> {resultado}") + +except ValueError: + # Si el valor introducido no es un número entero envía este error + print("Valor incorrecto. Por favor reinicie el programa.") + +# Cuarto test: introducir '100' como num cuando lo pide el programa +# Resultado al ejecutar 'python porcentajes.py': +# -------------------------- +# Introduce un número: 100 +# 15% de 100 --> 15.0 +# -------------------------- +# Éxito ✅ \ No newline at end of file diff --git a/02_estructuras/autonomos/redondeo.py b/02_estructuras/autonomos/redondeo.py new file mode 100644 index 0000000..019005c --- /dev/null +++ b/02_estructuras/autonomos/redondeo.py @@ -0,0 +1,24 @@ +# EJERCICIO AUTÓNOMO 3: REDONDEO +# Enunciado: redondea 3.14159 a 3 decimales. + +# Variable num con el número específico a redondear +num = 3.14159 + +# Variable num_redondo que redondea variable num a 3 decimales +# round(): devuelve un número con decimales que es una versión redondeada del +# mismo, con el número especificado de decimales. +# Sintaxis: round(number, digits) +# number --> Obligatorio. El número a ser redondeado +# digits --> Opcional. El número específico a usar para redondear +# number. Por defecto es 0. +num_redondo = round(num, 3) + +# Imprimir resultado del ejercicio +print(f"Número: {num}") +print(f"Número redondeado a 3 decimales: {num_redondo}") + +# Test: ejecutar 'python redondeo.py +# Resultado esperado: +# Número: 3.14159 +# Número redondeado a 3 decimales: 3.142 +# Éxito ✅ \ No newline at end of file diff --git a/02_estructuras/autonomos/strings.py b/02_estructuras/autonomos/strings.py new file mode 100644 index 0000000..63c782d --- /dev/null +++ b/02_estructuras/autonomos/strings.py @@ -0,0 +1,31 @@ +# EJERCICIO AUTÓNOMO 2: STRINGS +# Enunciado: une nombre y apellido con espacio y `title()`. + +# Variables nombre y apellido +# nombre: pide al usuario un nombre +# apellido: pide al usuario un apellido +nombre = input("Escribe tu nombre: ") +apellido = input("Escribe tu apellido: ") + +# Variable string +# string: devuelve una cadena de texto que une nombre y apellido con un espacio +string = f"{nombre} {apellido}" + +# Variable title +# title: devuelve string que incluye la funcion title() +# title(): devuelve una cadena en la que el primer carácter de cada palabra está en mayúscula. +# Como un encabezado o un título. +title = string.title() + +# Imprimir variable title en consola +print(title) + +# Primer test: ejecutamos 'python strings.py' +# Cuando pida el programa pondremos +# como nombre 'pepe' +# y como apellido 'viyuela' +# Resultado esperado: +# Escribe tu nombre: pepe +# Escribe tu apellido: viyuela +# Pepe Viyuela +# Realizado con éxito ✅ diff --git a/02_estructuras/casting/casting.py b/02_estructuras/casting/casting.py new file mode 100644 index 0000000..ce12d39 --- /dev/null +++ b/02_estructuras/casting/casting.py @@ -0,0 +1,19 @@ +# EJERCICIO GUIADO 2: CASTING Y VALICADIÓN +# Paso 1: Crea `casting.py` que pida un número con `input`. +# Paso 2: Convierte a `int` dentro de `try/except`. +# Paso 3: Si falla, imprime `Entrada inválida`. + +# Variable casting que pide un número con `input` +casting = input("Introduce un número --> ") + +try: + # Intentamos convertir casting en int + casting = int(casting) + # Si lo convierte, imprime en consola + print(casting) +except ValueError: + # Salta mensaje de error 'ValueError' si el resultado no es un número entero + print(f"Entrada inválida") + +# Cuarto test: introducir 35 cuando lo pidan +# Resultado impresión: 35 ✅ \ No newline at end of file diff --git a/02_estructuras/desafio/pesaje.py b/02_estructuras/desafio/pesaje.py new file mode 100644 index 0000000..1ec26df --- /dev/null +++ b/02_estructuras/desafio/pesaje.py @@ -0,0 +1,55 @@ +# DESAFIO: Bigotes Felices (pesaje) +# Enunciado: Pide el peso de tres gatos y calcula el promedio. +# Valida entradas numéricas. + +# Variable gato1 al pedir al usuario el peso del 1º gato +gato1 = input("Introduce el peso del primer gato: ") +# Variable gato2 al pedir al usuario el peso del 2º gato +gato2 = input("Introduce el peso del segundo gato: ") +# Variable gato3 al pedir al usuario el peso del 3º gato +gato3 = input("Introduce el peso del tercer gato: ") + +# Try/except para verificar si los datos introducidos son números enteros +try: + # Intentamos convertir gato1 en número entero + gato1 = int(gato1) + # Intentamos convertir gato2 en número entero + gato2 = int(gato2) + # Intentamos convertir gato3 en número entero + gato3 = int(gato3) + + # Variable promedio para calcular el peso promedio de los 3 gatos + promedio = (gato1 + gato2 + gato3) / 3 + + # Volver a declarar variable promedio para redondear a 3 decimales con la funcion round() + promedio = round(promedio, 3) + + # Imprimir titulo del pesaje de los gatos + print(f"Pesaje de los gatos: ") + # Imprimir peso del gato nº1 + print(f"Gato nº1: {gato1} kg") + # Imprimir peso del gato nº2 + print(f"Gato nº2: {gato2} kg") + # Imprimir peso del gato nº3 + print(f"Gato nº3: {gato3} kg") + # Imprimir peso promedio de los 3 gatos + print(f"Calculo promedio de los 3 gatos: {promedio} kg") + +# Metodo except por si el dato introducido no es un número entero +except ValueError: + # Si uno de los 3 valores pedidos no es un número entero mostrará este mensaje de error + print(f"Error al introducir los datos. Por favor, vuelva a iniciar el pesaje.") + +# Quinto test: introducir '12', '34' y '40' respectivamente cuando le pida el programa +# Resultado al ejecutar 'python pesaje.py': +# --------------------------------------- +# Introduce el peso del primer gato: 12 +# Introduce el peso del segundo gato: 34 +# Introduce el peso del tercer gato: 40 +# Pesaje de los gatos: +# Gato nº1: 12 kg +# Gato nº2: 34 kg +# Gato nº3: 40 kg +# Calculo promedio de los 3 gatos: 28.667 kg +# --------------------------------------- +# Éxito ✅ \ No newline at end of file diff --git a/02_estructuras/ejercicio_guiado/GUIA.md b/02_estructuras/ejercicio_guiado/GUIA.md index 6214164..d3b9d67 100644 --- a/02_estructuras/ejercicio_guiado/GUIA.md +++ b/02_estructuras/ejercicio_guiado/GUIA.md @@ -79,4 +79,5 @@ En el módulo 03 añadirás un menú interactivo que se repite hasta que el usua --- **Versión anterior**: [`01_intro/ejercicio_guiado/GUIA.md`](../../01_intro/ejercicio_guiado/GUIA.md) + **Siguiente versión**: [`03_control_flujo/ejercicio_guiado/GUIA.md`](../../03_control_flujo/ejercicio_guiado/GUIA.md) - Añadirás menú con bucles diff --git a/02_estructuras/ejercicio_guiado/calculadora_v2.py b/02_estructuras/ejercicio_guiado/calculadora_v2.py index 424d58f..2f76299 100644 --- a/02_estructuras/ejercicio_guiado/calculadora_v2.py +++ b/02_estructuras/ejercicio_guiado/calculadora_v2.py @@ -20,36 +20,60 @@ # TODO 1: Pide el primer número al usuario y conviértelo a float # num1 = ... - +num1 = input("Introduce el primer número --> ") # TODO 2: Pide el segundo número al usuario y conviértelo a float # num2 = ... - +num2 = input("Introduce el segundo número --> ") # TODO 3: Pregunta qué operación desea realizar # Pista: input("¿Qué operación deseas realizar? (+, -, *, /): ") # operacion = ... +operacion = input("¿Qué operación desea realizar? (+, -, *, /) --> ") +# TODO 3.5: Realiza try/except por si surge error al introducir números dados +try: + float_num1 = float(num1) + float_num2 = float(num2) -# TODO 4: Realiza la operación correspondiente usando if/elif/else -# Pista: Compara la variable 'operacion' con "+", "-", "*", "/" -# -# if operacion == "+": -# resultado = num1 + num2 -# elif operacion == "-": -# ... -# elif operacion == "*": -# ... -# elif operacion == "/": -# ... -# else: -# print("❌ Operación no válida") + # TODO 4: Realiza la operación correspondiente usando if/elif/else + # Pista: Compara la variable 'operacion' con "+", "-", "*", "/" + # + # if operacion == "+": + # resultado = num1 + num2 + # elif operacion == "-": + # ... + # elif operacion == "*": + # ... + # elif operacion == "/": + # ... + # else: + # print("❌ Operación no válida") + if operacion == "+": + resultado = float_num1 + float_num2 + elif operacion == "-": + resultado = float_num1 - float_num2 + elif operacion == "*": + resultado = float_num1 * float_num2 + elif operacion == "/": + resultado = float_num1 / float_num2 + else: + print("❌ Lo siento. No se reconoce la operación que ha introducido. Vuelva a intentarlo.") -# 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"...") + # 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"...") + print(f"{float_num1} {operacion} {float_num2} = {round(resultado, 2)}") + +# Añadir dos mensajes de error +except ValueError: + print(f"❌ Inválido. Uno de los números introducidos (num1: {num1} | num2: {num2}) es incorrecto.") + print(f"Por favor, reinicie el programa. 🛠️") +except NameError: + print(f"❌ No ha generado el resultado que esperaba.") + print(f"Por favor, reinicie el programa. 🛠️") # ¡Perfecto! Ahora tu calculadora puede hacer las 4 operaciones básicas @@ -63,3 +87,65 @@ # # 💡 Nota: Si intentas dividir por cero (10 / 0), Python mostrará un error. # Esto lo arreglaremos en la v3 con validación de entrada. + +# Primer test: introducir 5 como num1, 3 como num2 y cualquier signo sugerido en operador +# -------------------------------------------------- +# Operador '+': +# Introduce el primer número --> 5 +# Introduce el segundo número --> 3 +# ¿Qué operación desea realizar? (+, -, *, /) --> + +# 5.0 + 3.0 = 8.0 +# -------------------------------------------------- +# Operador '-': +# Introduce el primer número --> 5 +# Introduce el segundo número --> 3 +# ¿Qué operación desea realizar? (+, -, *, /) --> - +# 5.0 - 3.0 = 2.0 +# -------------------------------------------------- +# Operador '*': +# Introduce el primer número --> 5 +# Introduce el segundo número --> 3 +# ¿Qué operación desea realizar? (+, -, *, /) --> * +# 5.0 * 3.0 = 15.0 +# -------------------------------------------------- +# Operador '/': +# Introduce el primer número --> 5 +# Introduce el segundo número --> 3 +# ¿Qué operación desea realizar? (+, -, *, /) --> / +# 5.0 / 3.0 = 1.67 +# -------------------------------------------------- +# Cualquier otro operador '%, (, )...': +# Introduce el primer número --> 5 +# Introduce el segundo número --> 3 +# ¿Qué operación desea realizar? (+, -, *, /) --> % +# ❌ Lo siento. No se reconoce la operación que ha introducido. Vuelva a intentarlo. +# -------------------------------------------------- +# Éxito ✅ +# -------------------------------------------------- +# Segundo test: introducir un string en uno de los dos números que piden al usuario. +# -------------------------------------------------- +# Probar con dato 'hola': +# Introduce el primer número --> hola +# ERROR ❌ +# Motivo: ValueError: could not convert string to float: 'hola' +# -------------------------------------------------- +# Tercer test: al agregar try/except, volver a ingresar 'hola' por si surge el mensaje. +# -------------------------------------------------- +# Introduce el primer número --> hola +# Introduce el segundo número --> 3 +# ¿Qué operación desea realizar? (+, -, *, /) --> + +# ❌ Inválido. Uno de los números introducidos (num1: hola | num2: 3) es incorrecto. +# Por favor, reinicie el programa. 🛠️ +# -------------------------------------------------- +# Mensaje mostrado con éxito ✅ +# -------------------------------------------------- +# Cuarto test: al agregar try/except, ingresar un operador que no está donde le pide el programa (%) +# -------------------------------------------------- +# Introduce el primer número --> 5 +# Introduce el segundo número --> 3 +# ¿Qué operación desea realizar? (+, -, *, /) --> % +# ❌ Lo siento. No se reconoce la operación que ha introducido. Vuelva a intentarlo. +# ❌ No ha generado el resultado que esperaba. +# Por favor, reinicie el programa. 🛠️ +# -------------------------------------------------- +# Mensaje mostrado con éxito ✅ \ No newline at end of file diff --git a/02_estructuras/operaciones/operaciones.py b/02_estructuras/operaciones/operaciones.py new file mode 100644 index 0000000..20140d4 --- /dev/null +++ b/02_estructuras/operaciones/operaciones.py @@ -0,0 +1,42 @@ +# EJERCICIO GUIADO 1: OPERACIONES NUMÉRICAS +# Paso 1: Crea `operaciones.py` y define `a=10`, `b=3`. +# Paso 2: Calcula suma, resta, multiplicación y división. +# Paso 3: Imprime los resultados con f-strings. +# Paso 4: Redondea la división a 2 decimales. + +# Variables a y b +a = 10 +b = 3 + +# OPERACIONES NUMÉRICAS +# Suma +suma = a + b +# Resta +resta = a - b +# Multiplicación +multiplicacion = a * b +# División +division = a / b + +# Función round() para redondear la division a 2 decimales +# Sintaxis: round('numero float', 'numero decimales a redondear') +division = round(division, 2) + +# Impresión de resultados con f-strings +print(f"Valor de a: {a}") +print(f"Valor de b: {b}") +print("---------------------------") +print(f"Suma: {a} + {b} = {suma}") +print(f"Resta: {a} - {b} = {resta}") +print(f"Multiplicación: {a} X {b} = {multiplicacion}") +print(f"División: {a} / {b} = {division}") + +# Resultado esperado (ptyhon operaciones.py): +# Valor de a: 10 +# Valor de b: 3 +# --------------------------- +# Suma: 10 + 3 = 13 +# Resta: 10 - 3 = 7 +# Multiplicación: 10 X 3 = 30 +# División: 10 / 3 = 3.33 +# Test superado con éxito ✅ \ No newline at end of file diff --git "a/03_control_flujo/autonomos/contrase\303\261as.py" "b/03_control_flujo/autonomos/contrase\303\261as.py" new file mode 100644 index 0000000..9301e63 --- /dev/null +++ "b/03_control_flujo/autonomos/contrase\303\261as.py" @@ -0,0 +1,30 @@ +# EJERCICIO AUTÓNOMO 4: Contraseñas +# Enunciado: Pide contraseñas hasta que sea `gato123`. + +# TODO 0: Imprimir título del programa +print("---- Contraseñas ----") + +# TODO 1: Empezar bucle while que pida contraseñas hasta introducir 'gato123' +while True: + # TODO 2: Pedir contraseña al usuario + contrasena = input("\nIntroduce una contraseña ('gato123' para finalizar) --> ") + # TODO 3: Si se introduce la contraseña especificada se acaba el bucle + if contrasena == "gato123": + print("Fin contraseñas!!!") + break + # TODO 4: Si no se introduce la contraseña especificada se guardará la contraseña introducida y seguirá pidiendo la contraseña + else: + print(f"Contraseña {contrasena} agregada.") + continue + +# RESULTADO: +# ---- Contraseñas ---- +# +# Introduce una contraseña ('gato123' para finalizar) --> pepe +# Contraseña pepe agregada. +# +# Introduce una contraseña ('gato123' para finalizar) --> leoniko +# Contraseña leoniko agregada. +# +# Introduce una contraseña ('gato123' para finalizar) --> gato123 +# Fin contraseñas!!! \ No newline at end of file diff --git a/03_control_flujo/autonomos/cuenta_letras.py b/03_control_flujo/autonomos/cuenta_letras.py new file mode 100644 index 0000000..885eb10 --- /dev/null +++ b/03_control_flujo/autonomos/cuenta_letras.py @@ -0,0 +1,23 @@ +# EJERCICIO AUTÓNOMO 2: Contar letras +# Enunciado: Cuenta letras en un string usando un bucle. + +# TODO 0: Imprimir título del programa +print("---- Cuenta Letras ---- \n") + +# TODO 1: Pedir al usuario unas palabras +string = input("Escribe unas palabras --> ") + +# TODO 2: Iniciar un contador para las letras +count = 0 + +# TODO 3: Iniciar bucle for para recorrer cada caracter del string +print("Caracter --> Número") +for i in string: + # TODO 4: Incrementar el contador en 1 cada caracter que recorre + count += 1 + # TODO 5: Imprimir indice y letra del string recorrido + print(f"{i} --> {count}") + + +# TODO 6: Imprimir total del contador +print(f"Letras contadas: {count}") \ No newline at end of file diff --git a/03_control_flujo/autonomos/lista_gatos.py b/03_control_flujo/autonomos/lista_gatos.py new file mode 100644 index 0000000..2295360 --- /dev/null +++ b/03_control_flujo/autonomos/lista_gatos.py @@ -0,0 +1,28 @@ +# EJERCICIO AUTÓNOMO 1: Lista de gatos +# Enunciado: Recorre una lista de gatos y imprime sus nombres. + +# TODO 0: Imprimir título del programa +print("---- LISTA DE GATOS ----") +# TODO 1: Declarar array con nombres de gatos +gatos = ["Michi", "Leo", "Nico", "Fluffy", "Pimpi"] +# TODO 2: Imprimir nombres de gatos dentro del array +print(f"Nombres de gatos: {gatos}\n") + +# TODO 3: Iniciar bucle for que recorra el array de gatos con su longitud +print(f"Lista:") +for i in range(len(gatos)): + # TODO 4: Imprimir nombres de gatos hasta que no queden más nombres + print(f"Gato nº{i+1} --> {gatos[i]}") + +# Arranque del programa: python lista_gatos.py +# -------------------------------------------- +# Resultado: +# ---- LISTA DE GATOS ---- +# Nombres de gatos: ['Michi', 'Leo', 'Nico', 'Fluffy', 'Pimpi'] + +# Lista: +# Gato nº1 --> Michi +# Gato nº2 --> Leo +# Gato nº3 --> Nico +# Gato nº4 --> Fluffy +# Gato nº5 --> Pimpi \ No newline at end of file diff --git a/03_control_flujo/autonomos/tabla_multiplicar.py b/03_control_flujo/autonomos/tabla_multiplicar.py new file mode 100644 index 0000000..c455f37 --- /dev/null +++ b/03_control_flujo/autonomos/tabla_multiplicar.py @@ -0,0 +1,57 @@ +# EJERCICIO AUTÓNOMO 3: Tablas de multiplicar +# Enunciado: Genera una tabla de multiplicar del 1 al 5 usando `for` anidados. + +# TODO 0: Imprimir titulo del programa +print("---- TABLA DE MULTIPLICAR ----") + +# TODO 1: Identificar el rango del 1 al 5 para las tablas de multiplicar +numeros = list(range(1, 6)) +print(numeros) + +# TODO 2: Empezar un bucle for que muestre los números de las tablas +for num1 in numeros: + # TODO 3: Imprimir los numeros del 1 al 5 para que visualicen las tablas + print(f"\nTabla del {num1}") + # TODO 4: Añadir segundo bucle dentro del primero para que los numeros se crucen para las tablas + for num2 in numeros: + # TODO 5: Imprimir el calculo de cada tabla junto con el resultado + print(f"{num1} x {num2} = {num1 * num2}") + +# RESULTADO: +# ---- TABLA DE MULTIPLICAR ---- +# [1, 2, 3, 4, 5] +# +# Tabla del 1 +# 1 x 1 = 1 +# 1 x 2 = 2 +# 1 x 3 = 3 +# 1 x 4 = 4 +# 1 x 5 = 5 + +# Tabla del 2 +# 2 x 1 = 2 +# 2 x 2 = 4 +# 2 x 3 = 6 +# 2 x 4 = 8 +# 2 x 5 = 10 +# +# Tabla del 3 +# 3 x 1 = 3 +# 3 x 2 = 6 +# 3 x 3 = 9 +# 3 x 4 = 12 +# 3 x 5 = 15 +# +# Tabla del 4 +# 4 x 1 = 4 +# 4 x 2 = 8 +# 4 x 3 = 12 +# 4 x 4 = 16 +# 4 x 5 = 20 +# +# Tabla del 5 +# 5 x 1 = 5 +# 5 x 2 = 10 +# 5 x 3 = 15 +# 5 x 4 = 20 +# 5 x 5 = 25 \ No newline at end of file diff --git a/03_control_flujo/clasificador/clasificador.py b/03_control_flujo/clasificador/clasificador.py new file mode 100644 index 0000000..f2425ff --- /dev/null +++ b/03_control_flujo/clasificador/clasificador.py @@ -0,0 +1,46 @@ +# EJERCICIO GUIADO 1: Clasificador simple +# Enunciado: Pide un número y clasifícalo como negativo, cero o positivo. Valida `ValueError`. + +# TODO 0: Imprimir título del programa y su descripción +print("---- Clasificador cimple ----") +print("Pide un número y clasifícalo como negativo, cero o positivo.\n") + +# TODO 1: Pedir número al usuario +num = input("Escribe un número --> ") + +# TODO 2: Evaluar si es un número usando try/except +try: + # TODO 3: Intentar convertir num a float + num = float(num) + + # TODO 4: clasificar num usando if/elif/else + if num < 0: + print("Negativo") + elif num == 0: + print("Cero") + else: + print("Positivo") + +# TODO 5: Mensaje de error si num no es un número +except ValueError: + print(f"ERROR ❌. El número introducido no es un número.") + +# Perfecto! Ahora ya se tiene un clasificador de números interactivo. +# Vamos a hacer pruebas: +# ----------------------------------------------------------------- +# Nº1 +# Escribe un número --> 10 +# Positivo +# ----------------------------------------------------------------- +# Nº2 +# Escribe un número --> -25 +# Negativo +# ----------------------------------------------------------------- +# Nº3 +# Escribe un número --> 0 +# Cero +# ----------------------------------------------------------------- +# Nº4 +# Escribe un número --> pepe +# ERROR ❌. El número introducido no es un número. +# ----------------------------------------------------------------- \ No newline at end of file diff --git a/03_control_flujo/desafio/turnos.py b/03_control_flujo/desafio/turnos.py new file mode 100644 index 0000000..806d2b7 --- /dev/null +++ b/03_control_flujo/desafio/turnos.py @@ -0,0 +1,68 @@ +# DESAFIO: Bigotes Felices (turnos) +# Enunciado: Dado un número de gatos y dos cuidadores, asigna alternadamente gatos a Turno A y B. + +# TODO 0: Imprimir título y descripción del ejercicio +print("---- BIGOTES FELICES ----") +print("-- Asignación de gatos por turnos --") + +# TODO 1: Bucle while que se repite hasta insertar un número de gatos que sea mayor que 0 +while True: + # TODO 2: Intentar convertir 'gatos' a int a la hora que pida el programa al usuario + try: + # TODO 3: Pedir un número de gatos al usuario + gatos = int(input("\nIntroduce un número de gatos --> ")) + + # TODO 4: Condicional si el numero introducido es 0 o menor y se repetiría el bucle while + if gatos <= 0: + print("Debe ingresar al menos 1 gato para la lista de asignacion.") + continue + # TODO 5: Condicional si se asigna un numero específico de gatos se mostraría una lista de turnos + else: + # TODO 6: Imprimir lista + print(f"\nLista de asignación para {gatos} gatos") + print("---------------------") + # TODO 7: Agregar contadores para el número de turnos que tiene cada cuidador + cuidador_a = 0 + cuidador_b = 0 + + # TODO 8: Añadir bucle for para recorrer el numero de gatos introducido + for i in range(1, gatos + 1): + # TODO 9: Condicional si el numero recorrido es par se le asignará al cuidador A + if i % 2 == 0: + print(f"{i}º gato | Cuidador A") + cuidador_a += 1 + # TODO 10: Condicional si el numero recorrido es impar se le asignará al cuidador B + else: + print(f"{i}º gato | Cuidador B") + cuidador_b += 1 + # TODO 11: Una vez recorrido la lista, salir del bucle while + break + + # TODO 12: Mostrar mensaje de error si el valor introducido por el programa no es un número + except ValueError: + print("ERROR ❌. No ha insertado un número de gatos.") + continue + +# TODO 13: Imprimir cantidad de gatos y el número de turnos de cada cuidador +print(f"\nNúmero de gatos: {gatos}") +print(f"Número de gatos para la cuidadora A: {cuidador_a}") +print(f"Número de gatos para la cuidadora B: {cuidador_b}") + +# RESULTADO: +# ---- BIGOTES FELICES ---- +# -- Asignación de gatos por turnos -- +# +#Introduce un número de gatos --> 6 +# +# Lista de asignación para 6 gatos +# --------------------- +# 1º gato | Cuidador B +# 2º gato | Cuidador A +# 3º gato | Cuidador B +# 4º gato | Cuidador A +# 5º gato | Cuidador B +# 6º gato | Cuidador A +# +# Número de gatos: 6 +# Número de gatos para la cuidadora A: 3 +# Número de gatos para la cuidadora B: 3 \ No newline at end of file diff --git a/03_control_flujo/ejercicio_guiado/calculadora_v3.py b/03_control_flujo/ejercicio_guiado/calculadora_v3.py index 02191bc..a7d0505 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,53 +33,86 @@ # 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("¡Nos vemos 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 inválida. Vuelva a intentarlo.") + continue # TODO 6: Pide los dos números # num1 = float(input("Primer número: ")) # num2 = float(input("Segundo número: ")) - - - # 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 - - - # TODO 8: Realiza la operación según la opción elegida - # 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}") - + num1 = input("Introduce su primer número: ") + num2 = input("Introduce su segundo número: ") + + # TODO 6.5: Validar si los dos números son de tipo float + try: + num1 = float(num1) + num2 = float(num2) + + # 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("❌ Error: No se puede dividir por 0") + continue + + # TODO 8: Realiza la operación según la opción elegida + # 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 = "/" + if opcion == "1": + resultado = num1 + num2 + simbolo = "+" + if opcion == "2": + resultado = num1 - num2 + simbolo = "-" + if opcion == "3": + resultado = num1 * num2 + simbolo = "*" + if 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} = {round(resultado, 2)}") + + # TODO 10: Muestra el mensaje de error usando except + except ValueError: + print(f"ERROR ❌. Uno de los valores introducidos (num1: {num1} | num2: {num2}) no es un número. Vuelva a intentarlo.") + continue # ¡Excelente trabajo! Ahora tienes una calculadora interactiva que: # - Se repite hasta que el usuario quiera salir @@ -94,3 +127,13 @@ # 4. Sal con la opción 5 → el programa debe terminar correctamente # # 💡 En la v4 organizarás todo este código en funciones para que sea más limpio +# -------------------------------------------------- +# Primer test: calcular 4 como num1 y 5 como num2 con cualquier operacion +# Resultado: Éxito ✅ +# -------------------------------------------------- +# Segundo test: calcular 'hola' como num1 y 5 como num2 con cualquier operacion +# Resultado: Error ❌ +# Motivo: ValueError: could not convert string to float: 'hola' +# -------------------------------------------------- +# Tercer test: introducir 'hola' para verificar si sale el mensaje de error y que siga corriendo el programa +# Resultado: Éxito ✅ diff --git a/03_control_flujo/suma_acumulada/suma_acumulada.py b/03_control_flujo/suma_acumulada/suma_acumulada.py new file mode 100644 index 0000000..9a8fd7e --- /dev/null +++ b/03_control_flujo/suma_acumulada/suma_acumulada.py @@ -0,0 +1,63 @@ +# EJERCICIO GUIADO 2: Suma acumulada +# Enunciado: Suma números introducidos por el usuario hasta que escriba `fin`. Muestra el total. + +# TODO 0: Imprimir título del programa y su descripción +print("---- Suma acumulada ----") +print("Suma números introducidos por el usuario hasta que escriba 'fin'.\n") + +# TODO 1: definir variable que cuente el total de numeros sumados empezando desde 0 +total = 0 + +# TODO 2: iniciar bucle while que permite introducir tantos datos como quiera el usuario hasta escribir 'fin' +while True: + # TODO 3: pedir un número al usuario + num = input("Introduce un número (escribe 'fin' para terminar)--> ") + + # TODO 4: condicional 'if' si escribe 'fin' se acaba el programa y termina el bucle + if (num == 'fin'): + print("\nSe acabó!!") + print("------------------------") + break + + # TODO 5: condicional 'else' si no escribe 'fin' y siga funcionando el bucle + else: + # TODO 6: Evaluar el valor introducido usando try/except + try: + # TODO 7: Intentar convetir num a float + num = float(num) + # TODO 8: Acumular total con el número introducido + total = total + num + # TODO 9: Imprimir numero introducido y el total acumulado + print(f"Número: {num} | Suma total: {total}") + # TODO 10: Mostrar mensaje de error si el valor introducido no es un número + except ValueError: + print(f"El valor introducido ({num}) no es un número.") + print("Por favor, introduce un número válido o 'fin' para terminar\n") + continue + +# TODO 11: Imprimir el total acumulado una vez salido del bucle while +print(f"Total acumulado: {total}") + +# Prueba del programa: +# ---- Suma acumulada ---- +# Suma números introducidos por el usuario hasta que escriba 'fin'. +# +# Introduce un número (escribe 'fin' para terminar)--> 4 +# Número: 4.0 | Suma total: 4.0 +# Introduce un número (escribe 'fin' para terminar)--> 2 +# Número: 2.0 | Suma total: 6.0 +# Introduce un número (escribe 'fin' para terminar)--> 9 +# Número: 9.0 | Suma total: 15.0 +# Introduce un número (escribe 'fin' para terminar)--> 6 +# Número: 6.0 | Suma total: 21.0 +# Introduce un número (escribe 'fin' para terminar)--> yo +# El valor introducido (yo) no es un número. +# Por favor, introduce un número válido o 'fin' para terminar +# +# Introduce un número (escribe 'fin' para terminar)--> fin +# +# Se acabó!! +# ------------------------ +# Total acumulado: 21.0 +# +# Resultado: éxito ✅ \ No newline at end of file diff --git a/04_funciones/autonomos/ejercicio1.py b/04_funciones/autonomos/ejercicio1.py new file mode 100644 index 0000000..09a01b9 --- /dev/null +++ b/04_funciones/autonomos/ejercicio1.py @@ -0,0 +1,39 @@ +# EJERCICIO AUTÓNOMO 1: Es par +# Enunciado: `es_par(n)` -> bool + +# TODO 1: Crear la función 'def es_par(n)' +def es_par(n): + # TODO 1.1: Verificar si el número es divisible por 2 y devuelva 0 (par) o no es divisible por 2 (impar) + if n % 2 == 0: + # TODO 1.2: Devuelve True si el número es par + return True + else: + # TODO 1.3: Devuelve False si el número es impar + return False + +# TODO 2: Crear la funcion principal +def main(): + # TODO 2.1: Imprimir título del ejercicio + print("--- Par o Impar ---") + # TODO 2.2: Verificar si el valor introducido es un número usando try/except + try: + # TODO 2.3: Pedir un número al usuario + num = int(input("\nEscribe un número (Resultado 'True' si es par; 'False' si es impar) --> ")) + # TODO 2.4: Imprimir la función con el número introducido + print(es_par(num)) + # TODO 2.5: Mensaje de error si el valor introducido no es un número + except ValueError: + print("ERROR ❌. Debe introducir un número.") + + +# TODO 3: Punto de entrada del programa +if __name__ == "__main__": + main() + +# EJEMPLO: +# --- Par o Impar --- +# +# Escribe un número (Resultado 'True' si es par; 'False' si es impar) --> 4 +# True +# ------------------------------------------------------------------------- +# Éxito ✅ \ No newline at end of file diff --git a/04_funciones/autonomos/ejercicio2.py b/04_funciones/autonomos/ejercicio2.py new file mode 100644 index 0000000..f249580 --- /dev/null +++ b/04_funciones/autonomos/ejercicio2.py @@ -0,0 +1,48 @@ +# EJERCICIO AUTÓNOMO 2: Área del Rextángulo +# Enunciado: `area_rectangulo(a, b)` + +# TODO 1: Crear la función 'area_rectangulo(a, b)' +def area_rectangulo(a, b): + # TODO 1.1: Calcular el area (base X altura) + area = a * b + # TODO 1.2: Imprimir el area del rectángulo calculado + return f"\nÁrea del rectángulo: {area}" + +# TODO 2: Crear la función principal +def main(): + # TODO 2.1: Bucle 'while' para comprobar si han introducido bien los números + while True: + # TODO 2.2: Imprimir el título del ejercicio + print("--- Área del rectángulo ---") + # TODO 2.3: Verificar si se han introducido dos números usando try/except + try: + # TODO 2.4: Pedir la base del rectángulo + base = float(input("\nEscribe la base del rectángulo --> ")) + # TODO 2.5: Pedir la altura del rectángulo + altura = float(input("\nEscribe la altura del rectángulo --> ")) + + # TODO 2.6: Imprimir la función con la base y la altura introducidos + print(area_rectangulo(base, altura)) + # TODO 2.7: Terminar bucle 'while' al mostrar resultado + break + + # TODO 2.7: Mostrar mensaje de error si uno de los dos valores no es un número + except ValueError: + print("\nERROR ❌. Sólo se permiten introducir números.") + # TODO 2.8: Volver a empezar el bucle si no se han introducidos los datos correctos + continue + +# TODO 3: Punto de entrada del programa +if __name__ == "__main__": + main() + +# EJEMPLO: +# --- Área del rectángulo --- +# +#Escribe la base del rectángulo --> 9 +# +# Escribe la altura del rectángulo --> 4 +# +# Área del rectángulo: 36.0 +# --------------------------------------- +# Éxito ✅ \ No newline at end of file diff --git a/04_funciones/autonomos/ejercicio3.py b/04_funciones/autonomos/ejercicio3.py new file mode 100644 index 0000000..3823416 --- /dev/null +++ b/04_funciones/autonomos/ejercicio3.py @@ -0,0 +1,44 @@ +# EJERCICIO AUTÓNOMO 3: Formatear gato +# Enunciado: `formatear_gato(nombre, edad)` -> string con f-string + +# TODO 1: Crear funcion 'formatear_gato(nombre, edad) +def formatear_gato(nombre, edad): + + # TODO 1.1: Verificar si edad es un número usando try/except + try: + # TODO 1.2: Intentar convertir edad a int + edad = int(edad) + + # TODO 1.3: Devuelve un string con formato de texto f-string + return f"\nSu gato se llama {nombre} y tiene {edad} años." + + # TODO 1.4: Mensaje de error si edad no es un número + except ValueError: + print("\nERROR ❌. Edad debe ser un número") + +# TODO 2: Crear función principal +def main(): + + # TODO 2.1: Imprimir título del ejercicio + print("--- Formatear Gato ---") + + # TODO 2.2: Pedir datos al usuario + nombre = input("\nIntroduce el nombre de su gato --> ") + edad = input("Introduce la edad de su gato --> ") + + # TODO 2.3: Imprimir función con los valores añadidos + print(formatear_gato(nombre, edad)) + +# TODO 3: Punto de entrada del programa +if __name__ == "__main__": + main() + +# EJEMPLO: +# --- Formatear Gato --- +# +# Introduce el nombre de su gato --> Pequeflus +# Introduce la edad de su gato --> 10 +# +# Su gato se llama Pequeflus y tiene 10 años. +# --------------------------------------------- +# Éxito ✅ \ No newline at end of file diff --git a/04_funciones/autonomos/ejercicio4.py b/04_funciones/autonomos/ejercicio4.py new file mode 100644 index 0000000..d56b545 --- /dev/null +++ b/04_funciones/autonomos/ejercicio4.py @@ -0,0 +1,97 @@ +# EJERCICIO AUTÓNOMO 4: Promedio de números +# Enunciado: `promedio(nums)` con manejo de lista vacía + +# TODO 1: Crear la función 'promedio(nums)' +def promedio(nums): + + # TODO 1.2: Añadir una suma acumulable para la lista + suma = 0 + + # TODO 1.3: Agregar bucle 'while' para añadir números en la lista hasta introducir 0 + while True: + # TODO 1.4: Verificar si el valor introducido es un número usando try/except + try: + # TODO 1.4.1: Pedir un número al usuario + num = int(input("\nIntroduce un número (0 para terminar) --> ")) + + # TODO 1.4.2: No agregar a la lista si el numero es menor que 0 + if num < 0: + print("ERROR ❌. Introduce un número mayor que 0.") + continue + + # TODO 1.4.3: Terminar bucle si el número es 0 + if num == 0: + print("Fin de bucle!!") + break + + # TODO 1.4.4: Añadir número introducido a la lista + nums.append(num) + + # TODO 1.4.5: Imprimir lista actual + print(f"Lista: {nums}") + + # TODO 1.4.6: Acumular la suma de los valores de la lista e imprimir + print(f"Suma parcial: {suma} + {num} = ") + suma += num + print(suma) + + # TODO 1.4.7: Imprimir longitud de la lista actual + longitud = len(nums) + print(f"Longitud de la lista actual: {longitud}") + + # TODO 1.5: Mostrar mensaje de error si el valor introducido no es un número + except ValueError: + print("ERROR ❌. Número no válido.") + continue + + # TODO 1.6: Imprimir resumen de la lista al finalizar el bucle + print("\nResumen") + print(f"Lista: {nums} | Suma total: {suma} | Longitud: {longitud}") + + # TODO 1.7: Calcular el promedio de la lista e imprimirlo + medio = suma / longitud + return f"\nCálculo promedio: {medio:.2f}" + +# TODO 2: Crear la función principal +def main(): + # TODO 2.1: Imprimir título del ejercicio + print("--- Promedio de lista de números ---") + # TODO 2.2: Agregar lista vacía para dar forma a la función + nums = [] + # TODO 2.3: Imprimir función con la lista vacía + print(promedio(nums)) + +# TODO 3: Punto de entrada del programa +if __name__ == "__main__": + main() + +# EJEMPLO: +# --- Promedio de lista de números --- +# +# Introduce un número (0 para terminar) --> 2 +# Lista: [2] +# Suma parcial: 0 + 2 = +# 2 +# Longitud de la lista actual: 1 +# +# Introduce un número (0 para terminar) --> 7 +# Lista: [2, 7] +# Suma parcial: 2 + 7 = +# 9 +# Longitud de la lista actual: 2 +# +# Introduce un número (0 para terminar) --> 1 +# Lista: [2, 7, 1] +# Suma parcial: 9 + 1 = +# 10 +# Longitud de la lista actual: 3 +# +# Introduce un número (0 para terminar) --> 0 +# Fin de bucle!! +# +# Resumen +# Lista: [2, 7, 1] | Suma total: 10 | Longitud: 3 +# +# Cálculo promedio: 3.33 +# ------------------------------------------------ +# Éxito ✅ # \ No newline at end of file diff --git a/04_funciones/autonomos/ejercicio5.py b/04_funciones/autonomos/ejercicio5.py new file mode 100644 index 0000000..f1167b8 --- /dev/null +++ b/04_funciones/autonomos/ejercicio5.py @@ -0,0 +1,43 @@ +# EJERCICIO AUTÓNOMO 5: Leer edad +# Enunciado: `leer_edad()` pide una edad por `input()`, valida `ValueError` y retorna un entero o `None`. + +# TODO 1: Crear funcion 'leer_edad()' +def leer_edad(): + # TODO 1.2: Verificar si el valor introducido es un número usando try/except + try: + # TODO 1.3: Pedir la edad del usuario + edad = int(input("\nIntroduce tu edad --> ")) + + # TODO 1.4: Retorna el número entero en formato de texto f-string + return f"\nEdad: {edad} años \n" + # TODO 1.5: Mostrar 'None' si el valor introducido no es un número + except ValueError: + return None + +# TODO 2: Crear función principal +def main(): + # TODO 2.1: Imprimir titulo del ejercicio + print("--- Leer edad ---") + # TODO 2.2: Imprimir función con el valor a pedir + print(leer_edad()) + +# TODO 3: Punto de entrada del programa +if __name__ == "__main__": + main() + +# EJEMPLO 1: +# --- Leer edad --- +# +# Introduce tu edad --> 23 +# +# Edad: 23 años +# +# -------------------------- +# EJEMPLO 2: +# --- Leer edad --- +# +# Introduce tu edad --> e +# None +# +#--------------------------- +# Éxito ✅ \ No newline at end of file diff --git a/04_funciones/desafio/filtro.py b/04_funciones/desafio/filtro.py new file mode 100644 index 0000000..8d7de93 --- /dev/null +++ b/04_funciones/desafio/filtro.py @@ -0,0 +1,96 @@ +# DESAFÍO DE BIGOTES FELICES: Filtro +# Enunciado: Dada una lista de gatos con edades, retorna sólo los mayores de 5 años. + +# TODO 1: Crear funcion para recorrer lista de gatos +def listado(lista): + # TODO 1.1: Imprimir titulo de lista actual + print("\n--- Lista actual de gatos Bigotes Felices ---\n") + + # TODO 1.2: 'if/else' si existe la lista asignada en el parámetro + if lista: + # TODO 1.3: bucle 'for' para recorrer la lista + for gato in lista: + # TODO 1.4: Imprimir datos de la lista en formato de texto f-string + print(f"Nombre: {gato['nombre']} | Edad: {gato['edad']} años") + # TODO 1.5: Imprimir longitud de la lista en formato de texto f-string + print(f"\nNúmero de gatos en la lista: {len(lista)}") + # TODO 1.5: 'else' si no existe la lista de gatos + else: + print("No hay gatos en esa lista.") + +# TODO 2: Crear función para filtrar gatos mayores de 5 años +def mayor_de_5(lista): + # TODO 2.1: Crear lista vacía para agregar gatos filtrados + gatos_mayores = [] + + # TODO 2.2: 'if/else' si existe la lista asignada en el parámetro + if lista: + # TODO 2.3: Imprimir advertencia de filtrado + print("\n--- Filtrando lista de gatos mayores de 5 años ---") + # TODO 2.4: bucle 'for' para recorrer la lista + for gato in lista: + # TODO 2.5: filtrar gatos mayores de 5 años + if gato['edad'] > 5: + # TODO 2.6: añadir gato mayor de 5 años en la lista 'gatos_mayores' + gatos_mayores.append(gato) + # TODO 2.7: Devolver la lista con los datos actualizados + return gatos_mayores + # TODO 2.8: 'else' si no existe la lista de gatos + else: + print("No hay una lista para filtrar.") + +# TODO 3: Crear la función principal +def main(): + + # TODO 3.1: Imprimir título del ejercicio + print("--- BIGOTES FELICES (filtro) ---") + # TODO 3.2: Crear lista de objetos con los datos de los gatos + lista_gatos = [ + {"nombre": "Michi", "edad": 10}, + {"nombre": "Pelusa", "edad": 2}, + {"nombre": "Franky", "edad": 4}, + {"nombre": "Niko", "edad": 5}, + {"nombre": "Pachula", "edad": 7}, + {"nombre": "Simba", "edad": 8}, + {"nombre": "Chachito", "edad": 3} + ] + + # TODO 3.3: Llamar la función 'listado(lista_gatos)' + listado(lista_gatos) + + # TODO 3.4: Filtrar los gatos mayores de 5 años usando la función 'mayor_de_5(lista_gatos)' + gatos_mayores = mayor_de_5(lista_gatos) + + # TODO 3.5: Volver a llamar la función 'listado()' con los gatos mayores de 5 años + listado(gatos_mayores) + +# TODO 4: Punto de entrada del programa +if __name__ == "__main__": + main() + +# RESULTADO: +# --- BIGOTES FELICES (filtro) --- +# +# --- Lista actual de gatos Bigotes Felices --- +# +# Nombre: Michi | Edad: 10 años +# Nombre: Pelusa | Edad: 2 años +# Nombre: Franky | Edad: 4 años +# Nombre: Niko | Edad: 5 años +# Nombre: Pachula | Edad: 7 años +# Nombre: Simba | Edad: 8 años +# Nombre: Chachito | Edad: 3 años +# +# Número de gatos en la lista: 7 +# +# --- Filtrando lista de gatos mayores de 5 años --- +# +# --- Lista actual de gatos Bigotes Felices --- +# +# Nombre: Michi | Edad: 10 años +# Nombre: Pachula | Edad: 7 años +# Nombre: Simba | Edad: 8 años +# +# Número de gatos en la lista: 3 +# --------------------------------------------------- +# Éxito ✅ diff --git a/04_funciones/ejercicio_guiado/calculadora_v4.py b/04_funciones/ejercicio_guiado/calculadora_v4.py index de137ba..21a5a00 100644 --- a/04_funciones/ejercicio_guiado/calculadora_v4.py +++ b/04_funciones/ejercicio_guiado/calculadora_v4.py @@ -19,8 +19,8 @@ 4. Organiza todo en una función main() """ -# TODO 1: Define las funciones para cada operación matemática -# Cada función debe recibir dos parámetros (a, b) y devolver el resultado +# TODO 1: Define las funciones para cada operación matemática +# Cada función debe recibir dos parámetros (a, b) y devolver el resultado def sumar(a, b): """Suma dos números. @@ -33,19 +33,25 @@ def sumar(a, b): La suma de a y b """ # return a + b - pass # Borra esto y escribe el return + suma = a + b + return suma + # pass # Borra esto y escribe el return def restar(a, b): """Resta dos números.""" # TODO: Implementa la resta - pass + # pass --> sentencia nula + resta = a - b + return resta def multiplicar(a, b): """Multiplica dos números.""" # TODO: Implementa la multiplicación - pass + # pass --> sentencia nula + multi = a * b + return multi def dividir(a, b): @@ -59,7 +65,9 @@ def dividir(a, b): El resultado de a / b """ # TODO: Implementa la división - pass + # pass --> sentencia nula + division = a / b + return division # TODO 2: Crea una función para mostrar el menú @@ -71,7 +79,15 @@ def mostrar_menu(): # print("3. Multiplicar") # print("4. Dividir") # print("5. Salir") - pass + + # pass --> Sentencia nula + 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 @@ -84,7 +100,11 @@ def obtener_numeros(): # num1 = float(input("Primer número: ")) # num2 = float(input("Segundo número: ")) # return num1, num2 - pass + # pass --> Sentencia nula + num1 = float(input("Primer número --> ")) + num2 = float(input("Segundo número -->")) + return num1, num2 + # TODO 4: Crea la función principal que contiene el bucle del programa @@ -92,56 +112,89 @@ def main(): """Función principal de la calculadora.""" # while True: + while True: # TODO 4.1: Muestra el menú llamando a la función mostrar_menu() # mostrar_menu() + mostrar_menu() # TODO 4.2: Pide la opción al usuario # opcion = input("\nElige una opción: ") + opcion = input("\nElige una opción: ") # TODO 4.3: Si elige salir, termina # if opcion == "5": # print("¡Hasta pronto! 👋") # break + if opcion == "5": + print("Hasta luego Lucas! ✨") + break # TODO 4.4: Valida que la opción sea válida # if opcion not in ["1", "2", "3", "4"]: # print("❌ Opción no válida") # continue - - # TODO 4.5: Obtén los números llamando a la función obtener_numeros() - # num1, num2 = obtener_numeros() - - # TODO 4.6: Controla división por cero - # if opcion == "4" and num2 == 0: - # print("❌ No se puede dividir por cero") - # continue - - # TODO 4.7: Llama a la función correspondiente según la opción - # Nota cómo ahora el código es mucho más limpio - # 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 = "/" - - # TODO 4.8: Muestra el resultado - # print(f"✅ {num1} {simbolo} {num2} = {resultado:.2f}") - - pass + if opcion not in ["1", "2", "3", "4"]: + print("\n❌ Opción no válida.") + continue + + # TODO 4.4.5: Validar si el valor introducido es número usando try/except + try: + + # TODO 4.5: Obtén los números llamando a la función obtener_numeros() + # num1, num2 = obtener_numeros() + num1, num2 = obtener_numeros() + + # TODO 4.6: Controla división por cero + # if opcion == "4" and num2 == 0: + # print("❌ No se puede dividir por cero") + # continue + if opcion == "4" and num2 == 0: + print("\n❌ No se puede dividir por cero") + continue + + # TODO 4.7: Llama a la función correspondiente según la opción + # Nota cómo ahora el código es mucho más limpio + # 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 = "/" + if opcion == "1": + resultado = sumar(num1, num2) + simbolo = "+" + elif opcion == "2": + resultado = restar(num1, num2) + simbolo = "-" + elif opcion == "3": + resultado = multiplicar(num1, num2) + simbolo = "X" + elif opcion == "4": + resultado = dividir(num1, num2) + simbolo = "/" + + # TODO 4.8: Muestra el resultado + # print(f"✅ {num1} {simbolo} {num2} = {resultado:.2f}") + print(f"\n{num1} {simbolo} {num2} = {resultado:.2f}") + # TODO 4.9: Muestra el error si el valor introducido no es un número + except ValueError: + print("\n❌ Se debe introducir un número.") + continue + # pass --> Sentencia nula # 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/04_funciones/guiado/saludo.py b/04_funciones/guiado/saludo.py new file mode 100644 index 0000000..2c92097 --- /dev/null +++ b/04_funciones/guiado/saludo.py @@ -0,0 +1,24 @@ +# Guiado 1: Función saludo +# Enunciado: Crea `def saludar(nombre):` que retorne `Hola, `. + +# TODO 0: Imprime el titulo de ejercicio +print("--- Función Saludo ---") +# TODO 1: Crearemos una función con 1 parámetro (nombre) para mostrar el saludo +def saludar(nombre): + # TODO 2: Devuelve el saludo + return f"Hola, {nombre}" + +# TODO 2: Pide un nombre al usuario +nombre = input("\nIntroduce un nombre --> ") + +# TODO 3: Punto de entrada del programa +if __name__ == "__main__": + print(saludar(nombre)) + +# Resultado: +# --- Función Saludo --- +# +# Introduce un nombre --> Pedro +# Hola, Pedro +# ----------------------------- +# Éxito ✅ \ No newline at end of file diff --git a/04_funciones/guiado/sumar_lista.py b/04_funciones/guiado/sumar_lista.py new file mode 100644 index 0000000..dde5ff2 --- /dev/null +++ b/04_funciones/guiado/sumar_lista.py @@ -0,0 +1,34 @@ +# Guiado 2: Sumar lista +# Enunciado: Crea `def sumar(nums):` que sume elementos y retorne el total. +# Valida que `nums` sea lista. + +# TODO 0: Imprime el título del ejercicio +print("--- Función Sumar Lista ---") + +# TODO 1: Crear la funcion 'def sumar(nums)' +def sumar(nums): + # TODO 2: Añadir suma de los números de la lista + suma = 0 + # TODO 3: Iniciar bucle que recorra la lista de números + for i in nums: + # TODO 4: Imprimir numero actual y total actual + print(f"\nNúmero actual: {i} | Suma actual: {suma}") + print(f"Suma parcial: {i} + {suma} =") + # TODO 5: Acumular suma con el numero recorrido e imprimir resultado + suma += i + print(f"{suma}") + # TODO 6: Devolver la suma total + return f"\n --- Suma total: {suma} ---" + +# TODO 7: Declarar lista de números +nums = [9, 3, 2, 12] + +# TODO 8: Punto de entrada del programa +if __name__ == "__main__": + # TODO 9: Validar si 'nums' es una lista de números usando try/except + try: + # TODO 9.5: Imprimir función con el resultado si sale True + print(sumar(nums)) + # TODO 10: Mostrar mensaje de error si 'nums' no es una lista de números o si en la lista de números hay otro valor con diferente tipo de dato + except TypeError: + print("ERROR ❌. La variable 'nums' debe ser una lista de números.") \ No newline at end of file diff --git a/05_colecciones/autonomos/ejercicio1.py b/05_colecciones/autonomos/ejercicio1.py new file mode 100644 index 0000000..668eb16 --- /dev/null +++ b/05_colecciones/autonomos/ejercicio1.py @@ -0,0 +1,34 @@ +# EJERCICIO AUTÓNOMO 1: Vacunas +# Enunciado: Conjunto de vacunas (set) y prueba de pertenencia. + +# TODO 1: Crear conjunto de vacunas (set) +vacunas = {"rabia", "gripe", "hepatitis B", "tuberculosis"} + +# TODO 2: Crear función principal +def main(): + # TODO 2.1: Imprimir título del ejercicio + print("\n--- Lista de Vacunas ---") + # TODO 2.2: Hacer prueba booleana usando 'in' + print(f"1. Vacuna contra la rabia: {'rabia' in vacunas}") + print(f"2. Vacuna contra la gastroenteritis: {'gastroenteritis' in vacunas}") + print(f"3. Vacuna contra la gripe: {'gripe' in vacunas}") + print(f"4. Vacuna contra la hepatitis B: {'hepatitis b' in vacunas}") + print(f"5. Vacuna contra la tuberculosis: {'tuberculosis' in vacunas}") + print(f"6. Vacuna contra la varicela: {'varicela' in vacunas}") + print(f"7. Vacuna contra el tétanos: {'tetanos' in vacunas}") + +# TODO 3: Punto de entrada del programa +if __name__ == "__main__": + main() + +# RESULTADO: +# --- Lista de Vacunas --- +# 1. Vacuna contra la rabia: True +# 2. Vacuna contra la gastroenteritis: False +# 3. Vacuna contra la gripe: True +# 4. Vacuna contra la hepatitis B: False +# 5. Vacuna contra la tuberculosis: True +# 6. Vacuna contra la varicela: False +# 7. Vacuna contra el tétanos: False +# ------------------------------------------- +# Éxito ✅ \ No newline at end of file diff --git a/05_colecciones/autonomos/ejercicio2.py b/05_colecciones/autonomos/ejercicio2.py new file mode 100644 index 0000000..be7e240 --- /dev/null +++ b/05_colecciones/autonomos/ejercicio2.py @@ -0,0 +1,41 @@ +# EJERCICIO AUTÓNOMO 2: Combinación de listas +# Enunciado: Combina dos listas en un dict `{nombre: edad}`. + +# TODO 1: Crear funcion principal +def main(): + # TODO 1.1: Imprimir título del ejercicio + print("--- Combinación de listas ---") + + # TODO 1.2: Declarar 2 listas a combinar + lista1 = ["nombre", "edad", "color"] + lista2 = ["David", 25, "Verde"] + + # TODO 1.3: Declarar un diccionario que conjunte los dos listas + # zip() --> Esta función toma las dos listas y las combina en una secuencia de tuplas, + # donde cada tupla contiene un elemento de cada lista en la misma posición. + # EJ: zip(["nombre"], ["edad"]) crea [('nombre', 'edad')] + # dict() --> Esta función toma la iterable de tuplas y crea un diccionario a partir de él, + # usando el primer elemento de cada tupla como la clave y el segundo como valor + # EJ: dict(zip(["nombre"], ["edad"])) crea {'nombre': 'edad'} + diccionario = dict(zip(lista1, lista2)) + + # TODO 1.4: Imprimir las dos listas y el diccionario conjunto de dichas listas + print(f"\nPrimera lista: {lista1}") + print(f"\nSegunda lista: {lista2}") + print(f"\nDiccionario conjunto entre dos listas: {diccionario}\n") + +# TODO 2: Punto de entrada del programa +if __name__ == "__main__": + main() + +# RESULTADO: +# --- Combinación de listas --- +# +# Primera lista: ['nombre', 'edad', 'color'] +# +# Segunda lista: ['David', 25, 'Verde'] +# +# Diccionario conjunto entre dos listas: {'nombre': 'David', 'edad': 25, 'color': 'Verde'} +# +# ----------------------------------------------- +# Éxito ✅ \ No newline at end of file diff --git a/05_colecciones/autonomos/ejercicio3.py b/05_colecciones/autonomos/ejercicio3.py new file mode 100644 index 0000000..51f1857 --- /dev/null +++ b/05_colecciones/autonomos/ejercicio3.py @@ -0,0 +1,87 @@ +# EJERCICIO AUTÓNOMO 3: Ocurrencias de letras +# Enunciado: Cuenta ocurrencias de letras en un string con un dict. + +# TODO 1: Crear función que devuelva un diccionario de caractéres de un texto específico +def contar_letras(texto): + + # TODO 1.2: Comprobar si el texto está vacío o no + if not texto: + print("El texto está vacío.") + return + + # TODO 1.3: Comprobar si el texto tiene sólo espacios en blanco usando isspace() + if texto.isspace(): + print("El texto recibido sólo tiene espacios en blanco.") + return + + # TODO 1.4: + # Una vez pasadas las 2 comprobaciones, declarar dict vacío + # para después enumerar cuántas letras hay en el texto + contador = {} + # TODO 1.5: Imprimir texto solicitado + print(f"\nTexto recibido: {texto}\n") + + # TODO 1.6: Imprimir título de recorrido de letras antes del bucle + print(f"--- Recorriendo texto sin contar espacios... ---") + # TODO 1.7: Empezar bucle for que enumera las letras del texto + for i, letra in enumerate(texto, 1): + # TODO 1.7.1: Convertir las letras en minúsculas usando lower() + letra_min = letra.lower() + # TODO 1.7.2: Contar letras (ignoramos espacios y otros caracteres usando isalpha()) + if letra_min.isalpha(): + # TODO 1.7.3: Imprimir recorrido de la lista sin contar espacios ni otros caracteres + print(f"{i}: {letra}") + + # TODO 1.7.4: Verificar si la letra ya existe en el diccionario + if letra_min in contador: + # TODO 1.7.5: Aumentar su contador si la letra ya existe + contador[letra_min] += 1 + else: + # TODO 1.7.6: Crear con valor 1 si la letra NO existe todavía + contador[letra_min] = 1 + + # TODO 1.8: Retornar el diccionario con las letras recorridas + return contador + +# TODO 2: Crear funcion que muestre los resultados del contador +def mostrar_ocurrencias(contador): + + # TODO 2.1: Comprobar si hay contenido en el contador o no + if not contador: + print("No hay letras de texto para contar.") + return + # TODO 2.2: Seguir adelante si hay contenido + else: + # TODO 2.3: Imprimir contador + print(f"\nDiccionario con ocurrecias de letras: {contador}") + # TODO 2.4: Imprimir título del recorrido del diccionario del contador + print("\n--- Recorriendo diccionario... ---") + + # TODO 2.5: Empezar bucle for que recorre el contador de letras + for i, letra in enumerate(contador, 1): + # TODO 2.5.1: Comprobar si el número de veces que ha contado en cada carácter es 1 o más + if contador[letra] == 1: + # TODO 2.5.2: Imprimir que se ha contado una vez si el número de veces es 1. + print(f"Letra nº{i}: {letra} | Se ha contado {contador[letra]} vez.") + else: + # TODO 2.5.3: Imprimir que se contó muchas veces si el número es superior a 1. + print(f"Letra nº{i}: {letra} | Se han contado {contador[letra]} veces.") + + # TODO 2.6: Imprimir final del recorrido + print("\nFinal del recorrido!!") + +# TODO 3: Crear función principal +def main(): + # TODO 3.1: Imprimir título del ejercicio + print("--- Contador de letras ---") + # TODO 3.2: Pedir al usuario una frase + texto = input("\nIntroduce una frase --> ") + # TODO 3.3: Declarar variable para retornar un diccionario del texto pedido + contador = contar_letras(texto) + # Todo 3.4: Función para mostrar recorrido de las letras del texto + mostrar_ocurrencias(contador) + + +# TODO 4: Punto de entrada del programa +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/05_colecciones/autonomos/ejercicio4.py b/05_colecciones/autonomos/ejercicio4.py new file mode 100644 index 0000000..260fa0c --- /dev/null +++ b/05_colecciones/autonomos/ejercicio4.py @@ -0,0 +1,98 @@ +# EJERCICIO AUTÓNOMO 4: Slicing y comprehensions simples de listas. +# Enunciado: Slicing y comprensiones simples de listas. + +# TODO 1: Función que muestra contenido de slicing +def slicing(lista, texto): + print(f"\n--- Slicing de la lista --> {lista} ---") + + print("\nSintaxis de Slicing: lista[inicio:fin:paso]") + + # Slicing básico --> lista[inicio:fin] + print("\nEjemplos de slicing básicos (lista[inicio:fin])") + + print(f"\nNúmeros [2:6]: {lista[2:6]}") # Del índice 2 hasta el 5 (6 no incluído) + print(f"Números [:4]: {lista[:4]}") # Desde el principio hasta el índice 3 + print(f"Números [5:]: {lista[5:]}") # Desde el índice 5 hasta el final + print(f"Números [-3:]: {lista[-3:]}") # Los 3 últimos índices + print(f"Números [:-4]: {lista[:-4]}") # La lista excepto los 4 últimos índices + + # Slicing con paso --> lista[inicio:fin:paso] + print("\nEjemplos de slicing con paso (lista[inicio:fin:paso])") + + print(f"\nNúmeros [::2]: {lista[::2]}") # Todos, pero de 2 en 2 + print(f"Números [3::2]: {lista[3::2]}") # Desde el índice 3, de 2 en 2 + print(f"Números [::-1]: {lista[::-1]}") # Invertir la lista + + print(f"\n--- Slicing del texto --> {texto} ---") + print(f"String [0:6]: {texto[0:11]}") # Me encantan + print(f"String [12:]: {texto[12:]}") # los cachopos + print(f"String [::-1]: {texto[::-1]}") # Invierte el texto + +# TODO 2: Funcion que muestra contenido de compresiones +def comprensiones(lista, texto): + print(f"\n--- Comprensiones de la lista --> {lista} ---") + + print("\nFormato de las comprensiones: [expresion for elemento in lista]") + + print("\nEjemplos básicos:") + + print("\n1. Formato: [numero * 2 for numero in lista]") + dobles = [numero * 2 for numero in lista] + print(f"Lista de números multiplicados por dos: {dobles}") + + print("\n2. Formato: [numero ** 2 for numero in lista]") + cuadrados = [numero ** 2 for numero in lista] + print(f"Lista de números al cuadrado: {cuadrados}") + + print("\nEjemplos con condición --> Formato: [expresion for elemento in lista if condicion]") + + print("\n1. Formato: [numero for numero in lista if numero % 2 == 0]") + pares = [numero for numero in lista if numero % 2 == 0] + print(f"Lista de números pares: {pares}") + + print("\n2. Formato: [numero ** 3 for numero in lista if numero % 2 != 0]") + imparescubos = [numero ** 3 for numero in lista if numero % 2 != 0] + print(f"Lista de números impares al cubo: {imparescubos}") + +# TODO 3: Crear función principal +def main(): + print("--- Slicing y compresiones simples de listas ---") + + lista = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] + texto = "Me encantan los cachopos" + + print(f"\nLista predeterminada: {lista}") + print(f"Texto predefinido: {texto}") + + while True: + + print("\n1. Slicing de la lista") + print("2. Compresiones simples de la lista") + print("3. Salir") + + try: + opcion = int(input("\nElige una opcion --> ")) + + if opcion == 1: + print("Opción 1 confirmada!!") + slicing(lista, texto) + continue + elif opcion == 2: + print("Opcion 2 confirmada!!") + comprensiones(lista, texto) + continue + elif opcion == 3: + print("Opcion 3 confirmada!! Que tenga buen día!! ✨") + break + else: + print("❌ Opción no válida") + continue + + except ValueError: + print("❌ Opción no válida") + continue + + +# TODO 4: Punto de entrada del programa +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/05_colecciones/autonomos/ejercicio5.py b/05_colecciones/autonomos/ejercicio5.py new file mode 100644 index 0000000..1dd04a8 --- /dev/null +++ b/05_colecciones/autonomos/ejercicio5.py @@ -0,0 +1,62 @@ +# EJERCICIO AUTÓNOMO 5: Reporte de Gatos +# Enunciado: Imprime un reporte de gatos con `f-strings` a partir de un dict `{nombre: edad}`. + +# TODO 1: Definir función que imprima un reporte de gatos +def reporte(dict): + for i, gato in enumerate(dict, 1): + print("----------------") + print(f"{i}º Gato:") + for clave, valor in gato.items(): + if clave == "nombre": + print(f"Su {clave} es {valor}.") + + if clave == "edad": + print(f"Tiene {valor} años.") + + + print("----------------") + +# TODO 2: Definir función principal +def main(): + print("--- Reporte de gatos ---\n") + + reporte_gatos = [ + {"nombre": "Michi", "edad": 24}, + {"nombre": "Leo", "edad": 3}, + {"nombre": "Nico", "edad": 8}, + {"nombre": "Chuchi", "edad": 3}, + {"nombre": "Chachito", "edad": 5}, + ] + + reporte(reporte_gatos) + + +# TODO 3: Punto de entrada del programa +if __name__ == "__main__": + main() + +# RESULTADO: +# --- Reporte de gatos --- +# +# ---------------- +# 1º Gato: +# Su nombre es Michi. +# Tiene 24 años. +# ---------------- +# 2º Gato: +# Su nombre es Leo. +# Tiene 3 años. +# ---------------- +# 3º Gato: +# Su nombre es Nico. +# Tiene 8 años. +# ---------------- +# 4º Gato: +# Su nombre es Chuchi. +# Tiene 3 años. +# ---------------- +# 5º Gato: +# Su nombre es Chachito. +# Tiene 5 años. +# ---------------- +# Éxito ✅ \ No newline at end of file diff --git a/05_colecciones/desafio/top-k.py b/05_colecciones/desafio/top-k.py new file mode 100644 index 0000000..ed7b98b --- /dev/null +++ b/05_colecciones/desafio/top-k.py @@ -0,0 +1,60 @@ +# DESAFÍO DE BIGOTES FELICES: Top-K +# Enunciado: Dada una lista de pesos de gatos, muestra los 3 más pesados. + +# TODO 1: Función que imprime el recorrido de la lista de gatos +def imprimir(gatos): + + for i, gato in enumerate(gatos, 1): + print(f"{i}. Nombre: {gato['nombre']} | Peso: {gato['peso']} kg.") + +# TODO 2: Función que ordena de mayor a menor peso la lista de gatos +def los_tres_pesados(gatos): + + print("\n--- Listando gatos de menor a mayor... ---") + + gatos_ordenados = sorted(gatos, key=lambda p:p['peso'], reverse=True) + + return gatos_ordenados + +# TODO 3: Función que enumera los tres primeros gatos de una lista +def tres_primeros(gatos): + print("\n--- Listando los tres primeros gatos más pesados... ---") + + top_3 = gatos[:3] + + return top_3 + +# TODO 4: Función principal del programa +def main(): + print("--- DESAFÍO BIGOTES FELICES: Top-K ---") + + gatos = [ + {"nombre": "Michi", "peso": 4.5}, + {"nombre": "Luna", "peso": 3.2}, + {"nombre": "Pelusa", "peso": 5.8}, + {"nombre": "Garfield", "peso": 7.3}, + {"nombre": "Simba", "peso": 4.1}, + {"nombre": "Nala", "peso": 6.2}, + {"nombre": "Tom", "peso": 3.8}, + {"nombre": "Felix", "peso": 5.5} + ] + + print("\n--- Lista de gatos ---") + + imprimir(gatos) + + gatos_pesados = los_tres_pesados(gatos) + + print("\n--- Lista de gatos pesados de mayor a menor ---") + + imprimir(gatos_pesados) + + top_tres = tres_primeros(gatos_pesados) + + print("\n--- 👑 Top 3 Gatos Pesados 👑 ---") + + imprimir(top_tres) + +# TODO 5: Punto de entrada del programa +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/05_colecciones/ejercicio_guiado/calculadora_v5.py b/05_colecciones/ejercicio_guiado/calculadora_v5.py index 3caf649..2a5b813 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. @@ -84,11 +84,17 @@ def guardar_operacion(num1, num2, operacion, resultado): # "operacion": operacion, # "resultado": resultado # } + operacion_dict = { + "num1": num1, + "num2": num2, + "operacion": operacion, + "resultado": resultado + } # TODO 3: Añade el diccionario a la lista historial # historial.append(operacion_dict) - - pass + historial.append(operacion_dict) + # pass --> sentencia nula def mostrar_historial(): @@ -97,17 +103,23 @@ def mostrar_historial(): # if not historial: # print("📭 No hay operaciones en el historial") # return + if not historial: + print("👁️ No hay operaciones en el historial") + return # TODO 5: Muestra el título # print("\n📜 HISTORIAL DE OPERACIONES:") + print("\n HISTORIAL DE OPERACIONES:") # TODO 6: Itera sobre el historial con enumerate() # enumerate() nos da el índice (i) y el elemento (op) # El segundo parámetro (1) indica que empiece a contar desde 1 # for i, op in enumerate(historial, 1): # print(f"{i}. {op['num1']} {op['operacion']} {op['num2']} = {op['resultado']:.2f}") + for i, op in enumerate(historial, 1): + print(f"{i}. {op['num1']} {op['operacion']} {op['num2']} = {op['resultado']:.2f}") - pass + # pass --> sentencia nula # ===== FUNCIÓN PRINCIPAL ===== @@ -118,27 +130,43 @@ def main(): # while True: # mostrar_menu() # opcion = input("\nElige una opción: ") + while True: + mostrar_menu() + opcion = input("\nElige una opción: ") # TODO 7: Actualiza la condición de salir (ahora es la opción 6) # if opcion == "6": # print("¡Hasta pronto! 👋") # break + if opcion == "6": + print("¡Hasta luego Lucas! ✨") + break # TODO 8: Añade la nueva opción 5 para ver el historial # if opcion == "5": # mostrar_historial() # continue # Vuelve al menú sin pedir números + if opcion == "5": + mostrar_historial() + continue # TODO 9: Actualiza la validación (ahora hay 5 opciones válidas) # if opcion not in ["1", "2", "3", "4", "5"]: # print("❌ Opción no válida") # continue + if opcion not in ["1", "2", "3", "4", "5"]: + print("❌ Opción no válida.") + continue # num1, num2 = obtener_numeros() + num1, num2 = obtener_numeros() # if opcion == "4" and num2 == 0: # print("❌ No se puede dividir por cero") # continue + if opcion == "4" and num2 == 0: + print("❌ No se puede dividir por cero") + continue # TODO 10: Realiza la operación y guarda en el historial # if opcion == "1": @@ -153,13 +181,27 @@ def main(): # elif opcion == "4": # resultado = dividir(num1, num2) # simbolo = "/" + if opcion == "1": + resultado = sumar(num1, num2) + simbolo = "+" + if opcion == "2": + resultado = restar(num1, num2) + simbolo = "-" + if opcion == "3": + resultado = multiplicar(num1, num2) + simbolo = "*" + if opcion == "4": + resultado = dividir(num1, num2) + simbolo = "/" # print(f"✅ {num1} {simbolo} {num2} = {resultado:.2f}") + print(f"✅ {num1} {simbolo} {num2} = {resultado:.2f}") # TODO 11: Guarda la operación en el historial # guardar_operacion(num1, num2, simbolo, resultado) + guardar_operacion(num1, num2, simbolo, resultado) - pass + # pass --> sentencia nula if __name__ == "__main__": diff --git a/05_colecciones/guiado/lista_gatos.py b/05_colecciones/guiado/lista_gatos.py new file mode 100644 index 0000000..19c4d9d --- /dev/null +++ b/05_colecciones/guiado/lista_gatos.py @@ -0,0 +1,26 @@ +# EJERCICIO GUIADO 1: Lista de gatos +# ENUNCIADO: Crea una lista con 3 nombres y recórrela imprimiendo índices y valores. + +# TODO 1: Crear lista de gatos +lista_gatos = ["Niko", "Michi", "Chachito"] + +# TODO 2: Crear función principal +def main(): + # TODO 2.1: Imprimir título del ejercicio + print("--- Lista de gatos ---") + + # TODO 2.2: Iterar sobre la lista con enumerate() + for i, gato in enumerate(lista_gatos, 1): + print(f"{i}: {gato}") + +# TODO 3: Punto de entrada del programa +if __name__ == "__main__": + main() + +# RESULTADO: +# --- Lista de gatos --- +# 1: Niko +# 2: Michi +# 3: Chachito +# ----------------------- +# Éxito ✅ \ No newline at end of file diff --git a/05_colecciones/guiado/simple_dict.py b/05_colecciones/guiado/simple_dict.py new file mode 100644 index 0000000..6c12e60 --- /dev/null +++ b/05_colecciones/guiado/simple_dict.py @@ -0,0 +1,50 @@ +# EJERCICIO GUIADO 1: Diccionario simple +# ENUNCIADO: Crea un dict con `{"nombre": "Mishi", "edad": 3}` +# y accede a sus claves de forma segura con `get`. + +# TODO 1: Crear diccionario con los datos concretos +dict_gato = {"nombre": "Mishi", "edad": 3} + +# TODO 2: Crear función principal +def main(): + # TODO 2.1: Imprimir título del ejercicio y línea divisoria del principio + print("--- Diccionario del gato ---") + print("----------------------------") + # TODO 2.2: Acceder a la clave 'nombre' del diccionario e imprimir + # get() devuelve el valor de una clave específica + # nombre devuelve el valor de la clave 'nombre' + nombre = dict_gato.get('nombre') + print(f"1. Nombre | {nombre}") + + # TODO 2.3: Acceder a la clave 'edad' del diccionario e imprimir + # edad devuelve el valor de la clave 'edad' + edad = dict_gato.get('edad') + print(f"2. Edad | {edad} años") + + # TODO 2.4: Acceder a la clave 'peso' del diccionario e imprimir + # peso devuelve el valor de la clave 'peso' + # si no existe, devuelve el valor predeterminado 'None' + peso = dict_gato.get('peso') + print(f"3. Peso | {peso} Kg") + + # TODO 2.5: Acceder a la clave 'color' del diccionario e imprimir + # color devuelve el valor de la clave 'color' + # si no existe, devuelve el valor predeterminado 'No registrado' + color = dict_gato.get('color', "No registrado") + print(f"4. Color | {color}") + # TODO 2.6: Imprimir línea divisoria del final + print("----------------------------") + +# TODO 3: Punto de entrada del programa +if __name__ == "__main__": + main() + +# RESULTADO: +# --- Diccionario del gato --- +# ---------------------------- +# 1. Nombre | Mishi +# 2. Edad | 3 años +# 3. Peso | None Kg +# 4. Color | No registrado +# ---------------------------- +# Éxito ✅ \ No newline at end of file diff --git a/06_archivos_y_modulos/autonomos/ejercicio1/ejercicio1.py b/06_archivos_y_modulos/autonomos/ejercicio1/ejercicio1.py new file mode 100644 index 0000000..0ce6427 --- /dev/null +++ b/06_archivos_y_modulos/autonomos/ejercicio1/ejercicio1.py @@ -0,0 +1,80 @@ +# EJERCICIO AUTÓNOMO 1: Gatos CVS +# Enunciado: Guarda un resumen de gatos en `gatos.csv` (separado por comas). + +# Variables previos +# TODO 1: Declaramos una lista de diccionarios que almacenan una lista de gatos +lista_gatos = [ + {"nombre": "Michi", "edad": 3, "peso": 4.5, "color": "Naranja"}, + {"nombre": "Luna", "edad": 7, "peso": 3.2, "color": "Blanco"}, + {"nombre": "Pelusa", "edad": 2, "peso": 5.8, "color": "Gris"}, + {"nombre": "Garfield", "edad": 8, "peso": 7.3, "color": "Naranja"}, + {"nombre": "Simba", "edad": 5, "peso": 4.1, "color": "Marrón"}, + {"nombre": "Nala", "edad": 10, "peso": 6.2, "color": "Negro"}, + {"nombre": "Tom", "edad": 4, "peso": 3.8, "color": "Gris"} +] + +# TODO 2: Recorremos la lista de gatos que queremos guardar en el archivo csv +print("--- Gatos a guardar ---") +for i, gato in enumerate(lista_gatos, 1): + print(f"{i}. Nombre: {gato['nombre']} | Edad: {gato['edad']} años | Peso: {gato['peso']} kg | Color: {gato['color']}") + +# Guardar información en formato CSV +# TODO 1: Empezamos primero por importar el módulo csv +import csv + +# TODO 2: Crear y Escribir el contenido del archivo 'gatos.csv' +try: + print("\nCreando archivo...") + # TODO 2.1: Abrir archivo con permiso de escritura ("w") + # newline="" --> siempre se usa con archivo CSV para evitar problemas con los saltos de línea + # encoding="utf-8" --> evita problemas de codificación en el diccionario + with open("gatos.csv", "w", newline="", encoding="utf-8") as archivo: + + # Definimos nombres de las columnas + campos = ["nombre", "edad", "peso", "color"] + # Creamos el escritor CSV + # csv.DictWriter --> Objeto "escritor" especializado para escribir diccionarios en formato CSV + # archivo --> 1º parámetro con el archivo abierto donde se escribirá + # fieldnames=campos --> 2º parámetro con la lista con los nombres de las columnas del CSV + escritor = csv.DictWriter(archivo, fieldnames=campos) + + # Escribimos la cabecera + # writeheader() --> Escribe la primera línea del CSV con los nombres de las columnas (la cabecera) + # Resultado --> nombre,edad,peso,color + # ⚠️ Importante: Solo se llama UNA vez al inicio. + escritor.writeheader() + + # Escribimos todas las filas + # writerows(lista_gatos) --> Escribe múltiples filas a la vez. + # Toma una lista de diccionarios y escribe cada uno como una línea del CSV + # RESULTADO: + # Michi,3,4.5,Naranja + # Luna,7,3.2,Blanco + # ... + escritor.writerows(lista_gatos) + + print("\n✅ Archivo 'gatos.csv' creado con éxito con módulo csv!") +except Exception as e: + print(f"❌ Hay un error al guardar datos: {e}") + +# TODO 3: Leer y Mostrar el contenido del archivo csv creado +try: + print("\nLeyendo archivo...") + with open("gatos.csv", "r", encoding="utf-8") as archivo: + # Leeremos el contenido del archivo + contenido = archivo.read() + print(f"\n{contenido}") + + with open("gatos.csv", "r", encoding="utf-8") as archivo: + # Contamos las líneas (gatos + cabecera) + lineas = archivo.readlines() + print(f"Total de líneas: {len(lineas)}") + print(f"Total de gatos guardados: {len(lineas) - 1}") + + print("\n✅ Archivo leído correctamente.") + + +except FileNotFoundError: + print("❌ Archivo no encontrado.") +except Exception as e: + print(f"❌ Error al leer el archivo: {e}") \ No newline at end of file diff --git a/06_archivos_y_modulos/autonomos/ejercicio1/gatos.csv b/06_archivos_y_modulos/autonomos/ejercicio1/gatos.csv new file mode 100644 index 0000000..aef2886 --- /dev/null +++ b/06_archivos_y_modulos/autonomos/ejercicio1/gatos.csv @@ -0,0 +1,8 @@ +nombre,edad,peso,color +Michi,3,4.5,Naranja +Luna,7,3.2,Blanco +Pelusa,2,5.8,Gris +Garfield,8,7.3,Naranja +Simba,5,4.1,Marrón +Nala,10,6.2,Negro +Tom,4,3.8,Gris diff --git a/06_archivos_y_modulos/autonomos/ejercicio2/ejercicio2.py b/06_archivos_y_modulos/autonomos/ejercicio2/ejercicio2.py new file mode 100644 index 0000000..b82a406 --- /dev/null +++ b/06_archivos_y_modulos/autonomos/ejercicio2/ejercicio2.py @@ -0,0 +1,52 @@ +# EJERCICIO AUTÓNOMO 2: Módulo 'utiles.py' +# Enunciado: Crea un módulo `utiles.py` con `leer_lineas(ruta)` y `guardar_lineas(ruta, lineas)`. + +# TODO 1: Importamos las funciones del módulo 'utiles.py' +from utiles import leer_lineas, guardar_lineas + +# TODO 2: Imprimir titulo del ejercicio +print("--- Módulo utiles.py ---") + +# TODO 2: Ejemplo Nº 1 de lista de tareas +print("\nEjemplo 1 de guardar tareas:") + +# Definimos lista de tareas +tareas = [ + "Estudiar Python", + "Hacer la cama", + "Comer cachopo" +] + +# Definimos nombre de archivo txt +archivoTxt = "tarea.txt" + +# Función para guardar las líneas de la lista en el archivo txt +guardar_lineas(archivoTxt, tareas) + +# Función que lee las líneas en el archivo txt +leer_lineas(archivoTxt) + +# TODO 2: Ejemplo Nº2 de registro de gatos +print("\nEjemplo 2 de registro de gatos:") + +# Definimos lista de gatos +gatos = [ + "Leo - 6 años - 5.6 kg", + "Niko - 5 años - 6.5 kg", + "Chachito - 7 años - 7.0 kg" +] + +# Definimos nombre de archivo txt +gatosTxt = "gatos.txt" + +# Función para guardar las líneas de la lista en el archivo txt +guardar_lineas(gatosTxt, gatos) + +# Función de lectura de líneas de los gatos en el archivo txt +leer_lineas(gatosTxt) + +# Comprobar la lista de gatos +if gatos: + print(f"\nRegistro de gatos ({len(gatos)} gatos):") + for gato in gatos: + print(f" 🐱 {gato}") diff --git a/06_archivos_y_modulos/autonomos/ejercicio2/gatos.txt b/06_archivos_y_modulos/autonomos/ejercicio2/gatos.txt new file mode 100644 index 0000000..8c5d898 --- /dev/null +++ b/06_archivos_y_modulos/autonomos/ejercicio2/gatos.txt @@ -0,0 +1,4 @@ + +Leo - 6 años - 5.6 kg +Niko - 5 años - 6.5 kg +Chachito - 7 años - 7.0 kg \ No newline at end of file diff --git a/06_archivos_y_modulos/autonomos/ejercicio2/tarea.txt b/06_archivos_y_modulos/autonomos/ejercicio2/tarea.txt new file mode 100644 index 0000000..335e2c1 --- /dev/null +++ b/06_archivos_y_modulos/autonomos/ejercicio2/tarea.txt @@ -0,0 +1,4 @@ + +Estudiar Python +Hacer la cama +Comer cachopo \ No newline at end of file diff --git a/06_archivos_y_modulos/autonomos/ejercicio2/utiles.py b/06_archivos_y_modulos/autonomos/ejercicio2/utiles.py new file mode 100644 index 0000000..b3259f9 --- /dev/null +++ b/06_archivos_y_modulos/autonomos/ejercicio2/utiles.py @@ -0,0 +1,37 @@ +# utiles.py +# Módulo donde se almacena funciones útiles para leer y escribir archivos + +# TODO 1: Función que lee el contenido del archivo y las líneas de texto que contiene +def leer_lineas(ruta): + try: + print("Leyendo archivo...") + with open(ruta, 'r', encoding="utf-8") as archivo: + + contenido = archivo.read() + print(contenido) + + print("\nContando número de líneas:") + with open(ruta, 'r', encoding="utf-8") as archivo: + + lineas = archivo.readlines() + print(len(lineas) - 1) + + print(f"Archivo {ruta} corregido con éxito ✅") + + except FileNotFoundError: + print("❌ Archivo no encontrado") + except Exception as e: + print(f"\n❌ Error al leer el archivo: {e}") + +# TODO 2: Función para guardar las líneas a un archivo específico +def guardar_lineas(ruta, lineas): + try: + print("Escribiendo archivo...\n") + with open(ruta, 'w', encoding="utf-8") as archivo: + + for linea in lineas: + archivo.write(f"\n{linea}") + + print(f"Archivo {ruta} creado con éxito ✅") + except Exception as e: + print(f"\n❌ Error al escribir el archivo: {e}") diff --git a/06_archivos_y_modulos/autonomos/ejercicio3/app.py b/06_archivos_y_modulos/autonomos/ejercicio3/app.py new file mode 100644 index 0000000..a9f44e1 --- /dev/null +++ b/06_archivos_y_modulos/autonomos/ejercicio3/app.py @@ -0,0 +1,26 @@ +# app.py +# Script para utilizar las funciones de 'utiles.py' + +# TODO 1: Importar funciones de utiles +from utiles import leer_lineas, guardar_lineas + +# TODO 2: Imprimir título de app.py +print("--- APP ---") + +# TODO 3: Ejemplo básico + +# Gestión de tareas +print("\nEjemplo 1: Gestión de Tareas") + +tareas = [ + "Despertarme a las 8:30", + "Estudiar hasta las 14:30", + "Jugar Pokemon hasta las 21:30", + "Dormir hasta el día siguiente" +] + +tareaTxt = "tarea.txt" + +guardar_lineas(tareaTxt, tareas) + +leer_lineas(tareaTxt) diff --git a/06_archivos_y_modulos/autonomos/ejercicio3/ejercicio3.md b/06_archivos_y_modulos/autonomos/ejercicio3/ejercicio3.md new file mode 100644 index 0000000..7fcb563 --- /dev/null +++ b/06_archivos_y_modulos/autonomos/ejercicio3/ejercicio3.md @@ -0,0 +1,3 @@ +## Ejercicio Autónomo Nº 3 + +Usa `utiles` desde otro script `app.py`. diff --git a/06_archivos_y_modulos/autonomos/ejercicio3/tarea.txt b/06_archivos_y_modulos/autonomos/ejercicio3/tarea.txt new file mode 100644 index 0000000..b4480de --- /dev/null +++ b/06_archivos_y_modulos/autonomos/ejercicio3/tarea.txt @@ -0,0 +1,5 @@ + +Despertarme a las 8:30 +Estudiar hasta las 14:30 +Jugar Pokemon hasta las 21:30 +Dormir hasta el día siguiente \ No newline at end of file diff --git a/06_archivos_y_modulos/autonomos/ejercicio3/utiles.py b/06_archivos_y_modulos/autonomos/ejercicio3/utiles.py new file mode 100644 index 0000000..b3259f9 --- /dev/null +++ b/06_archivos_y_modulos/autonomos/ejercicio3/utiles.py @@ -0,0 +1,37 @@ +# utiles.py +# Módulo donde se almacena funciones útiles para leer y escribir archivos + +# TODO 1: Función que lee el contenido del archivo y las líneas de texto que contiene +def leer_lineas(ruta): + try: + print("Leyendo archivo...") + with open(ruta, 'r', encoding="utf-8") as archivo: + + contenido = archivo.read() + print(contenido) + + print("\nContando número de líneas:") + with open(ruta, 'r', encoding="utf-8") as archivo: + + lineas = archivo.readlines() + print(len(lineas) - 1) + + print(f"Archivo {ruta} corregido con éxito ✅") + + except FileNotFoundError: + print("❌ Archivo no encontrado") + except Exception as e: + print(f"\n❌ Error al leer el archivo: {e}") + +# TODO 2: Función para guardar las líneas a un archivo específico +def guardar_lineas(ruta, lineas): + try: + print("Escribiendo archivo...\n") + with open(ruta, 'w', encoding="utf-8") as archivo: + + for linea in lineas: + archivo.write(f"\n{linea}") + + print(f"Archivo {ruta} creado con éxito ✅") + except Exception as e: + print(f"\n❌ Error al escribir el archivo: {e}") diff --git a/06_archivos_y_modulos/autonomos/ejercicio4/app.py b/06_archivos_y_modulos/autonomos/ejercicio4/app.py new file mode 100644 index 0000000..24c73af --- /dev/null +++ b/06_archivos_y_modulos/autonomos/ejercicio4/app.py @@ -0,0 +1,36 @@ +# app.py +# Script para utilizar las funciones de 'utiles.py' + +# TODO 1: Importar funciones de utiles +from utiles import leer_lineas, guardar_lineas + +# TODO 2: Imprimir título de app.py +print("--- APP ---") + +# Lista de lineas de comida +lista = [ + "Cachopo", + "Escalopines", + "Solomillo", + "Merluza", + "Zanahoria" +] + +# Archivo (sin nombre ni prefijo) +archivoTXT = "" + +# Funcion que guarda las líneas +guardar_lineas(archivoTXT, lista) + +# Funcion que lee las líneas +leer_lineas(archivoTXT) + +# RESULTADO: +# --- APP --- +# Escribiendo archivo... +# +# ❌ Archivo no encontrado. +# +# Leyendo archivo... +# +# ❌ Archivo no encontrado. diff --git a/06_archivos_y_modulos/autonomos/ejercicio4/ejercicio4.md b/06_archivos_y_modulos/autonomos/ejercicio4/ejercicio4.md new file mode 100644 index 0000000..635f552 --- /dev/null +++ b/06_archivos_y_modulos/autonomos/ejercicio4/ejercicio4.md @@ -0,0 +1,3 @@ +## Ejercicio Autónomo Nº 4 + +Maneja `FileNotFoundError` de forma amable. \ No newline at end of file diff --git a/06_archivos_y_modulos/autonomos/ejercicio4/utiles.py b/06_archivos_y_modulos/autonomos/ejercicio4/utiles.py new file mode 100644 index 0000000..69c2121 --- /dev/null +++ b/06_archivos_y_modulos/autonomos/ejercicio4/utiles.py @@ -0,0 +1,39 @@ +# utiles.py +# Módulo donde se almacena funciones útiles para leer y escribir archivos + +# TODO 1: Función que lee el contenido del archivo y las líneas de texto que contiene +def leer_lineas(ruta): + try: + print("Leyendo archivo... \n") + with open(ruta, 'r', encoding="utf-8") as archivo: + + contenido = archivo.read() + print(contenido) + + print("\nContando número de líneas:") + with open(ruta, 'r', encoding="utf-8") as archivo: + + lineas = archivo.readlines() + print(len(lineas) - 1) + + print(f"Archivo {ruta} corregido con éxito ✅") + + except FileNotFoundError: + print("❌ Archivo no encontrado.\n") + except Exception as e: + print(f"\n❌ Error al leer el archivo: {e}") + +# TODO 2: Función para guardar las líneas a un archivo específico +def guardar_lineas(ruta, lineas): + try: + print("Escribiendo archivo...\n") + with open(ruta, 'w', encoding="utf-8") as archivo: + + for linea in lineas: + archivo.write(f"\n{linea}") + + print(f"Archivo {ruta} creado con éxito ✅") + except FileNotFoundError: + print("❌ Archivo no encontrado.\n") + except Exception as e: + print(f"\n❌ Error al escribir el archivo: {e}") diff --git a/06_archivos_y_modulos/autonomos/ejercicio5/app.py b/06_archivos_y_modulos/autonomos/ejercicio5/app.py new file mode 100644 index 0000000..4444f38 --- /dev/null +++ b/06_archivos_y_modulos/autonomos/ejercicio5/app.py @@ -0,0 +1,42 @@ +# app.py +# Script para utilizar las funciones de 'utiles.py' + +# TODO 1: Importar funciones de utiles +from utiles import leer_lineas, guardar_lineas + +# TODO 2: Imprimir título de app.py +print("--- APP ---") + +while True: + # TODO 3: Pedir al usuario un nombre para el archivo + ARCHIVO = input("\nEscribe un nombre para el archivo a guardar datos --> ") + + if len(ARCHIVO) == 0: + print("❌ No hay nombre de archivo.") + continue + + if not ARCHIVO.isalpha(): + print("❌ Sólo se imprime letras (no valen números ni símbolos).") + continue + + ARCHIVOTXT = ARCHIVO + ".txt" + + print("\nNombre de archivo validado ✅") + + print("\n--- Lista a imprimir datos ---") + lista_gatos = [ + "Michi", + "Simba", + "Niko", + "Leo", + "Chuski" + ] + + for gato in lista_gatos: + print(gato) + + guardar_lineas(ARCHIVOTXT, lista_gatos) + + leer_lineas(ARCHIVOTXT) + + break diff --git a/06_archivos_y_modulos/autonomos/ejercicio5/archivo.txt b/06_archivos_y_modulos/autonomos/ejercicio5/archivo.txt new file mode 100644 index 0000000..fa54c0d --- /dev/null +++ b/06_archivos_y_modulos/autonomos/ejercicio5/archivo.txt @@ -0,0 +1,6 @@ + +Michi +Simba +Niko +Leo +Chuski \ No newline at end of file diff --git a/06_archivos_y_modulos/autonomos/ejercicio5/ejercicio5.md b/06_archivos_y_modulos/autonomos/ejercicio5/ejercicio5.md new file mode 100644 index 0000000..6e50cef --- /dev/null +++ b/06_archivos_y_modulos/autonomos/ejercicio5/ejercicio5.md @@ -0,0 +1,3 @@ +## Ejercicio Autónomo Nº 5 + +Pide por `input()` una ruta de archivo y valida si existe antes de leer. \ No newline at end of file diff --git a/06_archivos_y_modulos/autonomos/ejercicio5/utiles.py b/06_archivos_y_modulos/autonomos/ejercicio5/utiles.py new file mode 100644 index 0000000..9c577e5 --- /dev/null +++ b/06_archivos_y_modulos/autonomos/ejercicio5/utiles.py @@ -0,0 +1,62 @@ +# utiles.py +# Módulo donde se almacena funciones útiles para leer y escribir archivos + +import os + +# TODO 1: Función que lee el contenido del archivo y las líneas de texto que contiene +def leer_lineas(ruta): + + if os.path.exists(ruta): + print(f"\nSobrescribiendo archivo {ruta}...") + + print("\nLeyendo archivo... ") + try: + + with open(ruta, 'r', encoding="utf-8") as archivo: + + contenido = archivo.read() + print(contenido) + + print("\nContando número de líneas:") + with open(ruta, 'r', encoding="utf-8") as archivo: + + lineas = archivo.readlines() + print(len(lineas) - 1) + + print(f"Archivo {ruta} corregido con éxito ✅") + + # Agregar mensaje de error usando FileNotFoundError si no encuentra el archivo + except FileNotFoundError: + print("❌ Archivo no encontrado.\n") + # Agregar mensaje de error usando FileExistsError si existe el archivo + except FileExistsError: + print(f"❌ El archivo {ruta} Ya existe ") + # Agregar mensaje de error usando Exception si ha surgido otro tipo de error + except Exception as e: + print(f"\n❌ Error al leer el archivo: {e}") + +# TODO 2: Función para guardar las líneas a un archivo específico +def guardar_lineas(ruta, lineas): + + print("\n Escribiendo archivo...") + if os.path.exists(ruta): + print(f"❌ El archivo {ruta} Ya existe ") + + else: + try: + + with open(ruta, 'w', encoding="utf-8") as archivo: + + for linea in lineas: + archivo.write(f"\n{linea}") + + print(f"Archivo {ruta} creado con éxito ✅") + # Agregar mensaje de error usando FileNotFoundError si no encuentra el archivo + except FileNotFoundError: + print("❌ Archivo no encontrado.\n") + # Agregar mensaje de error usando FileExistsError si existe el archivo + except FileExistsError: + print(f"❌ El archivo {ruta} Ya existe ") + # Agregar mensaje de error usando Exception si ha surgido otro tipo de error + except Exception as e: + print(f"\n❌ Error al escribir el archivo: {e}") diff --git a/06_archivos_y_modulos/desafio/app.py b/06_archivos_y_modulos/desafio/app.py new file mode 100644 index 0000000..14d7d88 --- /dev/null +++ b/06_archivos_y_modulos/desafio/app.py @@ -0,0 +1,34 @@ +# app.py +# EJERCICIO DESAFIO BIGOTES FELICES: LOGS +# Enunciado: Dado un archivo de logs `visitas.log`, cuenta por día cuántas visitas hubo y guarda un resumen. + +print("--- 😺 BIGOTES FELICES: LOGS 😺 ---") + +# Importamos las funciones necesarias del módulo logs +from logs import guardar_archivo, resumen_archivo, visita_por_dia + +# Listamos dicts de registros +registro_logs = [ + {"fecha": "2024-10-11 08:11:59", "visita": "Visita desde IP 192.168.1.1"}, + {"fecha": "2024-10-11 10:30:43", "visita": "Visita desde IP 192.168.1.2"}, + {"fecha": "2024-10-11 12:41:12", "visita": "Visita desde IP 192.168.1.4"}, + {"fecha": "2024-10-11 17:30:29", "visita": "Visita desde IP 192.168.1.6"}, + {"fecha": "2024-10-12 08:10:32", "visita": "Visita desde IP 192.168.1.8"}, + {"fecha": "2024-10-12 11:11:48", "visita": "Visita desde IP 192.168.1.9"}, + {"fecha": "2024-10-12 18:21:51", "visita": "Visita desde IP 192.168.1.10"}, + {"fecha": "2024-10-13 08:04:12", "visita": "Visita desde IP 192.168.1.11"}, +] + +# Mostramos previo la lista de registros +print("\n--- Registro de logs que queremos almacenar ---") +for log in registro_logs: + print(f"| {log["fecha"]} - {log["visita"]} |") + +# Función que se encarga de guardar el contenido del archivo 'visitas.log' +guardar_archivo("visitas.log", registro_logs) + +# Función que se encarga de leer el contenido del archivo 'visitas.log' +resumen_archivo("visitas.log") + +# Función que devuelve un resumen de los días contados y el total de visitas de x días +visita_por_dia("visitas.log") \ No newline at end of file diff --git a/06_archivos_y_modulos/desafio/logs.py b/06_archivos_y_modulos/desafio/logs.py new file mode 100644 index 0000000..a3c6e6c --- /dev/null +++ b/06_archivos_y_modulos/desafio/logs.py @@ -0,0 +1,87 @@ +# funciones.py +# Módulo donde se almacena funciones útiles para guardar y leer archivos LOG +import os + +# Función que almacena el contenido del archivo ruta +def guardar_archivo(ruta, lineas): + try: + print(f"\nEscribiendo archivo {ruta}...") + + with open(ruta, 'w', encoding="utf-8") as archivo: + + for i, linea in enumerate(lineas, 1): + archivo.write(f"\n{i}º log:\n") + for clave, valor in linea.items(): + line = f"| {clave} - {valor} |" + archivo.write(line) + + print(f"Archivo {ruta} creado y escrito con éxito ✅") + + except FileNotFoundError: + print("❌ El archivo no existe") + except Exception as e: + print(f"❌ Error al escribir el archivo: {e}") + +# Función que lee el contenido ruta +def resumen_archivo(ruta): + + try: + print(f"\nLeyendo y analizando archivo {ruta}...") + with open(ruta, "r", encoding="utf-8") as archivo: + + contenido = archivo.read() + print(contenido) + + with open(ruta, "r", encoding="utf-8") as archivo: + + lineas = archivo.readlines() + print(f"\nNúmero de líneas: {len(lineas)-1}") + + print(f"Archivo {ruta} leído correctamente ✅") + except FileNotFoundError: + print("❌ El archivo no existe.") + except Exception as e: + print(f"❌ Error al leer el archivo: {e}") + +# Funcion de número de visitas por día +def visita_por_dia(ruta): + print("\n-- Visitas por día --") + # Dict vacío para almacenar fechas de logs + visitasXdia = {} + + try: + print("--- Analizando ---") + with open(ruta, "r", encoding="utf-8") as archivo: + for linea in archivo: + # Verificar si la linea recorrida tiene más de 10 caracteres + if len(linea) >= 10: + # Extraer la fecha (| fecha - "2024-10-12" 18:21:51 | recogemos desde el índice 10 hasta el 20 que recoge la fecha) + fecha = linea[10:20] # Slicing para extraer la fecha + + # Contamos la fecha para ese día + if fecha in visitasXdia: + visitasXdia[fecha] += 1 + else: + visitasXdia[fecha] = 1 + + print("Ánalisis completo. ✅") + + print("\nRESUMEN:") + # Total de visitas de x días + total_visitas = 0 + # Recorremos la lista de x fechas que se almacenaron en visitasXdia + for fecha in visitasXdia: + visitas = visitasXdia[fecha] + total_visitas += visitas + if visitas == 1: + print(f"Fecha: {fecha} | {visitas} visita") + else: + print(f"Fecha: {fecha} | {visitas} visitas") + # Resumen del total de visitas en x días + print(f"Total de visitas: {total_visitas} visitas en {len(visitasXdia)} días.") + + + except FileNotFoundError: + print("❌ No se encontró el archivo especificado") + except Exception as e: + print(f"❌ Error al leer el archivo: {e}") \ No newline at end of file diff --git a/06_archivos_y_modulos/desafio/visitas.log b/06_archivos_y_modulos/desafio/visitas.log new file mode 100644 index 0000000..c7706f8 --- /dev/null +++ b/06_archivos_y_modulos/desafio/visitas.log @@ -0,0 +1,17 @@ + +1º log: +| fecha - 2024-10-11 08:11:59 || visita - Visita desde IP 192.168.1.1 | +2º log: +| fecha - 2024-10-11 10:30:43 || visita - Visita desde IP 192.168.1.2 | +3º log: +| fecha - 2024-10-11 12:41:12 || visita - Visita desde IP 192.168.1.4 | +4º log: +| fecha - 2024-10-11 17:30:29 || visita - Visita desde IP 192.168.1.6 | +5º log: +| fecha - 2024-10-12 08:10:32 || visita - Visita desde IP 192.168.1.8 | +6º log: +| fecha - 2024-10-12 11:11:48 || visita - Visita desde IP 192.168.1.9 | +7º log: +| fecha - 2024-10-12 18:21:51 || visita - Visita desde IP 192.168.1.10 | +8º log: +| fecha - 2024-10-13 08:04:12 || visita - Visita desde IP 192.168.1.11 | \ No newline at end of file diff --git a/06_archivos_y_modulos/ejercicio_guiado/calculadora_v6.py b/06_archivos_y_modulos/ejercicio_guiado/calculadora_v6.py index 27d34ed..e3fb8ab 100644 --- a/06_archivos_y_modulos/ejercicio_guiado/calculadora_v6.py +++ b/06_archivos_y_modulos/ejercicio_guiado/calculadora_v6.py @@ -21,8 +21,8 @@ """ # TODO 1: Importa el módulo json -# import json - +# import json, os +import json, os # Nombre del archivo donde se guardará el historial ARCHIVO_HISTORIAL = "historial_calculadora.json" @@ -121,8 +121,21 @@ def cargar_historial(): # print("⚠️ Archivo de historial corrupto, iniciando uno nuevo") # return [] - pass - return [] # Borra esto cuando implementes la función + try: + with open(ARCHIVO_HISTORIAL, "r", encoding="utf-8") as archivo: + datos = json.load(archivo) + print(f"✅ Historial cargado: {len(datos)} operaciones") + return datos + except FileNotFoundError: + # El archivo no existe (primera vez que se ejecuta) + print("🗒️ No hay historial previo, iniciando uno nuevo") + return [] + except json.JSONDecodeError: + # El archivo existe pero está corrupto + print("❌ Archivo de historial corrupto, iniciando uno nuevo") + return [] + + # pass --> sentencia nula def guardar_historial_archivo(): @@ -137,7 +150,16 @@ def guardar_historial_archivo(): # except Exception as e: # print(f"❌ Error al guardar el historial: {e}") - pass + try: + with open(ARCHIVO_HISTORIAL, "w", encoding="utf-8") as archivo: + # indent=2 hace que el JSON sea más legible + # ensure_ascii=False permite emojis y carácteres especiales + json.dump(historial, archivo, indent=2, ensure_ascii=False) + print("✅ Historial guardado correctamente") + except Exception as e: + print(f"❌ Error al guardar el historial: {e}") + + # pass --> sentencia nula def limpiar_historial(): @@ -151,9 +173,16 @@ def limpiar_historial(): # print("❌ Operación cancelada") # return + confirmacion = input("❗ ¿Estás seguro de que quieres limpiar el historial? (s/n): ") + if confirmacion.lower() != "s": + print("❌ Operación cancelada") + return + # Vacía la lista en memoria # historial = [] + historial = [] + # Elimina el archivo si existe # try: # if os.path.exists(ARCHIVO_HISTORIAL): @@ -162,7 +191,14 @@ def limpiar_historial(): # except Exception as e: # print(f"❌ Error al eliminar el archivo: {e}") - pass + try: + if os.path.exists(ARCHIVO_HISTORIAL): + os.remove(ARCHIVO_HISTORIAL) + print("🗑️ Historial limpiado correctamente") + except Exception as e: + print(f"❌ Error al eliminar el archivo: {e}") + + # pass --> Sentencia nula # ===== FUNCIÓN PRINCIPAL ===== @@ -175,10 +211,18 @@ def main(): # print("🔄 Cargando historial...") # historial = cargar_historial() + global historial + print("🔄 Cargando historial...") + historial = cargar_historial() + # while True: # mostrar_menu() # opcion = input("\nElige una opción: ") + while True: + mostrar_menu() + opcion = input("\nElige una opción: ") + # TODO 6: Actualiza la condición de salir (ahora es opción 7) # if opcion == "7": # print("💾 Guardando historial...") @@ -186,27 +230,51 @@ def main(): # print("¡Hasta pronto! 👋") # break + if opcion == "7": + print("💾 Guardando historial...") + guardar_historial_archivo() + print("¡Hasta pronto! 👋") + break + # TODO 7: Añade la opción 5 (ver historial) # if opcion == "5": # mostrar_historial() # continue + if opcion == "5": + mostrar_historial() + continue + # TODO 8: Añade la opción 6 (limpiar historial) # if opcion == "6": # limpiar_historial() # continue + if opcion == "6": + limpiar_historial() + continue + # TODO 9: Actualiza la validación de opciones (ahora son 1-6) # if opcion not in ["1", "2", "3", "4", "5", "6"]: # print("❌ Opción no válida") # continue + if opcion not in ["1", "2", "3", "4", "5", "6"]: + print("❌ Opción no válida") + continue + # num1, num2 = obtener_numeros() + num1, num2 = obtener_numeros() + # if opcion == "4" and num2 == 0: # print("❌ No se puede dividir por cero") # continue + if opcion == "4" and num2 == 0: + print("❌ No se puede dividir entre 0") + continue + # if opcion == "1": # resultado = sumar(num1, num2) # simbolo = "+" @@ -220,10 +288,26 @@ def main(): # resultado = dividir(num1, num2) # simbolo = "/" + 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) - pass + print(f"✅ {num1} {simbolo} {num2} = {resultado:.2f}") + guardar_operacion(num1, num2, simbolo, resultado) + + # pass --> sentencia nula if __name__ == "__main__": diff --git a/06_archivos_y_modulos/guiado/escribir_archivo.py b/06_archivos_y_modulos/guiado/escribir_archivo.py new file mode 100644 index 0000000..3895b55 --- /dev/null +++ b/06_archivos_y_modulos/guiado/escribir_archivo.py @@ -0,0 +1,38 @@ +# EJERCICIO GUIADO 1: Escribir archivo +# ENUNCIADO: Crea `escribir.txt` con tres líneas. + +ARCHIVOTXT = "escribir.txt" + +try: + with open(ARCHIVOTXT, "w") as archivo: + + # Escribir contenido en el archivo + archivo.write("Hola, que tal?") + archivo.write("\nMe encantan los cachopos") + archivo.write("\nY también los chipis") + + # Cerrar el archivo + archivo.close() + print("\n✅ Creado y escrito el archivo correctamente.") +except Exception as e: + print("\n❌ Error al escribir en el archivo txt: {e}") + +try: + with open(ARCHIVOTXT, "r") as archivo: + + print("\nLeyendo archivo...") + + # Leer el contenido del archivo + contenido = archivo.read() + + # Imprimir el contenido + print(contenido) + + # Cerrar el archivo + archivo.close() + + print("\nArchivo leído correcto ✅") +except FileNotFoundError: + print("❌ Archivo no encontrado") + + diff --git a/06_archivos_y_modulos/guiado/leer_archivo.py b/06_archivos_y_modulos/guiado/leer_archivo.py new file mode 100644 index 0000000..d3ca99d --- /dev/null +++ b/06_archivos_y_modulos/guiado/leer_archivo.py @@ -0,0 +1,20 @@ +# EJERCICIO GUIADO 2: Leer archivo +# ENUNCIADO: Lee `escribir.txt` e imprime las líneas numeradas. + +ARCHIVOTXT = 'escribir.txt' + +try: + with open(ARCHIVOTXT, 'r') as archivo: + lineas = archivo.readlines() + + print("\nContenido del archivo: ") + + for numero, linea in enumerate(lineas, 1): + # Usamos .rstrip() para eliminar el salto de línea al final + print(f"{numero}. {linea.rstrip()}") + + print(f"\n--- Información del archivo ---") + print(f"Total de líneas: {len(lineas)}") + +except FileNotFoundError: + print("❌ No se encontró el archivo") \ No newline at end of file diff --git a/07_mini_proyectos/ejercicio_guiado/calculadora_v7.py b/07_mini_proyectos/ejercicio_guiado/calculadora_v7.py index b5e330c..987b117 100644 --- a/07_mini_proyectos/ejercicio_guiado/calculadora_v7.py +++ b/07_mini_proyectos/ejercicio_guiado/calculadora_v7.py @@ -56,14 +56,14 @@ def dividir(a, b): 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(s := "1. Sumar") + print(r := "2. Restar") + print(m := "3. Multiplicar") + print(d := "4. Dividir") + print(v := "5. Ver historial") + print(l := "6. Limpiar historial") + print(s := "7. Salir") def obtener_numeros(): @@ -72,7 +72,7 @@ def obtener_numeros(): # TODO 1: Refactoriza usando operador morsa # Combina el input y la validación en una sola expresión # Pista: while not (entrada := input(...)).algo(): - + '''''''''''''''' while True: entrada1 = input("Primer número: ") try: @@ -90,6 +90,35 @@ def obtener_numeros(): print("❌ Ingresa un número válido") return num1, num2 + ''''''''''' + # Método 1: + while not (entrada1 := input("Primer número: ")).isdigit(): + print("❌ Ingresa un número 1 válido") + num1 = float(entrada1) + while not (entrada2 := input("Segundo número: ")).isdigit(): + print("❌ Ingresa un número 2 válido") + num2 = float(entrada2) + + return num1, num2 + + # Método 2: + '''''''''' + while True: + try: + num1 = float(entrada1 := input("Primer número: ")) + break + except ValueError: + print("❌ Ingresa un número válido") + + while True: + try: + num2 = float(entrada2 := input("Segundo número: ")) + break + except ValueError: + print("❌ Ingresa un número válido") + + return num1, num2 + ''''''''''' # ===== FUNCIONES DE HISTORIAL (memoria) ===== @@ -153,8 +182,8 @@ def limpiar_historial(): # 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": + + if (confirmacion := input("⚠️ ¿Estás seguro de que quieres limpiar el historial? (s/n): ").lower()) != "s": print("❌ Operación cancelada") return @@ -183,7 +212,6 @@ def main(): # TODO 3: Considera si puedes usar operador morsa aquí # ¿Se puede combinar mostrar_menu() y input() de alguna manera? opcion = input("\nElige una opción: ") - if opcion == "7": print("💾 Guardando historial...") guardar_historial_archivo() diff --git a/07_mini_proyectos/retos/reto1/reto1.py b/07_mini_proyectos/retos/reto1/reto1.py new file mode 100644 index 0000000..756dea8 --- /dev/null +++ b/07_mini_proyectos/retos/reto1/reto1.py @@ -0,0 +1,98 @@ +# Reto 1: Procesador interactivo de comandos +# Enunciado: Crea un programa que procese comandos hasta que el usuario escriba "salir". +# +# **Requisitos**: +# - Usa operador morsa en el bucle `while` +# - Comandos: `sumar x y`, `restar x y`, `multiplicar x y`, `dividir x y` +# - Valida que los números sean correctos +# - Muestra error si el comando no es válido +# +# **Ejemplo de uso**: +# ``` +# Comando: sumar 5 3 +# ✅ 5 + 3 = 8 +# +# Comando: dividir 10 0 +# ❌ No se puede dividir por cero +# +# Comando: hola +# ❌ Comando no válido +# +# Comando: salir +# ¡Hasta pronto! +# ``` + +# TODO 1: Función que imprime las instrucciones del reto 1 +def mostrar_instrucciones(): + print("\n--- Instrucciones de uso ---") + print("Escribe uno de estos comandos para interactuar con el programa:") + print("1. sumar x y --> Suma los valores x y") + print("2. restar x y --> Resta los valores x y") + print("3. multiplicar x y --> Multiplica los valores x y") + print("4. dividir x y --> Divide los valores x y (cuidado con agregar '0' en y)") + print("5. salir --> Salimos del programa") + print("'x' es el primer número a introducir en el programa; 'y' es el segundo número a introducir") + print("EJEMPLO: ") + print("Comando: sumar 5 3") + print("✅ 5 + 3 = 8") + print("\nAhora bien, ¿empezamos?") + +# TODO 2: Función de la lógica del programa reto1 +def reto1(): + # Llamamos la función de las intrucciones + mostrar_instrucciones() + + # Bucle principal while: ejecuta comandos hasta escribir la palabra 'salir' + # El operador := (operador morsa) asigna valor a 'comando' y lo evalúa en la misma línea + while (comando := input("\nComando: ").strip().lower()) != "salir": + + # Separar el comando en partes (en este caso 3) + partes = comando.split() + + # Comprobar que 'partes' tenga dividida 3 partes (operador, x, y) + if len(partes) != 3: + print("❌ Comando no válido.") + continue # Volver al inicio del bucle + + # Desempaquetamos las partes del comando + operador, str_x, str_y = partes + + # Intentar que x y sean números flotantes + try: + x, y = float(str_x), float(str_y) + except ValueError: + print("❌ Números no válidos.") + continue + + # Ejecutar la operacion solicitada + if operador == "sumar": + print(f"✅ {x} + {y} = {x + y}") + continue + elif operador == "restar": + print(f"✅ {x} + {y} = {x - y}") + continue + elif operador == "multiplicar": + print(f"✅ {x} + {y} = {x * y}") + continue + elif operador == "dividir": + if y != 0: + print(f"✅ {x} + {y} = {x / y}") + continue + else: + print("❌ No se puede dividir por 0.") + else: + print("❌ Comando no válido.") + + # Una vez introducido la palabra 'salir', finaliza el programa + print("Hasta pronto 👋") + +# TODO 3: Crear función principal +def main(): + # Imprimir título del reto 1 + print("--- 🛠️ Procesador interactivo de comandos 🛠️ ---") + # Llamar función reto1 + reto1() + +# TODO 4: Punto de entrada del programa +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/07_mini_proyectos/retos/reto2/antonio.json b/07_mini_proyectos/retos/reto2/antonio.json new file mode 100644 index 0000000..0cd5e5a --- /dev/null +++ b/07_mini_proyectos/retos/reto2/antonio.json @@ -0,0 +1,6 @@ +{ + "nombre": "antonio", + "email": "anotio@retro.com", + "edad": 45, + "contrasena": "antoniolobato" +} \ No newline at end of file diff --git a/07_mini_proyectos/retos/reto2/app.py b/07_mini_proyectos/retos/reto2/app.py new file mode 100644 index 0000000..ec65bc9 --- /dev/null +++ b/07_mini_proyectos/retos/reto2/app.py @@ -0,0 +1,28 @@ +# Reto 2: Validador de formulario +# Enunciado: Crea un programa que pida datos de registro y los valide: +# - Nombre (mínimo 3 caracteres) +# - Email (debe contener @) +# - Edad (debe ser número entre 18 y 100) +# - Contraseña (mínimo 6 caracteres) +# +# **Requisitos**: +# - Usa operador morsa en TODAS las validaciones +# - Repite la pregunta si el dato no es válido +# - Muestra un resumen al final +# - Guarda los datos en un archivo JSON + +# TODO 1: Importar función validador de formularios en el módulo 'formulario' +from formulario import validar_formulario + +# TODO 2: Crear función principal +def main(): + # Imprimir título del reto + print("--- Validador de formulario ---") + # Llamar función validar_formulario (más información en 'formulario.py') + validar_formulario() + # Imprimir mensaje de despedida + print("\nHasta pronto! 👋") + +# TODO 3: Punto de entrada del programa +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/07_mini_proyectos/retos/reto2/cachopoking.json b/07_mini_proyectos/retos/reto2/cachopoking.json new file mode 100644 index 0000000..101c80c --- /dev/null +++ b/07_mini_proyectos/retos/reto2/cachopoking.json @@ -0,0 +1,6 @@ +{ + "nombre": "david", + "email": "cachopo@gmail.com", + "edad": 23, + "contrasena": "cachopoenorme" +} \ No newline at end of file diff --git a/07_mini_proyectos/retos/reto2/formatoJSON.py b/07_mini_proyectos/retos/reto2/formatoJSON.py new file mode 100644 index 0000000..ee884d3 --- /dev/null +++ b/07_mini_proyectos/retos/reto2/formatoJSON.py @@ -0,0 +1,47 @@ +# formatoJSON.py +# Módulo donde se almacenan funciones de leer y guardar archivo en formato JSON + +# TODO 1: Importar módulos 'os' y'json' +import os, json + +# TODO 2: Función que guarda datos al archivo JSON +def guardar_archivo(ruta, datos): + + # Validación por si el nombre del archivo introducido ya existe + # Si existe el archivo, salta el mensaje de error y muestra el contenido de dicho archivo + if os.path.exists(ruta): + print(f"\n❌ El archivo {ruta} existe.") + print("\nMostrando contenido del archivo existente...") + leer_archivo(ruta) + else: + # Si no existe, se empieza a crear el archivo + print(f"Escribiendo datos en {ruta}...") + # Intentemos escribir el archivo JSON si no hay error + try: + # Escribimos archivo JSON usando 'with open()' y 'json.dump()' + with open(ruta, "w", encoding="utf-8") as archivo: + json.dump(datos, archivo, indent=4, ensure_ascii=False) + # Mensaje de éxito de escritura de datos + print(f"Archivo {ruta} creado y escrito correctamente. ✅") + # Leer los datos escritos + print(f"\nImprimiendo archivo {ruta}...") + leer_archivo(ruta) + # Mensaje de error si hay error al escribir + except Exception as e: + print(f"❌ Ups! Ha habido un error: {e}") + +# TODO 3: Función para leer un archivo +def leer_archivo(ruta): + # Intentemos que lea el archivo si se encuentra el archivo + try: + # Leemos archivo JSON usando 'with open()' y 'json.load()' + with open(ruta, "r", encoding="utf-8") as archivo: + datos = json.load(archivo) + print(f"\n{datos}") + print(f"Archivo {ruta} leído correctamente ✅") + # Mensaje de error si no se encuentra el archivo + except FileNotFoundError: + print(f"\n❌ No se ha encontrado el archivo {ruta}") + # Mensaje de error si hay error al leer + except Exception as e: + print(f"❌ Ups! Ha habido un error: {e}") \ No newline at end of file diff --git a/07_mini_proyectos/retos/reto2/formulario.py b/07_mini_proyectos/retos/reto2/formulario.py new file mode 100644 index 0000000..cd66947 --- /dev/null +++ b/07_mini_proyectos/retos/reto2/formulario.py @@ -0,0 +1,53 @@ +# formulario.py +# Archivo donde se almacena la validación del formulario + +# TODO 1: Importar función que guarda datos de formulario en un archivo JSON en el módulo formatoJSON +from formatoJSON import guardar_archivo + +# TODO 2: Función que valida el formulario +def validar_formulario(): + # Validación de nombre que tenga más de 3 carácteres + while not (nombre := input("\nIntroduce un nombre: ")) or len(nombre) < 3: + print("❌ Nombre inválido. El nombre debe tener al menos 3 caracteres.") + # Validación de email que contenga al menos un '@' y un '.' + while "@" not in (email := input("\nIntroduce un email válido: ")) or "." not in email: + print("❌ Email inválido. El email debe contener al menos un @ y un punto (.).") + # Validación de edad que sea número entero y que esté comprendido entre 18 y 100 + while True: + try: + if not (edad := int(input("\nIntroduce su edad: "))) or edad < 18 or edad > 100: + print("❌ Edad no válida. La edad debe ser entre 18 y 100 años.") + continue + break + except ValueError: + print("❌ Edad no válida. La edad debe ser un número.") + continue + # Validación de contraseña que tenga más de 6 carácteres + while not (contrasena := input("\nIntroduce una contraseña: ")) or len(contrasena) < 6: + print("❌ Contraseña no válida. Debe tener al menos 6 caracteres.") + # Imprimimos resumen del formulario + print("\n--- Resumen ---") + + print(f"Nombre: {nombre}") + print(f"Email: {email}") + print(f"Edad: {edad}") + print(f"Contraseña: {contrasena}") + # Pregunta del programa si desea guardar los datos en un archivo JSON o perder los datos para siempre + if not (guardar := input("\n¿Desea almacenar estos datos en un archivo JSON? (s/n) --> ")) or guardar != "s": + print("Datos no almacenados en JSON. Eliminando datos introducidos 🗑️") + else: + # Pedir al usuario un nombre para el archivo JSON (Inválido estar vacío o que sólo tenga números) + while not (texto := input("\nEscribe un nombre para el archivo JSON --> ")) or texto.isdigit(): + print("❌ Nombre inválido.") + + # Declarar diccionario con los datos guardados + resumen = { + "nombre": nombre, + "email": email, + "edad": edad, + "contrasena": contrasena + } + # Convertir texto en archivo JSON + textoJSON = texto + ".json" + # Llamar función 'guardar_archivo' para almacenar los datos en JSON (más información en formatoJSON.py) + guardar_archivo(textoJSON, resumen) \ No newline at end of file diff --git a/07_mini_proyectos/retos/reto3/app.py b/07_mini_proyectos/retos/reto3/app.py new file mode 100644 index 0000000..7207a34 --- /dev/null +++ b/07_mini_proyectos/retos/reto3/app.py @@ -0,0 +1,46 @@ +# Reto 3: Analizador de archivo línea por línea +# Enunciado: Crea un programa que lea un archivo línea por línea y procese solo las que cumplan ciertos criterios. +# +# **Requisitos**: +# - Usa operador morsa en el bucle de lectura +# - Filtra líneas que: +# - No estén vacías +# - No empiecen con `#` (comentarios) +# - Tengan más de 10 caracteres +# - Cuenta cuántas líneas procesaste vs. cuántas ignoraste +# - Guarda las líneas válidas en otro archivo + +# TODO 1: Importar módulos necesarios para las funciones +from read_write import read_content, write_content +from line_filter import filter + +# TODO 2: Crear función principal +def main(): + print("--- Analizador de archivos línea por línea ---") + + lista = [ + "# Este es un comentario", + "Línea válida para procesar", + "Corta", + "", + "# Otro comentario", + "Esta línea también es válida y debe procesarse" + ] + + # Pedir al usuario un nombre para el archivo de entrada para ver el contenido completo + # while not (entrada := input("\nEscribe un nombre para el archivo de lineas --> ")) or entrada.isdigit(): + #print("❌ Nombre de entrada inválido.") + + # Pedir al usuario un nombre para el archivo de salida con las lineas filtradas + # while not (entrada := input("\nEscribe un nombre para el archivo de lineas --> ")) or entrada.isdigit(): + # print("❌ Nombre de entrada inválido.") + + write_content("archivo.txt", lista) + + if read_content("archivo.txt"): + filter("archivo.txt", "salida.txt") + + +# TODO 3: Punto de entrada del programa +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/07_mini_proyectos/retos/reto3/archivo.txt b/07_mini_proyectos/retos/reto3/archivo.txt new file mode 100644 index 0000000..76c1392 --- /dev/null +++ b/07_mini_proyectos/retos/reto3/archivo.txt @@ -0,0 +1,7 @@ + +# Este es un comentario +Línea válida para procesar +Corta + +# Otro comentario +Esta línea también es válida y debe procesarse \ No newline at end of file diff --git a/07_mini_proyectos/retos/reto3/line_filter.py b/07_mini_proyectos/retos/reto3/line_filter.py new file mode 100644 index 0000000..34c5196 --- /dev/null +++ b/07_mini_proyectos/retos/reto3/line_filter.py @@ -0,0 +1,31 @@ +# line_filter +# Módulo que filtra las líneas del archivo con los criterios asignados + +def filter(entrada, salida): + + procesadas = 0 + ignoradas = 0 + lineas_validas = [] + + try: + with open(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(salida, "w", encoding="utf-8") as archivo: + for linea in lineas_validas: + archivo.write(f"\n{linea}") + + print("\n--- Resúmen de la filtración ---") + print(f"✅ Procesadas: {procesadas} líneas") + print(f"⏭️ Ignoradas: {ignoradas} líneas") + print(f"📝 Resultado guardado en: {salida}") + + except FileNotFoundError: + print(f"No se ha encontrado el archivo {entrada}") + except Exception as e: + print(f"❌ Error al leer el archivo: {e}") \ No newline at end of file diff --git a/07_mini_proyectos/retos/reto3/read_write.py b/07_mini_proyectos/retos/reto3/read_write.py new file mode 100644 index 0000000..628434b --- /dev/null +++ b/07_mini_proyectos/retos/reto3/read_write.py @@ -0,0 +1,32 @@ +# read_write.py +# Módulo para leer y escribir archivos + +def read_content(archive): + try: + with open(archive, "r", encoding="utf-8") as file: + + print(f"Leyendo archivo {archive}...") + print(file.read()) + + return True + + except FileNotFoundError: + print("❌ No se ha encontrado el archivo a leer.") + return False + except Exception as e: + print(f"❌ Error al leer el archivo: {e}") + return False + +def write_content(archive, lines): + + try: + with open(archive, "w", encoding="utf-8") as file: + print(f"\nEscribiendo archivo {archive}...") + for line in lines: + file.write(f"\n{line}") + + print(f"Archivo {archive} escrito correctamente ✅") + return True + except Exception as e: + print(f"❌ Error al escribir el archivo: {e}") + return False \ No newline at end of file diff --git a/07_mini_proyectos/retos/reto3/salida.txt b/07_mini_proyectos/retos/reto3/salida.txt new file mode 100644 index 0000000..fd2eebd --- /dev/null +++ b/07_mini_proyectos/retos/reto3/salida.txt @@ -0,0 +1,3 @@ + +Línea válida para procesar +Esta línea también es válida y debe procesarse \ No newline at end of file diff --git a/07_mini_proyectos/retos/reto4/app.py b/07_mini_proyectos/retos/reto4/app.py new file mode 100644 index 0000000..0243afc --- /dev/null +++ b/07_mini_proyectos/retos/reto4/app.py @@ -0,0 +1,34 @@ +# Reto 4: Estadísticas del refugio de gatos +# **Enunciado: ** +# - Entrada: archivo o lista de pesos y edades. +# - Tareas: conteo, media, mediana simple, top-k más pesados. +# - Salida: resumen por pantalla y guardado opcional a archivo. +# **Bonus**: Usa operador morsa para leer el archivo línea por línea. + +from read_write import read_file, write_file +from filtertodo import multitask, write + +def main(): + + print("--- Estadísticas del refugio de gatos ---") + + gatos = [ + {"nombre": "Michi", "edad": 9, "peso": 6.9}, + {"nombre": "Leo", "edad": 4, "peso": 4.8}, + {"nombre": "Nico", "edad": 5, "peso": 5.0}, + {"nombre": "Chachito", "edad": 10, "peso": 13.2} + ] + + write_file("gatos.txt", gatos) + + read_file("gatos.txt") + + media_edad, media_peso, mediana_edad, mediana_peso, top_3_pesados = multitask(gatos) + + resumen = [media_edad, media_peso, mediana_edad, mediana_peso, top_3_pesados] + + write("resumen.txt", resumen) + + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/07_mini_proyectos/retos/reto4/filtertodo.py b/07_mini_proyectos/retos/reto4/filtertodo.py new file mode 100644 index 0000000..02968cf --- /dev/null +++ b/07_mini_proyectos/retos/reto4/filtertodo.py @@ -0,0 +1,76 @@ +# filtertodo.py +# Módulo donde se calcula el conteo, la media, la mediana simple y el top-k más pesados de la lista de gatos + +def multitask(list): + + print("\n--- Tareas de la lista de gatos---") + + print("\n--- Conteo ---") + print(f"Total de gatos: {(contador := len(list))}") + + print("\n--- Media (Promedio) ---") + media_edad = (suma_edades := sum(gato["edad"] for gato in list)) / contador + print(f"Promedio de la edad de los gatos: {media_edad:.2f} años") + + media_peso = (suma_peso := sum(gato["peso"] for gato in list)) / contador + print(f"Promedio del peso de los gatos: {media_peso:.2f} kgs") + + print("\n--- Mediana simple ---") + # La mediana es el valor central cuando los datos están ordenados + # Extraemos y ordenamos las edades + m = len(edades_ordenadas := sorted(gato["edad"] for gato in list)) + + # Calcular la mediana de la edad + if m % 2 == 0: # Si hay cantidad par de elementos + # Promedio de los dos valores centrales + mediana_edad = (edades_ordenadas[m//2 - 1] + edades_ordenadas[m//2]) / 2 + else: # Si hay cantidad impar + # El valor del medio + mediana_edad = edades_ordenadas[m//2] + + # Extraemos y ordenamod los pesos + m = len(pesos_ordenados := sorted(gato["peso"] for gato in list)) + + # Calcular la mediana del peso + if m % 2 == 0: + mediana_peso = (pesos_ordenados[m//2 - 1] + pesos_ordenados[m//2]) / 2 + else: + mediana_peso = pesos_ordenados[m//2] + + print(f"Mediana de edad: {mediana_edad:.2f} años") + print(f"Mediana de peso: {mediana_peso:.2f} kgs") + + print("\n===== TOP 3 GATOS MÁS PESADOS =====") + # Ordenar los gatos por peso de mayor a menor + # sorted() con key=lambda: Ordena los diccionarios según el campo que elijas + gatos_por_peso = sorted(list, key=lambda gato: gato["peso"], reverse=True) + + # Tomar sólo los 3 primeros gatos ordenados por peso + top_3_pesados = gatos_por_peso[:3] + + for i, gato in enumerate(top_3_pesados, 1): + print(f"{i}. {gato['nombre']} | Edad: {gato['edad']} años | Peso: {gato['peso']} kgs.") + + return media_edad, media_peso, mediana_edad, mediana_peso, top_3_pesados + +def write(archive_out, resumen): + try: + with open(archive_out, "w", encoding="utf-8") as file: + for i, linea in enumerate(resumen, 1): + if i == 1: + file.write(f"Promedio de edad: {linea} años.\n") + elif i == 2: + file.write(f"\nPromedio de peso: {linea} kgs.\n") + elif i == 3: + file.write(f"\nMediana de edad: {linea} años.\n") + elif i == 4: + file.write(f"\nMediana de peso: {linea} kgs.\n") + elif i == 5: + file.write(f"\nTop 3 gatos más pesados:\n{linea}") + + print(f"\nArchivo {archive_out} escrito correctamente ✅") + + except FileNotFoundError: + print("❌ No se ha encontrado el archivo") + except Exception as e: + print(f"❌ Error en la lectura del archivo: {e}") \ No newline at end of file diff --git a/07_mini_proyectos/retos/reto4/gatos.txt b/07_mini_proyectos/retos/reto4/gatos.txt new file mode 100644 index 0000000..8f1a5c6 --- /dev/null +++ b/07_mini_proyectos/retos/reto4/gatos.txt @@ -0,0 +1,21 @@ + +Gato 1 +nombre: Michi +edad: 9 +peso: 6.9 +---------------- +Gato 2 +nombre: Leo +edad: 4 +peso: 4.8 +---------------- +Gato 3 +nombre: Nico +edad: 5 +peso: 5.0 +---------------- +Gato 4 +nombre: Chachito +edad: 10 +peso: 13.2 +---------------- \ No newline at end of file diff --git a/07_mini_proyectos/retos/reto4/read_write.py b/07_mini_proyectos/retos/reto4/read_write.py new file mode 100644 index 0000000..47fd037 --- /dev/null +++ b/07_mini_proyectos/retos/reto4/read_write.py @@ -0,0 +1,29 @@ +# read_write.py +# Módulo para leer y escribir archivos + +def read_file(archive): + try: + print(f"Leyendo archivo {archive}") + with open(archive, "r", encoding="utf-8") as file: + + print(content := file.read()) + print(f"\nArchivo {archive} leído correctamente. ✅") + except FileNotFoundError: + print("❌ No se ha encontrado el archivo.") + except Exception as e: + print("❌ Error en la lectura del archivo: {e}") + +def write_file(archive, dict): + + try: + print(f"Escribiendo archivo {archive}") + with open(archive, "w", encoding="utf-8") as file: + for i, line in enumerate(dict, 1): + file.write(f"\nGato {i}") + for key, value in line.items(): + file.write(f"\n{key}: {value}") + file.write("\n----------------") + + print(f"\nArchivo {archive} creado y escrito correctamente. ✅") + except Exception as e: + print(f"❌ Error en la escritura del archivo: {e}") \ No newline at end of file diff --git a/07_mini_proyectos/retos/reto4/resumen.txt b/07_mini_proyectos/retos/reto4/resumen.txt new file mode 100644 index 0000000..164a829 --- /dev/null +++ b/07_mini_proyectos/retos/reto4/resumen.txt @@ -0,0 +1,10 @@ +Promedio de edad: 7.0 años. + +Promedio de peso: 7.475 kgs. + +Mediana de edad: 7.0 años. + +Mediana de peso: 5.95 kgs. + +Top 3 gatos más pesados: +[{'nombre': 'Chachito', 'edad': 10, 'peso': 13.2}, {'nombre': 'Michi', 'edad': 9, 'peso': 6.9}, {'nombre': 'Nico', 'edad': 5, 'peso': 5.0}] \ No newline at end of file diff --git a/07_mini_proyectos/retos/reto5/app.py b/07_mini_proyectos/retos/reto5/app.py new file mode 100644 index 0000000..e6e5835 --- /dev/null +++ b/07_mini_proyectos/retos/reto5/app.py @@ -0,0 +1,43 @@ +# Reto 5: Mini sistema de tickets +# **Enunciado: ** +# - Usa listas y diccionarios para manejar tickets (id, título, estado). +# - Operaciones: crear, listar, cerrar. +# - Persistencia opcional en archivo. +# **Bonus**: Usa operador morsa en el menú principal. + +import json +from tickets import mostrar_menu + +def main(): + print("--- Mini sistema de tickets ---") + + tickets = [] + next_id = 1 + archivo = "contenido.json" + + print("\nLeyendo archivo...") + try: + with open(archivo, "r", encoding="utf-8") as file: + if (contenido := json.load(file)): + lista = contenido + next_id = max(l["id"] for l in lista) + 1 + + except FileNotFoundError: + print("❌ No se ha encontrado el archivo.") + except Exception as e: + print(f"❌ Error al leer el archivo: {e}") + + mostrar_menu(tickets, next_id) + + try: + with open(archivo, "w", encoding="utf-8") as file: + print(f"Escribiendo tickets en archivo {archivo}...") + json.dump(tickets, file, indent=2, ensure_ascii=False) + print(f"Tickets guardados en {archivo} ✅") + except Exception as e: + print(f"❌ Error al escribir el archivo: {e}") + + print("\nHasta pronto 👋") + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/07_mini_proyectos/retos/reto5/contenido.json b/07_mini_proyectos/retos/reto5/contenido.json new file mode 100644 index 0000000..41633a3 --- /dev/null +++ b/07_mini_proyectos/retos/reto5/contenido.json @@ -0,0 +1,22 @@ +[ + { + "id": 1, + "titulo": "pepe", + "estado": "abierto" + }, + { + "id": 2, + "titulo": "tolai", + "estado": "cerrado" + }, + { + "id": 3, + "titulo": "pendenciero", + "estado": "abierto" + }, + { + "id": 4, + "titulo": "cachopo", + "estado": "cerrado" + } +] \ No newline at end of file diff --git a/07_mini_proyectos/retos/reto5/tickets.py b/07_mini_proyectos/retos/reto5/tickets.py new file mode 100644 index 0000000..c88e4f9 --- /dev/null +++ b/07_mini_proyectos/retos/reto5/tickets.py @@ -0,0 +1,38 @@ +# tickets.py +# Módulo para crear, listar y cerrar tickets + +def mostrar_menu(lista, id): + while (opcion := input("\nOpciones:\n1)Crear ticket\n2)Listar ticket\n3)Cerrar ticket\n\nElige una opción --> ").strip()) != "4": + if opcion == "1": + if (titulo := input("\nTítulo del ticket --> ").strip()): + lista.append({"id": id, "titulo": titulo, "estado": "abierto"}) + id += 1 + print(f"Ticket creado: {titulo}") + else: + print("❌ Título no válido") + + elif opcion == "2": + if not lista: + print("No hay tickets") + else: + for l in lista: + print(f"{l['id']}: {l['titulo']} | Estado: {l['estado']}") + + elif opcion == "3": + while not (id_str := input("ID del ticket a cerrar: ").strip()).isdigit(): + print("ID no válido") + + id_ticket = int(id_str) + for t in lista: + + if t["id"] == id_ticket: + t["estado"] = "cerrado" + print("Encontrado!! Ticket cerrado") + break + else: + print("No se encontró el ticket o se sigue buscando...") + + else: + print("❌ Opción no válida.") + + diff --git a/07_mini_proyectos/retos/reto6/app.py b/07_mini_proyectos/retos/reto6/app.py new file mode 100644 index 0000000..cd857fd --- /dev/null +++ b/07_mini_proyectos/retos/reto6/app.py @@ -0,0 +1,18 @@ +# Reto 6: Parser de logs simple +# **Enunciado: ** +# - Lee un archivo de logs, separa por espacio, cuenta por tipo o fecha. +# - Guarda resultados en `resumen.txt`. +# **Bonus**: Usa operador morsa para leer y filtrar líneas en una sola expresión. + +from logs import log + +def main(): + print("--- Parser de logs simple ---") + + archivo_entrada = "logs.log" + archivo_salida = "resumen.txt" + + log(archivo_entrada, archivo_salida) + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/07_mini_proyectos/retos/reto6/logs.log b/07_mini_proyectos/retos/reto6/logs.log new file mode 100644 index 0000000..da44a74 --- /dev/null +++ b/07_mini_proyectos/retos/reto6/logs.log @@ -0,0 +1,5 @@ +2024-01-15 10:30:45 ERROR Conexión perdida con el servidor +2024-01-15 11:20:12 INFO Usuario admin realizó login exitoso +2024-01-15 14:45:23 WARNING Memoria baja detectada +2024-01-16 09:15:33 ERROR Fallo en base de datos +2024-01-16 10:22:11 INFO Sistema iniciado correctamente \ No newline at end of file diff --git a/07_mini_proyectos/retos/reto6/logs.py b/07_mini_proyectos/retos/reto6/logs.py new file mode 100644 index 0000000..babe399 --- /dev/null +++ b/07_mini_proyectos/retos/reto6/logs.py @@ -0,0 +1,75 @@ +# logs.py +# Módulo donde lee un archivo de logs, separa por espacio, cuenta por tipo o fecha +# Además, guarda los logs en 'resumen.txt' + +# Función para leer archivo logs y escribir su resumen +def log(entrada, salida): + + contador_fecha = {} + contador_tipo = {} + + try: + with open(entrada, "r", encoding="utf-8") as file: + + for line in file: + line = line.strip() + + if not line: + continue + + if len(partes := line.split()) < 3: + continue + + fecha = partes[0] + hora = partes[1] + tipo = partes[2] + + # Contar por tipo de log + if tipo in contador_tipo: + contador_tipo[tipo] += 1 + else: + contador_tipo[tipo] = 1 + + # Contar por fecha + if fecha in contador_fecha: + contador_fecha[fecha] += 1 + else: + contador_fecha[fecha] = 1 + + # Mostrar resultados en pantalla + print("--- RESUMEN DE LOGS ---") + + print("\n🔍 Conteo por tipo de log:") + for tipo, cantidad in sorted(contador_tipo.items()): + print(f" {tipo}: {cantidad}") + + print("📅 Conteo por fecha:") + for fecha, cantidad in sorted(contador_fecha.items()): + print(f" {fecha}: {cantidad}") + + # Guardar resultados en resumen.txt + with open(salida, "w", encoding="utf-8") as out: + out.write("RESUMEN DE ANÁLISIS DE LOGS\n") + + # Escribir conteo por tipo + out.write("CONTEO POR TIPO DE LOG:\n") + for tipo, cantidad in sorted(contador_tipo.items()): + out.write(f"{tipo}: {cantidad}\n") + out.write("\n") + + # Escribir conteo por fecha + out.write("CONTEO POR FECHA:\n") + for fecha, cantidad in sorted(contador_fecha.items()): + out.write(f"{fecha}: {cantidad}\n") + out.write("\n") + + # Escribir totales + total_logs = sum(contador_tipo.values()) + out.write(f"TOTAL DE LOGS PROCESADOS: {total_logs}\n") + + print(f"Resumen guardado en {salida}") + + except FileNotFoundError: + print("❌ No se ha encontrado el archivo.") + except Exception as e: + print(f"❌ Error al leer o escribir datos: {e}") \ No newline at end of file diff --git a/07_mini_proyectos/retos/reto6/resumen.txt b/07_mini_proyectos/retos/reto6/resumen.txt new file mode 100644 index 0000000..b667d5d --- /dev/null +++ b/07_mini_proyectos/retos/reto6/resumen.txt @@ -0,0 +1,11 @@ +RESUMEN DE ANÁLISIS DE LOGS +CONTEO POR TIPO DE LOG: +ERROR: 2 +INFO: 2 +WARNING: 1 + +CONTEO POR FECHA: +2024-01-15: 3 +2024-01-16: 2 + +TOTAL DE LOGS PROCESADOS: 5