diff --git a/01_intro/ejercicio_guiado/calculadora_v1.py b/01_intro/ejercicio_guiado/calculadora_v1.py index cb19414..b3107e3 100644 --- a/01_intro/ejercicio_guiado/calculadora_v1.py +++ b/01_intro/ejercicio_guiado/calculadora_v1.py @@ -21,25 +21,28 @@ # TODO 1: Pide el primer número al usuario # Pista: usa input() y guarda el valor en una variable # primer_numero = ... - +print("Valor 1:") +first_input = input() # TODO 2: Pide el segundo número al usuario # segundo_numero = ... - +print("Valor 2:") +second_input = input() # TODO 3: Convierte los strings a números decimales # Pista: usa float() para permitir decimales (ej: 3.5) # num1 = float(primer_numero) # num2 = ... - +num1 = float(first_input) +num2 = float(second_input) # TODO 4: Realiza la suma # resultado = ... - +result = num1 + num2 # TODO 5: Muestra el resultado # Pista: print("El resultado es:", resultado) - +print("Resultado: ", result) # ¡Ya está! Ejecuta el programa y prueba con diferentes números # Ejemplos para probar: diff --git a/02_estructuras/ejercicio_guiado/calculadora_v2.py b/02_estructuras/ejercicio_guiado/calculadora_v2.py index 424d58f..abcc484 100644 --- a/02_estructuras/ejercicio_guiado/calculadora_v2.py +++ b/02_estructuras/ejercicio_guiado/calculadora_v2.py @@ -20,16 +20,26 @@ # TODO 1: Pide el primer número al usuario y conviértelo a float # num1 = ... - +print("Valor 1:") +first_input = input() +num1 = int(first_input) # TODO 2: Pide el segundo número al usuario y conviértelo a float # num2 = ... - +print("Valor 2:") +second_input = input() +num2 = int(second_input) # TODO 3: Pregunta qué operación desea realizar # Pista: input("¿Qué operación deseas realizar? (+, -, *, /): ") # operacion = ... - +print("¿Operación a realizar?") +print("0 - Salir") +print("1 - [+] Sumar") +print("2 - [-] Restar") +print("3 - [x] Multiplicar") +print("4 - [%] Dividir") +user_sel = input() # TODO 4: Realiza la operación correspondiente usando if/elif/else # Pista: Compara la variable 'operacion' con "+", "-", "*", "/" @@ -45,7 +55,6 @@ # else: # print("❌ Operación no válida") - # TODO 5: Muestra el resultado usando f-strings # Pista: f"El resultado de {num1} {operacion} {num2} = {resultado:.2f}" # El :.2f muestra solo 2 decimales @@ -63,3 +72,21 @@ # # 💡 Nota: Si intentas dividir por cero (10 / 0), Python mostrará un error. # Esto lo arreglaremos en la v3 con validación de entrada. +if user_sel == "0": + print("Ten un buen día.") + exit() +elif user_sel == "1": + print(f"{num1 + num2}") + exit() +elif user_sel == "2": + print(f"{num1 - num2}") + exit() +elif user_sel == "3": + print(f"{num1 * num2}") + exit() +elif user_sel == "4": + print(f"{num1 / num2}") + exit() +else: + print("Operación no válida") + exit() \ No newline at end of file diff --git a/ejercicios_hechos/01_intro/E01_bigotes_felices.py b/ejercicios_hechos/01_intro/E01_bigotes_felices.py new file mode 100644 index 0000000..6cb49a0 --- /dev/null +++ b/ejercicios_hechos/01_intro/E01_bigotes_felices.py @@ -0,0 +1,17 @@ +print("Introduce nombre gato:") +name_input = input() +name = str(name_input) + +if not name: + print("Nombre no válido") + exit() + +print("Introduce la edad del felino:") +age_input = input() +age = int(age_input) + +if not isinstance(age, int): + print("Edad no válida") + +print("Añadido a la base de datos:") +print(f"Gato: {name} (edad: {age})") \ No newline at end of file diff --git a/ejercicios_hechos/01_intro/conversor.py b/ejercicios_hechos/01_intro/conversor.py new file mode 100644 index 0000000..8b5c418 --- /dev/null +++ b/ejercicios_hechos/01_intro/conversor.py @@ -0,0 +1,9 @@ +print("Dame un número") +input_num = input() +float_num = float(input_num) + +if isinstance(float_num, float): + print(f"{float_num}") +else: + print("Número no válido") + diff --git a/ejercicios_hechos/01_intro/eco.py b/ejercicios_hechos/01_intro/eco.py new file mode 100644 index 0000000..5e2cf83 --- /dev/null +++ b/ejercicios_hechos/01_intro/eco.py @@ -0,0 +1,8 @@ +print("Dime algo y haré eco:") +user_input = input() +message = str(user_input) + +if isinstance(message, str): + print(f"{message}") +else: + print("Mensaje no válido") \ No newline at end of file diff --git a/ejercicios_hechos/01_intro/primer_script.py b/ejercicios_hechos/01_intro/primer_script.py new file mode 100644 index 0000000..9ad9a9e --- /dev/null +++ b/ejercicios_hechos/01_intro/primer_script.py @@ -0,0 +1,4 @@ +name = "Ana" + +print("Hola, Python") +print(f"Hola, {name}") \ No newline at end of file diff --git a/ejercicios_hechos/01_intro/saludo_input.py b/ejercicios_hechos/01_intro/saludo_input.py new file mode 100644 index 0000000..8a9b660 --- /dev/null +++ b/ejercicios_hechos/01_intro/saludo_input.py @@ -0,0 +1,8 @@ +print("¿Cómo te llamas?") +name = input() +str_name = str(name) + +if not str_name: + print("Nombre no váido.") +else: + print(f"Hola, {name}") diff --git a/ejercicios_hechos/01_intro/tres_print.py b/ejercicios_hechos/01_intro/tres_print.py new file mode 100644 index 0000000..5c220ee --- /dev/null +++ b/ejercicios_hechos/01_intro/tres_print.py @@ -0,0 +1,27 @@ +print("¿Cuántos años tienes? (número)") +age_input = input() +age = int(age_input) + +if not isinstance(age, int): + print("Edad no válida.") + exit() + +print("¿Cuál es tu lugar favorito? (ciudad)") +city_input = input() +city = str(city_input) + +if not isinstance(city, str): + print("Ciudad no válida.") + exit() + +print("Dime tu color favorito:") +color_input = input() +color = str(color_input) + +if not isinstance(color, str): + print("color no válido.") + exit() + +print(f"Usuario actual tiene {age} años.") +print(f"Lugar favorito de usuario actual: {city}") +print(f"Color favorito de usuario actual: {color}") \ No newline at end of file diff --git a/ejercicios_hechos/01_intro/variables_basicas.py b/ejercicios_hechos/01_intro/variables_basicas.py new file mode 100644 index 0000000..8e6281f --- /dev/null +++ b/ejercicios_hechos/01_intro/variables_basicas.py @@ -0,0 +1,17 @@ +print("¿Cómo te llamas?") +name = input() +str_name = str(name) + +if not str_name: + print("Dato no válido: Nombre") + exit() + +print("¿Dónde vives?") +city = input() +str_city = str(city) + +if not str_city: + print("Dato no válido: Ciudad") + exit() + +print(f"{str_name} vive en {str_city}") \ No newline at end of file diff --git a/ejercicios_hechos/02_estructuras/E02_pesaje.py b/ejercicios_hechos/02_estructuras/E02_pesaje.py new file mode 100644 index 0000000..305d5ab --- /dev/null +++ b/ejercicios_hechos/02_estructuras/E02_pesaje.py @@ -0,0 +1,23 @@ +print("Indica peso (KG - solo numero) de gato 1:") +kg_gato_1_input = input() +kg_gato_1 = int(kg_gato_1_input) + +if not kg_gato_1: + print("Dato no válido") + +print("Indica peso (KG - solo numero) de gato 2:") +kg_gato_2_input = input() +kg_gato_2 = int(kg_gato_2_input) + +if not kg_gato_2: + print("Dato no válido") + +print("Indica peso (KG - solo numero) de gato 3:") +kg_gato_3_input = input() +kg_gato_3 = int(kg_gato_3_input) + +if not kg_gato_3: + print("Dato no válido") + +avg_kg = (kg_gato_1 + kg_gato_2 + kg_gato_3) / 3 +print(round(avg_kg, 2)) \ No newline at end of file diff --git a/ejercicios_hechos/02_estructuras/booleans.py b/ejercicios_hechos/02_estructuras/booleans.py new file mode 100644 index 0000000..3765e27 --- /dev/null +++ b/ejercicios_hechos/02_estructuras/booleans.py @@ -0,0 +1,8 @@ +a = 10 +b = 5 +c = 10 + +print("a >= b:", a >= b) +print("a == c:", a == c) +print("b == c:", b == c) +print("b >= a:", b >= a) \ No newline at end of file diff --git a/ejercicios_hechos/02_estructuras/casting.py b/ejercicios_hechos/02_estructuras/casting.py new file mode 100644 index 0000000..5d18167 --- /dev/null +++ b/ejercicios_hechos/02_estructuras/casting.py @@ -0,0 +1,8 @@ +print("Dame un número:") +num_input = input() + +try: + int(num_input) + print("Ejercicio completado") +except: + print("Entrada inválida") \ No newline at end of file diff --git a/ejercicios_hechos/02_estructuras/operaciones.py b/ejercicios_hechos/02_estructuras/operaciones.py new file mode 100644 index 0000000..b72276c --- /dev/null +++ b/ejercicios_hechos/02_estructuras/operaciones.py @@ -0,0 +1,9 @@ +a = 10 +b = 3 + +sum = a + b +rest = a - b +mult = a * b +div = a / b + +print(f"Results: {sum}, {rest}, {mult}, {div:.2f}") \ No newline at end of file diff --git a/ejercicios_hechos/02_estructuras/porcentajes.py b/ejercicios_hechos/02_estructuras/porcentajes.py new file mode 100644 index 0000000..6efcbc1 --- /dev/null +++ b/ejercicios_hechos/02_estructuras/porcentajes.py @@ -0,0 +1,5 @@ +quantity = 350 + +percentage = quantity * 0.15 + +print(percentage) \ No newline at end of file diff --git a/ejercicios_hechos/02_estructuras/redondeo.py b/ejercicios_hechos/02_estructuras/redondeo.py new file mode 100644 index 0000000..afc4547 --- /dev/null +++ b/ejercicios_hechos/02_estructuras/redondeo.py @@ -0,0 +1,3 @@ +PI = 3.14159 + +print(f"{round(PI)}") \ No newline at end of file diff --git a/ejercicios_hechos/02_estructuras/strings.py b/ejercicios_hechos/02_estructuras/strings.py new file mode 100644 index 0000000..cbad1d0 --- /dev/null +++ b/ejercicios_hechos/02_estructuras/strings.py @@ -0,0 +1,4 @@ +first_name = "antonio" +last_name = "cabrera" + +print(f"{first_name.title()} {last_name.title()}") \ No newline at end of file diff --git a/ejercicios_hechos/03_control_flujo/E03_turnos.py b/ejercicios_hechos/03_control_flujo/E03_turnos.py new file mode 100644 index 0000000..1b3ee73 --- /dev/null +++ b/ejercicios_hechos/03_control_flujo/E03_turnos.py @@ -0,0 +1,19 @@ +print("Indica el número de gatos:") +cats_input = input() + +try: + cats = int(cats_input) +except ValueError: + print("Por favor introduce un número válido.") + +turno_A = [] +turno_B = [] + +for i in range(1, cats + 1): + if i % 2 == 0: + turno_B.append(f"Gato {i}") + else: + turno_A.append(f"Gato {i}") + +print("Turno A:", turno_A) +print("Turno B:", turno_B) \ No newline at end of file diff --git a/ejercicios_hechos/03_control_flujo/cat_list.py b/ejercicios_hechos/03_control_flujo/cat_list.py new file mode 100644 index 0000000..9e3ae92 --- /dev/null +++ b/ejercicios_hechos/03_control_flujo/cat_list.py @@ -0,0 +1,4 @@ +cat_list = ["cat1", "cat2", "cat3", "cat4", "cat5"] + +for cat in cat_list: + print(cat) \ No newline at end of file diff --git a/ejercicios_hechos/03_control_flujo/letter_counter.py b/ejercicios_hechos/03_control_flujo/letter_counter.py new file mode 100644 index 0000000..d24f306 --- /dev/null +++ b/ejercicios_hechos/03_control_flujo/letter_counter.py @@ -0,0 +1,9 @@ +print("Escribe una palabra:") +user_input = input() + +i = 0 + +for letter in user_input: + i += 1 + +print(f"Tu palabra tiene {i} letras.") diff --git a/ejercicios_hechos/03_control_flujo/loop_sum.py b/ejercicios_hechos/03_control_flujo/loop_sum.py new file mode 100644 index 0000000..fce9f28 --- /dev/null +++ b/ejercicios_hechos/03_control_flujo/loop_sum.py @@ -0,0 +1,16 @@ +total = 0 + +while True: + print("Introduce un número (o FIN para terminar):") + num_input = input() + + if num_input.lower() == "fin": + break + + try: + num = float(num_input) + total += num + except ValueError: + print("Por favor introduce un número válido o FIN.") + +print(f"El total es: {total}") diff --git a/ejercicios_hechos/03_control_flujo/multipliers.py b/ejercicios_hechos/03_control_flujo/multipliers.py new file mode 100644 index 0000000..7d6eba4 --- /dev/null +++ b/ejercicios_hechos/03_control_flujo/multipliers.py @@ -0,0 +1,4 @@ +for i in range(1, 6): + for j in range(1, 11): + print(f"{i} x {j} = {i*j}") + print() diff --git a/ejercicios_hechos/03_control_flujo/number_type.py b/ejercicios_hechos/03_control_flujo/number_type.py new file mode 100644 index 0000000..7516505 --- /dev/null +++ b/ejercicios_hechos/03_control_flujo/number_type.py @@ -0,0 +1,16 @@ +print("Escribe un número:") +num_input = input() + +try: + num = int(num_input) +except ValueError: + print("The value has wrong format") +except: + print("Something else went wrong") + +if num < 0: + print(f"El número {num} es negativo") +elif num == 0: + print(f"El número {num} es 0.") +elif num > 0: + print(f"El número {num} es positivo.") \ No newline at end of file diff --git a/ejercicios_hechos/03_control_flujo/password.py b/ejercicios_hechos/03_control_flujo/password.py new file mode 100644 index 0000000..c9f8e1b --- /dev/null +++ b/ejercicios_hechos/03_control_flujo/password.py @@ -0,0 +1,7 @@ +password = input("Introduce la contraseña: ") + +while password != "gato123": + print("Contraseña incorrecta.") + password = input("Introduce la contraseña: ") + +print("Bienvenido, usuario.") diff --git a/ejercicios_hechos/04_funciones/average.py b/ejercicios_hechos/04_funciones/average.py new file mode 100644 index 0000000..6e50402 --- /dev/null +++ b/ejercicios_hechos/04_funciones/average.py @@ -0,0 +1,38 @@ +def media(nums): + if not isinstance(nums, list): + raise TypeError("nums debe ser una lista") + + if len(nums) == 0: + raise ValueError("La lista no puede estar vacía") + + for n in nums: + if not isinstance(n, (int, float)): + raise ValueError("Todos los elementos deben ser números") + + return sum(nums) / len(nums) + + +def media_user(): + nums = [] + + while True: + print("Introduce un número (o FIN para terminar):") + user_input = input() + + if user_input.lower() == "fin": + break + + try: + num = float(user_input) + nums.append(num) + except ValueError: + print("Por favor introduce un número válido o FIN.") + + if len(nums) == 0: + print("No se introdujo ningún número, no se puede calcular la media.") + return None + + result = media(nums) + print(f"La media es: {round(result, 2)}") + +media_user() diff --git a/ejercicios_hechos/04_funciones/is_even.py b/ejercicios_hechos/04_funciones/is_even.py new file mode 100644 index 0000000..245b324 --- /dev/null +++ b/ejercicios_hechos/04_funciones/is_even.py @@ -0,0 +1,18 @@ +def es_par(n): + if not isinstance(n, int): + raise TypeError("n debe ser un número entero") + return n % 2 == 0 + +def es_par_ans(ans): + if ans == True: + print("Tu número es PAR") + elif ans != True: + print("Tu número es IMPAR") + else: + print("¡Ha habido un error!") + +print("Dame un número (int):") +user_n_input = input() +user_n = int(user_n_input) +answer = es_par(user_n) +es_par_ans(answer) \ No newline at end of file diff --git a/ejercicios_hechos/04_funciones/rectangle_area.py b/ejercicios_hechos/04_funciones/rectangle_area.py new file mode 100644 index 0000000..51343bc --- /dev/null +++ b/ejercicios_hechos/04_funciones/rectangle_area.py @@ -0,0 +1,19 @@ +def area_rectangulo(a, b): + if not isinstance(a, float) or not isinstance(b, float): + raise TypeError("a y b deben ser números") + + if a <= 0 or b <= 0: + raise ValueError("a y b deben ser mayores que cero") + + return a * b + +print("Dame BASE (A - m2):") +user_input_a = input() +user_a = float(user_input_a) + +print("Dame ALTURA(B - m2):") +user_input_b = input() +user_b = float(user_input_b) + +area = area_rectangulo(user_a, user_b) +print(f"El área total es de: {area} m2") \ No newline at end of file diff --git a/ejercicios_hechos/04_funciones/saludar.py b/ejercicios_hechos/04_funciones/saludar.py new file mode 100644 index 0000000..0d501e0 --- /dev/null +++ b/ejercicios_hechos/04_funciones/saludar.py @@ -0,0 +1,7 @@ +print("Dime tu nombre:") +name = input() + +def saludar(name): + print(f"Hola, {name}") + +saludar(name) \ No newline at end of file diff --git a/ejercicios_hechos/04_funciones/sumar.py b/ejercicios_hechos/04_funciones/sumar.py new file mode 100644 index 0000000..1e45461 --- /dev/null +++ b/ejercicios_hechos/04_funciones/sumar.py @@ -0,0 +1,31 @@ +def sumar(nums): + if not isinstance(nums, list): + raise TypeError("nums debe ser una lista") + + for n in nums: + if not isinstance(n, (int, float)): + raise ValueError("Todos los elementos deben ser números") + + return sum(nums) + +def sumar_user(): + nums = [] + + while True: + print("Introduce un número (o FIN para terminar):") + entrada = input() + + if entrada.lower() == "fin": + break + + try: + valor = float(entrada) + nums.append(valor) + except ValueError: + print("Por favor introduce un número válido o FIN.") + + total = sumar(nums) + print(f"El total es: {total}") + return total + +sumar_user() \ No newline at end of file diff --git a/ejercicios_hechos/06_archivos_y_modulos/E06_cat_logs.py b/ejercicios_hechos/06_archivos_y_modulos/E06_cat_logs.py new file mode 100644 index 0000000..5d8036f --- /dev/null +++ b/ejercicios_hechos/06_archivos_y_modulos/E06_cat_logs.py @@ -0,0 +1,44 @@ +from collections import defaultdict +import re +from datetime import datetime + +def analizar_logs(input_path, output_path): + daily_view = defaultdict(int) + + try: + with open(input_path, "r", encoding="utf-8") as cat_view_file: + for line in cat_view_file: + match = re.search(r'\d{4}-\d{2}-\d{2}', line) + if match: + date = match.group() + daily_view[date] += 1 + + date_order = sorted(daily_view.keys()) + + with open(output_path, "w", encoding="utf-8") as sort_views_file: + sort_views_file.write("Fecha,Visitas\n") + for date in date_order: + sort_views_file.write(f"{date},{daily_view[date]}\n") + + print(f"Resumen guardado") + + total_view = sum(daily_view.values()) + print(f"\nEstadísticas:") + print(f"Total de días: {len(daily_view)}") + print(f"Total de visitas: {total_view}") + + if daily_view: + avg = total_view / len(daily_view) + print(f"Promedio de visitas por día: {avg:.2f}") + + except FileNotFoundError: + print(f"Error: No se encontró el archivo") + except Exception as e: + print(f"Error al procesar el archivo: {e}") + +if __name__ == "__main__": + all_views = "visitas.log" + views_short = "resumen_visitas.csv" + + print(f"Analizando archivo de logs...") + analizar_logs(all_views, views_short) \ No newline at end of file diff --git a/ejercicios_hechos/06_archivos_y_modulos/app.py b/ejercicios_hechos/06_archivos_y_modulos/app.py new file mode 100644 index 0000000..e488d9e --- /dev/null +++ b/ejercicios_hechos/06_archivos_y_modulos/app.py @@ -0,0 +1,28 @@ +import os +from utils03 import read_lines, save_lines + +def main(): + file_path = input("Ingresa la ruta del archivo a leer: ") + + if not os.path.exists(file_path): + print(f"Error: No se encontró ningún archivo con la ruta especificada") + return + + try: + print(f"\nLeyendo archivo:") + lines = read_lines(file_path) + for i, line in enumerate(lines, 1): + print(f"{i}: {line}") + + output_file = "file.txt" + num_lines = [f"Línea {i}: {line}" for i, line in enumerate(lines, 1)] + save_lines(output_file, num_lines) + print(f"\nSe ha guardado una copia numerada en {output_file}") + + except FileNotFoundError: + print(f"No se pudo encontrar el archivo") + except Exception as e: + print(f"Ocurrió un error: {e}") + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/ejercicios_hechos/06_archivos_y_modulos/cats_as_csv.py b/ejercicios_hechos/06_archivos_y_modulos/cats_as_csv.py new file mode 100644 index 0000000..ecf73ec --- /dev/null +++ b/ejercicios_hechos/06_archivos_y_modulos/cats_as_csv.py @@ -0,0 +1,27 @@ +cats = [ + ["Nombre", "Edad", "Color"], + ["Luna", "3", "gris"], + ["Simba", "2", "naranja"], + ["Michi", "5", "blanco y negro"], + ["Neko", "1", "negro"] +] + +print("Guardando información de gatos como csv...") +try: + with open("gatos.csv", "w", encoding="utf-8") as csv_file: + for cat in cats: + line = ",".join(cat) + "\n" + csv_file.write(line) + + print("Archivo gatos.csv creado correctamente.") + +except Exception as e: + print(f"Error al guardar el archivo: {e}") + +print("\nContenido del archivo gatos.csv:") +try: + with open("gatos.csv", "r", encoding="utf-8") as read_file: + for line in read_file: + print(line.strip()) +except FileNotFoundError: + print("Error: No se encontró el archivo gatos.csv") \ No newline at end of file diff --git a/ejercicios_hechos/06_archivos_y_modulos/leer_archivo.py b/ejercicios_hechos/06_archivos_y_modulos/leer_archivo.py new file mode 100644 index 0000000..b69bcb3 --- /dev/null +++ b/ejercicios_hechos/06_archivos_y_modulos/leer_archivo.py @@ -0,0 +1,17 @@ +# Parte 1: Escribir archivo +print("Escribiendo archivo...") +with open("escribir.txt", "w", encoding="utf-8") as text_file: + text_file.write("Primera línea\n") + text_file.write("Segunda línea\n") + text_file.write("Tercera línea\n") + +print("Archivo creado correctamente.") + +# Parte 2: Leer archivo +print("\nLeyendo archivo:") +try: + with open("escribir.txt", "r", encoding="utf-8") as read_file: + for i, line in enumerate(read_file, 1): + print(f"{i}: {line.strip()}") +except FileNotFoundError: + print("Error: No se encontró el archivo escribir.txt") \ No newline at end of file diff --git a/ejercicios_hechos/06_archivos_y_modulos/utils03.py b/ejercicios_hechos/06_archivos_y_modulos/utils03.py new file mode 100644 index 0000000..124a886 --- /dev/null +++ b/ejercicios_hechos/06_archivos_y_modulos/utils03.py @@ -0,0 +1,8 @@ +def read_lines(file_route): + with open(file_route, "r", encoding="utf-8") as read_file: + return [line.strip() for line in read_file] + +def save_lines(file_route, lines): + with open(file_route, "w", encoding="utf-8") as save_file_lines: + for line in lines: + save_file_lines.write(str(line) + "\n") \ No newline at end of file diff --git a/ejercicios_hechos/07_mini_proyectos/cat_shelter04.py b/ejercicios_hechos/07_mini_proyectos/cat_shelter04.py new file mode 100644 index 0000000..49fb3ad --- /dev/null +++ b/ejercicios_hechos/07_mini_proyectos/cat_shelter04.py @@ -0,0 +1,69 @@ +import statistics +from typing import List, Tuple +import json + +class RefugioStats: + def __init__(self, cats: List[Tuple[float, int]]): + self.cats = cats + self.weight = [weight for weight, _ in cats] + self.age = [age for _ , age in cats] + + def calcular_estadisticas(self) -> dict: + stats = { + "total_cats": len(self.cats), + "weight": { + "media": statistics.mean(self.weight), + "mediana": statistics.median(self.weight) + }, + "age": { + "media": statistics.mean(self.age), + "mediana": statistics.median(self.age) + }, + "top_pesados": sorted(self.cats, reverse=True)[:3] + } + return stats + + def mostrar_resumen(self, stats: dict): + """Muestra el resumen por pantalla""" + print("\n=== Estadísticas del Refugio ===") + print(f"Total de gatos: {stats['total_cats']}") + + print("\nEstadísticas de peso:") + print(f"- Media: {stats['weight']['media']:.2f} kg") + print(f"- Mediana: {stats['weight']['mediana']:.2f} kg") + + print("\nEstadísticas de edad:") + print(f"- Media: {stats['age']['media']:.1f} años") + print(f"- Mediana: {stats['age']['mediana']:.1f} años") + + print("\nTop 3 gatos más pesados:") + for i, (weight, age) in enumerate(stats['top_pesados'], 1): + print(f"{i}. {weight:.2f} kg ({age} años)") + + def guardar_resumen(self, stats: dict, file: str): + with open(file, 'w', encoding='utf-8') as f: + json.dump(stats, f, indent=2) + print(f"\nResumen guardado en {file}") + +def main(): + # Datos de ejemplo (peso en kg, edad en años) + gatos_ejemplo = [ + (4.5, 3), + (3.8, 2), + (5.2, 5), + (4.0, 1), + (6.1, 4), + (3.5, 2), + (4.8, 6), + (5.5, 3) + ] + + shelter = RefugioStats(gatos_ejemplo) + stats = shelter.calcular_estadisticas() + + shelter.mostrar_resumen(stats) + + shelter.guardar_resumen(stats, "estadisticas_refugio.json") + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/ejercicios_hechos/07_mini_proyectos/log_parser06.py b/ejercicios_hechos/07_mini_proyectos/log_parser06.py new file mode 100644 index 0000000..1be492d --- /dev/null +++ b/ejercicios_hechos/07_mini_proyectos/log_parser06.py @@ -0,0 +1,93 @@ +from collections import defaultdict +from datetime import datetime +import re +from typing import Dict, List, Tuple + +class ParserLogs: + def __init__(self, input_file: str, output_file: str = "resumen.txt"): + self.input_file = input_file + self.output_file = output_file + self.logs_by_type: Dict[str, int] = defaultdict(int) + self.logs_by_date: Dict[str, int] = defaultdict(int) + + def read_lines(self, line: str) -> Tuple[str, str]: + line_split = line.split() + if len(line_split) >= 4: + date = line_split[0] + type = line_split[2] + return date, type + return None, None + + def check_logs(self): + try: + with open(self.input_file, 'r', encoding='utf-8') as f: + for line in f: + date, type = self.read_lines(line.strip()) + if date and type: + self.logs_by_date[date] += 1 + self.logs_by_type[type] += 1 + return True + except FileNotFoundError: + print(f"Error: No se encontró el archivo") + return False + + def generar_resumen(self): + if not self.logs_by_date or not self.logs_by_type: + return "No hay datos para generar el resumen" + + resumen = [] + resumen.append("=== RESUMEN DE LOGS ===\n") + + resumen.append("EVENTOS POR TIPO:") + for type, count in sorted(self.logs_by_type.items()): + resumen.append(f"{type}: {count}") + + resumen.append("\nEVENTOS POR FECHA:") + for date, count in sorted(self.logs_by_date.items()): + resumen.append(f"{date}: {count}") + + total_events = sum(self.logs_by_type.values()) + resumen.append(f"\nTotal de eventos: {total_events}") + resumen.append(f"Días diferentes: {len(self.logs_by_date)}") + if self.logs_by_date: + avg = total_events / len(self.logs_by_date) + resumen.append(f"Promedio de eventos por día: {avg:.2f}") + + return "\n".join(resumen) + + def guardar_resumen(self): + resumen = self.generar_resumen() + try: + with open(self.output_file, 'w', encoding='utf-8') as f: + f.write(resumen) + print(f"Resumen guardado en {self.output_file}") + return True + except Exception as e: + print(f"Error al guardar el resumen: {e}") + return False + +def main(): + # Archivo de ejemplo (si no existe, crear uno) + ejemplo_logs = [ + "2025-11-07 10:15:30 INFO Sistema iniciado", + "2025-11-07 10:16:45 WARNING Espacio en disco bajo", + "2025-11-07 11:20:15 ERROR Base de datos no responde", + "2025-11-08 09:00:00 INFO Respaldo iniciado", + "2025-11-08 09:30:00 INFO Respaldo completado", + "2025-11-08 15:45:30 WARNING Memoria baja", + ] + + # Crear archivo de logs de ejemplo + with open("ejemplo.log", 'w', encoding='utf-8') as f: + for log in ejemplo_logs: + f.write(log + "\n") + + # Procesar logs + parser = ParserLogs("ejemplo.log") + if parser.check_logs(): + parser.guardar_resumen() + # Mostrar resumen en pantalla también + print("\n" + parser.generar_resumen()) + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/ejercicios_hechos/07_mini_proyectos/ticket_sys05.py b/ejercicios_hechos/07_mini_proyectos/ticket_sys05.py new file mode 100644 index 0000000..549433d --- /dev/null +++ b/ejercicios_hechos/07_mini_proyectos/ticket_sys05.py @@ -0,0 +1,107 @@ +import json +from typing import Dict, List +from datetime import datetime + +class TicketSys: + def __init__(self, file: str = "tickets.json"): + self.tickets: Dict[int, dict] = {} + self.next_id = 1 + self.file = file + self.load_tickets() + + def create_ticket(self, title: str, description: str) -> int: + ticket = { + "id": self.next_id, + "title": title, + "description": description, + "state": "active", + "created": datetime.now().strftime("%Y-%m-%d %H:%M:%S"), + "expire": None + } + + self.tickets[self.ne] = ticket + self.siguiente_id += 1 + self.save_tickets() + return ticket["id"] + + def list_tickets(self, only_active: bool = False) -> List[dict]: + tickets = self.tickets.values() + if only_active: + tickets = [t for t in tickets if t["state"] == "active"] + return list(tickets) + + def expire_ticket(self, ticket_id: int) -> bool: + if ticket_id not in self.tickets: + return False + + if self.tickets[ticket_id]["state"] == "expired": + return False + + self.tickets[ticket_id]["state"] = "expired" + self.tickets[ticket_id]["expire"] = datetime.now().strftime("%Y-%m-%d %H:%M:%S") + self.save_tickets() + return True + + def save_tickets(self): + with open(self.file, 'w', encoding='utf-8') as f: + json.dump({"tickets": self.tickets, "next_id": self.next_id}, f, indent=2) + + def load_tickets(self): + try: + with open(self.file, 'r', encoding='utf-8') as f: + data = json.load(f) + self.tickets = data["tickets"] + self.next_id = data["next_id"] + except FileNotFoundError: + self.tickets = {} + self.next_id = 1 + +def mostrar_menu(): + print("\n=== Sistema de Tickets ===") + print("1. Crear ticket") + print("2. Listar tickets") + print("3. Cerrar ticket") + print("4. Salir") + return input("Seleccione una opción: ") + +def main(): + sys_tickets = TicketSys() + + while True: + sel = mostrar_menu() + + if sel == "1": + title = input("Título del ticket: ") + description = input("Descripción: ") + ticket_id = sys_tickets.create_ticket(title, description) + print(f"Ticket creado con ID: {ticket_id}") + + elif sel == "2": + only_active = input("¿Mostrar solo tickets abiertos? (s/n): ").lower() == 's' + tickets = sys_tickets.list_tickets(only_active) + print("\n=== Lista de Tickets ===") + for t in tickets: + print(f"ID: {t['id']} - {t['title']} ({t['state']})") + print(f"Creado: {t['created']}") + if t['expired']: + print(f"Caducado: {t['expired']}") + print(f"Descripción: {t['description']}\n") + + elif sel == "3": + try: + ticket_id = int(input("ID del ticket a expirar: ")) + if sys_tickets.expire_ticket(ticket_id): + print("Ticket expirado correctamente") + else: + print("No se pudo expirar el ticket") + except ValueError: + print("ID inválido") + + elif sel == "4": + break + + else: + print("Opción inválida") + +if __name__ == "__main__": + main() \ No newline at end of file