diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 00000000..e1888d10 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,22 @@ +{ + "workbench.colorCustomizations": { + "activityBar.activeBackground": "#c5f75c", + "activityBar.background": "#c5f75c", + "activityBar.foreground": "#15202b", + "activityBar.inactiveForeground": "#15202b99", + "activityBarBadge.background": "#0ca9f3", + "activityBarBadge.foreground": "#15202b", + "commandCenter.border": "#15202b99", + "sash.hoverBorder": "#c5f75c", + "statusBar.background": "#b4f52b", + "statusBar.foreground": "#15202b", + "statusBarItem.hoverBackground": "#9de20b", + "statusBarItem.remoteBackground": "#b4f52b", + "statusBarItem.remoteForeground": "#15202b", + "titleBar.activeBackground": "#b4f52b", + "titleBar.activeForeground": "#15202b", + "titleBar.inactiveBackground": "#b4f52b99", + "titleBar.inactiveForeground": "#15202b99" + }, + "peacock.color": "#b4f52b" +} diff --git a/Advanced/01.SimuladorJJOO.py b/Advanced/01.SimuladorJJOO.py new file mode 100644 index 00000000..3f335da6 --- /dev/null +++ b/Advanced/01.SimuladorJJOO.py @@ -0,0 +1,112 @@ +""" +* EJERCICIO: + * ¡Los JJOO de París 2024 han comenzado! + * Crea un programa que simule la celebración de los juegos. + * El programa debe permitir al usuario registrar eventos y participantes, + * realizar la simulación de los eventos asignando posiciones de manera aleatoria + * y generar un informe final. Todo ello por terminal. + * Requisitos: + * 1. Registrar eventos deportivos. + * 2. Registrar participantes por nombre y país. + * 3. Simular eventos de manera aleatoria en base a los participantes (mínimo 3). + * 4. Asignar medallas (oro, plata y bronce) basándose en el resultado del evento. + * 5. Mostrar los ganadores por cada evento. + * 6. Mostrar el ranking de países según el número de medallas. + * Acciones: + * 1. Registro de eventos. + * 2. Registro de participantes. + * 3. Simulación de eventos. + * 4. Creación de informes. + * 5. Salir del programa. +""" +import random +from collections import defaultdict + +class Participante: + def __init__(self, nombre, pais): + self.nombre = nombre + self.pais = pais + +class Evento: + def __init__(self, nombre): + self.nombre = nombre + self.participantes = [] + self.resultados = [] + + def agregar_participante(self, participante): + self.participantes.append(participante) + + def simular(self): + if len(self.participantes) < 3: + print(f"No hay suficientes participantes en {self.nombre} para simular.") + return False + self.resultados = random.sample(self.participantes, len(self.participantes)) + return True + + def obtener_podio(self): + return self.resultados[:3] + +class JuegosOlimpicos: + def __init__(self): + self.eventos = [] + self.paises_medallas = defaultdict(lambda: {'oro': 0, 'plata': 0, 'bronce': 0}) + + def registrar_evento(self, nombre): + self.eventos.append(Evento(nombre)) + + def listar_eventos(self): + for i, evento in enumerate(self.eventos): + print(f"{i + 1}. {evento.nombre} ({len(evento.participantes)} participantes)") + + def registrar_participante(self, evento_index, nombre, pais): + if 0 <= evento_index < len(self.eventos): + self.eventos[evento_index].agregar_participante(Participante(nombre, pais)) + + def simular_eventos(self): + for evento in self.eventos: + if evento.simular(): + print(f"\nEvento: {evento.nombre}") + podio = evento.obtener_podio() + medallas = ['oro', 'plata', 'bronce'] + for idx, participante in enumerate(podio): + self.paises_medallas[participante.pais][medallas[idx]] += 1 + print(f"{medallas[idx].capitalize()}: {participante.nombre} ({participante.pais})") + + def mostrar_ranking(self): + print("\nRanking de países por medallas:") + ranking = sorted(self.paises_medallas.items(), key=lambda p: (p[1]['oro'], p[1]['plata'], p[1]['bronce']), reverse=True) + for pais, medallas in ranking: + print(f"{pais} - Oro: {medallas['oro']}, Plata: {medallas['plata']}, Bronce: {medallas['bronce']}") + +def menu(): + juegos = JuegosOlimpicos() + while True: + print("\n--- JJOO París 2024 ---") + print("1. Registrar evento") + print("2. Registrar participante") + print("3. Simular eventos") + print("4. Mostrar ranking de países") + print("5. Salir") + opcion = input("Seleccione una opción: ") + + if opcion == '1': + nombre = input("Nombre del evento: ") + juegos.registrar_evento(nombre) + elif opcion == '2': + juegos.listar_eventos() + idx = int(input("Seleccione evento por número: ")) - 1 + nombre = input("Nombre del participante: ") + pais = input("País: ") + juegos.registrar_participante(idx, nombre, pais) + elif opcion == '3': + juegos.simular_eventos() + elif opcion == '4': + juegos.mostrar_ranking() + elif opcion == '5': + print("¡Gracias por usar el simulador JJOO!") + break + else: + print("Opción no válida.") + +if __name__ == "__main__": + menu() diff --git a/Advanced/02.BatallaDeadpoolWolverine.py b/Advanced/02.BatallaDeadpoolWolverine.py new file mode 100644 index 00000000..fabba9f6 --- /dev/null +++ b/Advanced/02.BatallaDeadpoolWolverine.py @@ -0,0 +1,68 @@ +import random +import time + +class Personaje: + def __init__(self, nombre, vida, min_dano, max_dano, evasion): + self.nombre = nombre + self.vida = vida + self.min_dano = min_dano + self.max_dano = max_dano + self.evasion = evasion # probabilidad entre 0 y 1 + self.omitir_turno = False + + def atacar(self): + return random.randint(self.min_dano, self.max_dano) + + def esquiva(self): + return random.random() < self.evasion + + def recibir_dano(self, dano): + self.vida -= dano + + +def simular_batalla(deadpool, wolverine): + turno = 1 + atacante = deadpool + defensor = wolverine + + while deadpool.vida > 0 and wolverine.vida > 0: + print(f"\n--- Turno {turno} ---") + time.sleep(1) + + if atacante.omitir_turno: + print(f"{atacante.nombre} se está recuperando del daño máximo anterior y pierde este turno.") + atacante.omitir_turno = False + else: + if defensor.esquiva(): + print(f"{defensor.nombre} esquivó el ataque de {atacante.nombre}!") + else: + dano = atacante.atacar() + defensor.recibir_dano(dano) + print(f"{atacante.nombre} ataca a {defensor.nombre} y causa {dano} de daño.") + if dano == atacante.max_dano: + print(f"¡Daño máximo! {defensor.nombre} pierde su próximo turno para recuperarse.") + defensor.omitir_turno = True + + print(f"Vida de {deadpool.nombre}: {deadpool.vida} | Vida de {wolverine.nombre}: {wolverine.vida}") + + atacante, defensor = defensor, atacante + turno += 1 + + print("\n=== ¡Fin del combate! ===") + if deadpool.vida <= 0 and wolverine.vida <= 0: + print("Ambos héroes han caído. ¡Es un empate épico!") + elif deadpool.vida <= 0: + print("Wolverine gana la batalla.") + else: + print("Deadpool gana la batalla.") + + +if __name__ == "__main__": + print("=== ¡Deadpool vs Wolverine! ===") + vida_deadpool = int(input("Introduce la vida inicial de Deadpool: ")) + vida_wolverine = int(input("Introduce la vida inicial de Wolverine: ")) + + deadpool = Personaje("Deadpool", vida_deadpool, 10, 100, 0.25) + wolverine = Personaje("Wolverine", vida_wolverine, 10, 120, 0.20) + + simular_batalla(deadpool, wolverine) diff --git a/Advanced/03.RescatandoMickey.py b/Advanced/03.RescatandoMickey.py new file mode 100644 index 00000000..73415e26 --- /dev/null +++ b/Advanced/03.RescatandoMickey.py @@ -0,0 +1,104 @@ +""" +/* + * EJERCICIO: + * ¡Disney ha presentado un montón de novedades en su D23! + * Pero... ¿Dónde está Mickey? + * Mickey Mouse ha quedado atrapado en un laberinto mágico + * creado por Maléfica. + * Desarrolla un programa para ayudarlo a escapar. + * Requisitos: + * 1. El laberinto está formado por un cuadrado de 6x6 celdas. + * 2. Los valores de las celdas serán: + * - ⬜️ Vacío + * - ⬛️ Obstáculo + * - 🐭 Mickey + * - 🚪 Salida + * Acciones: + * 1. Crea una matriz que represente el laberinto (no hace falta + * que se genere de manera automática). + * 2. Interactúa con el usuario por consola para preguntarle hacia + * donde se tiene que desplazar (arriba, abajo, izquierda o derecha). + * 3. Muestra la actualización del laberinto tras cada desplazamiento. + * 4. Valida todos los movimientos, teniendo en cuenta los límites + * del laberinto y los obstáculos. Notifica al usuario. + * 5. Finaliza el programa cuando Mickey llegue a la salida. + */ +""" +import os + +# Símbolos del laberinto +VACIO = "⬜️" +OBSTACULO = "⬛️" +MICKEY = "🐭" +SALIDA = "🚪" + +# Laberinto 6x6 definido manualmente +laberinto = [ + [VACIO, OBSTACULO, VACIO, VACIO, VACIO, VACIO], + [VACIO, OBSTACULO, VACIO, OBSTACULO, OBSTACULO, VACIO], + [VACIO, VACIO, VACIO, VACIO, VACIO, VACIO], + [OBSTACULO, OBSTACULO, OBSTACULO, OBSTACULO, VACIO, OBSTACULO], + [VACIO, VACIO, VACIO, VACIO, VACIO, VACIO], + [VACIO, OBSTACULO, OBSTACULO, OBSTACULO, VACIO, SALIDA], +] + +# Posición inicial de Mickey +mickey_pos = [0, 0] +laberinto[mickey_pos[0]][mickey_pos[1]] = MICKEY + +def imprimir_laberinto(): + os.system('cls' if os.name == 'nt' else 'clear') + for fila in laberinto: + print(" ".join(fila)) + print() + +def mover_mickey(direccion): + dx, dy = 0, 0 + if direccion == "arriba": + dx = -1 + elif direccion == "abajo": + dx = 1 + elif direccion == "izquierda": + dy = -1 + elif direccion == "derecha": + dy = 1 + else: + print("Dirección no válida. Usa arriba, abajo, izquierda o derecha.") + return False + + nueva_x = mickey_pos[0] + dx + nueva_y = mickey_pos[1] + dy + + if not (0 <= nueva_x < 6 and 0 <= nueva_y < 6): + print("¡No puedes salirte del laberinto!") + return False + if laberinto[nueva_x][nueva_y] == OBSTACULO: + print("¡Hay un obstáculo en esa dirección!") + return False + + # Verifica si llegó a la salida + if laberinto[nueva_x][nueva_y] == SALIDA: + laberinto[mickey_pos[0]][mickey_pos[1]] = VACIO + mickey_pos[0], mickey_pos[1] = nueva_x, nueva_y + laberinto[nueva_x][nueva_y] = MICKEY + imprimir_laberinto() + print("¡Mickey ha escapado del laberinto! 🎉🚪") + return True + + # Mueve a Mickey + laberinto[mickey_pos[0]][mickey_pos[1]] = VACIO + mickey_pos[0], mickey_pos[1] = nueva_x, nueva_y + laberinto[nueva_x][nueva_y] = MICKEY + return False + +def juego(): + imprimir_laberinto() + while True: + direccion = input("¿Hacia dónde debe ir Mickey? (arriba, abajo, izquierda, derecha): ").strip().lower() + terminado = mover_mickey(direccion) + imprimir_laberinto() + if terminado: + break + +if __name__ == "__main__": + juego() diff --git a/Advanced/04.ArbolGenealogico.py b/Advanced/04.ArbolGenealogico.py new file mode 100644 index 00000000..2a5d8a8f --- /dev/null +++ b/Advanced/04.ArbolGenealogico.py @@ -0,0 +1,145 @@ +""" +* EJERCICIO: + * ¡La Casa del Dragón ha finalizado y no volverá hasta 2026! + * ¿Alguien se entera de todas las relaciones de parentesco + * entre personajes que aparecen en la saga? + * Desarrolla un árbol genealógico para relacionarlos (o invéntalo). + * Requisitos: + * 1. Estará formado por personas con las siguientes propiedades: + * - Identificador único (obligatorio) + * - Nombre (obligatorio) + * - Pareja (opcional) + * - Hijos (opcional) + * 2. Una persona sólo puede tener una pareja (para simplificarlo). + * 3. Las relaciones deben validarse dentro de lo posible. + * Ejemplo: Un hijo no puede tener tres padres. + * Acciones: + * 1. Crea un programa que permita crear y modificar el árbol. + * - Añadir y eliminar personas + * - Modificar pareja e hijos + * 2. Podrás imprimir el árbol (de la manera que consideres). + * + * NOTA: Ten en cuenta que la complejidad puede ser alta si + * se implementan todas las posibles relaciones. Intenta marcar + * tus propias reglas y límites para que te resulte asumible. +""" +class Persona: + def __init__(self, id, nombre): + self.id = id + self.nombre = nombre + self.pareja_id = None + self.hijos_ids = [] + + def __str__(self): + return f"{self.nombre} (ID: {self.id})" + + +class ArbolGenealogico: + def __init__(self): + self.personas = {} + + def agregar_persona(self, id, nombre): + if id in self.personas: + print("⚠️ Ya existe una persona con ese ID.") + return + self.personas[id] = Persona(id, nombre) + print(f"✅ Persona '{nombre}' añadida.") + + def eliminar_persona(self, id): + if id not in self.personas: + print("⚠️ Persona no encontrada.") + return + + # Eliminar de pareja y de hijos + for persona in self.personas.values(): + if persona.pareja_id == id: + persona.pareja_id = None + if id in persona.hijos_ids: + persona.hijos_ids.remove(id) + + del self.personas[id] + print(f"🗑️ Persona con ID {id} eliminada.") + + def asignar_pareja(self, id1, id2): + if id1 not in self.personas or id2 not in self.personas: + print("⚠️ Uno de los ID no existe.") + return + p1, p2 = self.personas[id1], self.personas[id2] + if p1.pareja_id or p2.pareja_id: + print("⚠️ Alguno ya tiene pareja.") + return + p1.pareja_id = id2 + p2.pareja_id = id1 + print(f"💍 {p1.nombre} y {p2.nombre} ahora son pareja.") + + def agregar_hijo(self, padre_id, hijo_id): + if padre_id not in self.personas or hijo_id not in self.personas: + print("⚠️ ID no encontrado.") + return + padre = self.personas[padre_id] + hijo = self.personas[hijo_id] + + # Contar cuántos padres tiene ya + padres = [p for p in self.personas.values() if hijo_id in p.hijos_ids] + if len(padres) >= 2: + print("⚠️ El hijo ya tiene dos padres.") + return + if hijo_id not in padre.hijos_ids: + padre.hijos_ids.append(hijo_id) + print(f"👶 {hijo.nombre} ha sido asignado como hijo de {padre.nombre}.") + + def imprimir_arbol(self): + for persona in self.personas.values(): + print(f"\n🧍 {persona}") + if persona.pareja_id: + pareja = self.personas.get(persona.pareja_id) + print(f" 💞 Pareja: {pareja.nombre}") + if persona.hijos_ids: + hijos = [self.personas[hid].nombre for hid in persona.hijos_ids] + print(f" 👶 Hijos: {', '.join(hijos)}") + + def menu(self): + while True: + print("\n--- Árbol Genealógico ---") + print("1. Añadir persona") + print("2. Eliminar persona") + print("3. Asignar pareja") + print("4. Asignar hijo") + print("5. Mostrar árbol") + print("6. Salir") + opcion = input("Elige una opción: ") + + if opcion == "1": + id = input("ID: ") + nombre = input("Nombre: ") + self.agregar_persona(id, nombre) + + elif opcion == "2": + id = input("ID de la persona a eliminar: ") + self.eliminar_persona(id) + + elif opcion == "3": + id1 = input("ID de la primera persona: ") + id2 = input("ID de la segunda persona: ") + self.asignar_pareja(id1, id2) + + elif opcion == "4": + padre_id = input("ID del padre o madre: ") + hijo_id = input("ID del hijo: ") + self.agregar_hijo(padre_id, hijo_id) + + elif opcion == "5": + self.imprimir_arbol() + + elif opcion == "6": + print("¡Hasta la próxima! 🐉") + break + + else: + print("❌ Opción no válida.") + + +# Ejecución +if __name__ == "__main__": + arbol = ArbolGenealogico() + arbol.menu() diff --git a/Advanced/05.AnillosPoder.py b/Advanced/05.AnillosPoder.py new file mode 100644 index 00000000..97592913 --- /dev/null +++ b/Advanced/05.AnillosPoder.py @@ -0,0 +1,60 @@ +""" +/* + * EJERCICIO: + * ¡La temporada 2 de "Los Anillos de Poder" está a punto de estrenarse! + * ¿Qué pasaría si tuvieras que encargarte de repartir los anillos + * entre las razas de la Tierra Media? + * Desarrolla un programa que se encargue de distribuirlos. + * Requisitos: + * 1. Los Elfos recibirán un número impar. + * 2. Los Enanos un número primo. + * 3. Los Hombres un número par. + * 4. Sauron siempre uno. + * Acciones: + * 1. Crea un programa que reciba el número total de anillos + * y busque una posible combinación para repartirlos. + * 2. Muestra el reparto final o el error al realizarlo. + */ +""" +import math + +def es_primo(n): + if n < 2: + return False + for i in range(2, int(math.sqrt(n))+1): + if n % i == 0: + return False + return True + +def buscar_reparto(total_anillos): + total_sin_sauron = total_anillos - 1 + encontrado = False + + for elfos in range(1, total_sin_sauron, 2): # números impares + for enanos in range(2, total_sin_sauron - elfos): + if not es_primo(enanos): + continue + hombres = total_sin_sauron - elfos - enanos + if hombres >= 0 and hombres % 2 == 0: + print("\n🎉 Reparto posible:") + print(f"🧝 Elfos: {elfos}") + print(f"⛏️ Enanos: {enanos}") + print(f"🧔 Hombres: {hombres}") + print(f"👁️ Sauron: 1") + encontrado = True + return + + if not encontrado: + print("❌ No hay una combinación válida para repartir los anillos.") + +# --- Interacción principal --- + +if __name__ == "__main__": + try: + total = int(input("🔢 Introduce el número total de anillos: ")) + if total < 4: + print("⚠️ Debe haber al menos 4 anillos para hacer un reparto.") + else: + buscar_reparto(total) + except ValueError: + print("⚠️ Por favor, introduce un número válido.") diff --git a/Advanced/06.SombreoSeleccionador.py b/Advanced/06.SombreoSeleccionador.py new file mode 100644 index 00000000..1e23e797 --- /dev/null +++ b/Advanced/06.SombreoSeleccionador.py @@ -0,0 +1,161 @@ +""" +/* + * EJERCICIO: + * Cada 1 de septiembre, el Hogwarts Express parte hacia la escuela + * de programación de Hogwarts para magos y brujas del código. + * En ella, su famoso sombrero seleccionador ayuda a los programadores + * a encontrar su camino... + * Desarrolla un programa que simule el comportamiento del sombrero. + * Requisitos: + * 1. El sombrero realizará 10 preguntas para determinar la casa del alumno. + * 2. Deben existir 4 casas. Por ejemplo: Frontend, Backend, Mobile y Data. + * (Puedes elegir las que quieras) + * Acciones: + * 1. Crea un programa que solicite el nombre del alumno y realice 10 + * preguntas, con cuatro posibles respuestas cada una. + * 2. Cada respuesta asigna puntos a cada una de las casas (a tu elección). + * 3. Una vez finalizado, el sombrero indica el nombre del alumno + * y a qué casa pertenecerá (resuelve el posible empate de manera aleatoria, + * pero indicándole al alumno que la decisión ha sido complicada). + */ +""" +import random + +# Definición de casas +casas = { + "Frontend": 0, + "Backend": 0, + "Mobile": 0, + "Data": 0 +} + +# Preguntas y respuestas con puntuación +preguntas = [ + { + "texto": "¿Qué parte de un proyecto disfrutas más?", + "respuestas": { + "a": ("Diseñar interfaces llamativas", "Frontend"), + "b": ("Optimizar bases de datos", "Backend"), + "c": ("Construir apps nativas", "Mobile"), + "d": ("Analizar grandes volúmenes de datos", "Data") + } + }, + { + "texto": "¿Cuál es tu herramienta favorita?", + "respuestas": { + "a": ("Figma", "Frontend"), + "b": ("PostgreSQL", "Backend"), + "c": ("Flutter", "Mobile"), + "d": ("Jupyter Notebook", "Data") + } + }, + { + "texto": "¿Qué te motiva a programar?", + "respuestas": { + "a": ("Crear experiencias bonitas", "Frontend"), + "b": ("Resolver problemas complejos", "Backend"), + "c": ("Innovar en dispositivos móviles", "Mobile"), + "d": ("Descubrir patrones en los datos", "Data") + } + }, + { + "texto": "¿Qué lenguaje prefieres?", + "respuestas": { + "a": ("JavaScript", "Frontend"), + "b": ("Python", "Backend"), + "c": ("Kotlin", "Mobile"), + "d": ("R", "Data") + } + }, + { + "texto": "¿Cuál sería tu hechizo favorito?", + "respuestas": { + "a": ("Lumos: iluminar interfaces", "Frontend"), + "b": ("Alohomora: desbloquear lógica", "Backend"), + "c": ("Accio: invocar apps", "Mobile"), + "d": ("Legilimens: leer datos", "Data") + } + }, + { + "texto": "¿Qué tipo de bugs odias más?", + "respuestas": { + "a": ("Desalineación de elementos", "Frontend"), + "b": ("Problemas de concurrencia", "Backend"), + "c": ("Errores de compatibilidad", "Mobile"), + "d": ("Errores estadísticos", "Data") + } + }, + { + "texto": "¿Dónde te gustaría trabajar?", + "respuestas": { + "a": ("Agencia de diseño web", "Frontend"), + "b": ("Startup de IA", "Backend"), + "c": ("Empresa de wearables", "Mobile"), + "d": ("Laboratorio de datos", "Data") + } + }, + { + "texto": "¿Qué superpoder querrías tener?", + "respuestas": { + "a": ("Crear belleza visual al instante", "Frontend"), + "b": ("Resolver algoritmos imposibles", "Backend"), + "c": ("Adaptarte a cualquier dispositivo", "Mobile"), + "d": ("Predecir el futuro con datos", "Data") + } + }, + { + "texto": "¿Qué prefieres en tu tiempo libre?", + "respuestas": { + "a": ("Explorar webs creativas", "Frontend"), + "b": ("Ver documentales de tecnología", "Backend"), + "c": ("Probar nuevas apps", "Mobile"), + "d": ("Leer sobre ciencia y datos", "Data") + } + }, + { + "texto": "¿Con qué personaje te identificas más?", + "respuestas": { + "a": ("Hermione: brillante y detallista", "Frontend"), + "b": ("Snape: estratega y profundo", "Backend"), + "c": ("Harry: valiente e intuitivo", "Mobile"), + "d": ("Dumbledore: sabio y analítico", "Data") + } + } +] + +def preguntar(nombre): + print(f"\n🎩 Bienvenido/a, {nombre}. El Sombrero Seleccionador hablará...") + print("Responde las siguientes preguntas eligiendo a, b, c o d:\n") + + for i, pregunta in enumerate(preguntas): + print(f"{i + 1}. {pregunta['texto']}") + for clave, (texto, _) in pregunta["respuestas"].items(): + print(f" {clave}) {texto}") + while True: + respuesta = input("Tu elección: ").lower() + if respuesta in pregunta["respuestas"]: + casa = pregunta["respuestas"][respuesta][1] + casas[casa] += 1 + break + else: + print("Por favor, elige a, b, c o d.") + print() + +def determinar_casa(nombre): + max_puntos = max(casas.values()) + ganadoras = [casa for casa, puntos in casas.items() if puntos == max_puntos] + + print(f"🧙 El sombrero ha analizado tus respuestas, {nombre}...") + if len(ganadoras) == 1: + print(f"✅ ¡Has sido asignado a la casa: {ganadoras[0]}!") + else: + seleccionada = random.choice(ganadoras) + print("🤔 Hmm... ¡Qué decisión tan difícil!") + print(f"✅ Finalmente, el sombrero ha decidido: ¡{seleccionada}!") + +# ---- Ejecución principal ---- + +if __name__ == "__main__": + nombre = input("🎓 ¿Cuál es tu nombre, joven aprendiz? ") + preguntar(nombre) + determinar_casa(nombre) diff --git a/Advanced/07.OasisLinkinPark.py b/Advanced/07.OasisLinkinPark.py new file mode 100644 index 00000000..aa60bbcf --- /dev/null +++ b/Advanced/07.OasisLinkinPark.py @@ -0,0 +1,98 @@ +""" + * EJERCICIO: + * ¡Dos de las bandas más grandes de la historia están de vuelta! + * Oasis y Linkin Park han anunciado nueva gira, pero, ¿quién es más popular? + * Desarrolla un programa que se conecte al API de Spotify y los compare. + * Requisitos: + * 1. Crea una cuenta de desarrollo en https://developer.spotify.com. + * 2. Conéctate al API utilizando tu lenguaje de programación. + * 3. Recupera datos de los endpoint que tú quieras. + * Acciones: + * 1. Accede a las estadísticas de las dos bandas. + * Por ejemplo: número total de seguidores, escuchas mensuales, + * canción con más reproducciones... + * 2. Compara los resultados de, por lo menos, 3 endpoint. + * 3. Muestra todos los resultados por consola para notificar al usuario. + * 4. Desarrolla un criterio para seleccionar qué banda es más popular. +""" +import requests +import base64 + +# Rellena con tus credenciales de Spotify +CLIENT_ID = "TU_CLIENT_ID" +CLIENT_SECRET = "TU_CLIENT_SECRET" + +# Obtener token de autenticación +def obtener_token(): + auth = f"{CLIENT_ID}:{CLIENT_SECRET}" + auth_bytes = auth.encode('utf-8') + auth_base64 = base64.b64encode(auth_bytes).decode('utf-8') + + headers = { + "Authorization": f"Basic {auth_base64}" + } + + data = { + "grant_type": "client_credentials" + } + + response = requests.post("https://accounts.spotify.com/api/token", headers=headers, data=data) + return response.json()["access_token"] + +# Buscar artista por nombre +def buscar_artista(nombre, token): + url = f"https://api.spotify.com/v1/search?q={nombre}&type=artist" + headers = {"Authorization": f"Bearer {token}"} + response = requests.get(url, headers=headers) + items = response.json()["artists"]["items"] + return items[0] if items else None + +# Obtener top tracks de un artista +def obtener_top_tracks(artist_id, token, market="US"): + url = f"https://api.spotify.com/v1/artists/{artist_id}/top-tracks?market={market}" + headers = {"Authorization": f"Bearer {token}"} + response = requests.get(url, headers=headers) + return response.json()["tracks"] + +# Comparar artistas +def comparar_artistas(artista1, artista2): + token = obtener_token() + + datos = {} + for nombre in [artista1, artista2]: + artista = buscar_artista(nombre, token) + top_tracks = obtener_top_tracks(artista["id"], token) + datos[nombre] = { + "followers": artista["followers"]["total"], + "popularity": artista["popularity"], + "top_track": top_tracks[0]["name"], + "top_track_popularity": top_tracks[0]["popularity"] + } + + print("\n🎵 RESULTADOS COMPARATIVOS:") + for nombre in datos: + info = datos[nombre] + print(f"\n🎤 {nombre}") + print(f"- Seguidores: {info['followers']:,}") + print(f"- Popularidad (0-100): {info['popularity']}") + print(f"- Canción más popular: {info['top_track']} (popularidad: {info['top_track_popularity']})") + + # Evaluar popularidad + print("\n🔥 VEREDICTO FINAL:") + puntos = {artista1: 0, artista2: 0} + + # Comparación por puntos + for criterio in ["followers", "popularity", "top_track_popularity"]: + ganador = artista1 if datos[artista1][criterio] > datos[artista2][criterio] else artista2 + puntos[ganador] += 1 + + if puntos[artista1] > puntos[artista2]: + print(f"🏆 ¡{artista1} es más popular!") + elif puntos[artista1] < puntos[artista2]: + print(f"🏆 ¡{artista2} es más popular!") + else: + print("🤝 ¡Empate técnico!") + +# Ejecutar comparación +if __name__ == "__main__": + comparar_artistas("Oasis", "Linkin Park") diff --git a/Advanced/08.MoureDevPro.py b/Advanced/08.MoureDevPro.py new file mode 100644 index 00000000..76dbae01 --- /dev/null +++ b/Advanced/08.MoureDevPro.py @@ -0,0 +1,73 @@ +""" +/* + * EJERCICIO: + * He presentado mi proyecto más importante del año: mouredev pro. + * Un campus para la comunidad, que lanzaré en octubre, donde estudiar + * programación de una manera diferente. + * Cualquier persona suscrita a la newsletter de https://mouredev.pro + * accederá a sorteos mensuales de suscripciones, regalos y descuentos. + * + * Desarrolla un programa que lea los registros de un fichero .csv y + * seleccione de manera aleatoria diferentes ganadores. + * Requisitos: + * 1. Crea un .csv con 3 columnas: id, email y status con valor "activo" + * o "inactivo" (y datos ficticios). + * Ejemplo: 1 | test@test.com | activo + * 2 | test2@test.com | inactivo + * (El .csv no debe subirse como parte de la corrección) + * 2. Recupera los datos desde el programa y selecciona email aleatorios. + * Acciones: + * 1. Accede al fichero .csv y selecciona de manera aleatoria un email + * ganador de una suscripción, otro ganador de un descuento y un último + * ganador de un libro (sólo si tiene status "activo" y no está repetido). + * 2. Muestra los emails ganadores y su id. + * 3. Ten en cuenta que la primera fila (con el nombre de las columnas) + * no debe tenerse en cuenta. + */ +""" +import csv +import random + +def cargar_usuarios_activos(ruta_csv): + usuarios = [] + + with open(ruta_csv, newline='', encoding='utf-8') as archivo: + lector = csv.DictReader(archivo) + + for fila in lector: + if fila["status"].strip().lower() == "activo": + usuarios.append({ + "id": fila["id"], + "email": fila["email"] + }) + + return usuarios + +def seleccionar_ganadores(usuarios): + if len(usuarios) < 3: + raise ValueError("No hay suficientes usuarios activos para seleccionar 3 ganadores distintos.") + + ganadores = random.sample(usuarios, 3) + + premios = ["Suscripción", "Descuento", "Libro"] + + return list(zip(premios, ganadores)) + +def mostrar_ganadores(ganadores): + print("🎉 GANADORES DEL SORTEO MOUREDEV PRO 🎉\n") + + for premio, ganador in ganadores: + print(f"🏆 {premio}: {ganador['email']} (ID: {ganador['id']})") + +if __name__ == "__main__": + ruta_csv = "suscriptores.csv" + + try: + usuarios_activos = cargar_usuarios_activos(ruta_csv) + ganadores = seleccionar_ganadores(usuarios_activos) + mostrar_ganadores(ganadores) + + except FileNotFoundError: + print(f"❌ El archivo '{ruta_csv}' no se encuentra.") + except ValueError as e: + print(f"⚠️ {str(e)}") diff --git a/Advanced/09.BatmanDay.py b/Advanced/09.BatmanDay.py new file mode 100644 index 00000000..be2c6a91 --- /dev/null +++ b/Advanced/09.BatmanDay.py @@ -0,0 +1,103 @@ +""" +/* + * EJERCICIO: + * Cada año se celebra el Batman Day durante la tercera semana de septiembre... + * ¡Y este año cumple 85 años! Te propongo un reto doble: + * + * RETO 1: + * Crea un programa que calcule cuándo se va a celebrar el Batman Day hasta + * su 100 aniversario. + * + * RETO 2: + * Crea un programa que implemente el sistema de seguridad de la Batcueva. + * Este sistema está diseñado para monitorear múltiples sensores distribuidos + * por Gotham, detectar intrusos y activar respuestas automatizadas. + * Cada sensor reporta su estado en tiempo real, y Batman necesita un programa + * que procese estos datos para tomar decisiones estratégicas. + * Requisitos: + * - El mapa de Gotham y los sensores se representa con una cuadrícula 20x20. + * - Cada sensor se identifica con una coordenada (x, y) y un nivel + * de amenaza entre 0 a 10 (número entero). + * - Batman debe concentrar recursos en el área más crítica de Gotham. + * - El programa recibe un listado de tuplas representando coordenadas de los + * sensores y su nivel de amenaza. El umbral de activación del protocolo de + * seguridad es 20 (sumatorio de amenazas en una cuadrícula 3x3). + * Acciones: + * - Identifica el área con mayor concentración de amenazas + * (sumatorio de amenazas en una cuadrícula 3x3). + * - Si el sumatorio de amenazas es mayor al umbral, activa el + * protocolo de seguridad. + * - Calcula la distancia desde la Batcueva, situada en (0, 0). La distancia es + * la suma absoluta de las coordenadas al centro de la cuadrícula amenazada. + * - Muestra la coordenada al centro de la cuadrícula más amenazada, la suma de + * sus amenazas, la distancia a la Batcueva y si se debe activar el + * protocolo de seguridad. + */ +""" +import datetime +import calendar + +def obtener_batman_day(anio): + # Buscar el tercer sábado de septiembre + mes = 9 # septiembre + sabados = [day for day in range(1, 31) + if calendar.weekday(anio, mes, day) == 5] # 5: sábado + return datetime.date(anio, mes, sabados[2]) # tercer sábado + +print("🦇 Próximos Batman Day hasta el centenario:") +for anio in range(2024, 2040): # De 85 a 100 aniversario + dia = obtener_batman_day(anio) + print(f"{anio} ({anio - 1939}º aniversario): {dia.strftime('%A, %d %B %Y')}") + +import random + +TAMANO = 20 +UMBRAL_AMENAZA = 20 + +# Simular sensores: lista de (x, y, amenaza) +def generar_sensores(num_sensores): + sensores = [] + for _ in range(num_sensores): + x = random.randint(0, TAMANO - 1) + y = random.randint(0, TAMANO - 1) + amenaza = random.randint(0, 10) + sensores.append((x, y, amenaza)) + return sensores + +# Crear mapa de Gotham +def construir_mapa(sensores): + mapa = [[0 for _ in range(TAMANO)] for _ in range(TAMANO)] + for x, y, amenaza in sensores: + mapa[x][y] = amenaza + return mapa + +# Buscar la mejor zona 3x3 +def buscar_zona_critica(mapa): + max_amenaza = -1 + centro_critico = None + for i in range(TAMANO - 2): + for j in range(TAMANO - 2): + suma = sum(mapa[i + dx][j + dy] for dx in range(3) for dy in range(3)) + if suma > max_amenaza: + max_amenaza = suma + centro_critico = (i + 1, j + 1) + return centro_critico, max_amenaza + +# Calcular distancia Manhattan +def distancia_batcueva(centro): + x, y = centro + return abs(x - 0) + abs(y - 0) + +# Programa principal +if __name__ == "__main__": + sensores = generar_sensores(100) + mapa = construir_mapa(sensores) + centro, amenaza_total = buscar_zona_critica(mapa) + distancia = distancia_batcueva(centro) + activar_protocolo = amenaza_total > UMBRAL_AMENAZA + + print("\n🛡️ Sistema de Seguridad de la Batcueva:") + print(f"📍 Centro zona crítica: {centro}") + print(f"🔥 Nivel total de amenaza: {amenaza_total}") + print(f"📏 Distancia a la Batcueva (0,0): {distancia}") + print(f"{'🚨 PROTOCOLO ACTIVADO' if activar_protocolo else '✅ Sin amenazas graves'}") diff --git a/Advanced/10.ForniteRubius.py b/Advanced/10.ForniteRubius.py new file mode 100644 index 00000000..2070aa09 --- /dev/null +++ b/Advanced/10.ForniteRubius.py @@ -0,0 +1,100 @@ +""" +/* + * EJERCICIO: + * ¡Rubius tiene su propia skin en Fortnite! + * Y va a organizar una competición para celebrarlo. + * Esta es la lista de participantes: + * https://x.com/Rubiu5/status/1840161450154692876 + * + * Desarrolla un programa que obtenga el número de seguidores en + * Twitch de cada participante, la fecha de creación de la cuenta + * y ordene los resultados en dos listados. + * - Usa el API de Twitch: https://dev.twitch.tv/docs/api/reference + * (NO subas las credenciales de autenticación) + * - Crea un ranking por número de seguidores y por antigüedad. + * - Si algún participante no tiene usuario en Twitch, debe reflejarlo. + */ + Obtener token de autenticación: + curl -X POST "https://id.twitch.tv/oauth2/token" \ +-d "client_id=TU_CLIENT_ID" \ +-d "client_secret=TU_CLIENT_SECRET" \ +-d "grant_type=client_credentials" + """ +import requests +import time + +# Sustituye con tus credenciales de Twitch +CLIENT_ID = "TU_CLIENT_ID" +AUTH_TOKEN = "TU_AUTH_TOKEN" + +HEADERS = { + "Client-ID": CLIENT_ID, + "Authorization": f"Bearer {AUTH_TOKEN}" +} + +# Lista de participantes desde el tweet (puedes adaptarla a mano o scrapear el tweet) +PARTICIPANTES = [ + "Rubiu5", "Auronplay", "Ibai", "TheGrefg", "xQc", "ElMariana", "Rivers_gg", "JuanSGuarnizo", + "BarbeQ", "Biyin_", "Cristinini", "Folagor03", "Gemita", "Illojuan", "Komanche", + "Luzu", "Quackity", "Reborn_Live", "Spursito", "Zeling", "Sekiam", "Mayichi", "Axel", "Tortillaland", "Karchez" +] + +def obtener_usuario(usuario): + url = f"https://api.twitch.tv/helix/users?login={usuario}" + resp = requests.get(url, headers=HEADERS) + data = resp.json() + if data["data"]: + return data["data"][0] + return None + +def obtener_seguidores(user_id): + url = f"https://api.twitch.tv/helix/users/follows?to_id={user_id}" + resp = requests.get(url, headers=HEADERS) + data = resp.json() + return data.get("total", 0) + +datos_usuarios = [] + +for nombre in PARTICIPANTES: + print(f"Buscando datos de: {nombre}") + user = obtener_usuario(nombre) + if user: + seguidores = obtener_seguidores(user["id"]) + datos_usuarios.append({ + "nombre": nombre, + "seguidores": seguidores, + "creacion": user["created_at"] + }) + else: + datos_usuarios.append({ + "nombre": nombre, + "seguidores": None, + "creacion": None + }) + time.sleep(0.5) # Para evitar rate limiting + +# Ranking por seguidores +ranking_seguidores = sorted( + [u for u in datos_usuarios if u["seguidores"] is not None], + key=lambda x: x["seguidores"], + reverse=True +) + +# Ranking por antigüedad +ranking_antiguedad = sorted( + [u for u in datos_usuarios if u["creacion"] is not None], + key=lambda x: x["creacion"] +) + +print("\n📊 Ranking por número de seguidores:") +for i, u in enumerate(ranking_seguidores, 1): + print(f"{i}. {u['nombre']} - {u['seguidores']} seguidores") + +print("\n📜 Ranking por antigüedad:") +for i, u in enumerate(ranking_antiguedad, 1): + print(f"{i}. {u['nombre']} - Creado el {u['creacion']}") + +print("\n❌ Usuarios no encontrados en Twitch:") +no_encontrados = [u for u in datos_usuarios if u["seguidores"] is None] +for u in no_encontrados: + print(f"- {u['nombre']}") diff --git a/Advanced/11.CamisetaRAR.py b/Advanced/11.CamisetaRAR.py new file mode 100644 index 00000000..1d7aaf58 --- /dev/null +++ b/Advanced/11.CamisetaRAR.py @@ -0,0 +1,33 @@ +""" +/* + * EJERCICIO: + * ¿Has visto la camiseta.rar? + * https://x.com/MoureDev/status/1841531938961592740 + * + * Crea un programa capaz de comprimir un archivo + * en formato .zip (o el que tú quieras). + * - No subas el archivo o el zip. + */ +""" +import zipfile +import os + +def comprimir_archivo(ruta_origen, ruta_destino_zip): + with zipfile.ZipFile(ruta_destino_zip, 'w', zipfile.ZIP_DEFLATED) as zipf: + if os.path.isfile(ruta_origen): + zipf.write(ruta_origen, arcname=os.path.basename(ruta_origen)) + print(f"Archivo comprimido: {ruta_destino_zip}") + elif os.path.isdir(ruta_origen): + for root, dirs, files in os.walk(ruta_origen): + for file in files: + ruta_completa = os.path.join(root, file) + arcname = os.path.relpath(ruta_completa, start=ruta_origen) + zipf.write(ruta_completa, arcname=arcname) + print(f"Carpeta comprimida: {ruta_destino_zip}") + else: + print("Ruta no válida.") + +# Ejemplo de uso +origen = "camiseta.txt" # O una carpeta, por ejemplo: "mi_carpeta/" +destino = "camiseta.zip" +comprimir_archivo(origen, destino) diff --git a/Advanced/12.DragonBall.py b/Advanced/12.DragonBall.py new file mode 100644 index 00000000..a2d3de7b --- /dev/null +++ b/Advanced/12.DragonBall.py @@ -0,0 +1,117 @@ +""" +/* + * EJERCICIO: + * ¡El último videojuego de Dragon Ball ya está aquí! + * Se llama Dragon Ball: Sparking! ZERO. + * + * Simula un Torneo de Artes Marciales, al más puro estilo + * de la saga, donde participarán diferentes luchadores, y el + * sistema decidirá quién es el ganador. + * + * Luchadores: + * - Nombre. + * - Tres atributos: velocidad, ataque y defensa + * (con valores entre 0 a 100 que tú decidirás). + * - Comienza cada batalla con 100 de salud. + * Batalla: + * - En cada batalla se enfrentan 2 luchadores. + * - El luchador con más velocidad comienza atacando. + * - El daño se calcula restando el daño de ataque del + * atacante menos la defensa del oponente. + * - El oponente siempre tiene un 20% de posibilidad de + * esquivar el ataque. + * - Si la defensa es mayor que el ataque, recibe un 10% + * del daño de ataque. + * - Después de cada turno y ataque, el oponente pierde salud. + * - La batalla finaliza cuando un luchador pierde toda su salud. + * Torneo: + * - Un torneo sólo es válido con un número de luchadores + * potencia de 2. + * - El torneo debe crear parejas al azar en cada ronda. + * - Los luchadores se enfrentan en rondas eliminatorias. + * - El ganador avanza a la siguiente ronda hasta que sólo + * quede uno. + * - Debes mostrar por consola todo lo que sucede en el torneo, + * así como el ganador. + */ +""" +import random +import time +from typing import List + +class Luchador: + def __init__(self, nombre, velocidad, ataque, defensa): + self.nombre = nombre + self.velocidad = velocidad + self.ataque = ataque + self.defensa = defensa + self.salud = 100 + + def restablecer_salud(self): + self.salud = 100 + + def __str__(self): + return f"{self.nombre} [VEL: {self.velocidad} | ATK: {self.ataque} | DEF: {self.defensa}]" + +def batalla(l1: Luchador, l2: Luchador) -> Luchador: + print(f"\n🔔 ¡Comienza la batalla entre {l1.nombre} y {l2.nombre}!") + l1.restablecer_salud() + l2.restablecer_salud() + + atacante, defensor = (l1, l2) if l1.velocidad >= l2.velocidad else (l2, l1) + print(f"⚡ {atacante.nombre} ataca primero por su mayor velocidad.") + + while l1.salud > 0 and l2.salud > 0: + if random.random() <= 0.2: + print(f"🛡️ {defensor.nombre} esquiva el ataque de {atacante.nombre}!") + else: + if atacante.ataque > defensor.defensa: + dano = atacante.ataque - defensor.defensa + else: + dano = int(atacante.ataque * 0.1) + defensor.salud -= dano + print(f"💥 {atacante.nombre} ataca a {defensor.nombre} causando {dano} de daño. ({defensor.salud} de salud restante)") + + atacante, defensor = defensor, atacante + time.sleep(0.5) + + ganador = l1 if l1.salud > 0 else l2 + print(f"🏆 ¡{ganador.nombre} gana la batalla!\n") + return ganador + +def es_potencia_de_2(n): + return (n != 0) and (n & (n - 1) == 0) + +def torneo(luchadores: List[Luchador]): + if not es_potencia_de_2(len(luchadores)): + print("❌ El número de luchadores debe ser una potencia de 2 (2, 4, 8, 16, ...)") + return + + ronda = 1 + while len(luchadores) > 1: + print(f"\n🔶 RONDA {ronda} 🔶") + random.shuffle(luchadores) + ganadores = [] + for i in range(0, len(luchadores), 2): + ganador = batalla(luchadores[i], luchadores[i+1]) + ganadores.append(ganador) + luchadores = ganadores + ronda += 1 + + print(f"\n🎉 ¡El campeón del torneo es {luchadores[0].nombre}!") + print("🥇 ¡Dragon Ball Sparking! ZERO Torneo Finalizado 🐉") + +# 🧙‍♂️ Luchadores de ejemplo +luchadores = [ + Luchador("Goku", 90, 85, 70), + Luchador("Vegeta", 85, 90, 65), + Luchador("Gohan", 75, 80, 60), + Luchador("Piccolo", 70, 75, 80), + Luchador("Trunks", 80, 78, 68), + Luchador("Freezer", 60, 88, 72), + Luchador("Cell", 65, 82, 75), + Luchador("Majin Buu", 55, 95, 85), +] + +# 🏁 Iniciar torneo +torneo(luchadores) diff --git a/Advanced/13.GithubCli.py b/Advanced/13.GithubCli.py new file mode 100644 index 00000000..a6dd55d0 --- /dev/null +++ b/Advanced/13.GithubCli.py @@ -0,0 +1,125 @@ +""" +/* + * EJERCICIO: + * ¡Me voy de viaje al GitHub Universe 2024 de San Francisco! + * + * Desarrolla un CLI (Command Line Interface) que permita + * interactuar con Git y GitHub de manera real desde terminal. + * + * El programa debe permitir las siguientes opciones: + * 1. Establecer el directorio de trabajo + * 2. Crear un nuevo repositorio + * 3. Crear una nueva rama + * 4. Cambiar de rama + * 5. Mostrar ficheros pendientes de hacer commit + * 6. Hacer commit (junto con un add de todos los ficheros) + * 7. Mostrar el historial de commits + * 8. Eliminar rama + * 9. Establecer repositorio remoto + * 10. Hacer pull + * 11. Hacer push + * 12. Salir + * + * Puedes intentar controlar los diferentes errores. + */ + """ +import subprocess +import os + +def ejecutar_comando(comando): + try: + resultado = subprocess.run(comando, shell=True, text=True, capture_output=True) + if resultado.stdout: + print(resultado.stdout) + if resultado.stderr: + print("⚠️", resultado.stderr) + except Exception as e: + print("❌ Error ejecutando el comando:", e) + +def establecer_directorio(): + ruta = input("📁 Introduce el path del directorio de trabajo: ").strip() + if os.path.isdir(ruta): + os.chdir(ruta) + print(f"✅ Directorio cambiado a: {os.getcwd()}") + else: + print("❌ El directorio no existe.") + +def crear_repositorio(): + ejecutar_comando("git init") + +def crear_rama(): + nombre = input("🌿 Nombre de la nueva rama: ").strip() + ejecutar_comando(f"git branch {nombre}") + +def cambiar_rama(): + nombre = input("🔀 Nombre de la rama a cambiar: ").strip() + ejecutar_comando(f"git checkout {nombre}") + +def ficheros_pendientes(): + ejecutar_comando("git status") + +def hacer_commit(): + mensaje = input("✏️ Escribe el mensaje del commit: ").strip() + ejecutar_comando("git add .") + ejecutar_comando(f'git commit -m "{mensaje}"') + +def mostrar_historial(): + ejecutar_comando("git log --oneline") + +def eliminar_rama(): + nombre = input("🧨 Nombre de la rama a eliminar: ").strip() + ejecutar_comando(f"git branch -d {nombre}") + +def establecer_remoto(): + url = input("🔗 URL del repositorio remoto: ").strip() + ejecutar_comando(f"git remote add origin {url}") + +def hacer_pull(): + rama = input("⬇️ Rama desde la que hacer pull (ej. main): ").strip() + ejecutar_comando(f"git pull origin {rama}") + +def hacer_push(): + rama = input("⬆️ Rama a la que hacer push (ej. main): ").strip() + ejecutar_comando(f"git push origin {rama}") + +def mostrar_menu(): + print(""" +========= 🌌 GitHub Universe CLI 🌌 ========= +1. Establecer directorio de trabajo +2. Crear un nuevo repositorio +3. Crear una nueva rama +4. Cambiar de rama +5. Mostrar ficheros pendientes de hacer commit +6. Hacer commit +7. Mostrar el historial de commits +8. Eliminar rama +9. Establecer repositorio remoto +10. Hacer pull +11. Hacer push +12. Salir +============================================ +""") + +def main(): + while True: + mostrar_menu() + opcion = input("Selecciona una opción (1-12): ").strip() + match opcion: + case "1": establecer_directorio() + case "2": crear_repositorio() + case "3": crear_rama() + case "4": cambiar_rama() + case "5": ficheros_pendientes() + case "6": hacer_commit() + case "7": mostrar_historial() + case "8": eliminar_rama() + case "9": establecer_remoto() + case "10": hacer_pull() + case "11": hacer_push() + case "12": + print("👋 ¡Hasta luego, GitHubnauta!") + break + case _: print("❌ Opción no válida.") + +if __name__ == "__main__": + main() diff --git a/Advanced/14.CuentaAtras.py b/Advanced/14.CuentaAtras.py new file mode 100644 index 00000000..e599a89d --- /dev/null +++ b/Advanced/14.CuentaAtras.py @@ -0,0 +1,74 @@ +""" +/* + * EJERCICIO: + * ¡El 12 de noviembre lanzo mouredev pro! + * El campus de la comunidad para estudiar programación de + * una manera diferente: https://mouredev.pro + * + * Crea un programa que funcione como una cuenta atrás. + * + * - Al iniciarlo tendrás que indicarle el día, mes, año, + * hora, minuto y segundo en el que quieres que finalice. + * - Deberás transformar esa fecha local a UTC. + * - La cuenta atrás comenzará y mostrará los días, horas, + * minutos y segundos que faltan. + * - Se actualizará cada segundo y borrará la terminal en + * cada nueva representación del tiempo restante. + * - Una vez finalice, mostrará un mensaje. + * - Realiza la ejecución, si el lenguaje lo soporta, en + * un hilo independiente. + */ +""" +import datetime +import time +import threading +import os + +def limpiar_terminal(): + os.system('cls' if os.name == 'nt' else 'clear') + +def cuenta_atras(fecha_objetivo_local): + # Convertimos la fecha local a UTC + fecha_utc = fecha_objetivo_local.astimezone(datetime.timezone.utc) + print(f"📅 Fecha objetivo (UTC): {fecha_utc.strftime('%Y-%m-%d %H:%M:%S')}") + + while True: + ahora_utc = datetime.datetime.now(datetime.timezone.utc) + diferencia = fecha_utc - ahora_utc + + if diferencia.total_seconds() <= 0: + limpiar_terminal() + print("🚀 ¡Ha llegado el momento! ¡MoureDev Pro ya está disponible! 🎉") + break + + dias = diferencia.days + horas, resto = divmod(diferencia.seconds, 3600) + minutos, segundos = divmod(resto, 60) + + limpiar_terminal() + print("⌛ Cuenta atrás para el lanzamiento de MoureDev Pro:") + print(f"{dias} días, {horas:02} horas, {minutos:02} minutos, {segundos:02} segundos restantes.") + time.sleep(1) + +def iniciar_cuenta_atras(): + try: + print("Introduce la fecha y hora de finalización (hora local):") + anio = int(input("Año: ")) + mes = int(input("Mes: ")) + dia = int(input("Día: ")) + hora = int(input("Hora (0-23): ")) + minuto = int(input("Minuto: ")) + segundo = int(input("Segundo: ")) + + fecha_local = datetime.datetime(anio, mes, dia, hora, minuto, segundo) + # Asumimos zona horaria local (sin especificar tzinfo explícito) + fecha_local = fecha_local.astimezone() # Lo convierte a la zona local con tzinfo + except Exception as e: + print("❌ Error al introducir la fecha:", e) + return + + hilo = threading.Thread(target=cuenta_atras, args=(fecha_local,)) + hilo.start() + +if __name__ == "__main__": + iniciar_cuenta_atras() diff --git a/Advanced/15.Octoverse.py b/Advanced/15.Octoverse.py new file mode 100644 index 00000000..f704b320 --- /dev/null +++ b/Advanced/15.Octoverse.py @@ -0,0 +1,90 @@ +""" +/* + * EJERCICIO: + * GitHub ha publicado el Octoverse 2024, el informe + * anual del estado de la plataforma: + * https://octoverse.github.com + * + * Utilizando el API de GitHub, crea un informe asociado + * a un usuario concreto. + * + * - Se debe poder definir el nombre del usuario + * sobre el que se va a generar el informe. + * + * - Crea un informe de usuario basándote en las 5 métricas + * que tú quieras, utilizando la información que te + * proporciona GitHub. Por ejemplo: + * - Lenguaje más utilizado + * - Cantidad de repositorios + * - Seguidores/Seguidos + * - Stars/forks + * - Contribuciones + * (lo que se te ocurra) + */ +""" +import requests +from collections import Counter + +# Token personal opcional para más peticiones sin límites +GITHUB_TOKEN = None # O pon tu token aquí como string + +def get_headers(): + headers = {"Accept": "application/vnd.github.v3+json"} + if GITHUB_TOKEN: + headers["Authorization"] = f"token {GITHUB_TOKEN}" + return headers + +def get_user_info(username): + url = f"https://api.github.com/users/{username}" + response = requests.get(url, headers=get_headers()) + response.raise_for_status() + return response.json() + +def get_user_repos(username): + repos = [] + page = 1 + while True: + url = f"https://api.github.com/users/{username}/repos?per_page=100&page={page}" + response = requests.get(url, headers=get_headers()) + response.raise_for_status() + data = response.json() + if not data: + break + repos.extend(data) + page += 1 + return repos + +def generar_informe(username): + try: + user = get_user_info(username) + repos = get_user_repos(username) + + lenguajes = Counter() + estrellas = 0 + forks = 0 + + for repo in repos: + lenguaje = repo.get("language") + if lenguaje: + lenguajes[lenguaje] += 1 + estrellas += repo.get("stargazers_count", 0) + forks += repo.get("forks_count", 0) + + lenguaje_principal = lenguajes.most_common(1)[0][0] if lenguajes else "Desconocido" + + print(f"\n🧾 Informe de GitHub para @{username}\n" + "-"*40) + print(f"👤 Nombre: {user.get('name') or 'No disponible'}") + print(f"📁 Repos públicos: {user.get('public_repos')}") + print(f"🌍 Lenguaje más utilizado: {lenguaje_principal}") + print(f"⭐ Total de estrellas recibidas: {estrellas}") + print(f"🍴 Total de forks: {forks}") + print(f"👥 Seguidores: {user.get('followers')} | Siguiendo: {user.get('following')}") + print(f"🔗 Perfil: {user.get('html_url')}") + print("-" * 40) + + except requests.HTTPError as e: + print(f"❌ Error al recuperar datos de GitHub: {e}") + +if __name__ == "__main__": + username = input("Introduce el nombre de usuario de GitHub: ") + generar_informe(username.strip()) diff --git a/Advanced/16.XBluesky.py b/Advanced/16.XBluesky.py new file mode 100644 index 00000000..4683e318 --- /dev/null +++ b/Advanced/16.XBluesky.py @@ -0,0 +1,141 @@ +""" +/* + * EJERCICIO: + * La alternativa descentralizada a X, Bluesky, comienza a atraer + * a nuevos usuarios. ¿Cómo funciona una red de este estilo? + * + * Implementa un sistema que simule el comportamiento de estas + * redes sociales. + * + * Debes crear las siguientes operaciones: + * - Registrar un usuario por nombre e identificador único. + * - Un usuario puede seguir/dejar de seguir a otro. + * - Creación de post asociado a un usuario. Debe poseer + * texto (200 caracteres máximo), fecha de creación + * e identificador único. + * - Eliminación de un post. + * - Posibilidad de hacer like (y eliminarlo) en un post. + * - Visualización del feed de un usuario con sus 10 publicaciones + * más actuales ordenadas desde la más reciente. + * - Visualización del feed de un usuario con las 10 publicaciones + * más actuales de los usuarios que sigue ordenadas + * desde la más reciente. + * + * Cuando se visualiza un post, debe mostrarse: + * ID de usuario, nombre de usuario, texto del post, + * fecha de creación y número total de likes. + * + * Controla errores en duplicados o acciones no permitidas. + */ +""" +import uuid +from datetime import datetime + +class Usuario: + def __init__(self, nombre): + self.id = str(uuid.uuid4()) + self.nombre = nombre + self.seguidores = set() + self.seguidos = set() + self.posts = [] + + def seguir(self, otro_usuario): + if otro_usuario != self: + self.seguidos.add(otro_usuario) + otro_usuario.seguidores.add(self) + else: + print("No puedes seguirte a ti mismo.") + + def dejar_de_seguir(self, otro_usuario): + if otro_usuario != self: + self.seguidos.discard(otro_usuario) + otro_usuario.seguidores.discard(self) + else: + print("No puedes dejar de seguirte a ti mismo.") + + def crear_post(self, texto): + if len(texto) > 200: + print("El texto excede el límite de 200 caracteres.") + return + post = Post(self, texto) + self.posts.append(post) + print(f"Post creado con ID: {post.id}") + + def eliminar_post(self, post_id): + post = next((p for p in self.posts if p.id == post_id), None) + if post: + self.posts.remove(post) + print(f"Post {post_id} eliminado.") + else: + print("Post no encontrado.") + + def mostrar_feed(self, num_posts=10): + feed = sorted(self.posts, key=lambda p: p.fecha_creacion, reverse=True)[:num_posts] + for post in feed: + print(post.mostrar()) + + def mostrar_feed_seguidos(self, num_posts=10): + feed = [] + for seguido in self.seguidos: + feed.extend(seguido.posts) + feed = sorted(feed, key=lambda p: p.fecha_creacion, reverse=True)[:num_posts] + for post in feed: + print(post.mostrar()) + + +class Post: + def __init__(self, usuario, texto): + self.id = str(uuid.uuid4()) + self.usuario = usuario + self.texto = texto + self.fecha_creacion = datetime.now() + self.likes = set() + + def dar_like(self, usuario): + if usuario != self.usuario: + self.likes.add(usuario) + print(f"Like dado por {usuario.nombre}.") + else: + print("No puedes dar like a tu propio post.") + + def quitar_like(self, usuario): + if usuario in self.likes: + self.likes.remove(usuario) + print(f"Like quitado por {usuario.nombre}.") + else: + print(f"{usuario.nombre} no había dado like a este post.") + + def mostrar(self): + return f"Post ID: {self.id}\nUsuario: {self.usuario.nombre} | Texto: {self.texto}\nFecha: {self.fecha_creacion}\nLikes: {len(self.likes)}" + + +# Interacción con el sistema +if __name__ == "__main__": + # Crear usuarios + usuario1 = Usuario("Alice") + usuario2 = Usuario("Bob") + + # Crear posts + usuario1.crear_post("¡Este es mi primer post!") + usuario2.crear_post("¡Este es el post de Bob!") + + # Seguir usuarios + usuario1.seguir(usuario2) + + # Dar like a un post + post_bob = usuario2.posts[0] + usuario1.dar_like(post_bob) + + # Mostrar feeds + print("\nFeed de Alice (mis posts):") + usuario1.mostrar_feed() + + print("\nFeed de Alice (posts de los que sigo):") + usuario1.mostrar_feed_seguidos() + + # Eliminar post + usuario1.eliminar_post(post_bob.id) + + # Mostrar feed después de eliminar + print("\nFeed de Alice (posts de los que sigo) después de eliminar:") + usuario1.mostrar_feed_seguidos() diff --git a/Advanced/17.Adviento.py b/Advanced/17.Adviento.py new file mode 100644 index 00000000..d9be7216 --- /dev/null +++ b/Advanced/17.Adviento.py @@ -0,0 +1,83 @@ +""" +/* + * EJERCICIO: + * ¡Cada año celebramos el aDEViento! 24 días, 24 regalos para + * developers. Del 1 al 24 de diciembre: https://adviento.dev + * + * Dibuja un calendario por terminal e implementa una + * funcionalidad para seleccionar días y mostrar regalos. + * - El calendario mostrará los días del 1 al 24 repartidos + * en 6 columnas a modo de cuadrícula. + * - Cada cuadrícula correspondiente a un día tendrá un tamaño + * de 4x3 caracteres, y sus bordes serán asteríscos. + * - Las cuadrículas dejarán un espacio entre ellas. + * - En el medio de cada cuadrícula aparecerá el día entre el + * 01 y el 24. + * + * Ejemplo de cuadrículas: + * **** **** **** + * *01* *02* *03* ... + * **** **** **** + * + * - El usuario selecciona qué día quiere descubrir. + * - Si está sin descubrir, se le dirá que ha abierto ese día + * y se mostrará de nuevo el calendario con esa cuadrícula + * cubierta de asteríscos (sin mostrar el día). + * + * Ejemplo de selección del día 1 + * **** **** **** + * **** *02* *03* ... + * **** **** **** + * + * - Si se selecciona un número ya descubierto, se le notifica + * al usuario. + */ +""" +class CalendarioADEViento: + def __init__(self): + self.dias_descubiertos = set() # Conjunto de días descubiertos + + def dibujar_calendario(self): + dia = 1 + calendario = '' + + # Recorremos las filas del calendario (6 filas de 4 días) + for i in range(6): + fila = '' + for j in range(4): + # Si el día ha sido descubierto, mostramos asteriscos + # Si no, mostramos el número del día + if dia in self.dias_descubiertos: + fila += '**** ' + else: + fila += f'*{self.formatear_dia(dia)}* ' + dia += 1 + if dia > 24: + break + calendario += fila.strip() + '\n' + + print(calendario) + + def formatear_dia(self, dia): + """ Formatea el día para que siempre tenga dos dígitos """ + return f'{dia:02d}' + + def seleccionar_dia(self, dia): + """ Permite al usuario seleccionar un día para descubrirlo """ + if dia in self.dias_descubiertos: + print(f'El día {self.formatear_dia(dia)} ya ha sido descubierto.') + else: + self.dias_descubiertos.add(dia) + print(f'¡Felicidades! Has descubierto el día {self.formatear_dia(dia)}.') + self.dibujar_calendario() # Redibuja el calendario actualizado + +# Crear el calendario +calendario = CalendarioADEViento() + +# Dibujar el calendario inicial +calendario.dibujar_calendario() + +# Simulación de selección de días +calendario.seleccionar_dia(1) # Seleccionar el día 1 +calendario.seleccionar_dia(1) # Intentar seleccionar el día 1 de nuevo +calendario.seleccionar_dia(5) # Seleccionar el día 5 diff --git a/Advanced/18.ArbolNavidad.py b/Advanced/18.ArbolNavidad.py new file mode 100644 index 00000000..0221d942 --- /dev/null +++ b/Advanced/18.ArbolNavidad.py @@ -0,0 +1,196 @@ +""" +/* + * EJERCICIO: + * ¡Ha comenzado diciembre! Es hora de montar nuestro + * árbol de Navidad... + * + * Desarrolla un programa que cree un árbol de Navidad + * con una altura dinámica definida por el usuario por terminal. + * + * Ejemplo de árbol de altura 5 (el tronco siempre será igual): + * + * * + * *** + * ***** + * ******* + * ********* + * ||| + * ||| + * + * El usuario podrá seleccionar las siguientes acciones: + * + * - Añadir o eliminar la estrella en la copa del árbol (@) + * - Añadir o eliminar bolas de dos en dos (o) aleatoriamente + * - Añadir o eliminar luces de tres en tres (+) aleatoriamente + * - Apagar (*) o encender (+) las luces (conservando su posición) + * - Una luz y una bola no pueden estar en el mismo sitio + * + * Sólo puedes añadir una estrella, y tantas luces o bolas + * como tengan cabida en el árbol. El programa debe notificar + * cada una de las acciones (o por el contrario, cuando no + * se pueda realizar alguna). + */ +""" +import random + +class ArbolNavidad: + def __init__(self, altura): + self.altura = altura + self.estrella = False + self.bolas = set() # Conjunto de posiciones de bolas + self.luces = set() # Conjunto de posiciones de luces + self.tree = self.crear_arbol() + + def crear_arbol(self): + """ Crea el árbol representado por una lista de cadenas. """ + tree = [] + for i in range(self.altura): + espacios = ' ' * (self.altura - i - 1) + estrellas = '*' * (2 * i + 1) + tree.append(espacios + estrellas) + # Tronco del árbol + tree.append(' ' * (self.altura - 1) + '|||') + return tree + + def dibujar_arbol(self): + """ Dibuja el árbol con las interacciones actuales. """ + arbol_con_elementos = self.tree[:] + + # Agregar estrella en la copa + if self.estrella: + arbol_con_elementos[0] = ' ' * (self.altura - 1) + '@' + ' ' * (self.altura - 1) + + # Agregar bolas y luces en las posiciones correspondientes + for i in range(self.altura): + arbol_con_elementos[i] = list(arbol_con_elementos[i]) + for pos in self.bolas: + if pos == i: + arbol_con_elementos[i][self.altura - 1 - (i * 2 + 1) // 2] = 'o' + for pos in self.luces: + if pos == i: + arbol_con_elementos[i][self.altura - 1 - (i * 2 + 1) // 2] = '+' + arbol_con_elementos[i] = ''.join(arbol_con_elementos[i]) + + # Mostrar árbol + for linea in arbol_con_elementos: + print(linea) + + def añadir_estrella(self): + """ Añade o elimina la estrella en la copa del árbol. """ + if self.estrella: + print("La estrella ya está en la copa del árbol.") + else: + self.estrella = True + print("¡Estrella añadida en la copa del árbol!") + + def eliminar_estrella(self): + """ Elimina la estrella en la copa del árbol. """ + if not self.estrella: + print("La estrella ya está eliminada.") + else: + self.estrella = False + print("¡Estrella eliminada!") + + def añadir_bolas(self): + """ Añade dos bolas aleatoriamente en el árbol. """ + if len(self.bolas) + 2 > self.altura * self.altura - self.altura: + print("No hay suficiente espacio para añadir más bolas.") + else: + while len(self.bolas) < len(self.bolas) + 2: + pos = random.randint(0, self.altura - 1) + if pos not in self.bolas: + self.bolas.add(pos) + print("¡Bolas añadidas aleatoriamente!") + + def eliminar_bolas(self): + """ Elimina dos bolas aleatoriamente. """ + if len(self.bolas) < 2: + print("No hay suficientes bolas para eliminar.") + else: + for _ in range(2): + bola = random.choice(list(self.bolas)) + self.bolas.remove(bola) + print("¡Bolas eliminadas aleatoriamente!") + + def añadir_luces(self): + """ Añade tres luces aleatoriamente en el árbol. """ + if len(self.luces) + 3 > self.altura * self.altura - self.altura: + print("No hay suficiente espacio para añadir más luces.") + else: + while len(self.luces) < len(self.luces) + 3: + pos = random.randint(0, self.altura - 1) + if pos not in self.luces and pos not in self.bolas: + self.luces.add(pos) + print("¡Luces añadidas aleatoriamente!") + + def eliminar_luces(self): + """ Elimina tres luces aleatoriamente. """ + if len(self.luces) < 3: + print("No hay suficientes luces para eliminar.") + else: + for _ in range(3): + luz = random.choice(list(self.luces)) + self.luces.remove(luz) + print("¡Luces eliminadas aleatoriamente!") + + def encender_luces(self): + """ Enciende las luces (cambia su estado). """ + if len(self.luces) == 0: + print("No hay luces para encender.") + else: + print("¡Luces encendidas!") + + def apagar_luces(self): + """ Apaga las luces (cambia su estado). """ + if len(self.luces) == 0: + print("No hay luces para apagar.") + else: + print("¡Luces apagadas!") + + +# Interacción con el programa +def main(): + altura = int(input("Introduce la altura del árbol de Navidad: ")) + arbol = ArbolNavidad(altura) + + while True: + arbol.dibujar_arbol() + + print("\nOpciones:") + print("1. Añadir estrella en la copa") + print("2. Eliminar estrella en la copa") + print("3. Añadir bolas") + print("4. Eliminar bolas") + print("5. Añadir luces") + print("6. Eliminar luces") + print("7. Encender luces") + print("8. Apagar luces") + print("9. Salir") + + opcion = int(input("Selecciona una opción: ")) + + if opcion == 1: + arbol.añadir_estrella() + elif opcion == 2: + arbol.eliminar_estrella() + elif opcion == 3: + arbol.añadir_bolas() + elif opcion == 4: + arbol.eliminar_bolas() + elif opcion == 5: + arbol.añadir_luces() + elif opcion == 6: + arbol.eliminar_luces() + elif opcion == 7: + arbol.encender_luces() + elif opcion == 8: + arbol.apagar_luces() + elif opcion == 9: + print("¡Feliz Navidad!") + break + else: + print("Opción no válida.") + +# Ejecutar el programa +if __name__ == "__main__": + main() diff --git a/Advanced/19.AlmacenPapaNoel.py b/Advanced/19.AlmacenPapaNoel.py new file mode 100644 index 00000000..8c927b24 --- /dev/null +++ b/Advanced/19.AlmacenPapaNoel.py @@ -0,0 +1,63 @@ +import random + +def generar_codigo(): + """Genera un código aleatorio de 4 caracteres con letras (A-C) y números (1-3).""" + letras = ['A', 'B', 'C'] + numeros = ['1', '2', '3'] + elementos = letras + numeros + codigo = random.sample(elementos, 4) + return ''.join(codigo) + +def verificar_codigo(codigo_secreto, intento): + """Compara el código de intento con el código secreto y devuelve las pistas.""" + pistas = [] + + for i in range(4): + if intento[i] == codigo_secreto[i]: + pistas.append('Correcto') + elif intento[i] in codigo_secreto: + pistas.append('Presente') + else: + pistas.append('Incorrecto') + + return pistas + +def juego(): + """Simula el juego de adivinar el código secreto.""" + codigo_secreto = generar_codigo() + intentos = 0 + max_intentos = 10 + + print("Bienvenido a la adivinanza del código secreto de Papá Noel!") + print("El código tiene 4 caracteres y está compuesto por letras (A, B, C) y números (1, 2, 3).") + print("No hay repetidos y puedes realizar hasta 10 intentos.") + + while intentos < max_intentos: + intento = input(f"Intento {intentos + 1}/{max_intentos}: Introduce el código de 4 caracteres: ").upper() + + # Comprobar si el intento tiene una longitud de 4 caracteres y está compuesto por caracteres válidos + if len(intento) != 4: + print("Error: El código debe tener exactamente 4 caracteres.") + continue + + if not all(c in "ABC123" for c in intento): + print("Error: El código solo puede contener letras A, B, C y números 1, 2, 3.") + continue + + # Verificar el código y dar pistas + pistas = verificar_codigo(codigo_secreto, intento) + + print("Pistas: " + " | ".join(pistas)) + + if all(pista == 'Correcto' for pista in pistas): + print(f"¡Felicidades! Has adivinado el código secreto: {codigo_secreto}") + break + + intentos += 1 + + if intentos == max_intentos: + print(f"Lo siento, no has adivinado el código en {max_intentos} intentos. El código secreto era: {codigo_secreto}") + +# Ejecutar el juego +if __name__ == "__main__": + juego() diff --git a/Advanced/20.PlanificadorObjetivos.py b/Advanced/20.PlanificadorObjetivos.py new file mode 100644 index 00000000..51c31203 --- /dev/null +++ b/Advanced/20.PlanificadorObjetivos.py @@ -0,0 +1,140 @@ +""" +/* + * EJERCICIO: + * El nuevo año está a punto de comenzar... + * ¡Voy a ayudarte a planificar tus propósitos de nuevo año! + * + * Programa un gestor de objetivos con las siguientes características: + * - Permite añadir objetivos (máximo 10) + * - Calcular el plan detallado + * - Guardar la planificación + * + * Cada entrada de un objetivo está formado por (con un ejemplo): + * - Meta: Leer libros + * - Cantidad: 12 + * - Unidades: libros + * - Plazo (en meses): 12 (máximo 12) + * + * El cálculo del plan detallado generará la siguiente salida: + * - Un apartado para cada mes + * - Un listado de objetivos calculados a cumplir en cada mes + * (ejemplo: si quiero leer 12 libros, dará como resultado + * uno al mes) + * - Cada objetivo debe poseer su nombre, la cantidad de + * unidades a completar en cada mes y su total. Por ejemplo: + * + * Enero: + * [ ] 1. Leer libros (1 libro/mes). Total: 12. + * [ ] 2. Estudiar Git (1 curso/mes). Total: 1. + * Febrero: + * [ ] 1. Leer libros (1 libro/mes). Total: 12. + * ... + * Diciembre: + * [ ] 1. Leer libros (1 libro/mes). Total: 12. + * + * - Si la duración es menor a un año, finalizará en el mes + * correspondiente. + * + * Por último, el cálculo detallado debe poder exportarse a .txt + * (No subir el fichero) + */ +""" +import os + +class Objetivo: + def __init__(self, meta, cantidad, unidades, plazo): + self.meta = meta + self.cantidad = cantidad + self.unidades = unidades + self.plazo = plazo + + def calcular_plan(self): + plan_mensual = self.cantidad // self.plazo # División entera + if self.cantidad % self.plazo != 0: + plan_mensual += 1 # Si no es divisible, ajusta para el último mes + return plan_mensual + + def mostrar_plan(self): + plan_mensual = self.calcular_plan() + plan_total = self.cantidad + return f"[ ] 1. {self.meta} ({plan_mensual} {self.unidades}/mes). Total: {plan_total}." + + +class GestorObjetivos: + def __init__(self): + self.objetivos = [] + + def añadir_objetivo(self): + if len(self.objetivos) >= 10: + print("¡Ya has alcanzado el número máximo de objetivos (10)! No puedes añadir más.") + return + + meta = input("Meta: ") + cantidad = int(input("Cantidad: ")) + unidades = input("Unidades: ") + plazo = int(input("Plazo (en meses, máximo 12): ")) + + if plazo > 12: + print("El plazo no puede ser superior a 12 meses.") + return + + objetivo = Objetivo(meta, cantidad, unidades, plazo) + self.objetivos.append(objetivo) + print(f"Objetivo '{meta}' añadido correctamente.") + + def calcular_plan_detallado(self): + meses = [ + "Enero", "Febrero", "Marzo", "Abril", "Mayo", "Junio", + "Julio", "Agosto", "Septiembre", "Octubre", "Noviembre", "Diciembre" + ] + plan_detallado = "" + for mes in meses[:min(12, max([obj.plazo for obj in self.objetivos]))]: + plan_detallado += f"\n{mes}:\n" + for objetivo in self.objetivos: + if objetivo.plazo >= meses.index(mes) + 1: # Si el objetivo se cumple en ese mes + plan_detallado += f" {objetivo.mostrar_plan()}\n" + return plan_detallado + + def guardar_plan(self, plan_detallado): + with open("plan_detallado.txt", "w") as file: + file.write(plan_detallado) + print("Plan guardado en 'plan_detallado.txt'.") + + def mostrar_objetivos(self): + if not self.objetivos: + print("No tienes objetivos añadidos.") + return + + for idx, obj in enumerate(self.objetivos, 1): + print(f"{idx}. {obj.meta} - {obj.cantidad} {obj.unidades} en {obj.plazo} meses") + +def ejecutar_programa(): + gestor = GestorObjetivos() + + while True: + print("\nGestor de Objetivos del Nuevo Año") + print("1. Añadir Objetivo") + print("2. Calcular Plan Detallado") + print("3. Guardar Plan Detallado") + print("4. Ver Objetivos") + print("5. Salir") + opcion = input("Elige una opción (1-5): ") + + if opcion == "1": + gestor.añadir_objetivo() + elif opcion == "2": + plan_detallado = gestor.calcular_plan_detallado() + print(plan_detallado) + elif opcion == "3": + plan_detallado = gestor.calcular_plan_detallado() + gestor.guardar_plan(plan_detallado) + elif opcion == "4": + gestor.mostrar_objetivos() + elif opcion == "5": + print("¡Hasta el próximo año! ¡Que cumplas tus objetivos!") + break + else: + print("Opción no válida. Intenta nuevamente.") + +if __name__ == "__main__": + ejecutar_programa() diff --git a/Basic/04_lists.py b/Basic/04_lists.py index d6e6d58b..c34561ae 100644 --- a/Basic/04_lists.py +++ b/Basic/04_lists.py @@ -19,6 +19,11 @@ print(type(my_list)) print(type(my_other_list)) +# Creating a list using list() function +r=range(0, 10) +l=list(r) +print(l) + # Acceso a elementos y búsqueda print(my_other_list[0]) @@ -92,3 +97,18 @@ my_list = "Hola Python" print(my_list) print(type(my_list)) + +names_list = ['John', 'James', 'Lily', 'Emily', 'Nina'] +print(names_list[::2]) + +# List Comprehensions +my_list = [1, 2, 3, 4] +my_list_2 = [ i*2 for i in my_list] +print(my_list) +print(my_list_2) + +s=range(1, 20, 3) +for i in s: #This loop is for knowing what is in s + print(i) +m=[x for x in s if x%2==0] #List comprehension +print(m) diff --git a/Basic/05_tuples.py b/Basic/05_tuples.py index d2cca5b5..dfb8e660 100644 --- a/Basic/05_tuples.py +++ b/Basic/05_tuples.py @@ -10,8 +10,13 @@ my_tuple = (35, 1.77, "Brais", "Moure", "Brais") my_other_tuple = (35, 60, 30) +# Parenthesis is optional for tuple +one_more_tuple = 35, 60, 30 + print(my_tuple) print(type(my_tuple)) +print(my_other_tuple) +print(one_more_tuple) # Acceso a elementos y búsqueda @@ -20,6 +25,7 @@ # print(my_tuple[4]) IndexError # print(my_tuple[-6]) IndexError + print(my_tuple.count("Brais")) print(my_tuple.index("Moure")) print(my_tuple.index("Brais")) @@ -52,3 +58,54 @@ del my_tuple # print(my_tuple) NameError: name 'my_tuple' is not defined + +# Operaciones + +## Multiplication +t1 = (10, 20, 30) +t2 = t1 * 3 +print(t2) + +## Longitud +t = (10, 20, 30, 40) +print(len(t)) + +## Count +t = (10, 20, 10, 10, 20) +print(t.count(10)) + +## Index +t = (10, 20, 10, 10, 20) +print(t.index(10)) +# print(t.index(30))# # ValueError + +## Sort +t = (40, 10, 30, 20) +t1 = sorted(t) +print(t) +print(t1) + +## Min y Max +t = (40, 10, 30, 20) +print(min(t)) # 10 +print(max(t)) # 40 + +# tuple packing +a = 10 +b = 20 +c = 30 +d = 40 +t = a, b, c, d +print(t) + +# tuple unpacking +t = (10, 20, 30, 40) +a, b, c, d = t +print("a=", a, "b=", b, " c=", c, "d=", d) + +# Tuple comprehension +t= ( x**2 for x in range(1,6)) +print(type(t)) +for x in t: + print(x) + \ No newline at end of file diff --git a/Basic/06_sets.py b/Basic/06_sets.py index 4a6d2b19..6c3ec51f 100644 --- a/Basic/06_sets.py +++ b/Basic/06_sets.py @@ -15,6 +15,11 @@ print(len(my_other_set)) +#Creating a set using range function +s=set(range(5)) +print(s) + + # Inserción my_other_set.add("MoureDev") @@ -25,6 +30,13 @@ print(my_other_set) +# Actualización +s = {10,20,30} +l = [40,50,60,10] +s.update(l) +print(s) + + # Búsqueda print("Moure" in my_other_set) @@ -55,3 +67,43 @@ my_new_set = my_set.union(my_other_set) print(my_new_set.union(my_new_set).union(my_set).union({"JavaScript", "C#"})) print(my_new_set.difference(my_set)) + +x={10,20,30,40} +y={30,40,50,60} +print(x.symmetric_difference(y)) +print(x^y) + + +s={10,20,30} +s1=s.copy() +print(s1) + +s = {40,10,30,20} +print(s) +print(s.pop()) +print(s) + + +s={10,20,30} +s.discard(10) +print(s) + +s= {1, 2, 3, "Sharuk"} +print(s) +print(1 in s) +print('S' in s) +print(2 not in s) + +s = {x*x for x in range(5)} +print(s) + +#remove duplicates elements in sets +l=[10,20,30,10,20,40] +s=set(l) +print(s) + +#frozen sets +vowels = ('a', 'e', 'i', 'o', 'u') +fSet = frozenset(vowels) +print(fSet) +print(type(fSet)) \ No newline at end of file diff --git a/Basic/07_dicts.py b/Basic/07_dicts.py index b76aff1f..069c4cc0 100644 --- a/Basic/07_dicts.py +++ b/Basic/07_dicts.py @@ -10,15 +10,14 @@ print(type(my_dict)) print(type(my_other_dict)) -my_other_dict = {"Nombre": "Brais", - "Apellido": "Moure", "Edad": 35, 1: "Python"} +my_other_dict = {"Nombre": "Brais", "Apellido": "Moure", "Edad": 35, 1: "Python"} my_dict = { "Nombre": "Brais", "Apellido": "Moure", "Edad": 35, "Lenguajes": {"Python", "Swift", "Kotlin"}, - 1: 1.77 + 1: 1.77, } print(my_other_dict) @@ -27,6 +26,17 @@ print(len(my_other_dict)) print(len(my_dict)) +d = dict() +print(d) +print(type(d)) + +d = dict({1: "Ramesh", 2: "Suresh", 3: "Mahesh"}) +print(d) + +d = dict([(1, "Ramesh"), (2, "Arjun")]) +print(d) + + # Búsqueda print(my_dict[1]) @@ -74,3 +84,42 @@ print(list(dict.fromkeys(list(my_new_dict.values())).keys())) print(tuple(my_new_dict)) print(set(my_new_dict)) + +d = {1: "Ramesh", 2: "Suresh", 3: "Mahesh"} +print("Before clearing dictionary: ", d) +d.clear() +print("After cleared entries in dictionary: ", d) + +d = {1: "Ramesh", 2: "Suresh", 3: "Mahesh"} +print("Before delete dictionary: ", d) +del d + +d = dict([(1, "Ramesh"), (2, "Arjun")]) +print("length of dictionary is: ", len(d)) + +d = {1: "Ramesh", 2: "Suresh", 3: "Mahesh"} +print(d.get(1)) +print(d.get(100)) + +d = {1: "Ramesh", 2: "Suresh", 3: "Mahesh"} +print(d.get(1)) +print(d.get(100, "No key found")) + +d = {1: "Ramesh", 2: "Suresh", 3: "Mahesh"} +print("Before pop:", d) +d.pop(1) +print("After pop:", d) + +# This method removes an arbitrary item(key-value) from the dictionary and returns it. +d = {1: "Ramesh", 2: "Suresh", 3: "Mahesh"} +print("Before popitem:", d) +d.popitem() +print("After popitem:", d) + +d1 = {1: "Ramesh", 2: "Suresh", 3: "Mahesh"} +d2 = d1.copy() +print(d1) +print(d2) + +squares = {a: a * a for a in range(1, 6)} +print(squares) diff --git a/Basic/10_functions.py b/Basic/10_functions.py index 73604666..0dec0dd4 100644 --- a/Basic/10_functions.py +++ b/Basic/10_functions.py @@ -4,6 +4,7 @@ # Definición + def my_function(): print("Esto es una función") @@ -68,3 +69,174 @@ def print_upper_texts(*texts): print_upper_texts("Hola", "Python", "MoureDev") print_upper_texts("Hola") + +# Assigning a function to a variable in Python: + + +def add(): + print("We assigned function to variable") + + +# Assign function to variable +sum = add +# calling function +sum() + + +# Pass function as a parameter to another function in Python +def display(x): + print("This is display function") + + +def message(): + print("This is message function") + + +# calling function +display(message()) + +# Define one function inside another function in Python: + + +def first(): + print("This is outer function") + + def second(): + print("this is inner function") + + second() + + +# calling outer function +first() + + +# The function can return another function in Python: + + +def first(): + def second(): + print("This function is return type to outer function") + + return second + + +x = first() +x() + + +# Factorial using the recursive function in python (Demo33.py) +def factorial(n): + if n == 0: + result = 1 + else: + result = n * factorial(n - 1) + return result + + +x = factorial(4) +print("Factorial of 4 is: ", x) + +# Lambda Function in Python (Demo35.py) +s = lambda a: a * a +x = s(4) +print(x) + +# Lambda Function in Python (Demo36.py) +add = lambda a, b: a + b +x = add(4, 5) +print(x) + +# Filter Function in python (Demo37.py) +items_cost = [999, 888, 1100, 1200, 1300, 777] +gt_thousand = filter(lambda x: x > 1000, items_cost) +x = list(gt_thousand) +print("Eligible for discount: ", x) + +# Map Function in Python (Demo38.py) +without_gst_cost = [100, 200, 300, 400] +with_gst_cost = map(lambda x: x+10, without_gst_cost) +x=list(with_gst_cost) +print("Without GST items costs: ",without_gst_cost) +print("With GST items costs: ",x) + +# Reduce Function (Demo39.py) +from functools import reduce +each_items_costs = [111, 222, 333, 444] +total_cost = reduce(lambda x, y: x+y, each_items_costs) +print(total_cost) + +#Decorator +def add(a,b): + res = a + b + return res +print(add(20,30)) +print(add(-10,5)) + +def decor(func): #Here ‘func’ is the the argument/parameter which receives the function + def inner_function(x,y): + if x<0: + x = 0 + if y<0: + y = 0 + return func(x,y) + return inner_function #Decor returns the func passed to it. + +add = decor(add) +print(add(20,30)) +print(add(-10,5)) + +# @ symbol in python +def decor(func): + def inner_function(x,y): + if x<0: + x = 0 + if y<0: + y = 0 + return func(x,y) + return inner_function + +@decor +def sub(a,b): + res = a - b + return res + +print(sub(30,20)) +print(sub(10,-5)) + +#Generators in Python +def m(): + yield 'Mahesh' + yield 'Suresh' + +g = m() +print(g) +print(type(g)) +for y in g: + print(y) + +def m(x, y): + while x<=y: + yield x + x+=1 + +g = m(5, 10) +for y in g: + print(y) + +#next function in Python +def m(): + yield 'Mahesh' + yield 'Suresh' +g = m() + +print(type(g)) +print(next(g)) +print(next(g)) + +#dir() function in Python +x=10 +y=20 +def f1(): + print("Hello") +print(dir()) \ No newline at end of file diff --git a/Basic/11_classes.py b/Basic/11_classes.py index 28e84692..3005fc1d 100644 --- a/Basic/11_classes.py +++ b/Basic/11_classes.py @@ -4,6 +4,7 @@ # Definición + class MyEmptyPerson: pass # Para poder dejar la clase vacía @@ -39,3 +40,1586 @@ def walk(self): my_other_person.full_name = 666 print(my_other_person.full_name) + + +# DotNetTutorials Examples +class Employee: + def display( + self, + ): # self is a default variable that refers to a current class object or the current instance(object) of a class. Como this en .Net + print("Hello my name is Shiksha") + + +emp_obj = Employee() +emp_obj.display() + + +class Employee: + def __init__( + self, + ): # constructor is a method with the name ‘__init__’. The methods first parameter should be ‘self’ (referring to the current object). Optional + print("constructor") + + +emp = Employee() +emp.__init__() +print(dir(Employee)) + + +# constructor con parametros +class Employee: + def __init__(self, id, name): + self.id = id + self.name = name + + def display(self): + print("Hello my id is :", self.id) + print("My name is :", self.name) + + +e1 = Employee(1, "Nithin") +e1.display() +e2 = Employee(2, "Arjun") +e2.display() + + +# Instance Variables +class Student: + def __init__(self, name, id): + self.name = name + self.id = id + + +s1 = Student("Nitya", 1) +s2 = Student("Anushka", 2) +print("Studen1 info:") +print("Name: ", s1.name) +print("Id : ", s1.id) +print("Studen2 info:") +print("Name: ", s2.name) +print("Id : ", s2.id) + + +class Employee: + def __init__(self): + self.eno = 1 + self.ename = "Nithya" + self.esal = 100 + + +e = Employee() + +print("Employee number: ", e.eno) +print("Employee name: ", e.ename) +print("Employee salary: ", e.esal) +print(e.__dict__) + + +class Student: + def m1(self): + self.a = 11 + self.b = 21 + self.c = 34 + print(self.a) + print(self.b) + print(self.c) + + +s = Student() +s.m1() +print(s.__dict__) + + +class Test: + def __init__(self): + print("This is constructor") + + def m1(self): + print("This is instance method") + + +t = Test() +t.m1() +t.a = 10 +t.b = 20 +t.c = 55 +print(t.a) +print(t.b) +print(t.c) +print(t.__dict__) + + +# Static Variables +class Student: + college_name = "GITAM" # static + + def __init__(self, name, id): + self.name = name + self.id = id + + +s1 = Student("Nithya", 1) +s2 = Student("Anushka", 2) + +print("Studen1 info:") +print("Name: ", s1.name) +print("Id : ", s1.id) +print("College name n : ", Student.college_name) + +print("\n") +print("Studen2 info:") +print("Name: ", s2.name) +print("Id : ", s2.id) +print("College name : ", Student.college_name) + + +class Student: + college_name = "GITAM" + + def __init__(self, name, id): + self.name = name + self.id = id + + +s1 = Student("Nithya", 1) +s2 = Student("Anushka", 2) + +print("Studen1 info:") +print("Name: ", s1.name) +print("Id : ", s1.id) +print("College name n : ", s1.college_name) + +print("\n") +print("Studen2 info:") +print("Name: ", s2.name) +print("Id : ", s2.id) +print("College name : ", s1.college_name) + +# Declaring static variables + + +class Demo: + a = 20 + + def m(self): + print("this is method") + + +print(Demo.__dict__) + + +class Demo: + def __init__(self): + Demo.b = 20 + + +d = Demo() +print(Demo.__dict__) + + +class Demo: + def m1(self): + Demo.b = 20 + + +obj = Demo() +obj.m1() +print(Demo.__dict__) + + +# class method + + +class Demo: + @classmethod + def m2(cls): + Demo.b = 30 + + +obj = Demo() +obj.m2() +print(Demo.__dict__) + + +class Demo: + @classmethod + def m2(cls): + cls.b = 30 + + +obj = Demo() +obj.m2() +print(Demo.__dict__) + + +class Demo: + @staticmethod + def m3(): + Demo.z = 10 + + +Demo.m3() +print(Demo.__dict__) + + +class Demo: + a = 10 + + def __init__(self): + print(self.a) + print(Demo.a) + + +d = Demo() + + +class Demo: + a = 10 + + def m1(self): + print(self.a) + print(Demo.a) + + +obj = Demo() +obj.m1() + + +class Demo: + a = 10 + + @classmethod + def m1(cls): + print(cls.a) + print(Demo.a) + + +obj = Demo() +obj.m1() + + +class Demo: + a = 10 + + @staticmethod + def m1(): + print(Demo.a) + + +obj = Demo() +obj.m1() + +# Local Variables + + +class Demo: + def m(self): + a = 10 # Local Variable + print(a) + + +d = Demo() +d.m() + + +class Demo: + def m(self): + a = 10 # Local Variable + print(a) + + def n(self): + print(a) #'a' is local variable of m() + + +d = Demo() + +# Types of Class Methods in Python + + +##Instance Methods +class Demo: + def __init__(self, a): + self.a = a + + def m(self): + print(self.a) + + +d = Demo(10) +d.m() + + +# Setter and Getter methods +class Customer: + def set_name(self, name): + self.name = name + + def set_id(self, id): + self.id = id + + +c = Customer() +c.set_name("Balayya") +c.set_id(1) + +print(c.name) + + +class Customer: + def set_name(self, name): + self.name = name + + def set_id(self, id): + self.id = id + + def get_name(self): + return self.name + + def get_id(self): + return self.id + + +c = Customer() +c.set_name("Balayya") +c.set_id(1) + +print("My name is: ", c.get_name()) +print("My id is: ", c.get_id()) + + +##Class Methods in Python +class Pizza: + radius = 200 + + @classmethod + def get_radius(cls): + return cls.radius + + +print(Pizza.get_radius()) + + +##Static Methods +class Demo: + @staticmethod + def sum(x, y): + print(x + y) + + @staticmethod + def multiply(x, y): + print(x * y) + + +Demo.sum(2, 3) +Demo.multiply(2, 4) + + +# Nested Classes +class A: + def __init__(self): + print("outer class object creation") + + class B: + def __init__(self): + print("inner class object creation") + + def m1(self): + print("inner class method") + + +a = A() +b = a.B() +b.m1() + +# Garbage Collection +import gc + +print(gc.isenabled()) +gc.disable() +print(gc.isenabled()) +gc.enable() +print(gc.isenabled()) + + +# Herencia +class One: + def m1(self): + print("Parent class m1 method") + + +class Two(One): + def m2(self): + print("Child class m2 method") + + +c = Two() +c.m1() +c.m2() + + +##Single Inheritance +class A: + def m1(self): + print("A class m1 Method") + + +class B(A): + def m2(self): + print("Child B is derived from A class: m2 Method") + + +obj = B() +obj.m1() +obj.m2() + + +##Multilevel inheritance +class A: + def m1(self): + print("Parent class A: m1 Method") + + +class B(A): + def m2(self): + print("Child class B derived from A: m2 Method") + + +class C(B): + def m3(self): + print("Child class C derived from B: m3 Method") + + +obj = C() +obj.m1() +obj.m2() +obj.m3() + + +class P1: + def m1(self): + print("Parent1 Method") + + +class P2: + def m2(self): + print("Parent2 Method") + + +class C(P1, P2): + def m3(self): + print("Child Method") + + +c = C() +c.m1() +c.m2() +c.m3() + + +class P1: + def m1(self): + print("Parent1 Method") + + +class P2: + def m1(self): + print("Parent2 Method") + + +class C(P1, P2): + def m2(self): + print("Child Method") + + +c = C() +c.m2() + + +class P1: + def m1(self): + print("Parent1 Method") + + +class P2: + def m1(self): + print("Parent2 Method") + + +class C(P1, P2): + def m2(self): + print("Child Method") + + +c = C() +c.m2() +c.m1() + + +class P1: + def m1(self): + print("Parent1 Method") + + +class P2: + def m1(self): + print("Parent2 Method") + + +class C(P2, P1): + def m2(self): + print("Child Method") + + +c = C() +c.m2() +c.m1() + +# CONSTRUCTORS in INHERITANCE + + +class A: + def __init__(self): + print("super class A constructor") + + +class B(A): + def m1(): + print("Child Class B: m1 method from B") + + +b = B() + + +class A: + def __init__(self): + print("super class A constructor") + + +class B(A): + def __init__(self): + print("Child class B constructor") + + +b = B() + + +class A: + def __init__(self): + print("super class A constructor") + + +class B(A): + def __init__(self): + print("Child class B constructor") + super().__init__() + + +b = B() + + +# Method Resolution Order (MRO) + + +class A: + def m1(self): + print("m1 from A") + + +class B(A): + def m1(self): + print("m1 from B") + + +class C(A): + def m1(self): + print("m1 from C") + + +class D(B, C): + def m1(self): + print("m1 from D") + + +print(A.mro()) +print(B.mro()) +print(C.mro()) +print(D.mro()) + + +class A: + def m1(self): + print("m1 from A") + + +class B(A): + def m1(self): + print("m1 from B") + + +class C(A): + def m1(self): + print("m1 from C") + + +class D(B, C): + def m1(self): + print("m1 from D") + + +c = C() +c.m1() +print(C.mro()) + + +class A: + def m1(self): + print("m1 from A") + + +class B(A): + def m1(self): + print("m1 from B") + + +class C(A): + def m2(self): + print("m2 from C") + + +class D(B, C): + def m1(self): + print("m1 from D") + + +c = C() +c.m1() +print(C.mro()) + + +class A: + def m1(self): + print("m1 from A") + + +class B(A): + def m1(self): + print("m1 from B") + + +class C(A): + def m1(self): + print("m1 from C") + + +class D(B, C): + def m1(self): + print("m1 from D") + + +d = D() +d.m1() +print(D.mro()) + + +class A: + def m1(self): + print("m1 from A") + + +class B(A): + def m2(self): + print("m1 from B") + + +class C(A): + def m1(self): + print("m1 from C") + + +class D(B, C): + def m3(self): + print("m3 from D") + + +d = D() +d.m1() +print(D.mro()) + + +class A: + def m1(self): + print("m1 from A") + + +class B: + def m1(self): + print("m1 from B") + + +class C: + def m1(self): + print("m1 from C") + + +class X(A, B): + def m1(self): + print("m1 from C") + + +class Y(B, C): + def m1(self): + print("m1 from A") + + +class P(X, Y, C): + def m1(self): + print("m1 from P") + + +print(A.mro()) # AO +print(X.mro()) # XABO +print(Y.mro()) # YBCO +print(P.mro()) # PXAYBCO + + +# Super Function in Python +class A: + def __init__(self): + print("super class A constructor") + + +class B(A): + def __init__(self): + print("Child class B constructor") + super().__init__() + + +b = B() + + +class A: + def m1(self): + print("Super class A: m1 method") + + +class B(A): + def m1(self): + print("Child class B: m1 method") + super().m1() + + +b = B() +b.m1() + + +class A: + x = 10 + + def m1(self): + print("Super class A: m1 method") + + +class B(A): + x = 20 + + def m1(self): + print("Child class x variable", self.x) + print("Super class x variable", super().x) + + +b = B() +b.m1() + + +class Person: + def __init__(self, name, age): + self.name = name + self.age = age + + def display(self): + print("Name:", self.name) + print("Age:", self.age) + + +class Employee(Person): + def __init__(self, name, age, empno, address): + super().__init__(name, age) + self.empno = empno + self.address = address + + def display(self): + super().display() + print("Emp No:", self.empno) + print("Address:", self.address) + + +e1 = Employee("Neethu", 16, 111, "Delhi") +e1.display() + + +class A: + def m1(self): + print("m1() method from A class") + + +class B(A): + def m1(self): + print("m1() method from B class") + + +class C(B): + def m1(self): + print("m1() method from C class") + + +class D(C): + def m1(self): + print("m1() method from D class") + + +class E(D): + def m1(self): + A.m1(self) + + +e = E() +e.m1() + + +class A: + def m1(self): + print("m1() method from A class") + + +class B(A): + def m1(self): + print("m1() method from B class") + + +class C(B): + def m1(self): + print("m1() method from C class") + + +class D(C): + def m1(self): + print("m1() method from D class") + + +class E(D): + def m1(self): + # A.m1(self) + super(D, self).m1() + + +e = E() +e.m1() + +""" +class P: + def __init__(self): + self.a=20 +class C(P): + def m1(self): + print(super().a) + +c=C() +c.m1() +""" + + +class P: + def __init__(self): + self.a = 20 + + +class C(P): + def m1(self): + print(self.a) + + +c = C() +c.m1() + + +class P: + a = 10 + + def m1(self): + print("m1 from Parent class") + + +class C(P): + def m2(self): + print(super().a) + + +c = C() +c.m2() + + +class P: + def __init__(self): + print("Parent class Constructor") + + def m1(self): + print("m1() instance method from Parent class") + + @classmethod + def m2(cls): + print("m2() class method from Parent class") + + @staticmethod + def m3(): + print("m3() static method from Parent class") + + +class C(P): + def __init__(self): + super().__init__() + super().m1() + super().m2() + super().m3() + + +c = C() + + +class P: + def __init__(self): + print("Parent class Constructor") + + def m1(self): + print("m1() instance method from Parent class") + + @classmethod + def m2(cls): + print("m2() class method from Parent class") + + @staticmethod + def m3(): + print("m3() static method from Parent class") + + +class C(P): + def __init__(self): + print("Child class constructor") + + def m1(self): + super().__init__() + super().m1() + super().m2() + super().m3() + + +c = C() +c.m1() + +""" +class P: + def __init__(self): + print('Parent Constructor') + def m1(self): + print('Parent instance method') + @classmethod + def m2(cls): + print('Parent class method') + @staticmethod + def m3(): + print('Parent static method') +class C(P): + @classmethod + def m1(cls): + super().__init__() + super().m1() + +C.m1() +""" + + +class P: + def __init__(self): + print("Parent Constructor") + + def m1(self): + print("Parent instance method") + + @classmethod + def m2(cls): + print("Parent class method") + + @staticmethod + def m3(): + print("Parent static method") + + +class C(P): + @classmethod + def m1(cls): + super().m2() + super().m3() + + +C.m1() + + +class P: + def __init__(self): + print("Parent Constructor") + + def m1(self): + print("Parent instance method") + + @classmethod + def m2(cls): + print("Parent class method") + + @staticmethod + def m3(): + print("Parent static method") + + +class C(P): + @classmethod + def m1(cls): + super(C, cls).__init__(cls) + super(C, cls).m1(cls) + + +C.m1() + +# Polymorphism in Python + + +## Duck typing philosophy +class Duck: + def talk(self): + print("Quack.. Quack") + + +class Dog: + def talk(self): + print("Bow...Bow") + + +class Cat: + def talk(self): + print("Moew...Moew ") + + +def m(obj): + obj.talk() + + +duck = Duck() +m(duck) + +cat = Cat() +m(cat) + +dog = Dog() +m(dog) + +# Operator overloading +print(10 + 20) +print("Python" + "Programming") +print([1, 2, 3] + [4, 5, 6]) + +print(10 * 20) +print("Python" * 3) +print([1, 2, 3] * 3) + + +# Addition Operator (+) +class Book: + def __init__(self, pages): + self.pages = pages + + +b1 = Book(100) +b2 = Book(200) +print(type(b1)) +print(type(b2)) + +print(type(b1.pages)) +print(type(b2.pages)) + +print(b1.pages + b2.pages) +print((b1.pages).__add__(b2.pages)) + +""" +class Book: + def __init__(self, pages): + self.pages=pages + +b1=Book(100) +b2=Book(200) + +print(b1 + b2) +""" + + +# Magic Methods +class Book: + def __init__(self, pages): + self.pages = pages + + def __add__(self, others): + return self.pages + others.pages + + +b1 = Book(100) +b2 = Book(200) + +print(b1 + b2) + +""" +class Student: + def __init__(self, name, marks): + self.name=name + self.marks=marks + + +s1=Student("Samvida", 100) +s2=Student("Surya", 200) +print("s1>s2 =", s1>s2) +print("s1=s2 =", s1>=s2) +""" + + +class Student: + def __init__(self, name, marks): + self.name = name + self.marks = marks + + def __gt__(self, other): + return self.marks > other.marks + + def __lt__(self, other): + return self.marks <= other.marks + + +s1 = Student("Samvida", 100) +s2 = Student("Surya", 200) +print("s1>s2 =", s1 > s2) +print("s160: + raise TooOldException("Your age already crossed marriage age...no chance of getting marriage") +elif age<18: + raise TooYoungException("Plz wait some more time you will get best match soon!!!") +else: + print("You will get match details soon by email!!!") + diff --git a/Basic/13_modules.py b/Basic/13_modules.py index c6c2657f..5910039b 100644 --- a/Basic/13_modules.py +++ b/Basic/13_modules.py @@ -2,7 +2,7 @@ ### Modules ### -from math import pi as PI_VALUE +from math import pi as PI_VALUE #Crea un alias import math from my_module import sumValue, printValue import my_module diff --git a/Ejercicios/00_helloworld_exercises.py b/Ejercicios/00_helloworld_exercises.py new file mode 100644 index 00000000..926d6e07 --- /dev/null +++ b/Ejercicios/00_helloworld_exercises.py @@ -0,0 +1,59 @@ +# 1. Imprime "¡Hola Mundo!" por consola. + +print("¡Hola Mundo!") + +# 2. Escribe un comentario de una sola línea explicando qué hace el código del Ejercicio 1. + +# Este código imprime "¡Hola Mundo!" por consola. + +# 3. Imprime tu nombre y edad en la misma línea utilizando la función print. + +print("Mi nombre es Brais y tengo", 37, "años.") + +# 4. Usa la función type() para imprimir el tipo de dato de una cadena de texto, un número entero y un número decimal. + +print(type("Brais")) # str +print(type(37)) # int +print(type(3.14)) # float + +# 5. Escribe un comentario en varias líneas explicando qué son los tipos de datos en Python. + +""" +En Python, los tipos de datos más comunes son: +- str: para cadenas de texto +- int: para números enteros +- float: para números con decimales +- bool: para valores booleanos (True/False) +""" + +# 6. Imprime el resultado de concatenar dos cadenas de texto, por ejemplo: "Hola" y "Mundo". + +print("Hola" + " " + "Mundo") + +# 7. Crea una variable para almacenar tu nombre, otra para tu edad, e imprime ambas en la misma línea. + +my_name = "Brais" +my_age = 37 +print("Mi nombre es", my_name, "y tengo", my_age, "años.") + +# 8. Escribe un programa que solicite al usuario su nombre y lo imprima junto con un saludo. + +user_name = input("¿Cuál es tu nombre? ") +print("¡Hola", user_name + "!") + +# 9. Usa print() para mostrar el resultado de la suma de dos números enteros y el tipo de dato resultante. + +result = 5 + 10 +print("El resultado es:", result) +print("El tipo de dato del resultado es:", type(result)) + +# 10. Comenta el código del Ejercicio 9, y explica qué hace cada línea usando comentarios de una sola línea. + +# Suma dos números enteros. +result = 5 + 10 + +# Imprime el resultado de la suma. +print("El resultado es:", result) + +# Imprime el tipo de dato del resultado, que es 'int'. +print("El tipo de dato del resultado es:", type(result)) \ No newline at end of file diff --git a/Ejercicios/01_variables_exercises.py b/Ejercicios/01_variables_exercises.py new file mode 100644 index 00000000..d1df4a93 --- /dev/null +++ b/Ejercicios/01_variables_exercises.py @@ -0,0 +1,62 @@ +# 1. Declara y asigna valores a las siguientes variables: +# • name: una cadena que contenga tu nombre. +# • age: un número entero que represente tu edad. +# • height: un número flotante que represente tu altura. +# • Imprime cada variable en una línea separada. + +name = "Brais" +age = 37 +height = 1.77 + +print(name) +print(age) +print(height) + +# 2. Convierte la variable edad de entero a cadena y concatenala con un texto que diga cuántos años tienes. + +print("Tengo " + str(age) + " años") + +# 3. Declara una variable booleana is_student que indique si eres estudiante o no. Usa True o False según corresponda e imprímela. + +is_student = True +print(is_student) + +# 4. Usa la función len() para calcular cuántos caracteres tiene tu nombre completo, almacenado en una variable. + +full_name = "Brais Moure" +print(len(full_name)) + +# 5. Declara tres variables en una sola línea que representen tu nombre, apellido y ciudad de origen. Luego, imprime estos valores. + +name, surname, city = "Brais", "Moure", "Galicia" +print(name, surname, city) + +# 6. Usa la función input() para solicitar al usuario su color favorito y almacénalo en una variable color. Luego, imprime el valor ingresado. + +color = input("¿Cuál es tu color favorito? ") +print(color) + +# 7. Declara una variable fruit e inicialízala con un valor. Luego, cambia el valor de la fruta a otro diferente y vuelve a imprimirla. + +fruit = "Manzana" +print(fruit) +fruit = "Naranja" +print(fruit) + +# 8. Convierte un número decimal, almacenado en la variable price, a un número entero y luego imprímelo. + +price = 9.99 +print(int(price)) + +# 9. Declara una variable llamada address_len y almacena en ella la cantidad de caracteres de una dirección usando la función len(). Imprime el resultado. + +address = "Calle 123, Ciudad" +address_len = len(address) +print(address_len) + +# 10. Usa un tipo de dato forzado para declarar una variable phone, asegurándote de que siempre será un número. Luego, cambia su valor a un número diferente y verifica el tipo de la variable con type(). + +phone: int = 123456789 +print(type(phone)) +phone = 987654321 +print(type(phone)) diff --git a/Ejercicios/02_operators_exercises.py b/Ejercicios/02_operators_exercises.py new file mode 100644 index 00000000..fc87be4e --- /dev/null +++ b/Ejercicios/02_operators_exercises.py @@ -0,0 +1,53 @@ +# 1. Realiza las siguientes operaciones aritméticas: +# • Suma: 15 + 25 +# • Resta: 50 - 22 +# • Multiplicación: 8 * 7 +# • División: 100 / 20 + +print(15 + 25) +print(50 - 22) +print(8 * 7) +print(100 / 20) + +# 2. Calcula el resto de la división de 37 entre 5 y almacénalo en una variable remainder. Luego imprímelo. + +remainder = 37 % 5 +print(remainder) + +# 3. Convierte el número 7 en una cadena de texto y concaténalo con la frase “ es mi número favorito”. Imprime el resultado. + +number = 7 +result = str(number) + " es mi número favorito" +print(result) + +# 4. Repite la palabra “Python” 10 veces usando el operador de multiplicación para cadenas y luego imprímela. + +print("Python" * 10) + +# 5. Crea dos variables: a y b con los valores 12 y 8 respectivamente. Compara si a es mayor que b y almacena el resultado en una variable booleana resultado. Imprime el valor de resultado. + +a = 12 +b = 8 +result = a > b +print(result) + +# 6. Compara dos cadenas de texto (“apple” y “banana”) usando los operadores > y < y explica cuál tiene mayor orden alfabético. + +print("apple" > "banana") +print("apple" < "banana") + +# 7. Realiza una comparación lógica usando and para verificar si el número 10 es mayor que 5 y menor que 20. Imprime el resultado. + +print(10 > 5 and 10 < 20) + +# 8. Usa el operador or para verificar si el número 7 es menor que 3 o mayor que 5. Imprime el resultado. + +print(7 < 3 or 7 > 5) + +# 9. Aplica el operador not para invertir el resultado de la comparación 15 > 20. ¿Cuál es el resultado? + +print(not (15 > 20)) + +# 10. Combina operadores aritméticos y lógicos: Verifica si el número resultante de la expresión (5 * 3) + 2 es mayor que 10 y menor que 20. Imprime el resultado. + +print((5 * 3) + 2 > 10 and (5 * 3) + 2 < 20) diff --git a/Ejercicios/03_strings_exercices.py b/Ejercicios/03_strings_exercices.py new file mode 100644 index 00000000..ef5ce766 --- /dev/null +++ b/Ejercicios/03_strings_exercices.py @@ -0,0 +1,46 @@ +# 1. Declara una variable text con la frase “Aprendiendo Python” y luego imprime la longitud de la cadena usando len(). +text = "Aprendiendo Python" +print(len(text)) + +# 2. Concatena dos cadenas: “Hola” y “Python”, y muestra el resultado en una sola línea. +text2 = "Hola " + "Python" +print(text2) + +# 3. Crea una cadena que incluya un salto de línea, y luego imprímela para ver el resultado. +text_salto = "Hola\nPython" +print(text_salto) + +# 4. Usa el formateo de cadenas con f-strings para imprimir tu nombre, apellido y edad en una cadena de texto. +nombre, apellido, edad = "Brais", "Moure", 37 +print(f"Mi nombre es {nombre} {apellido} y tengo {edad} años") + +# 5. Desempaqueta los caracteres de la palabra “Python” en variables separadas y luego imprímelos uno por uno. +language_slice = "Python" +a, b, c, d, e, f = language_slice +print(a) +print(b) +print(c) +print(d) +print(e) +print(f) + +# 6. Extrae un “slice” de la palabra “Programación” para obtener los caracteres desde la posición 3 hasta la 7. +lenguaje = "Programación" +language_slice = lenguaje[3:7] +print(language_slice) + +# 7. Invierte la cadena “Python” usando slicing y muestra el resultado. +reverse_language = lenguaje[::-1] +print(reverse_language) + +# 8. Convierte la cadena “aprendiendo python” en mayúsculas usando el método adecuado e imprímela. +cadena = "aprendiendo python" +print(cadena.upper()) + +# 9. Cuenta cuántas veces aparece la letra “n” en la cadena “Programación en Python”. +cadena2 = "Programación en Python" +print(cadena2.count("n")) + +# 10. Verifica si la cadena “12345” es numérica usando el método adecuado e imprime el resultado. +cadena3 = "12345" +print(cadena3.isnumeric()) diff --git a/Ejercicios/04_lists_exercises.py b/Ejercicios/04_lists_exercises.py new file mode 100644 index 00000000..6b83f394 --- /dev/null +++ b/Ejercicios/04_lists_exercises.py @@ -0,0 +1,43 @@ +# 1. Crea una lista con los números del 1 al 5 e imprímela. +mi_lista = [1, 2, 3, 4, 5] +print(mi_lista) + +# 2. Accede e imprime el tercer elemento de la lista [10, 20, 30, 40, 50]. +mi_lista2 = [10, 20, 30, 40, 50] +print(mi_lista2[2]) + +# 3. Agrega el número 6 al final de la lista [1, 2, 3, 4, 5] e imprímela. +mi_lista.append(6) +print(mi_lista) + +# 4. Inserta el número 15 en la posición 2 de la lista [10, 20, 30, 40, 50]. +mi_lista2.insert(1, 15) +print(mi_lista2) + +# 5. Elimina el primer valor 30 de la lista [10, 20, 30, 30, 40, 50]. +mi_lista2.remove(30) +print(mi_lista2) + +# 6. Usa la función pop() para eliminar el último elemento de la lista [1, 2, 3, 4, 5] y almacénalo en una variable. Imprime la variable y la lista. +mi_lista.pop() +print(mi_lista) + +# 7. Invierte la lista [100, 200, 300, 400, 500] e imprímela. +mi_lista3 = [100, 200, 300, 400, 500] +mi_lista3.reverse() +print(mi_lista3) + +# 8. Ordena la lista [3, 1, 4, 2, 5] en orden ascendente e imprímela. +mi_lista4 = [3, 1, 4, 2, 5] +mi_lista4.sort() +print(mi_lista4) + +# 9. Concatena las listas [1, 2, 3] y [4, 5, 6] y almacena el resultado en una nueva lista. Imprime la lista resultante. +mi_lista5 = [1, 2, 3] + [4, 5, 6] +print(mi_lista5) + +# 10. Crea una sublista con los elementos de la lista [10, 20, 30, 40, 50] que van desde la posición 1 hasta la 3 (sin incluir la posición 3). +mi_lista6 = [10, 20, 30, 40, 50] +mi_lista6 = mi_lista6[1:3] +print(mi_lista6) + diff --git a/Ejercicios/05_tuples_exercises.py b/Ejercicios/05_tuples_exercises.py new file mode 100644 index 00000000..ddac0248 --- /dev/null +++ b/Ejercicios/05_tuples_exercises.py @@ -0,0 +1,51 @@ +# 1. Crea una tupla con los valores (10, 20, 30, 40, 50) e imprímela. +mi_tupla = (10, 20, 30, 40, 50) +print(mi_tupla) +print(type(mi_tupla)) + +# 2. Accede al segundo elemento de la tupla (100, 200, 300, 400, 500) y muéstralo. +mi_tupla = (100, 200, 300, 400, 500) +print(mi_tupla[1]) + +# 3. Intenta modificar el primer elemento de la tupla (1, 2, 3) a 10 y observa el resultado. +mi_tupla = (1, 2, 3) +mi_tupla = list(mi_tupla) +mi_tupla[0] = 10 +mi_tupla = tuple(mi_tupla) +print(mi_tupla) + +# 4. Cuenta cuántas veces aparece el número 3 en la tupla (1, 2, 3, 3, 4, 5, 3). +mi_tupla = (1, 2, 3, 3, 4, 5, 3) +print(mi_tupla.count(3)) + +# 5. Encuentra el índice de la primera aparición de la cadena "Python" en la tupla ("Java", "Python", "JavaScript", "Python"). +mi_tupla = ("Java", "Python", "JavaScript", "Python") +print(mi_tupla.index("Python")) + +# 6. Concatena dos tuplas: (1, 2, 3) y (4, 5, 6) e imprime la tupla resultante. +my_tupla1 = (1, 2, 3) +my_tupla2 = (4, 5, 6) +my_tupla3 = my_tupla1 + my_tupla2 +print(my_tupla3) + +# 7. Crea una subtupla con los elementos desde la posición 2 hasta la 4 (sin incluir la 4) de la tupla (10, 20, 30, 40, 50). +my_tupla1 = (10, 20, 30, 40, 50) +my_tupla2 = my_tupla1[1:4] +print(my_tupla2) + +# 8. Convierte la tupla ("rojo", "verde", "azul") en una lista, cambia el segundo elemento a "amarillo" y vuelve a convertirla en una tupla. Imprime la tupla resultante. +my_tupla1 = ("rojo", "verde", "azul") +my_tupla1 = list(my_tupla1) +my_tupla1[1] = "amarillo" +my_tupla1 = tuple(my_tupla1) +print(my_tupla1) + +# 9. Elimina una tupla llamada my_tuple usando del y luego intenta imprimirla para ver el resultado. +my_tupla1 = (1, 2, 3) +del my_tupla1 +# print(my_tupla1) # NameError: name 'my_tupla1' is not defined + +# 10. Crea una tupla con un solo elemento (el número 100) e imprímela. Asegúrate de usar la sintaxis correcta para crear una tupla con un solo elemento. +my_tupla1 = (100,) +print(my_tupla1) +print(type(my_tupla1)) diff --git a/Ejercicios/06_sets_exercises.py b/Ejercicios/06_sets_exercises.py new file mode 100644 index 00000000..9f808d81 --- /dev/null +++ b/Ejercicios/06_sets_exercises.py @@ -0,0 +1,47 @@ +# 1. Crea un set con los números del 1 al 5 e imprímelo. +my_set = {1, 2, 3, 4, 5} +print(my_set) +print(type(my_set)) + +# 2. Añade el número 6 al set {1, 2, 3, 4, 5} e imprímelo. +my_set.add(6) +print(my_set) + +# 3. Intenta añadir el número 5 al set {1, 2, 3, 4, 5} nuevamente. ¿Qué sucede? +my_set.add(5) +print(my_set) + +# 4. Verifica si el número 3 está en el set {1, 2, 3, 4, 5} e imprime el resultado. +my_set = {1, 2, 3, 4, 5} +print(3 in my_set) + +# 5. Elimina el número 4 del set {1, 2, 3, 4, 5} e imprime el set resultante. +my_set.remove(4) +print(my_set) + +# 6. Usa el método clear() para vaciar un set y luego imprime su longitud. +my_set.clear() +print(len(my_set)) + +# 7. Convierte el set {"manzana", "naranja", "plátano"} en una lista e imprime el primer elemento de la lista. +my_set = {"manzana", "naranja", "plátano"} +my_list = list(my_set) +print(my_list[0]) +print(type(my_list)) + +# 8. Realiza la unión de dos sets: {1, 2, 3} y {4, 5, 6}, e imprime el set resultante. +my_set1 = {1, 2, 3} +my_set2 = {4, 5, 6} +my_set3 = my_set1.union(my_set2) +print(my_set3) + +# 9. Calcula la diferencia entre los sets {1, 2, 3, 4} y {3, 4, 5, 6} e imprime el resultado. +my_set1 = {1, 2, 3, 4} +my_set2 = {3, 4, 5, 6} +my_set3 = my_set1.difference(my_set2) +print(my_set3) + +# 10. Elimina un set llamado my_set usando del y luego intenta imprimirlo para ver el resultado. +my_set = {1, 2, 3} +del my_set +# print(my_set) # NameError: name 'my_set' is not defined diff --git a/Ejercicios/07_dicts_exercises.py b/Ejercicios/07_dicts_exercises.py new file mode 100644 index 00000000..1918cb85 --- /dev/null +++ b/Ejercicios/07_dicts_exercises.py @@ -0,0 +1,50 @@ +# 1. Crea un diccionario con las claves name, age, y country, asignando valores a cada una. Imprime el diccionario. +my_dict = {"name": "Brais", "age": 37, "country": "Galicia"} +print(my_dict) + +# 2. Accede al valor de la clave name en el diccionario. +my_dict = {"name": "Brais", "age": 37, "country": "Galicia"} +print(my_dict["name"]) + +# 3. Añade una nueva clave job con el valor "Programador" al diccionario del punto anterior. Imprime el diccionario actualizado. +my_dict = {"name": "Brais", "age": 37, "country": "Galicia"} +my_dict["job"] = "Programador" +print(my_dict) + +# 4. Modifica el valor de la clave age en el diccionario para que sea 38. Imprime el diccionario actualizado. +my_dict = {"name": "Brais", "age": 37, "country": "Galicia"} +my_dict["age"] = 38 +print(my_dict) + +# 5. Elimina la clave country del diccionario e imprime el diccionario resultante. +my_dict = {"name": "Brais", "age": 37, "country": "Galicia"} +my_dict.pop("country") +print(my_dict) +my_dict = {"name": "Brais", "age": 37, "country": "Galicia"} +del my_dict["country"] +print(my_dict) + + +# 6. Crea un diccionario donde las claves sean números del 1 al 5 y los valores sean sus cuadrados (ejemplo: 1: 1, 2: 4, ...). +my_dict = {1: 1, 2: 4, 3: 9, 4: 16, 5: 25} +print(my_dict) + +# 7. Verifica si la clave age está presente en el diccionario {"name": "Brais", "age": 37, "country": "Galicia"}. +my_dict = {"name": "Brais", "age": 37, "country": "Galicia"} +print("age" in my_dict) + +# 8. Imprime solo las claves del diccionario. +my_dict = {"name": "Brais", "age": 37, "country": "Galicia"} +print(my_dict.keys()) + +# 9. Convierte las claves del diccionario en una lista e imprime la lista resultante. +my_dict = {"name": "Brais", "age": 37, "country": "Galicia"} +my_list = list(my_dict.keys()) +print(my_list) + +# 10. Crea un nuevo diccionario a partir de una lista de claves ["name", "age", "job"] usando fromkeys(), asignando a todas las claves el valor "Desconocido". +my_dict = dict.fromkeys(["name", "age", "job"], "Desconocido") +print(my_dict) +print(type(my_dict)) + +print(my_dict["Nokey"]) diff --git a/Ejercicios/08_conditionals_exercises.py b/Ejercicios/08_conditionals_exercises.py new file mode 100644 index 00000000..e096b10c --- /dev/null +++ b/Ejercicios/08_conditionals_exercises.py @@ -0,0 +1,83 @@ +# 1. Escribe un programa que verifique si un número es positivo, negativo o cero. +my_number = int(input("Introduce un número: ")) +if my_number > 0: + print("El número es positivo.") +elif my_number < 0: + print("El número es negativo.") +else: + print("El número es cero.") + +# 2. Solicita al usuario que ingrese su edad y muestra un mensaje indicando si es mayor de edad(18 años o más) o menor de edad. +my_edad = int(input("Introduce tu edad: ")) +if my_edad >= 18: + print("Eres mayor de edad.") +else: + print("Eres menor de edad.") + +# 3. Escribe un programa que verifique si una cadena de texto está vacía y muestre un mensaje en consecuencia. +my_cadena = input("Introduce una cadena de texto: ") +if len(my_cadena) == 0: + print("La cadena de texto está vacía.") +else: + print("La cadena de texto no está vacía.") + +# 4. Crea un programa que solicite dos números al usuario y compare cuál es mayor. Si son iguales, muestra un mensaje indicando la igualdad. +my_number1 = int(input("Introduce un número: ")) +my_number2 = int(input("Introduce otro número: ")) +if my_number1 > my_number2: + print("El primer número es mayor que el segundo.") +elif my_number1 < my_number2: + print("El segundo número es mayor que el primero.") +else: + print("Los números son iguales.") + +# 5. Escribe un programa que verifique si un número es divisible por 3 y por 5 al mismo tiempo. +my_number = int(input("Introduce un número: ")) +if my_number % 3 == 0 and my_number % 5 == 0: + print("El número es divisible por 3 y por 5.") +else: + print("El número no es divisible por 3 y por 5.") + +# 6. Solicita al usuario que ingrese un número y verifica si es par o impar. +my_number = int(input("Introduce un número: ")) +if my_number % 2 == 0: + print("El número es par.") +else: + print("El número es impar.") + +# 7. Escribe un programa que determine si una persona puede votar en función de su edad(mayor o igual a 18). Si tiene 16 o 17 años, indica que puede votar con permiso especial. +my_edad = int(input("Introduce tu edad: ")) +if my_edad >= 18: + print("Puedes votar.") +elif my_edad == 16 or my_edad == 17: + print("Puedes votar con permiso especial.") +else: + print("No puedes votar.") + +# 8. Crea un programa que solicite una contraseña al usuario y verifique si coincide con una contraseña predefinida. Si no coincide, muestra un mensaje de error. +my_user = input("Introduce un usuario: ") +my_password = input("Introduce una contraseña: ") +if my_user == "admin" and my_password == "1234": + print("Acceso concedido.") +else: + print("Acceso denegado.") + + +# 9. Escribe un programa que determine si un número está entre 10 y 20 (ambos incluidos). +my_number = int(input("Introduce un número: ")) +if my_number >= 10 and my_number <= 20: + print("El número está entre 10 y 20.") +else: + print("El número no está entre 10 y 20.") + + +# 10. Escribe un programa que simule un semáforo: solicita al usuario que ingrese un color(rojo, amarillo, verde) y muestra un mensaje indicando si debe detenerse, estar alerta o avanzar. +my_color = input("Introduce un color (rojo, amarillo, verde): ") +if my_color == "rojo": + print("Detente.") +elif my_color == "amarillo": + print("Estate alerta.") +elif my_color == "verde": + print("Avanza.") +else: + print("Color no válido.") diff --git a/Ejercicios/09_loops_exercises.py b/Ejercicios/09_loops_exercises.py new file mode 100644 index 00000000..c45114d2 --- /dev/null +++ b/Ejercicios/09_loops_exercises.py @@ -0,0 +1,60 @@ +# 1. Usa un bucle while para imprimir los números del 1 al 10. +i = 1 +while i <= 10: + print(i) + i += 1 + +# 2. Usa un bucle for para recorrer la lista[10, 20, 30, 40, 50] e imprime cada número. +my_lista = [10, 20, 30, 40, 50] +for number in my_lista: + print(number) + +# 3. Escribe un programa que use un bucle while para sumar los números del 1 al 100 e imprime el resultado. +i_number = 1 +sum_number = 0 +while i_number <= 100: + sum_number += i_number + i_number += 1 +print(sum_number) + +# 4. Escribe un bucle for que imprima cada carácter de la cadena "Python". +for letter in "Python": + print(letter) + +# 5. Usa un bucle while para encontrar el primer número divisible por 7 entre 1 y 50. +i_number = 1 +while i_number <= 50: + if i_number % 7 == 0: + print(i_number) + break + i_number += 1 + +# 6. Usa un bucle for para recorrer el diccionario {"name": "Brais", "age": 37, "country": "Galicia"} e imprime las claves. +for key in {"name": "Brais", "age": 37, "country": "Galicia"}: + print(key) + +# 7. Escribe un programa que use un bucle while para imprimir los números pares entre 1 y 20. +i_number = 1 +while i_number <= 20: + if i_number % 2 == 0: + print(i_number) + i_number += 1 + +# 8. Usa un bucle for con la función range() para imprimir los números del 1 al 10 en orden inverso. +for i in range(10, 0, -1): + print(i) + +# 9. Escribe un programa que use un bucle for para contar cuántas veces aparece el número 30 en la lista[30, 10, 30, 20, 30, 40]. +count_number = 0 +for number in [30, 10, 30, 20, 30, 40]: + if number == 30: + count_number += 1 +print(count_number) + +# 10. Usa un bucle for para recorrer una lista de nombres y detener el bucle cuando se encuentre el nombre "Brais". +my_lista = ["Ana", "Carlos", "Brais", "David", "Elena"] +for name in my_lista: + print(name) + if name == "Brais": + break + \ No newline at end of file diff --git a/Ejercicios/10_functions_exercises.py b/Ejercicios/10_functions_exercises.py new file mode 100644 index 00000000..b8e15263 --- /dev/null +++ b/Ejercicios/10_functions_exercises.py @@ -0,0 +1,50 @@ +# 1. Crea una función llamada "personalized_greeting" que reciba un nombre como argumento e imprima "Hola, ". Si no se proporciona ningún nombre, debe saludar diciendo "Hola, desconocido". +def personalized_greeting(name="desconocido"): + print(f"Hola, {name}") +personalized_greeting("Brais") + +# 2. Escribe una función llamada "multiply" que reciba dos números como argumentos y retorne el resultado de multiplicarlos. +def multiply(number1, number2): + return number1 * number2 +print(multiply(2, 3)) + +# 3. Crea una función llamada "is_even" que reciba un número entero como argumento y retorne True si es par y False si es impar. +def is_even(number): + return number % 2 == 0 +print(is_even(4)) + +# 4. Escribe una función llamada "convert_to_uppercase" que reciba una cadena de texto y la retorne en mayúsculas. +def convert_to_uppercase(text): + return text.upper() +print(convert_to_uppercase("Hola")) + +# 5. Crea una función llamada "arbitrary_sum" que reciba un número arbitrario de números como argumentos y retorne la suma de todos ellos. +def arbitrary_sum(*numbers): + return sum(numbers) +print(arbitrary_sum(1, 2, 3, 4, 5)) + +# 6. Escribe una función llamada "generate_full_greeting" que reciba dos argumentos: nombre y apellido, y retorne el saludo completo "Hola, ". Los argumentos deben ser pasados por clave. +def generate_full_greeting(name, surname): + return f"Hola, {name} {surname}" +print(generate_full_greeting(name="Brais", surname="Moure")) + +# 7. Crea una función llamada "power" que reciba dos números: base y exponente, y retorne el resultado de elevar la base al exponente. +def power(base, exponent): + return base ** exponent +print(power(2, 3)) + +# 8. Escribe una función llamada "calculate_average" que reciba tres números y retorne su promedio. +def calculate_average(number1, number2, number3): + return (number1 + number2 + number3) / 3 +print(calculate_average(2, 4, 6)) + +# 9. Crea una función llamada "count_characters" que reciba una cadena de texto y retorne el número de caracteres que contiene. +def count_characters(text): + return len(text) +print(count_characters("Hola")) + +# 10. Escribe una función llamada "display_messages" que reciba un número indefinido de cadenas y las imprima en mayúsculas, una por una, tal como se hizo en el archivo proporcionado. +def display_messages(*messages): + for message in messages: + print(message.upper()) +display_messages("Hola", "Adiós", "Buenos días") diff --git a/Ejercicios/11_classes_exercises.py b/Ejercicios/11_classes_exercises.py new file mode 100644 index 00000000..e7bcc53e --- /dev/null +++ b/Ejercicios/11_classes_exercises.py @@ -0,0 +1,176 @@ +# 1. Crea una clase llamada "Animal" que tenga una propiedad "species" y un método "make_sound" que imprima un sonido genérico. +class Animal: + def __init__(self, species): + self.species = species + + def make_sound(self): + print("Sonido genérico") +print("Ejercicio 1:") +animal = Animal("Perro") +print(animal.species) +animal.make_sound() + +# 2. Modifica la clase "Animal" para que reciba la especie al crear un objeto y almacénala en una propiedad pública. Añade el método "make_sound" que imprima un sonido dependiendo de la especie. +class Animal: + def __init__(self, species): + self.species = species + + def make_sound(self): + if self.species == "Perro": + print("Guau guau") + elif self.species == "Gato": + print("Miau miau") + else: + print("Sonido genérico") +print("Ejercicio 2:") +animal = Animal("Perro") +print(animal.species) +animal.make_sound() +animal = Animal("Gato") +print(animal.species) +animal.make_sound() +animal = Animal("Pájaro") +print(animal.species) +animal.make_sound() + +# 3. Crea una clase llamada "Car" con las propiedades públicas "brand" y "model". Además, debe tener una propiedad privada "_speed" que inicialmente será 0. +class Car: + def __init__(self, brand, model): + self.brand = brand + self.model = model + self._speed = 0 +print("Ejercicio 3:") +car = Car("Ford", "Focus") +print(car.brand) +print(car.model) +print(car._speed) + +# 4. Añade a la clase "Car" un método llamado "accelerate" que aumente la velocidad en 10 unidades. Añade también un método "brake" que reduzca la velocidad en 10 unidades. Asegúrate de que la velocidad no sea negativa. +class Car: + def __init__(self, brand, model): + self.brand = brand + self.model = model + self._speed = 0 + + def accelerate(self): + self._speed += 10 + + def brake(self): + self._speed -= 10 + if self._speed < 0: + self._speed = 0 +print("Ejercicio 4:") +car = Car("Ford", "Focus") +print(car._speed) +car.accelerate() +print(car._speed) +car.brake() +print(car._speed) +car.brake() +print(car._speed) + +# 5. Crea una clase "Book" que tenga propiedades como "title" (público) y "author" (privado). Añade un método para obtener el autor y otro para cambiar el título del libro. +class Book: + def __init__(self, title, author): + self.title = title + self._author = author + + def get_author(self): + return self._author + + def set_title(self, title): + self.title = title +print("Ejercicio 5:") +book = Book("El Quijote", "Miguel de Cervantes") +print(book.title) +print(book.get_author()) +book.set_title("Don Quijote") +print(book.title) + +# 6. Crea una clase "Estudiante" que tenga como propiedades su nombre, apellido y una lista de notas. Añade un método para calcular y devolver la nota media del estudiante. +class Student: + def __init__(self, name, surname, grades): + self.name = name + self.surname = surname + self.grades = grades + + def calculate_average(self): + return sum(self.grades) / len(self.grades) +print("Ejercicio 6:") +student = Student("Brais", "Moure", [7, 8, 9]) +print(student.name) +print(student.surname) +print(student.grades) +print(student.calculate_average()) + +# 7. Crea una clase "BankAccount" con propiedades como "owner" y "balance". Añade métodos para depositar y retirar dinero, asegurándote de que no se pueda retirar más de lo que hay en la cuenta. +class BankAccount: + def __init__(self, owner, balance): + self.owner = owner + self.balance = balance + + def deposit(self, amount): + self.balance += amount + + def withdraw(self, amount): + if amount <= self.balance: + self.balance -= amount + else: + print("No hay suficiente saldo.") +print("Ejercicio 7:") +account = BankAccount("Brais", 1000) +print(account.owner) +print(account.balance) +account.deposit(500) +print(account.balance) +account.withdraw(200) +print(account.balance) +account.withdraw(2000) +print(account.balance) + +# 8. Crea una clase "Point" que represente un punto en el espacio 2D con coordenadas "x" e "y". Añade un método que calcule la distancia entre dos puntos. +class Point: + def __init__(self, x, y): + self.x = x + self.y = y + + def calculate_distance(self, point): + return ((self.x - point.x) ** 2 + (self.y - point.y) ** 2) ** 0.5 +print("Ejercicio 8:") +point1 = Point(0, 0) +point2 = Point(3, 4) +print(point1.calculate_distance(point2)) + +# 9. Crea una clase "Employee" que tenga propiedades como "name", "hourly_wage" (pago por hora) y "hours_worked". Añade un método que calcule el pago total basado en las horas trabajadas y el salario por hora. +class Employee: + def __init__(self, name, hourly_wage, hours_worked): + self.name = name + self.hourly_wage = hourly_wage + self.hours_worked = hours_worked + + def calculate_payment(self): + return self.hourly_wage * self.hours_worked +print("Ejercicio 9:") +employee = Employee("Brais", 10, 40) +print(employee.name) +print(employee.hourly_wage) +print(employee.hours_worked) +print(employee.calculate_payment()) + +# 10. Crea una clase "Store" que tenga una propiedad "inventory" (una lista de productos). Añade un método para agregar un producto al inventario y otro para mostrar todos los productos disponibles. +class Store: + def __init__(self): + self.inventory = [] + + def add_product(self, product): + self.inventory.append(product) + + def show_inventory(self): + for product in self.inventory: + print(product) +print("Ejercicio 10:") +store = Store() +store.add_product("Leche") +store.add_product("Pan") +store.add_product("Huevos") +store.show_inventory() diff --git a/Ejercicios/12_exceptions_exercises.py b/Ejercicios/12_exceptions_exercises.py new file mode 100644 index 00000000..d4cf2d9b --- /dev/null +++ b/Ejercicios/12_exceptions_exercises.py @@ -0,0 +1,108 @@ +# 1. Crea una función que intente dividir dos números proporcionados por el usuario. Usa try-except para capturar cualquier error de división (por ejemplo, división por cero). +def divide_numbers(): + try: + number1 = int(input("Introduce un número: ")) + number2 = int(input("Introduce otro número: ")) + result = number1 / number2 + print(f"El resultado de la división es {result}") + except ZeroDivisionError: + print("No se puede dividir por cero.") +divide_numbers() + +# 2. Crea una función que tome una cadena e intente convertirla en un número entero. Usa try-except para capturar cualquier error en la conversión. +def convert_to_integer(text): + try: + number = int(text) + print(f"El número es {number}") + except ValueError: + print("No se pudo convertir la cadena en un número entero.") +convert_to_integer("Hola") + +# 3. Crea una función que abra un archivo, lea su contenido y maneje posibles errores (por ejemplo, archivo no encontrado). Usa try-except para gestionar las operaciones de archivos de forma segura. +def read_file(file_name): + try: + with open(file_name, "r") as file: + print(file.read()) + except FileNotFoundError: + print("El archivo no se encontró.") +read_file("file.txt") + +# 4. Crea una función que realice múltiples operaciones (suma, resta, división, multiplicación) con dos números. Usa try-except-else-finally para manejar errores y asegurar que se imprima un mensaje final, independientemente de los errores. +def operations(number1, number2): + try: + print(f"Suma: {number1 + number2}") + print(f"Resta: {number1 - number2}") + print(f"División: {number1 / number2}") + print(f"Multiplicación: {number1 * number2}") + except ZeroDivisionError: + print("No se puede dividir por cero.") + else: + print("Operaciones realizadas con éxito.") + finally: + print("Operaciones finalizadas.") +operations(10, 0) + +# 5. Crea una función que le pida al usuario su edad y lance un ValueError si la entrada no es un número entero positivo. Usa el manejo de excepciones para gestionar la entrada y lanzar excepciones personalizadas cuando sea necesario. +def get_age(): + try: + age = int(input("Introduce tu edad: ")) + if age < 0: + raise ValueError("La edad debe ser un número entero positivo.") + print(f"Tu edad es {age}") + except ValueError as e: + print(e) +get_age() + +# 6. Crea una función que intente acceder a un elemento de una lista por índice. Usa try-except para manejar el caso donde el índice esté fuera de rango. +def get_element(my_list, index): + try: + print(my_list[index]) + except IndexError: + print("El índice está fuera de rango.") +get_element([1, 2, 3], 3) + +# 7. Crea una función que use try-except para manejar múltiples excepciones: ZeroDivisionError, ValueError y TypeError. +def multiple_exceptions(): + try: + number = int(input("Introduce un número: ")) + result = 10 / number + print(result) + except ZeroDivisionError: + print("No se puede dividir por cero.") + except ValueError: + print("La entrada no es un número válido.") + except TypeError: + print("Error de tipo.") +multiple_exceptions() + +# 8. Crea una función que simule una transacción. Lanza una excepción personalizada llamada InsufficientFundsError si el saldo es menor que la cantidad a retirar. +def transaction(balance, amount): + class InsufficientFundsError(Exception): + pass + try: + if amount > balance: + raise InsufficientFundsError("Saldo insuficiente.") + balance -= amount + print(f"Transacción exitosa. Saldo restante: {balance}") + except InsufficientFundsError as e: + print(e) +transaction(100, 200) + +# 9. Crea una función que intente convertir una lista de cadenas en enteros. Maneja cualquier error que surja cuando una cadena no pueda convertirse. +def convert_to_integers(my_list): + try: + integers = [int(value) for value in my_list] + print(integers) + except ValueError: + print("Error al convertir las cadenas en enteros.") +convert_to_integers(["1", "2", "3", "a"]) + +# 10. Crea una función que calcule la raíz cuadrada de un número. Lanza un ValueError si el número es negativo. +def calculate_square_root(number): + if number < 0: + raise ValueError("No se puede calcular la raíz cuadrada de un número negativo.") + return number ** 0.5 +try: + print(calculate_square_root(-1)) +except ValueError as e: + print(e) diff --git a/Ejercicios/13_modules_exercises.py b/Ejercicios/13_modules_exercises.py new file mode 100644 index 00000000..2a7bde34 --- /dev/null +++ b/Ejercicios/13_modules_exercises.py @@ -0,0 +1,71 @@ +# 1. Crea un módulo llamado "calculator" que contenga funciones para sumar, restar, multiplicar y dividir dos números. Importa este módulo en otro archivo y usa sus funciones. +import calculator + +print(calculator.sum(2, 3)) +print(calculator.subtract(5, 3)) +print(calculator.multiply(2, 3)) +print(calculator.divide(6, 3)) + + +# 2. Crea un módulo llamado "converter" que tenga funciones para convertir temperaturas entre Celsius y Fahrenheit. Escribe un programa que importe este módulo y realice conversiones. +import converter + +print(converter.celsius_to_fahrenheit(0)) +print(converter.celsius_to_fahrenheit(100)) + + +# 3. Crea un módulo que contenga una lista de nombres de estudiantes y una función que imprima todos los nombres. Importa este módulo en otro archivo y usa la función para mostrar la lista. +import lista_nombres + +lista_nombres.print_students() + +# 4. Crea un módulo llamado "geometry" que tenga una función para calcular el área de un círculo y un cuadrado. Usa este módulo en otro archivo para calcular áreas. + +import geometry + +print(geometry.circle_area(5)) +print(geometry.square_area(5)) + + +# 5. Escribe un módulo que contenga una función que acepte cualquier número de argumentos y devuelva su suma. Importa y usa la función en otro archivo. +import operaciones + +print(operaciones.sum(1, 2, 3, 4, 5)) + + +# 6. Crea un módulo que defina una clase llamada "Car" con propiedades como marca, modelo y año. Importa este módulo en otro archivo y crea una instancia de la clase "Car". + +import cars + +car = cars.Car("Toyota", "Corolla", 2020) +print(car.brand) +print(car.model) +print(car.year) + +# 7. Escribe un módulo que contenga funciones para leer y escribir en archivos de texto. Crea un programa que use estas funciones para escribir y leer datos. + +import archivos as ficheros + +ficheros.write_file("data.txt", "Hello, world!") +print(ficheros.read_file("data.txt")) + + +# 8. Crea un módulo llamado "statistics" que tenga funciones para calcular la media y la mediana de una lista de números. Usa este módulo para calcular estos valores en una lista dada. +import statistics + +numbers = [1, 2, 3, 4, 5] +print(statistics.mean(numbers)) +print(statistics.median(numbers)) + +# 9. Crea un módulo que contenga una función para contar cuántas veces aparece una palabra en un texto. Escribe un programa que importe el módulo y lo use para contar palabras en una cadena. + +import operaciones + +text = "Hello, world! Hello, Python!" +print(operaciones.count_words(text, "Hello")) + +# 10 Crea un módulo llamado "dates" que contenga funciones para obtener la fecha actual y calcular la diferencia entre dos fechas. Usa este módulo en un programa para mostrar la fecha actual y la diferencia entre dos fechas específicas. +import dates + +print(dates.get_current_date()) +print(dates.get_date_diff("2021-01-01", "2021-12-31")) diff --git a/Ejercicios/archivos.py b/Ejercicios/archivos.py new file mode 100644 index 00000000..00f0ae55 --- /dev/null +++ b/Ejercicios/archivos.py @@ -0,0 +1,10 @@ +# 7. Escribe un módulo que contenga funciones para leer y escribir en archivos de texto. Crea un programa que use estas funciones para escribir y leer datos. + +def write_file(file_name, data): + with open(file_name, "w") as file: + file.write(data) + +def read_file(file_name): + with open(file_name, "r") as file: + return file.read() + diff --git a/Ejercicios/calculator.py b/Ejercicios/calculator.py new file mode 100644 index 00000000..56ef731b --- /dev/null +++ b/Ejercicios/calculator.py @@ -0,0 +1,13 @@ +# 1. Crea un módulo llamado "calculator" que contenga funciones para sumar, restar, multiplicar y dividir dos números. + +def sum(number1, number2): + return number1 + number2 + +def subtract(number1, number2): + return number1 - number2 + +def multiply(number1, number2): + return number1 * number2 + +def divide(number1, number2): + return number1 / number2 diff --git a/Ejercicios/cars.py b/Ejercicios/cars.py new file mode 100644 index 00000000..ff2c9f17 --- /dev/null +++ b/Ejercicios/cars.py @@ -0,0 +1,11 @@ +# 6. Crea un módulo que defina una clase llamada "Car" con propiedades como marca, modelo y año. + +class Car: + def __init__(self, brand, model, year): + self.brand = brand + self.model = model + self.year = year + + def __str__(self): + return f"{self.brand} {self.model} ({self.year})" + diff --git a/Ejercicios/converter.py b/Ejercicios/converter.py new file mode 100644 index 00000000..8377bc79 --- /dev/null +++ b/Ejercicios/converter.py @@ -0,0 +1,3 @@ +# Crea un módulo llamado "converter" que tenga funciones para convertir temperaturas entre Celsius y Fahrenheit. +def celsius_to_fahrenheit(celsius): + return celsius * 9/5 + 32 diff --git a/Ejercicios/dates.py b/Ejercicios/dates.py new file mode 100644 index 00000000..c95481ab --- /dev/null +++ b/Ejercicios/dates.py @@ -0,0 +1,10 @@ +# 10 Crea un módulo llamado "dates" que contenga funciones para obtener la fecha actual y calcular la diferencia entre dos fechas. + +import datetime + +def current_date(): + return datetime.date.today() + +def days_between_dates(date1, date2): + return abs((date2 - date1).days) + diff --git a/Ejercicios/geometry.py b/Ejercicios/geometry.py new file mode 100644 index 00000000..90e41880 --- /dev/null +++ b/Ejercicios/geometry.py @@ -0,0 +1,10 @@ +# 4. Crea un módulo llamado "geometry" que tenga una función para calcular el área de un círculo y un cuadrado. + +import math + +def circle_area(radius): + return math.pi * radius ** 2 + +def square_area(side): + return side ** 2 + diff --git a/Ejercicios/lista_nombres.py b/Ejercicios/lista_nombres.py new file mode 100644 index 00000000..fb491e84 --- /dev/null +++ b/Ejercicios/lista_nombres.py @@ -0,0 +1,9 @@ +# 3. Crea un módulo que contenga una lista de nombres de estudiantes y una función que imprima todos los nombres. + +students = ["Alice", "Bob", "Charlie", "David", "Eve"] + +def print_students(): + for student in students: + print(student) + + \ No newline at end of file diff --git a/Ejercicios/operaciones.py b/Ejercicios/operaciones.py new file mode 100644 index 00000000..b85cb75a --- /dev/null +++ b/Ejercicios/operaciones.py @@ -0,0 +1,9 @@ +# 5. Escribe un módulo que contenga una función que acepte cualquier número de argumentos y devuelva su suma. + +def sum(*numbers): + return sum(numbers) + +# 9. Crea un módulo que contenga una función para contar cuántas veces aparece una palabra en un texto. + +def count_words(text, word): + return text.count(word) diff --git a/Ejercicios/statistics.py b/Ejercicios/statistics.py new file mode 100644 index 00000000..6a98c3fd --- /dev/null +++ b/Ejercicios/statistics.py @@ -0,0 +1,12 @@ +# 8. Crea un módulo llamado "statistics" que tenga funciones para calcular la media y la mediana de una lista de números. + +def mean(numbers): + return sum(numbers) / len(numbers) + +def median(numbers): + numbers.sort() + n = len(numbers) + mid = n // 2 + if n % 2 == 0: + return (numbers[mid - 1] + numbers[mid]) / 2 + return numbers[mid] diff --git a/Hello-Python.code-workspace b/Hello-Python.code-workspace new file mode 100644 index 00000000..1cfc2759 --- /dev/null +++ b/Hello-Python.code-workspace @@ -0,0 +1,29 @@ +{ + "folders": [ + { + "path": "." + } + ], + "settings": { + "workbench.colorCustomizations": { + "activityBar.activeBackground": "#d69640", + "activityBar.background": "#d69640", + "activityBar.foreground": "#15202b", + "activityBar.inactiveForeground": "#15202b99", + "activityBarBadge.background": "#cbf4e2", + "activityBarBadge.foreground": "#15202b", + "commandCenter.border": "#15202b99", + "sash.hoverBorder": "#d69640", + "statusBar.background": "#bb7c28", + "statusBar.foreground": "#15202b", + "statusBarItem.hoverBackground": "#91601f", + "statusBarItem.remoteBackground": "#bb7c28", + "statusBarItem.remoteForeground": "#15202b", + "titleBar.activeBackground": "#bb7c28", + "titleBar.activeForeground": "#15202b", + "titleBar.inactiveBackground": "#bb7c2899", + "titleBar.inactiveForeground": "#15202b99" + }, + "peacock.color": "#bb7c28" + } +} \ No newline at end of file diff --git a/IAapps/Globotickets/.env b/IAapps/Globotickets/.env new file mode 100644 index 00000000..9705b73a --- /dev/null +++ b/IAapps/Globotickets/.env @@ -0,0 +1 @@ +TICKETMASTER_API_KEY="MY_TOCKETMASTER_KEY" diff --git a/IAapps/Globotickets/Prompts.txt b/IAapps/Globotickets/Prompts.txt new file mode 100644 index 00000000..9a8ddcce --- /dev/null +++ b/IAapps/Globotickets/Prompts.txt @@ -0,0 +1,62 @@ +Quiero crear una aplicación sencilla para eventos llamada Globotickets, utilizando Python y Javascript. +El usuario podrá entrar el nombre de una ciudad y entonces la aplicación obtendrá y visualizara una lista de eventos en la ciudad +llamando al API de Ticketmaster. ¿Puedes describir a alto nivel como deberia encarar esta aplicación? + +trabajemos en el backend.Escribe el código Python/Flask necesario + +Te paso la documentacion de la API para Tocketmaster's Event Images API. Escribe el código necesario en Python/Flask para el backend de la aplicacion Globotickets. +### +Get Event Images +Method: GET + +Summary: Get Event Images + +Description: Get images for a specific event using the unique identifier for the event. + +/discovery/v2/events/{id}/images + +URL parameters: +Parameter Description Type Default Value Required +id ID of the event String Yes +Query parameters: +Parameter Description Type Default Value Required +locale The locale in ISO code format. Multiple comma-separated values can be provided. When omitting the country part of the code (e.g. only 'en' or 'fr') then the first matching locale is used. When using a '*' it matches all locales. '*' can only be used at the end (e.g. 'en-us,en,*') String * No +domain Filter entities based on domains they are available on Array No +Response structure: +200successful operation + +_links(object) - links to data sets +type(string) - Type of the entity +id(string) - Unique id of the entity in the discovery API +images(array) - Images of the entity +JavaScript +$.ajax({ + type:"GET", + url:"https://app.ticketmaster.com/discovery/v2/events/k7vGFKzleBdwS/images.json?apikey=d925CRYN8ZjvPzKCUKbMZBweY8iDaZjB", + async:true, + dataType: "json", + success: function(json) { + console.log(json); + // Parse the response. + // Do other things. + }, + error: function(xhr, status, err) { + // This time, we do not end up here! + } +}); +Examples: +RequestResponse + +GET /discovery/v2/events/0B004F0401BD55E5/images.json?apikey=d925CRYN8ZjvPzKCUKbMZBweY8iDaZjB HTTP/1.1 +Host: app.ticketmaster.com +X-Target-URI: https://app.ticketmaster.com +Connection: Keep-Alive + +# Ahora trabajemos en el front-end de la aplicacion. Escribe el código Javascript necesario para obtener la entrada del usuario y la envie al backend. + +Vamos a trabajar en el estilo, y luego tengo un par de requisitos sencillos. +La parte superior de la página debe tener un banner negro y un logotipo llamado logo.png que añadiré a mi proyecto. +Queremos que esté alineado a la izquierda. El color de énfasis debe ser rosa. Tengo el código hexadecimal aqui #FF1675 +.La fuente debe ser Segoe UI. El código deberia estar en un archivo CSS aparte. + +Por favor, escribe test unitarios para la aplicación utilizando el framework pytest \ No newline at end of file diff --git a/IAapps/Globotickets/app.py b/IAapps/Globotickets/app.py new file mode 100644 index 00000000..ed000e08 --- /dev/null +++ b/IAapps/Globotickets/app.py @@ -0,0 +1,88 @@ +import os +import requests +from flask import Flask, request, jsonify +from flask import render_template +from dotenv import load_dotenv +from flask_cors import CORS + +# Cargar variables de entorno (como la API Key) +load_dotenv() + +app = Flask(__name__) +CORS(app) # Habilita CORS para permitir peticiones desde frontend +@app.route('/') +def index(): + return render_template('index.html') + +TICKETMASTER_API_KEY = os.getenv("TICKETMASTER_API_KEY") +TICKETMASTER_BASE_URL = "https://app.ticketmaster.com/discovery/v2/events.json" + +@app.route('/api/events', methods=['GET']) +def get_events(): + city = request.args.get('city') + if not city: + return jsonify({"error": "Debe proporcionar el nombre de una ciudad."}), 400 + + params = { + 'apikey': TICKETMASTER_API_KEY, + 'city': city, + 'size': 10, # Puedes ajustar cuántos eventos devolver + 'sort': 'date,asc' + } + + try: + response = requests.get(TICKETMASTER_BASE_URL, params=params) + response.raise_for_status() + data = response.json() + + # Parsear resultados relevantes + events = [] + for event in data.get('_embedded', {}).get('events', []): + events.append({ + 'id': event['id'], + 'name': event['name'], + 'date': event['dates']['start'].get('localDate'), + 'time': event['dates']['start'].get('localTime'), + 'venue': event['_embedded']['venues'][0]['name'], + 'url': event['url'] + }) + + return jsonify(events) + + except requests.exceptions.RequestException as e: + return jsonify({"error": "Error al contactar con Ticketmaster", "details": str(e)}), 500 + except KeyError: + return jsonify([]) # Devuelve lista vacía si no hay eventos + +@app.route('/api/events//images', methods=['GET']) +def get_event_images(event_id): + locale = request.args.get('locale', '*') # valor por defecto + params = { + 'apikey': TICKETMASTER_API_KEY, + 'locale': locale + } + + url = f"https://app.ticketmaster.com/discovery/v2/events/{event_id}/images.json" + + try: + response = requests.get(url, params=params) + response.raise_for_status() + data = response.json() + + images = data.get('images', []) + + # Devuelve lista de URLs e información básica + result = [{ + 'url': img.get('url'), + 'width': img.get('width'), + 'height': img.get('height'), + 'ratio': img.get('ratio') + } for img in images] + + return jsonify(result) + + except requests.exceptions.RequestException as e: + return jsonify({"error": "Error al obtener imágenes del evento", "details": str(e)}), 500 + +if __name__ == '__main__': + app.run(debug=True) diff --git a/IAapps/Globotickets/copilot.js b/IAapps/Globotickets/copilot.js new file mode 100644 index 00000000..e69de29b diff --git a/IAapps/Globotickets/requirements.txt b/IAapps/Globotickets/requirements.txt new file mode 100644 index 00000000..5e021efb --- /dev/null +++ b/IAapps/Globotickets/requirements.txt @@ -0,0 +1,3 @@ +Flask==3.0.3 +requests==2.31.0 +pytest==8.1.1 diff --git a/IAapps/Globotickets/static/logo.png b/IAapps/Globotickets/static/logo.png new file mode 100644 index 00000000..2ad39e1a Binary files /dev/null and b/IAapps/Globotickets/static/logo.png differ diff --git a/IAapps/Globotickets/static/styles.css b/IAapps/Globotickets/static/styles.css new file mode 100644 index 00000000..8b461a15 --- /dev/null +++ b/IAapps/Globotickets/static/styles.css @@ -0,0 +1,67 @@ +body { + font-family: 'Segoe UI', sans-serif; + margin: 0; + background-color: #f9f9f9; +} + +header { + background-color: #000; + color: #FF1675; + display: flex; + align-items: center; + padding: 10px 20px; +} + +header img { + height: 40px; + margin-right: 15px; +} + +h1 { + font-size: 1.5em; + margin: 0; +} + +.container { + padding: 20px; +} + +input[type="text"] { + padding: 8px; + font-size: 16px; + border: 1px solid #ccc; + border-radius: 4px; +} + +button { + background-color: #FF1675; + color: white; + border: none; + padding: 8px 12px; + margin-left: 5px; + cursor: pointer; + border-radius: 4px; +} + +button:hover { + background-color: #e31369; +} + +.event { + border: 1px solid #ccc; + background-color: white; + padding: 15px; + margin-bottom: 15px; + border-radius: 6px; + box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); +} + +.images { + margin-top: 10px; +} + +.images img { + max-width: 200px; + border-radius: 4px; + margin: 5px; +} \ No newline at end of file diff --git a/IAapps/Globotickets/templates/index.html b/IAapps/Globotickets/templates/index.html new file mode 100644 index 00000000..142f1fd1 --- /dev/null +++ b/IAapps/Globotickets/templates/index.html @@ -0,0 +1,84 @@ + + + + + + Globotickets + + + + + +
+ Globotickets Logo +

Globotickets

+
+ +
+ + + +
+
+ + + + + + \ No newline at end of file diff --git a/IAapps/Globotickets/tests/test_app.py b/IAapps/Globotickets/tests/test_app.py new file mode 100644 index 00000000..64baf224 --- /dev/null +++ b/IAapps/Globotickets/tests/test_app.py @@ -0,0 +1,124 @@ +import pytest +import sys +import os +sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))) + +from app import app + +@pytest.fixture +def client(): + app.testing = True + with app.test_client() as client: + yield client + +def test_get_events_success(client, monkeypatch): + mock_data = { + "_embedded": { + "events": [ + { + "name": "Concierto de Prueba", + "id": "123", + "url": "https://ticketmaster.com/event/123", + "dates": { + "start": { + "localDate": "2025-10-01", + "localTime": "20:00" + } + }, + "_embedded": { + "venues": [ + { + "name": "Auditorio Nacional" + } + ] + } + } + ] + } + } + + class MockResponse: + status_code = 200 + + def json(self): + return mock_data + + def raise_for_status(self): + pass # Do nothing for a successful response + + def mock_get(*args, **kwargs): + return MockResponse() + + # Patch the requests.get method to use the mock_get + monkeypatch.setattr("requests.get", mock_get) + + # Call the endpoint + response = client.get("/api/events?city=Madrid") + + # Assert the response data if needed + assert response.status_code == 200 + assert response.json() == mock_data # You can add more assertions as needed + + + def mock_get(*args, **kwargs): + class MockResponse: + status_code = 200 + def json(self): + return mock_data + return MockResponse() + + monkeypatch.setattr("requests.get", mock_get) + + response = client.get("/api/events?city=Madrid") + assert response.status_code == 200 + data = response.get_json() + assert isinstance(data, list) + assert data[0]["name"] == "Concierto de Prueba" + +def test_get_events_empty(client, monkeypatch): + def mock_get(*args, **kwargs): + class MockResponse: + status_code = 200 + def json(self): + return {} + return MockResponse() + + monkeypatch.setattr("requests.get", mock_get) + response = client.get("/api/events?city=Desconocido") + assert response.status_code == 200 + assert response.get_json() == [] + +def test_get_event_images_success(client, monkeypatch): + mock_data = { + "images": [ + {"url": "http://example.com/image1.jpg"}, + {"url": "http://example.com/image2.jpg"} + ] + } + + def mock_get(*args, **kwargs): + class MockResponse: + status_code = 200 + def json(self): + return mock_data + return MockResponse() + + monkeypatch.setattr("requests.get", mock_get) + response = client.get("/api/events/123/images") + assert response.status_code == 200 + data = response.get_json() + assert isinstance(data, list) + assert data[0]["url"] == "http://example.com/image1.jpg" + +def test_get_event_images_empty(client, monkeypatch): + def mock_get(*args, **kwargs): + class MockResponse: + status_code = 200 + def json(self): + return {"images": []} + return MockResponse() + + monkeypatch.setattr("requests.get", mock_get) + response = client.get("/api/events/000/images") + assert response.status_code == 200 + assert response.get_json() == [] diff --git a/Intermediate/00_dates.py b/Intermediate/00_dates.py index 26b14113..aa42e264 100644 --- a/Intermediate/00_dates.py +++ b/Intermediate/00_dates.py @@ -73,3 +73,95 @@ def print_date(date): print(end_timedelta - start_timedelta) print(end_timedelta + start_timedelta) + +""" +1. Crea una variable con la fecha y hora actual. +2. Imprime solo el año, mes y día de la fecha actual. +3. Crea una fecha específica: 25 de diciembre de 2025 y +muéstrala. +4. Muestra solo la hora, los minutos y los segundos de un +objeto time. +5. Calcula cuántos días faltan para el 1 de enero del año +siguiente. +6. Crea una función que reciba una fecha y devuelva su +timestamp. +7. Suma 30 días a la fecha actual usando timedelta. +8. Crea una fecha y añade 1 mes (consejo: hazlo sumando 30 +días como simplificación). +9. Compara dos fechas y muestra cuál es anterior. +10. Crea una lista con varias fechas y ordénalas +cronológicamente +""" +# Ejercicio 1: Crear una variable con la fecha y hora actual +current_datetime = datetime.now() +print("Fecha y hora actual:", current_datetime) + +# Ejercicio 2: Imprimir solo el año, mes y día de la fecha actual +date_today = current_datetime.date() +print("Año:", date_today.year) +print("Mes:", date_today.month) +print("Día:", date_today.day) + +# Ejercicio 3: Crear una fecha específica: 25 de diciembre de 2025 +specific_date = date(2025, 12, 25) +print("Fecha específica:", specific_date) + +# Ejercicio 4: Mostrar solo la hora, los minutos y los segundos de un objeto time +define_time = time(15, 30, 45) # 3:30:45 PM +print("Hora:", define_time.hour) +print("Minutos:", define_time.minute) +print("Segundos:", define_time.second) + +# Ejercicio 5: Calcular cuántos días faltan para el 1 de enero del año siguiente +next_year = date_today.year + 1 +next_year_date = date(next_year, 1, 1) +days_until_next_year = (next_year_date - date_today).days +print("Días hasta el 1 de enero del año siguiente:", days_until_next_year) + +# Ejercicio 6: Crear una función que reciba una fecha y devuelva su timestamp +def get_timestamp(date_obj): + # Convertimos el objeto date a datetime para obtener el timestamp + datetime_obj = datetime.combine(date_obj, datetime.min.time()) + return datetime_obj.timestamp() +date_obj = date(2023, 10, 6) +timestamp = get_timestamp(date_obj) +print("Timestamp de la fecha", date_obj, ":", timestamp) + +# Ejercicio 7: Sumar 30 días a la fecha actual usando timedelta +date_plus_30_days = current_datetime + timedelta(days=30) +print("Fecha actual + 30 días:", date_plus_30_days) + +# Ejercicio 8: Crear una fecha y añadir 1 mes (simplificación sumando 30 días) +date_plus_1_month = current_datetime + timedelta(days=30) +print("Fecha actual + 1 mes (30 días):", date_plus_1_month) + +# Ejercicio 9: Comparar dos fechas y mostrar cuál es anterior +date1 = date(2023, 10, 6) +date2 = date(2024, 1, 1) +if date1 < date2: + print(f"La fecha {date1} es anterior a {date2}.") +elif date1 > date2: + print(f"La fecha {date1} es posterior a {date2}.") +else: + print(f"Las fechas {date1} y {date2} son iguales.") + +# Ejercicio 10: Crear una lista con varias fechas y ordenarlas cronológicamente +list_of_dates = [ + date(2023, 10, 6), + date(2022, 5, 15), + date(2024, 1, 1), + date(2023, 7, 20) +] +sorted_dates = sorted(list_of_dates) +print("Fechas ordenadas cronológicamente:") +for d in sorted_dates: + print(d) + +# Fin del ejercicio + + + + + + + diff --git a/Intermediate/01_list_comprehension.py b/Intermediate/01_list_comprehension.py index eb847494..f5948190 100644 --- a/Intermediate/01_list_comprehension.py +++ b/Intermediate/01_list_comprehension.py @@ -26,3 +26,48 @@ def sum_five(number): my_list = [sum_five(i) for i in range(8)] print(my_list) + +#EJERCICIOS + +#1. Genera una lista utilizando comprensión con los números del 0 al 10. +my_list = [i for i in range(11)] +print(my_list) + +#2. Crea una lista utilizando comprensión con los cuadrados de los números del 1 al 10. +my_list = [i * i for i in range(1, 11)] +print(my_list) + +#3. Genera una lista utilizando comprensión con los números pares del 0 al 20. +my_list = [i for i in range(21) if i % 2 == 0] +print(my_list) + +#4. Convierte una lista de temperaturas en Celsius a Fahrenheit utilizando comprensión. +my_list = [temp * 9 / 5 + 32 for temp in [0, 10, 20, 30, 40]] +print(my_list) + +#5. Crea una lista utilizando comprensión con los caracteres de una cadena. +my_string = "Hola" +my_list = [char for char in my_string] +print(my_list) + +#6. Filtra una lista de palabras y deja solo las que tienen más de 4 letras utilizando comprensión. +my_list = [word for word in ["Hola", "mundo", "Python", "es", "genial"] if len(word) > 4] +print(my_list) + +#7. Aumenta en 5 cada número de una lista con comprensión usando una función externa. +def sum_five(number): + return number + 5 +my_list = [sum_five(i) for i in [0, 1, 2, 3, 4, 5, 6, 7]] +print(my_list) + +#8. Crea una lista de booleanos que indique si cada número es mayor que 10 utilizando comprensión. +my_list = [num > 10 for num in [5, 10, 15, 20, 25]] +print(my_list) + +#9. Multiplica solo los números impares por 3 en una lista utilizando comprensión. +my_list = [num * 3 for num in [1, 2, 3, 4, 5] if num % 2 != 0] +print(my_list) + +#10. Usa comprensión de listas anidada para generar una matriz 3x3 con números del 1 al 9. +my_list = [[i + j * 3 for i in range(1, 4)] for j in range(3)] +print(my_list) diff --git a/Intermediate/03_lambdas.py b/Intermediate/03_lambdas.py index d23507ac..18581ed2 100644 --- a/Intermediate/03_lambdas.py +++ b/Intermediate/03_lambdas.py @@ -21,3 +21,46 @@ def sum_three_values(value): print(sum_three_values(5)(2, 4)) + +# Ejercicios Lambdas + +#1. Crea una lambda que sume dos números. +def sum_two_numbers(a, b): return a + b +print(sum_two_numbers(3, 5)) + +#2. Crea una lambda que calcule el cuadrado de un número. +def square_number(x): return x * x +print(square_number(4)) + +#3. Crea una lambda que devuelva el mayor de dos números. +def max_of_two(a, b): return a if a > b else b +print(max_of_two(10, 5)) + +#4. Crea una lambda que sume 10 a un número dado. +def add_ten(x): return x + 10 +print(add_ten(5)) + +#5. Crea una lambda que devuelva el último carácter de una cadena. +def last_character(string): return string[-1] if string else None +print(last_character("Python")) + +#6. Crea una lambda que indique si una palabra tiene más de 6 letras. +def has_more_than_six_letters(word): return len(word) > 6 +print(has_more_than_six_letters("Pythonista")) + +#7. Crea una lambda que convierta una cadena a minúsculas. +def to_lowercase(string): return string.lower() +print(to_lowercase("PYTHON")) + +#8. Crea una lambda que devuelva True si un número es positivo. +def is_positive(number): return number > 0 +print(is_positive(5)) + +#9. Crea una lambda que devuelva "Cadena vacía" si el string está vacío. +def empty_string(string): return "Cadena vacía" if not string else string +print(empty_string("")) +print(empty_string("Python")) + +#10. Crea una lambda que calcule el precio final con un impuesto añadido del 21%. +def final_price(price): return price * 1.21 +print(final_price(100)) diff --git a/Intermediate/04_higher_order_functions.py b/Intermediate/04_higher_order_functions.py index 4c0c6e04..cf759505 100644 --- a/Intermediate/04_higher_order_functions.py +++ b/Intermediate/04_higher_order_functions.py @@ -67,3 +67,90 @@ def sum_two_values(first_value, second_value): print(reduce(sum_two_values, numbers)) + +#Ejercicios Funciones de orden superior + +#1. Crea una función que reciba una función y un número, y devuelva el resultado de aplicar la función al número. +def apply_function(func, number): + return func(number) +def square(x): + return x * x +print(apply_function(square, 5)) #25 + + +#2. Crea una función que reciba dos números y una función, y devuelva el resultado de sumar los dos números y aplicar la función. +def apply_function_to_sum(func, a, b): + return func(a + b) +def double(x): + return x * 2 +print(apply_function_to_sum(double, 2, 3)) #10 + +#3. Crea una función que devuelva otra función que sume un número fijo. +def add_fixed_value(fixed_value): + def add(value): + return value + fixed_value + return add +add_five = add_fixed_value(5) +print(add_five(10)) #15 + +#4. Usa map() con lambda para multiplicar cada número de una lista por 10. +numbers = [1, 2, 3, 4, 5] +print(list(map(lambda x: x * 10, numbers))) # [10, 20, 30, 40, 50] + +#5. Usa filter() con lambda para quedarte solo con los números pares. +numbers = [1, 2, 3, 4, 5, 6] +print(list(filter(lambda x: x % 2 == 0, numbers))) # [2, 4, 6] + +#6. Usa reduce() con lambda para obtener la suma total de una lista. +from functools import reduce +numbers = [1, 2, 3, 4, 5] +print(reduce(lambda x, y: x + y, numbers)) #15 + +#7. Escribe una función que devuelva una función que reciba un nombre y devuelva "Hola, ". +# seguido del nombre. +def greet(greeting): + def say_hello(name): + return f"{greeting}, {name}" + return say_hello +def hello(name): + return greet("Hola")(name) +print(hello("Juan")) #Hola, Juan + +#8. Crea una función que reciba una lista y una función, y cuente cuántos elementos cumplen con la función. +def count_elements(lst, func): + return len(list(filter(func, lst))) +def is_even(x): + return x % 2 == 0 +numbers = [1, 2, 3, 4, 5, 6] +print(count_elements(numbers, is_even)) #3 + +#9. Crea una función que reciba dos funciones y un número, y las aplique en orden. +def apply_functions_in_order(func1, func2, number): + return func2(func1(number)) +def add_one(x): + return x + 1 +def multiply_by_two(x): + return x * 2 +print(apply_functions_in_order(add_one, multiply_by_two, 5)) #12 + +#10. Crea una función que reciba una lista y una función, y aplique esa función a cada elemento usando un bucle (sin map). +def apply_function_with_loop(lst, func): + result = [] + for item in lst: + result.append(func(item)) + return result +def square(x): + return x * x +numbers = [1, 2, 3, 4, 5] +print(apply_function_with_loop(numbers, square)) # [1, 4, 9, 16, 25] +# +#11. Crea una función que reciba una lista y una función, y aplique esa función a cada elemento usando un bucle (sin map). +def apply_function_with_loop(lst, func): + result = [] + for item in lst: + result.append(func(item)) + return result +def square(x): + return x * x +numbers = [1, 2, 3, 4, 5] +print(apply_function_with_loop(numbers, square)) # [1, 4, 9, 16, 25] diff --git a/Intermediate/05_error_types.py b/Intermediate/05_error_types.py index 853f329e..23adf026 100644 --- a/Intermediate/05_error_types.py +++ b/Intermediate/05_error_types.py @@ -49,3 +49,43 @@ # ZeroDivisionError # print(4/0) # Descomentar para Error print(4/2) + +#Ejercicios Tipos de error +#1. Genera un SyntaxError al imprimir una cadena sin paréntesis. +#from math import pi +#print "¡Hola comunidad!" # Descomentar para Error + +#2. Genera un NameError intentando usar una variable no definida. +#language = "Spanish" # Comentar para Error +print(language) # Descomentar para Error + +#3. Genera un IndexError accediendo a un índice inexistente de una lista. +my_list = ["Python", "Swift", "Kotlin", "Dart", "JavaScript"] +#print(my_list[5]) # Descomentar para Error + +#4. Genera un ModuleNotFoundError al importar un módulo inexistente. +#import maths # Descomentar para Error + +#5. Genera un AttributeError accediendo a un atributo que no existe. +#print(math.PI) # Descomentar para Error + +#6. Genera un KeyError al acceder a una clave inexistente de un diccionario. +my_dict = {"Nombre": "Brais", "Apellido": "Moure", "Edad": 35, 1: "Python"} +#print(my_dict["Apelido"]) # Descomentar para Error + +#7. Genera un TypeError usando tipos incorrectos (índice string en lista). +my_list = ["Python", "Swift", "Kotlin", "Dart", "JavaScript"] +#print(my_list["0"]) # Descomentar para Error + +#8. Genera un ImportError al importar una función que no existe desde un módulo. +# from math import PI # Descomentar para Error + +#9. Genera un ValueError intentando convertir un string no numérico a entero. +#my_int = int("10 Años") # Descomentar para Error + +#10. Intenta detectar si un error ocurre usando tryexcept con un KeyError. +my_dict = {"Nombre": "Brais", "Apellido": "Moure", "Edad": 35, 1: "Python"} +try: + print(my_dict["Apelido"]) +except KeyError: + print("Error: La clave 'Apelido' no existe en el diccionario.") diff --git a/Intermediate/06_file_handling.py b/Intermediate/06_file_handling.py index 05ab8df1..38c8b093 100644 --- a/Intermediate/06_file_handling.py +++ b/Intermediate/06_file_handling.py @@ -13,7 +13,8 @@ txt_file = open("Intermediate/my_file.txt", "w+") txt_file.write( - "Mi nombre es Brais\nMi apellido es Moure\n35 años\nY mi lenguaje preferido es Python") + "Mi nombre es Brais\nMi apellido es Moure\n35 años\nY mi lenguaje preferido es Python" +) # print(txt_file.read()) print(txt_file.read(10)) @@ -44,7 +45,8 @@ "surname": "Moure", "age": 35, "languages": ["Python", "Swift", "Kotlin"], - "website": "https://moure.dev"} + "website": "https://moure.dev", +} json.dump(json_test, json_file, indent=2) @@ -81,3 +83,309 @@ # .xml file # ¿Te atreves a practicar cómo trabajar con este tipo de ficheros? + +# Ejercicios File Handling +# 1. Crea un archivo de texto y escribe en él la frase "Hola desde Python". +file_fer_txt = open("Intermediate/fer.txt", "w+") +file_fer_txt.write("Hola desde Python") +file_fer_txt.close() + +# 2. Abre un archivo y lee todo su contenido. +file_fer_txt = open("Intermediate/fer.txt", "r") +print(file_fer_txt.read()) +file_fer_txt.close() + +# 3. Añade una nueva línea al final del archivo con el texto "Línea añadida". +file_fer_txt = open("Intermediate/fer.txt", "a") +file_fer_txt.write("\nLínea añadida") +file_fer_txt.close() + +# 4. Lee solo los primeros 10 caracteres del archivo. +file_fer_txt = open("Intermediate/fer.txt", "r") +print(file_fer_txt.read(10)) +file_fer_txt.close() + +# 5. Usa seek para volver al inicio del archivo y leer desde ahí. +file_fer_txt = open("Intermediate/fer.txt", "r") +file_fer_txt.seek(0) +print(file_fer_txt.read()) +file_fer_txt.close() + +# 6. Lee e imprime el contenido línea por línea usando readline. +file_fer_txt = open("Intermediate/fer.txt", "r") +print(file_fer_txt.readline()) +print(file_fer_txt.readline()) +print(file_fer_txt.readline()) +file_fer_txt.close() + +# 7. Lee todas las líneas del archivo en una lista y recórrelas con un bucle. +file_fer_txt = open("Intermediate/fer.txt", "r") +lines = file_fer_txt.readlines() +for line in lines: + print(line) +file_fer_txt.close() + +# 8. Crea un archivo nuevo que sobrescriba si ya existe, y escribe varias líneas. +file_fer_txt = open("Intermediate/fer.txt", "w+") +file_fer_txt.write("Línea 1\nLínea 2\nLínea 3") +file_fer_txt.close() + + +# 9. Usa una función para abrir un archivo, escribir texto y cerrarlo automáticamente con with. +def write_to_file(filename, text): + with open(filename, "w") as file: + file.write(text) + + +write_to_file("Intermediate/fer.txt", "Texto escrito con función") + +# 10. Lee un archivo línea por línea y muestra solo las que contienen la palabra "Python". +file_fer_txt = open("Intermediate/fer.txt", "r") +for line in file_fer_txt: + if "Python" in line: + print(line) +file_fer_txt.close() +# 11. Crea un archivo CSV y escribe varias filas de datos en él. +csv_file = open("Intermediate/fer.csv", "w+") +csv_writer = csv.writer(csv_file) +csv_writer.writerow(["name", "surname", "age", "language", "website"]) +csv_writer.writerow(["Brais", "Moure", 35, "Python", "https://moure.dev"]) +csv_writer.writerow(["Roswell", "", 2, "COBOL", ""]) +csv_file.close() + +# 12. Lee un archivo CSV y muestra su contenido. +csv_file = open("Intermediate/fer.csv", "r") +csv_reader = csv.reader(csv_file) +for row in csv_reader: + print(row) +csv_file.close() + +# 13. Crea un archivo JSON y escribe un diccionario en él. +json_file = open("Intermediate/fer.json", "w+") +json_test = { + "name": "Brais", + "surname": "Moure", + "age": 35, + "languages": ["Python", "Swift", "Kotlin"], + "website": "https://moure.dev", +} +json.dump(json_test, json_file, indent=2) +json_file.close() +# 14. Lee un archivo JSON y muestra su contenido. +json_file = open("Intermediate/fer.json", "r") +json_dict = json.load(json_file) +print(json_dict) +print(type(json_dict)) +print(json_dict["name"]) +json_file.close() +# 15. Crea un archivo XML y escribe un documento XML básico en él. +xml_file = open("Intermediate/fer.xml", "w+") +xml_file.write( + '\n\n\tBrais\n\tMoure\n\t35\n' +) +xml_file.close() +# 16. Lee un archivo XML y muestra su contenido. +xml_file = open("Intermediate/fer.xml", "r") +xml_content = xml_file.read() +print(xml_content) +xml_file.close() + + +##DotNetTutorials Examples +f = open("abc.txt", "w") +print("File Name: ", f.name) +print("File Mode: ", f.mode) +print("Is File Readable: ", f.readable()) +print("Is File Writable: ", f.writable()) +print("Is File Closed : ", f.closed) +f.close() +print("Is File Closed : ", f.closed) + +f = open("wish.txt", "w") +f.write("Welcome\n") +f.write("to\n") +f.write("python world\n") +print("Data written to the file successfully") +f.close() + +f = open("wish.txt", "a") +f.write("Welcome\n") +f.write("to\n") +f.write("python world\n") +print("Data written to the file successfully") +f.close() + +f = open("wish.txt", "a") +f.write("Welcome ") +f.write("to ") +f.write("python world") +print("Data written to the file successfully") +f.close() + +f = open("names.txt", "w") +list = ["Ramesh\n", "Arjun\n", "Senthil\n", "Vignesh"] +f.writelines(list) +print("List of lines written to the file successfully") +f.close() + +f = open("abc.txt", "r") +data = f.read() +print(data) +f.close() + +f = open("abc.txt", "r") +line1 = f.readline() +print(line1, end="") +line2 = f.readline() +print(line2, end="") +line3 = f.readline() +print(line3, end="") +f.close() + +f = open("abc.txt", "r") +lines = f.readlines() +for line in lines: + print(line, end="") +f.close() + +with open("test.txt", "w") as f: + f.write("Welcome\n") + f.write("to\n") + f.write("Python\n") + print("Is File Closed: ", f.closed) +print("Is File Closed: ", f.closed) + +f = open("test.txt", "r") +print(f.tell()) +print(f.read(2)) +print(f.tell()) +print(f.read(3)) +print(f.tell()) + +data = "SampurneshBabu movie is excellent" +f = open("abc.txt", "w") +f.write(data) +with open("abc.txt", "r+") as f: + text = f.read() + print(text) + print("The Current Cursor Position: ", f.tell()) + f.seek(24) + print("The Current Cursor Position: ", f.tell()) + f.write("Britania Bisket") + f.seek(0) + text = f.read() + print("Data After Modification:") + print(text) + +""" +import os, sys +fname=input("Enter File Name: ") +if os.path.isfile(fname): + print("File exists:", fname) + f=open(fname, "r") +else: + print("File does not exist:", fname) + sys.exit(0) +print("The content of file is:") +data=f.read() +print(data) + +import os, sys +fname=input("Enter File Name: ") +if os.path.isfile(fname): + print("File exists:", fname) + f=open(fname, "r") +else: + print("File does not exist:", fname) + sys.exit(0) +lcount=wcount=ccount=0 +for line in f: + lcount=lcount+1 + ccount=ccount+len(line) + words=line.split() + wcount=wcount+len(words) +print("The number of Lines:", lcount) +print("The number of Words:", wcount) +print("The number of Characters:", ccount) +""" + +##Binary +f1 = open("thor.jpeg", "rb") +f2 = open("newpic.jpeg", "wb") +bytes = f1.read() +f2.write(bytes) +print("New Image is available with the name: newpic.jpg") + +import csv + +with open("emp.csv", "w", newline="") as f: + w = csv.writer(f) + w.writerow(["EMP NO", "EMP NAME", "EMP SAL", "EMP ADDR"]) + n = int(input("Enter Number of Employees:")) + for i in range(n): + eno = input("Enter Employee No:") + ename = input("Enter Employee Name:") + esal = input("Enter Employee Salary:") + eaddr = input("Enter Employee Address:") + w.writerow([eno, ename, esal, eaddr]) +print("Total Employees data written to csv file successfully") + +from zipfile import * + +f = ZipFile("files.zip", "w", ZIP_DEFLATED) +f.write("abc.txt") +f.write("thor.jpeg") +f.write("names.txt") +f.close() +print("files.zip file created successfully") + +from zipfile import * + +f = ZipFile("files.zip", "r", ZIP_STORED) +names = f.namelist() +for name in names: + print("File Name: ", name) + + +import os + +cwd = os.getcwd() +print("Current Working Directory:", cwd) + +import os + +os.mkdir("mysub") +print("mysub directory created in current working directory") + +import os + +os.makedirs("sub1/sub2/sub3") +print("sub1 and in that sub2 and in that sub3 directories created") + +import os + +os.removedirs("sub1/sub2/sub3") +print("All 3 directories sub1,sub2 and sub3 removed") + +import pickle + + +class Employee: + def __init__(self, eno, ename, esal, eaddr): + self.eno = eno + self.ename = ename + self.esal = esal + self.eaddr = eaddr + + def display(self): + print(self.eno, "\t", self.ename, "\t", self.esal, "\t", self.eaddr) + + +with open("emp.dat", "wb") as f: + e = Employee(100, "Nireekshan", 1000, "Hyd") + pickle.dump(e, f) + print("Pickling of Employee Object completed...") +with open("emp.dat", "rb") as f: + obj = pickle.load(f) + print("Printing Employee Information after unpickling") + obj.display() diff --git a/Intermediate/07_regular_expressions.py b/Intermediate/07_regular_expressions.py index d2b1f9a7..4494c066 100644 --- a/Intermediate/07_regular_expressions.py +++ b/Intermediate/07_regular_expressions.py @@ -78,3 +78,353 @@ email = "mouredev@mouredev.com.mx" print(re.findall(pattern, email)) + +# Ejercicios Regular Expressions +# 1. Busca si una cadena empieza por "Hola". +cadena = "Hola, ¿cómo estás?" +pattern = r"^Hola" +print(re.match(pattern, cadena)) + +# 2. Busca la palabra "Python" en una cadena aunque esté en minúsculas. +cadena = "Me encanta programar en python" +pattern = r"python" +print(re.search(pattern, cadena, re.I)) + +# 3. Encuentra todas las apariciones de la palabra "curso" en una cadena. +cadena = "Este curso es genial. El curso de Python es el mejor curso." +pattern = r"curso" +print(re.findall(pattern, cadena)) + +# 4. Reemplaza todas las apariciones de "lección" por "LECCIÓN". +cadena = "Esta es la lección número 7: Lección llamada Expresiones Regulares" +pattern = r"lección" +print(re.sub(pattern, "LECCIÓN", cadena, flags=re.I)) + +# 5. Divide un texto en partes separadas por comas. +cadena = "manzana,pera,plátano,naranja" +pattern = r"," +print(re.split(pattern, cadena)) + +# 6. Busca la primera palabra que comience con "A" o "a". +cadena = "Aprender Python es asombroso" +pattern = r"\b[Aa]\w*" +print(re.search(pattern, cadena)) + +# 7. Encuentra todas las palabras en una cadena que terminen en "ción". +cadena = "La educación es la clave para la evolución y la revolución." +pattern = r"\b\w*ción\b" +print(re.findall(pattern, cadena)) + +# 8. Verifica si una cadena contiene solo números. +cadena = "1234567890" +pattern = r"^\d+$" +print(re.match(pattern, cadena)) + +# 9. Reemplaza todos los números de una cadena por el texto "[número]". +cadena = "El año es 2023 y tengo 30 años." +pattern = r"\d+" +print(re.sub(pattern, "[número]", cadena)) +cadena = "El año es 2023 y tengo 30 años." +pattern = r"\d+" +print(re.sub(pattern, "[número]", cadena)) + +# 10. Encuentra todas las palabras de 4 letras exactas en una cadena. +cadena = "Este es un texto con varias palabras de cuatro letras." +pattern = r"\b\w{4}\b" +print(re.findall(pattern, cadena)) +# 11. Busca si una cadena contiene un número de teléfono en formato (XXX) XXX-XXXX. +cadena = "(123) 456-7890" +pattern = r"\(\d{3}\) \d{3}-\d{4}" +print(re.match(pattern, cadena)) + +# DotNetTutorials Examples + +import re + +count = 0 +pattern = re.compile("ab") +matcher = pattern.finditer("abaababa") +for match in matcher: + count += 1 + print(match.start(), "...", match.end(), "...", match.group()) + print("The number of occurrences: ", count) + +import re + +count = 0 +matcher = re.finditer("ab", "abaababa") +for match in matcher: + count += 1 + print(match.start(), "...", match.end(), "...", match.group()) + print("The number of occurrences: ", count) + + +import re + +matcher = re.finditer("[abc]", "a7b@k9z") +for match in matcher: + print(match.start(), "......", match.group()) + + +import re + +matcher = re.finditer("[^abc]", "a7b@k9z") +for match in matcher: + print(match.start(), "......", match.group()) + +import re + +matcher = re.finditer("[a-z]", "a7b@k9z") +for match in matcher: + print(match.start(), "......", match.group()) + +import re + +matcher = re.finditer("[0-9]", "a7b@k9z") +for match in matcher: + print(match.start(), "......", match.group()) + +import re + +matcher = re.finditer("[a-zA-Z0-9]", "a7b@k9z") +for match in matcher: + print(match.start(), "......", match.group()) + + +import re + +matcher = re.finditer("[^a-zA-Z0-9]", "a7b@k9z") +for match in matcher: + print(match.start(), "......", match.group()) + +import re + +matcher = re.finditer("\s", "a7b @k9z") +for match in matcher: + print(match.start(), "......", match.group()) + +import re + +matcher = re.finditer("\S", "a7b @k9z") +for match in matcher: + print(match.start(), "......", match.group()) + + +import re + +matcher = re.finditer("\d", "a7b @k9z") +for match in matcher: + print(match.start(), "......", match.group()) + +import re + +matcher = re.finditer("\D", "a7b @k9z") +for match in matcher: + print(match.start(), "......", match.group()) + +import re + +matcher = re.finditer("\w", "a7b @k9z") +for match in matcher: + print(match.start(), "......", match.group()) + +import re + +matcher = re.finditer("\W", "a7b @k9z") +for match in matcher: + print(match.start(), "......", match.group()) + +import re + +matcher = re.finditer(".", "a7b @k9z") +for match in matcher: + print(match.start(), "......", match.group()) + +import re + +matcher = re.finditer("a", "abaabaaab") +for match in matcher: + print(match.start(), "......", match.group()) + +import re + +matcher = re.finditer("a+", "abaabaaab") +for match in matcher: + print(match.start(), "......", match.group()) + +import re + +matcher = re.finditer("a*", "abaabaaab") +for match in matcher: + print(match.start(), "......", match.group()) + +import re + +matcher = re.finditer("a?", "abaabaaab") +for match in matcher: + print(match.start(), "......", match.group()) + +import re + +matcher = re.finditer("a{3}", "abaabaaab") +for match in matcher: + print(match.start(), "......", match.group()) + +import re + +matcher = re.finditer("a{2,4}", "abaabaaab") +for match in matcher: + print(match.start(), "......", match.group()) + +# match + +import re + +s = input("Enter pattern to check: ") +m = re.match(s, "abcabdefg") +if m != None: + print("Match is available at the beginning of the String") + print("Start Index:", m.start(), "and End Index:", m.end()) +else: + print("Match is not available at the beginning of the String") + +# fullmatch(): + + +import re + +s = input("Enter pattern to check: ") +m = re.fullmatch(s, "ababab") +if m != None: + print("Full String Matched") +else: + print("Full String not Matched") + +# search(): + + +import re + +s = input("Enter pattern to check: ") +m = re.search(s, "abaaaba") +if m != None: + print("Match is available") + print( + "First Occurrence of match with start index:", + m.start(), + "and end index:", + m.end(), + ) +else: + print("Match is not available") + +# findall(): + +import re + +l = re.findall("[0-9]", "a7b9c5kz") +print(l) + + +# finditer(): + + +import re + +itr = re.finditer("[a-z]", "a7b9c5k8z") +for m in itr: + print(m.start(), "...", m.end(), "...", m.group()) + +# sub(): +re.sub(regex, replacement, targetstring) + + +import re + +s = re.sub("[a-z]", "#", "a7b9c5k8z") +print(s) + +# subn(): + +import re + +t = re.subn("[a-z]", "#", "a7b9c5k8z") +print(t) +print("The Result String:", t[0]) +print("The number of replacements:", t[1]) + +# split(): + +import re + +l = re.split(",", "KGF,BB1,BB2") +print(l) +for t in l: + print(t) + +import re + +s = "Learning Python is Very Easy" +res = re.search("^Learn", s) +if res != None: + print("Target String starts with Learn") +else: + print("Target String Not starts with Learn") + +import re + +s = "Learning Python is Very Easy" +res = re.search("Easy$", s) +if res != None: + print("Target String ends with Easy") +else: + print("Target String Not ends with Easy") + +import re + +s = "Learning Python is Very Easy" +res = re.search("easy$", s, re.IGNORECASE) +if res != None: + print("Target String ends with Easy by ignoring case") +else: + print("Target String Not ends with Easy by ignoring case") + +import re + +s = input("Enter string:") +m = re.fullmatch("[a-k][0369][a-zA-Z0-9#]*", s) +if m != None: + print(s, "Entered regular expression is matched") +else: + print(s, " Entered regular expression is not matched ") + + +import re + +n = input("Enter number:") +m = re.fullmatch("[7-9]\d{9}", n) +if m != None: + print("Valid Mobile Number") +else: + print("Please enter valid Mobile Number") + +import re + +f1 = open("input.txt", "r") +f2 = open("output.txt", "w") +for line in f1: + items = re.findall("[7-9]\d{9}", line) + for n in items: + f2.write(n + "\n") +print("Extracted all Mobile Numbers into output.txt") +f1.close() +f2.close() + +import re + +s = input("Enter Mail id:") +m = re.fullmatch("\w[a-zA-Z0-9_.]*@gmail[.]com", s) +if m != None: + print("Valid Mail Id") +else: + print("Invalid Mail id") diff --git a/Intermediate/08_python_package_manager.py b/Intermediate/08_python_package_manager.py index e0e7410e..5ecf5bf9 100644 --- a/Intermediate/08_python_package_manager.py +++ b/Intermediate/08_python_package_manager.py @@ -37,3 +37,82 @@ print(arithmetics.sum_two_values(1, 4)) + +#EJERCICIOS Manejo de paquetes +# 1. Importa el módulo math y muestra el valor de pi. +import math +print(math.pi) + +# 2. Crea un array de números usando numpy y multiplícalo por 3. +import numpy as np +array = np.array([1, 2, 3, 4, 5]) +print(array * 3) + +# 3. Muestra la versión instalada de numpy. +print(numpy.__version__) + +# 4. Realiza una petición HTTP con requests a una API pública y muestra el código de estado. +response = requests.get("https://api.github.com") +print(response.status_code) + +# 5. Importa una función llamada sum_two_values desde un paquete personalizado mypackage.arithmetics y utilízala. +from mypackage.arithmetics import sum_two_values +result = sum_two_values(5, 10) +print(result) + +# 6. Usa pandas para crear un DataFrame con nombres en español. +import pandas as pd +data = {'Nombre': ['Juan', 'Ana', 'Pedro'], 'Edad': [28, 22, 35]} +df = pd.DataFrame(data) +print(df) + +# 7. Ejecuta el comando para instalar el paquete requests desde la terminal. +# pip install requests + +# 8. Usa requests para obtener datos de una API y extrae solo los nombres de los primeros Pokémon. +response = requests.get("https://pokeapi.co/api/v2/pokemon?limit=10") +data = response.json() +pokemon_names = [pokemon['name'] for pokemon in data['results']] +print(pokemon_names) + +# 9. Muestra todos los paquetes instalados con pip desde la terminal. +# pip list +# pip freeze +# pip show requests +# pip show pandas +# 10. Escribe una línea de código que muestre la ayuda sobre el paquete numpy desde Python. +help(numpy) +# 11. Crea un entorno virtual y activa el entorno. +# python -m venv myenv +# source myenv/bin/activate (Linux/Mac) +# myenv\Scripts\activate (Windows) +# 12. Instala un paquete en el entorno virtual. +# pip install requests +# 13. Desactiva el entorno virtual. +# deactivate +# 14. Elimina el entorno virtual. +# rm -rf myenv (Linux/Mac) +# 15. Crea un archivo requirements.txt con los paquetes instalados. +# pip freeze > requirements.txt +# 16. Instala los paquetes desde requirements.txt. +# pip install -r requirements.txt +# 17. Actualiza un paquete específico. +# pip install --upgrade requests +# 18. Desinstala un paquete. +# pip uninstall requests +# 19. Busca un paquete en PyPI. +# pip search requests +# 20. Muestra la documentación de un paquete. +# pip show -f requests +# 21. Usa pipenv para crear un entorno virtual y gestionar dependencias. +# pip install pipenv +# pipenv install requests +# pipenv shell +# 22. Usa poetry para gestionar dependencias y crear un entorno virtual. +# pip install poetry +# poetry new myproject +# cd myproject +# poetry add requests +# poetry install +# 23. Usa conda para crear un entorno virtual y gestionar dependencias.q + diff --git a/Intermediate/09.logging.py b/Intermediate/09.logging.py new file mode 100644 index 00000000..640eecca --- /dev/null +++ b/Intermediate/09.logging.py @@ -0,0 +1,178 @@ +import logging + +logging.basicConfig(filename="sample_log.txt", level=logging.WARNING) +print("Logging started") +logging.debug("Debug Information") +logging.info("info Information") +logging.warning("warning Information") +logging.error("error Information") +logging.critical("critical Information") +print("Logging end") + +import logging + +logging.basicConfig(filename="sample_log2.txt", level=logging.DEBUG) +print("Logging started") +logging.debug("Debug Information") +logging.info("info Information") +logging.warning("warning Information") +logging.error("error Information") +logging.critical("critical Information") +print("Logging end") + +import logging + +logging.basicConfig() +print("Logging started") +logging.debug("Debug Information") +logging.info("info Information") +logging.warning("warning Information") +logging.error("error Information") +logging.critical("critical Information") +print("Logging end") + +import logging + +logging.basicConfig(format="%(levelname)s") +print("Logging started") +logging.debug("Debug Information") +logging.info("info Information") +logging.warning("warning Information") +logging.error("error Information") +logging.critical("critical Information") +print("Logging end") + +import logging + +logging.basicConfig(format="%(levelname)s:%(message)s") +print("Logging started") +logging.debug("Debug Information") +logging.info("info Information") +logging.warning("warning Information") +logging.error("error Information") +logging.critical("critical Information") +print("Logging end") + +import logging + +logging.basicConfig(format="%(asctime)s:%(levelname)s:%(message)s") +print("Logging started") +logging.debug("Debug Information") +logging.info("info Information") +logging.warning("warning Information") +logging.error("error Information") +logging.critical("critical Information") +print("Logging end") + +import logging + +logging.basicConfig( + format="%(asctime)s:%(levelname)s:%(message)s", datefmt="%d/%m/%Y %I:%M:%S %p" +) +print("Logging started") +logging.debug("Debug Information") +logging.info("info Information") +logging.warning("warning Information") +logging.error("error Information") +logging.critical("critical Information") +print("Logging end") + +import logging + +logging.basicConfig( + filename="demo.txt", + level=logging.INFO, + format="%(asctime)s:%(levelname)s:%(message)s", + datefmt="%d/%m/%Y%I:%M:%S %p", +) +logging.info("A new Request Came") +try: + x = int(input("Enter First Number:")) + y = int(input("Enter Second Number:")) + print("The Result:", x / y) +except ZeroDivisionError as msg: + print("Cannot divide with zero") + logging.exception(msg) +except ValueError as msg: + print("Please provide int values only") + logging.exception(msg) +logging.info("Request Processing Completed") + +# Customized Logging in Python +import logging + + +class LoggerDemoConsole: + def testLog(self): + logger = logging.getLogger("demologger") + logger.setLevel(logging.INFO) + consoleHandler = logging.StreamHandler() + consoleHandler.setLevel(logging.INFO) + formatter = logging.Formatter( + "%(asctime)s - %(name)s%(levelname)s: %(message)s", + datefmt="%m/%d/%Y %I:%M:%S%p", + ) + consoleHandler.setFormatter(formatter) + logger.addHandler(consoleHandler) + logger.debug("debug message") + logger.info("info message") + logger.warn("warn message") + logger.error("error message") + logger.critical("critical message") + + +demo = LoggerDemoConsole() +demo.testLog() + +import logging + + +class LoggerDemoConsole: + def testLog(self): + # logger = logging.getLogger('demologger') + logger = logging.getLogger(LoggerDemoConsole.__name__) + logger.setLevel(logging.INFO) + consoleHandler = logging.StreamHandler() + consoleHandler.setLevel(logging.INFO) + formatter = logging.Formatter( + "%(asctime)s - %(name)s%(levelname)s: %(message)s", + datefmt="%m/%d/%Y %I:%M:%S%p", + ) + consoleHandler.setFormatter(formatter) + logger.addHandler(consoleHandler) + logger.debug("debug message") + logger.info("info message") + logger.warn("warn message") + logger.error("error message") + logger.critical("critical message") + + +demo = LoggerDemoConsole() +demo.testLog() + +import logging + + +class LoggerDemoConsole: + def testLog(self): + # logger = logging.getLogger('demologger') + logger = logging.getLogger(LoggerDemoConsole.__name__) + logger.setLevel(logging.INFO) + fileHandler = logging.FileHandler("demo.log", mode="a") + fileHandler.setLevel(logging.INFO) + formatter = logging.Formatter( + "%(asctime)s - %(name)s%(levelname)s: %(message)s", + datefmt="%m/%d/%Y %I:%M:%S%p", + ) + fileHandler.setFormatter(formatter) + logger.addHandler(fileHandler) + logger.debug("debug message") + logger.info("info message") + logger.warn("warn message") + logger.error("error message") + logger.critical("critical message") + + +demo = LoggerDemoConsole() +demo.testLog() +print("Done") diff --git a/Intermediate/10.multithreading.py b/Intermediate/10.multithreading.py new file mode 100644 index 00000000..e2e00213 --- /dev/null +++ b/Intermediate/10.multithreading.py @@ -0,0 +1,542 @@ +import threading + +print("Current Executing Thread:", threading.current_thread().getName()) + +from threading import * + + +def display(): + for i in range(6): + print("Child Thread") + + +t = Thread(target=display) +t.start() +for i in range(6): + print("Main Thread") + +from threading import * + + +class Demo: + def display(self): + for i in range(6): + print("Child Thread") + + +obj = Demo() +t = Thread(target=obj.display) +t.start() +for i in range(6): + print("Main Thread") + +from threading import * + + +class MyThread(Thread): + def run(self): + for i in range(6): + print("Child Thread") + + +t = MyThread() +t.start() +for i in range(6): + print("Main Thread") + +from threading import * +import time + + +def divison(numbers): + for n in numbers: + time.sleep(1) + print("Double:", n / 5) + + +def multiplication(numbers): + for n in numbers: + time.sleep(1) + print("Square:", n * 5) + + +numbers = [10, 20, 30, 40, 50] +begintime = time.time() +divison(numbers) +multiplication(numbers) +print("The total time taken:", time.time() - begintime) + +from threading import * +import time + + +def divison(numbers): + for n in numbers: + time.sleep(1) + print("Double:", n / 5) + + +def multiplication(numbers): + for n in numbers: + time.sleep(1) + print("Square:", n * 5) + + +numbers = [10, 20, 30, 40, 50] +begintime = time.time() +t1 = Thread(target=divison, args=(numbers,)) +t2 = Thread(target=multiplication, args=(numbers,)) +t1.start() +t2.start() +t1.join() +t2.join() + +print("The total time taken:", time.time() - begintime) + +from threading import * + +print("Main thread name", current_thread().getName()) +current_thread().setName("MyThread") + +print("After customise the thread name: ", current_thread().getName()) + +from threading import * + + +def m(): + print("Child Thread") + + +t = Thread(target=m) +t.start() +print("Main Thread Identification Number:", current_thread().ident) +print("Child Thread Identification Number:", t.ident) + +# Metodos +# active_count() method: + +from threading import * +import time + + +def display(): + print(current_thread().getName(), "...started") + time.sleep(3) + print(current_thread().getName(), "...ended") + + +print("The Number of active Threads:", active_count()) +t1 = Thread(target=display, name="ChildThread1") +t2 = Thread(target=display, name="ChildThread2") +t3 = Thread(target=display, name="ChildThread3") +t1.start() +t2.start() +t3.start() +print("The Number of active Threads:", active_count()) +time.sleep(5) +print("The Number of active Threads:", active_count()) + +# enumerate() function: + +from threading import * +import time + + +def display(): + print(current_thread().getName(), "...started") + time.sleep(3) + print(current_thread().getName(), "...ended") + + +t1 = Thread(target=display, name="ChildThread1") +t2 = Thread(target=display, name="ChildThread2") +t3 = Thread(target=display, name="ChildThread3") +t1.start() +t2.start() +t3.start() +l = enumerate() +for t in l: + print("Thread Name:", t.name) +time.sleep(5) +l = enumerate() +for t in l: + print("Thread Name:", t.name) + +# isAlive() method: + +from threading import * +import time + + +def display(): + print(current_thread().getName(), "...started") + time.sleep(3) + print(current_thread().getName(), "...ended") + + +print("The Number of active Threads:", active_count()) +t1 = Thread(target=display, name="ChildThread1") +t2 = Thread(target=display, name="ChildThread2") +t1.start() +t2.start() +print(t1.name, "is Alive :", t1.isAlive()) +print(t2.name, "is Alive :", t2.isAlive()) +time.sleep(5) +print(t1.name, "is Alive :", t1.isAlive()) +print(t2.name, "is Alive :", t2.isAlive()) + +# join() method: + +from threading import * +import time + + +def display(): + for i in range(5): + print("First Thread") + + +t = Thread(target=display, name="ChildThread") +t.start() +t.join() # This is executed by Main Thread +for i in range(5): + print("Second Thread") + + +# join(seconds) method: + +from threading import * +import time + + +def display(): + for i in range(5): + print("First Thread") + time.sleep(2) + + +t = Thread(target=display, name="ChildThread") +t.start() +t.join(5) # This is executed by Main Thread +for i in range(5): + print("Second Thread") + +# Daemon Threads in Python with Examples +from threading import * + +print(current_thread().isDaemon()) +print(current_thread().daemon) + +from threading import * + + +def display(): + print("Child Thread") + + +t = Thread(target=display) +t.start() +t.setDaemon(True) + +from threading import * +import time + + +def display(): + for i in range(5): + print("Child Thread") + time.sleep(2) + + +t = Thread(target=display) +# t.setDaemon(True) +t.start() +time.sleep(5) +print("End Of Main Thread") + +from threading import * +import time + + +def display(): + for i in range(5): + print("Child Thread") + time.sleep(2) + + +t = Thread(target=display) +t.setDaemon(True) +t.start() +time.sleep(5) +print("End Of Main Thread") + +# Synchronization in Python with Examples +from threading import * +import time + + +def wish(name, age): + for i in range(3): + print("Hi", name) + time.sleep(2) + print("Your age is", age) + + +t1 = Thread(target=wish, args=("Sireesh", 15)) +t2 = Thread(target=wish, args=("Nitya", 20)) +t1.start() +t2.start() + + +from threading import * + +l = Lock() +l.acquire() +print("lock acquired") +l.release() +print("lock released") + + +from threading import * + +l = Lock() +l.release() +print("lock released") + + +from threading import * +import time + +l = Lock() + + +def wish(name, age): + for i in range(3): + l.acquire() + print("Hi", name) + time.sleep(2) + print("Your age is", age) + l.release() + + +t1 = Thread(target=wish, args=("Sireesh", 15)) +t2 = Thread(target=wish, args=("Nitya", 20)) +t1.start() +t2.start() + + +from threading import * +import time + +l = RLock() + + +def factorial(n): + l.acquire() + if n == 0: + result = 1 + else: + result = n * factorial(n - 1) + l.release() + return result + + +def results(n): + print("The Factorial of", n, "is:", factorial(n)) + + +t1 = Thread(target=results, args=(5,)) +t2 = Thread(target=results, args=(9,)) +t1.start() +t2.start() + + +from threading import * +import time + +s = Semaphore(2) + + +def wish(name, age): + for i in range(3): + s.acquire() + print("Hi", name) + time.sleep(2) + s.release() + + +t1 = Thread(target=wish, args=("Sireesh", 15)) +t2 = Thread(target=wish, args=("Nitya", 20)) +t3 = Thread(target=wish, args=("Shiva", 16)) +t4 = Thread(target=wish, args=("Ajay", 25)) +t1.start() +t2.start() +t3.start() +t4.start() + + +from threading import * + +s = Semaphore(2) +s.acquire() +s.acquire() +s.release() +s.release() +s.release() +s.release() +print("End") + + +from threading import * + +s = BoundedSemaphore(2) +s.acquire() +s.acquire() +s.release() +s.release() +s.release() +s.release() +print("End") + +# Inter Thread communication in Python +from threading import * +import time + + +def traffic_police(): + while True: + time.sleep(5) + print("Traffic Police Giving GREEN Signal") + event.set() + time.sleep(10) + print("Traffic Police Giving RED Signal") + event.clear() + + +def driver(): + num = 0 + while True: + print("Drivers waiting for GREEN Signal") + event.wait() + print("Traffic Signal is GREEN...Vehicles can move") + while event.isSet(): + num = num + 1 + print("Vehicle No:", num, " Crossing the Signal") + time.sleep(2) + print("Traffic Signal is RED...Drivers have to wait") + + +event = Event() +t1 = Thread(target=traffic_police) +t2 = Thread(target=driver) +t1.start() +t2.start() + + +from threading import * +import time +import random + +items = [] + + +def produce(c): + while True: + c.acquire() # Step 1.1 + item = random.randint(1, 10) # Step 1.2 + print("Producer Producing Item:", item) + items.append(item) # Step 1.3 + print("Producer giving Notification") + c.notify() # Step 1.4 + c.release() # Step 1.5 + time.sleep(5) + + +def consume(c): + while True: + c.acquire() # Step 2.1 + print("Consumer waiting for update") + c.wait() # Step 2.2 + print("Consumer consumed the item", items.pop()) # Step 2.3 + c.release() # Step 2.4 + time.sleep(5) + + +c = Condition() +t1 = Thread(target=consume, args=(c,)) +t2 = Thread(target=produce, args=(c,)) +t1.start() +t2.start() + + +from threading import * +import time +import random +import queue + +items = [] + + +def produce(c): + while True: + item = random.randint(1, 10) # Step 1.2 + print("Producer Producing Item:", item) + q.put(item) + print("Producer giving Notification") + time.sleep(5) + + +def consume(c): + while True: + print("Consumer waiting for update") + print("Consumer consumed the item", q.get()) + time.sleep(5) + + +q = queue.Queue() +t1 = Thread(target=consume, args=(q,)) +t2 = Thread(target=produce, args=(q,)) +t1.start() +t2.start() + + +import queue + +q = queue.Queue() +q.put(10) +q.put(5) +q.put(20) +q.put(15) +while not q.empty(): + print(q.get()) + +import queue + +q = queue.LifoQueue() +q.put(10) +q.put(5) +q.put(20) +q.put(15) +while not q.empty(): + print(q.get()) + +import queue + +q = queue.PriorityQueue() +q.put(10) +q.put(5) +q.put(20) +q.put(15) +while not q.empty(): + print(q.get()) + + +import queue + +q = queue.PriorityQueue() +q.put((1, "Ruhan")) +q.put((3, "Sharuk")) +q.put((4, "Ajay")) +q.put((2, "Siva")) +while not q.empty(): + print(q.get()[1]) diff --git a/Intermediate/11.database_connectivity.py b/Intermediate/11.database_connectivity.py new file mode 100644 index 00000000..eb070bf1 --- /dev/null +++ b/Intermediate/11.database_connectivity.py @@ -0,0 +1,203 @@ +# Oracle + +import cx_Oracle + +try: + con = cx_Oracle.connect("system/root@localhost") + cursor = con.cursor() + cursor.execute( + "create table employees(eno number, ename varchar2(10),esal number(10,2),eaddr varchar2(10))" + ) + print("Table created successfully") +except cx_Oracle.DatabaseError as e: + if con: + con.rollback() + print(e) +finally: + if cursor: + cursor.close() + if con: + con.close() + +import cx_Oracle + +try: + con = cx_Oracle.connect("system/root@localhost") + cursor = con.cursor() + cursor.execute("insert into employees values(100,'Durga',1000,'Hyd')") + con.commit() + print("Record Inserted Successfully") +except cx_Oracle.DatabaseError as e: + if con: + con.rollback() + print(e) +finally: + if cursor: + cursor.close() + if con: + con.close() + +import cx_Oracle + +try: + con = cx_Oracle.connect("system/root@localhost") + cursor = con.cursor() + cursor.execute("insert into employees values(2,'Prasad',20000,'Banglore')") + con.commit() + print("Record Inserted Successfully") +except cx_Oracle.DatabaseError as e: + if con: + con.rollback() + print(e) +finally: + if cursor: + cursor.close() + if con: + con.close() + +import cx_Oracle + +try: + con = cx_Oracle.connect("system/root@localhost") + cursor = con.cursor() + sql = "insert into employees values(:eno, :ename, :esal, :eaddr)" + records = [ + (3, "Hari", 30000, "Mumbai"), + (4, "Hema", 40000, "BZA"), + (5, "Mohan", 50000, "Banglore"), + ] + cursor.executemany(sql, records) + con.commit() + print("Record Inserted Successfully") +except cx_Oracle.DatabaseError as e: + if con: + con.rollback() + print(e) +finally: + if cursor: + cursor.close() + if con: + con.close() + +import cx_Oracle + +try: + con = cx_Oracle.connect("system/root@localhost") + cursor = con.cursor() + while True: + eno = int(input("Enter Employee Number:")) + ename = input("Enter Employee Name:") + esal = float(input("Enter Employee Salary:")) + eaddr = input("Enter Employee Address:") + sql = "insert into employees values(%d, '%s', %f, '%s')" + cursor.execute(sql % (eno, ename, esal, eaddr)) + print("Record Inserted Successfully") + option = input("Do you want to insert one more record[Yes| No] :") + if option == "No": + con.commit() + break +except cx_Oracle.DatabaseError as e: + if con: + con.rollback() + print(e) +finally: + if cursor: + cursor.close() + if con: + con.close() + + +import cx_Oracle + +try: + con = cx_Oracle.connect("system/root@localhost") + cursor = con.cursor() + increment = float(input("How much amount need to Increment:")) + salrange = float(input("Enter Salary Range:")) + sql = "update employees set esal=esal+%f where esal<%f" + cursor.execute(sql % (increment, salrange)) + print("Records Updated Successfully") + con.commit() +except cx_Oracle.DatabaseError as e: + if con: + con.rollback() + print(e) +finally: + if cursor: + cursor.close() + if con: + con.close() + +import cx_Oracle +try: + con=cx_Oracle.connect('system/root@localhost') + cursor=con.cursor() + cursor.execute("select * from employees") + row=cursor.fetchone() + while row is not None: + print(row) + row=cursor.fetchone() +except cx_Oracle.DatabaseError as e: + if con: + con.rollback() + print(e) +finally: + if cursor: + cursor.close() + if con: + con.close() + +import cx_Oracle +try: + con=cx_Oracle.connect('system/root@localhost') + cursor=con.cursor() + cursor.execute("select * from employees") + n=int(input("Enter the number of required rows:")) + data=cursor.fetchmany(n) + for row in data: + print(row) +except cx_Oracle.DatabaseError as e: + if con: + con.rollback() + print(e) +finally: + if cursor: + cursor.close() + if con: + con.close() + +import cx_Oracle +try: + con=cx_Oracle.connect('system/root@localhost') + cursor=con.cursor() + cursor.execute("select * from employees") + data=cursor.fetchall() + print(data) +except cx_Oracle.DatabaseError as e: + if con: + con.rollback() + print(e) +finally: + if cursor: + cursor.close() + if con: + con.close() + +import cx_Oracle +try: + con=cx_Oracle.connect('system/root@localhost') + cursor=con.cursor() + cursor.execute("select * from employees") + data=cursor.fetchall() + print(data[0][0]) + print(data[0][1]) +except cx_Oracle.DatabaseError as e: + if con: + con.rollback() + print(e) +finally: + if cursor: + cursor.close() + if con: + con.close() + diff --git a/Intermediate/fer.csv b/Intermediate/fer.csv new file mode 100644 index 00000000..3ef1edec --- /dev/null +++ b/Intermediate/fer.csv @@ -0,0 +1,3 @@ +name,surname,age,language,website +Brais,Moure,35,Python,https://moure.dev +Roswell,,2,COBOL, diff --git a/Intermediate/fer.json b/Intermediate/fer.json new file mode 100644 index 00000000..dec5a3cc --- /dev/null +++ b/Intermediate/fer.json @@ -0,0 +1,11 @@ +{ + "name": "Brais", + "surname": "Moure", + "age": 35, + "languages": [ + "Python", + "Swift", + "Kotlin" + ], + "website": "https://moure.dev" +} \ No newline at end of file diff --git a/Intermediate/fer.txt b/Intermediate/fer.txt new file mode 100644 index 00000000..492824e2 --- /dev/null +++ b/Intermediate/fer.txt @@ -0,0 +1 @@ +Texto escrito con funcin \ No newline at end of file diff --git a/Intermediate/fer.xml b/Intermediate/fer.xml new file mode 100644 index 00000000..f8251cf0 --- /dev/null +++ b/Intermediate/fer.xml @@ -0,0 +1,6 @@ + + + Brais + Moure + 35 + \ No newline at end of file diff --git a/Intermediate/my_file.csv b/Intermediate/my_file.csv index eeb0e38e..3ef1edec 100644 --- a/Intermediate/my_file.csv +++ b/Intermediate/my_file.csv @@ -1,3 +1,3 @@ -name,surname,age,language,website -Brais,Moure,35,Python,https://moure.dev -Roswell,,2,COBOL, +name,surname,age,language,website +Brais,Moure,35,Python,https://moure.dev +Roswell,,2,COBOL, diff --git a/Intermediate/my_file.txt b/Intermediate/my_file.txt index e8fb1103..e4e0aff7 100644 --- a/Intermediate/my_file.txt +++ b/Intermediate/my_file.txt @@ -1,6 +1,6 @@ Mi nombre es Brais Mi apellido es Moure -35 años +35 aos Y mi lenguaje preferido es Python -Aunque también me gusta Kotlin +Aunque tambin me gusta Kotlin Y Swift \ No newline at end of file diff --git a/Logic/01.Sintaxis.py b/Logic/01.Sintaxis.py new file mode 100644 index 00000000..05f7b1ca --- /dev/null +++ b/Logic/01.Sintaxis.py @@ -0,0 +1,36 @@ +# https://python.org + +# Comentario en una línea + +""" +Comentario en +varias líneas +""" + +''' +Otro forma +de comentario en +varias líneas +''' + +my_variable = "Hola Mundo" +my_entero = 5 +my_decimal = 1.5 +my_complejo = 3 + 1j +my_booleano = True +my_texto = "Mi cadena de texto" +my_array = [1, 2, 3, 4, 5] +my_object = { + "key": "value", + "key2": "value2" +} +my_function = print + +#Por convención las constantes se escriben en mayúsculas +#Pero realmente no existen como tal, son mutables. +MY_CONSTANT = "Mi constante" +print(MY_CONSTANT) + +print(type(my_variable)) +print("Hola Python") +print('Hola Python') \ No newline at end of file diff --git a/Logic/02.OperadoresYEstructurasControl.py b/Logic/02.OperadoresYEstructurasControl.py new file mode 100644 index 00000000..9b78d7cf --- /dev/null +++ b/Logic/02.OperadoresYEstructurasControl.py @@ -0,0 +1,12 @@ +# Ejercicio Operadores + Estrucuturas de Control + +my_number = 10 + +while my_number < 56: + if (my_number % 2 == 0) and (my_number != 16) and (my_number % 3 != 0): + print(my_number) + my_number += 1 + +for number in range(10, 56): + if number % 2 == 0 and number != 16 and number % 3 != 0: + print(number) \ No newline at end of file diff --git a/Logic/03.Funciones.py b/Logic/03.Funciones.py new file mode 100644 index 00000000..11700196 --- /dev/null +++ b/Logic/03.Funciones.py @@ -0,0 +1,26 @@ +def imprimir_numeros(texto1, texto2) -> int: + num_veces = 0; + texto_devolver = texto1 + texto2; + for number in range(1, 101): + texto_devolver = validar_numero(number, texto1, texto2); + if texto_devolver != "": + print(texto_devolver); + num_veces+=1; + return num_veces; + +def validar_numero(num, texto1, texto2): + texto_devolver = ""; + es_multiplo_3 = num % 3 == 0; + es_multiplo_5 = num % 5 == 0; + + if es_multiplo_3: + texto_devolver = texto1; + if es_multiplo_5: + texto_devolver = texto2; + if es_multiplo_3 and es_multiplo_5: + texto_devolver = texto1 + " " + texto2; + return texto_devolver; + + +print(f"Se han impreso {imprimir_numeros("Fizz", "Buzz")} veces los textos"); + diff --git a/Logic/04.EstructurasDatos.py b/Logic/04.EstructurasDatos.py new file mode 100644 index 00000000..e05817f9 --- /dev/null +++ b/Logic/04.EstructurasDatos.py @@ -0,0 +1,63 @@ +# Este es un ejemplo de una agenda simple, donde se pueden añadir, modificar, buscar y eliminar contactos. + +def mi_agenda(): + + agenda = {} # Esta es la agenda como tal + def up_numero(): # Esta es la funcion para añadir/modificar un contacto + numero = input("Introduce numero de contacto:") + if numero.isdigit() and len(numero) > 0 and len(numero) <= 10: + agenda[name] = numero + print("Contacto añadido.") + else: + print("Solo se aceptan numeros de hasta 10 digitos.") + + while True: # De esta manera se mantiene la funcion en bucle + + # Se inicia imprimiendo el menu + + print("") + print("1 - Buscar contacto") + print("2 - Agregar Contacto") + print("3 - Actualizar contacto") + print("4 - Eliminar contactos") + print("5 - Salir") + print("6 - Ver agenda") + + option = input("Elige la opcion deseada:") # Input se utiliza para poder interactuar con terminal + + match option: # Se puede usar if, elif y else, pero en python existe match + case "1": + name = input("Introduce el nombre de contacto:") + if name in agenda: + print( + f"El numero de {name} es {agenda[name]}") + else: + print(f"El nombre {name} no existe en la agenda.") + case "2": + name = input("Introduce nombre de contacto:") + up_numero() + case "3": + name = input("Introduce el nombre de contacto que desea actualizar:") + if name in agenda: + up_numero() + else: + print(f"El nombre {name} no existe en la agenda.") + + case "4": + name = input("Introduce el nombre de contacto que desea eliminar:") + if name in agenda: + del agenda[name] + print("El contacto se ha borrado.") + else: + print(f"El nombre {name} no existe en la agenda.") + case "5": + print("Saliendo") + break + case "6": + print(agenda) + case _: + print("Opcion invalida. Elige del 1 al 6") + + +mi_agenda() + diff --git a/Logic/05.Cadenas.py b/Logic/05.Cadenas.py new file mode 100644 index 00000000..bacc4c5c --- /dev/null +++ b/Logic/05.Cadenas.py @@ -0,0 +1,48 @@ +#función palindromo +def palindromo (cadena1, cadena2) -> str: + if cadena1.upper() == cadena2.upper()[::-1]: + return "Es un palindromo" + return "No es un palindromo" + +print(palindromo("oso", "perro")) +print(palindromo("oso", "oso")) + +#función anagrama +def anagrama (cadena1, cadena2) -> str: + if sorted(cadena1.upper()) == sorted(cadena2.upper()): + return "Es un anagrama" + return "No es un anagrama" +print(anagrama("pozo", "oso")) +print(anagrama("pozo", "zopo")) + +#función isograma +def isograma (cadena) -> str: + cadena_sin_espacios = cadena.replace(" ", "") + cadena_sin_repetidos = "".join(set(cadena_sin_espacios)) + if cadena_sin_espacios == cadena_sin_repetidos: + return "Es un isograma" + return "No es un isograma" + +print(isograma("oso")) +print(isograma("murcielago")) + +# Unificada + +def check (word: str, word2: str) -> str: + #palindromo + print(f"¿{word} es un palindromo? {word.upper() == word2.upper()[::-1]}") + + #anagrama + print(f"¿{word} es un anagrama de {word2}? {sorted(word.upper()) == sorted(word2.upper())}") + + #isograma + word_sin_espacios = word.replace(" ", "") + word_sin_repetidos = "".join(set(word_sin_espacios)) + print(f"¿{word} es un isograma? {word_sin_espacios == word_sin_repetidos}") + +check("oso", "oso") +check("oso", "perro") +check("pozo", "oso") +check("pozo", "zopo") +check("oso", "oso") +check("murcielago", "murcielago") diff --git a/Logic/06.ValoryReferencia.py b/Logic/06.ValoryReferencia.py new file mode 100644 index 00000000..21116958 --- /dev/null +++ b/Logic/06.ValoryReferencia.py @@ -0,0 +1,30 @@ +valor1 = 3 +valor2 = 5 + +def programValor(paramValor1: int, paramValor2:int): + tempValor = paramValor2 + paramValor2 = paramValor1 + paramValor1 = tempValor + +print("Programa por Valor:") +print(f"valor1 {valor1}, valor2 {valor2}") +programValor(valor1,valor2) +print(f"valor1 {valor1}, valor2 {valor2}") + +valorRef1 = [3] +valorRef2 = [5] + + +def programReferencia(paramValor1: list, paramValor2:list): + tempValor = paramValor2 + paramValor2 = paramValor1 + paramValor1 = tempValor + paramValor1.append(10) + paramValor2.append(20) + + +print("Programa por Referencia:") +print(f"valor1 {valorRef1}, valor2 {valorRef2}") +programReferencia(valorRef1, valorRef2) +print(f"valor1 {valorRef1}, valor2 {valorRef2}") + diff --git a/Logic/07.Recursividad.py b/Logic/07.Recursividad.py new file mode 100644 index 00000000..4fdcdf12 --- /dev/null +++ b/Logic/07.Recursividad.py @@ -0,0 +1,21 @@ +# Función que calcula el factorial de un número +def factorial(number:int) -> int: + if number == 0: + return 1 + else: + return number * factorial(number-1) + +print(factorial(5)) + +# Funcion que calcula el valor de un elemento concreto (según su posición) en la sucesión de Fibonacci +def fibonacci(number:int) -> int: + if number == 0: + return 0 + elif number == 1: + return 1 + else: + return fibonacci(number-1) + fibonacci(number-2) + +print(fibonacci(5)) + + \ No newline at end of file diff --git a/Logic/08.PilasYColas.py b/Logic/08.PilasYColas.py new file mode 100644 index 00000000..ee46f630 --- /dev/null +++ b/Logic/08.PilasYColas.py @@ -0,0 +1,131 @@ +# Utilizando una pila y cadenas de texto, simula el mecanismo adelante/atrás de un navegador web. Crea un programa en el que puedes navegar a una página o indicarle que te quieresdesplazar aledante o atrás, mostrando en cada caso el nombre de la web +# Las palabras "adelante", "atras" desencadena esta acción, el resto se interpreta como el nombre de una nueva web. + +# Importamos la librería de pilas +from collections import deque + +# Creamos una pila vacía +pila = deque() + +# Creamos una variable para almacenar la página actual + +pagina_actual = "" +# Creamos un bucle infinito +while True: + # Pedimos al usuario que introduzca un comando + comando = input("Introduce un comando: ") + # Si el comando es "atras" + if comando == "atras": + # Si la pila no está vacía + if len(pila) > 0: + # Sacamos el último elemento de la pila + pagina_actual = pila.pop() + # Mostramos la página actual + print("Página actual:", pagina_actual) + # Si la pila está vacía + else: + # Mostramos un mensaje de error + print("No hay páginas para retroceder") + # Si el comando es "adelante" + elif comando == "adelante": + # Si la página actual no está vacía + if pagina_actual != "": + # Añadimos la página actual a la pila + pila.append(pagina_actual) + # Mostramos un mensaje de error + print("No hay páginas para avanzar") + # Si el comando no es "atras" ni "adelante" + else: + # Si la página actual no está vacía + if pagina_actual != "": + # Añadimos la página actual a la pila + pila.append(pagina_actual) + # Actualizamos la página actual con el comando introducido + pagina_actual = comando + # Mostramos la página actual + print("Página actual:", pagina_actual) + +# Ejecuta el programa y prueba a navegar entre diferentes páginas web utilizando los comandos "adelante" y "atras". +# Introduce el nombre de una página web para navegar a ella. +# Por ejemplo, puedes probar a introducir los siguientes comandos: +# google.com +# youtube.com +# facebook.com + +# ¿Qué ocurre si introduces el comando "adelante" cuando no hay ninguna página actual? +# ¿Qué ocurre si introduces el comando "atras" cuando no hay ninguna página en la pila? +# ¿Qué ocurre si introduces el comando "atras" después de haber introducido una página web? + +# Respuestas: +# Si introduces el comando "adelante" cuando no hay ninguna página actual, el programa mostrará el mensaje "No hay páginas para avanzar". +# Si introduces el comando "atras" cuando no hay ninguna página en la pila, el programa mostrará el mensaje "No hay páginas para retroceder". +# Si introduces el comando "atras" después de haber introducido una página web, la página actual se moverá a la pila y se mostrará la página anterior. + + +# Utilizando colas y cadenas de texto, simula el mecanismo de una cola de impresión. Crea un programa en el que puedes añadir trabajos a la cola, mostrar el trabajo que se está imprimiendo y eliminar el trabajo que se ha impreso. +# Las palabras "imprimir", "siguiente" y "eliminar" desencadenan estas acciones, el resto se interpreta como un trabajo a añadir a la cola. + +# Importamos la librería de colas +from collections import deque + +# Creamos una cola vacía +cola = deque() + +# Creamos un bucle infinito +while True: + # Pedimos al usuario que introduzca un comando + comando = input("Introduce un comando: ") + # Si el comando es "imprimir" + if comando == "imprimir": + # Si la cola no está vacía + if len(cola) > 0: + # Sacamos el primer + trabajo = cola.popleft() + # Mostramos el trabajo que se está imprimiendo + print("Imprimiendo:", trabajo) + # Si la cola está vacía + else: + # Mostramos un mensaje de error + print("No hay trabajos para imprimir") + # Si el comando es "siguiente" + elif comando == "siguiente": + # Si la cola no está vacía + if len(cola) > 0: + # Mostramos el siguiente trabajo a imprimir + print("Siguiente trabajo:", cola[0]) + # Si la cola está vacía + else: + # Mostramos un mensaje de error + print("No hay trabajos para imprimir") + # Si el comando es "eliminar" + elif comando == "eliminar": + # Si la cola no está vacía + if len(cola) > 0: + # Sacamos el primer trabajo de la cola + trabajo = cola.popleft() + # Mostramos un mensaje de éxito + print("Trabajo eliminado:", trabajo) + # Si la cola está vacía + else: + # Mostramos un mensaje de error + print("No hay trabajos para eliminar") + # Si el comando no es "imprimir", "siguiente" ni "eliminar" + else: + # Añadimos el trabajo a la cola + cola.append(comando) + # Mostramos un mensaje de éxito + print("Trabajo añadido a la cola:", comando) + +# Ejecuta el programa y prueba a añadir trabajos a la cola de impresión utilizando el comando "imprimir". +# Utiliza el comando "siguiente" para ver cuál es el siguiente trabajo a imprimir. +# Utiliza el comando "eliminar" para eliminar el trabajo que se ha impreso. +# Por ejemplo, puedes probar a introducir los siguientes comandos: + +# imprimir +# siguiente +# eliminar +# imprimir +# siguiente + + + diff --git a/Logic/09.Clases.py b/Logic/09.Clases.py new file mode 100644 index 00000000..3283326a --- /dev/null +++ b/Logic/09.Clases.py @@ -0,0 +1,76 @@ +# Implementa dos clases que representen las estructuras de Pila y Cola. Deben poder inicializarse y disponer de operaciones para añadir, eliminar, retornar el número de elementos e imprimir todo su contenido + +class Pila: + def __init__(self): + self.items = [] + + def esta_vacia(self): + return len(self.items) == 0 + + def apilar(self, item): + self.items.append(item) + + def desapilar(self): + if not self.esta_vacia(): + return self.items.pop() + else: + return None + + def tamano(self): + return len(self.items) + + def imprimir(self): + print(self.items) + + +class Cola: + def __init__(self): + self.items = [] + + def esta_vacia(self): + return len(self.items) == 0 + + def encolar(self, item): + self.items.insert(0, item) + + def desencolar(self): + if not self.esta_vacia(): + return self.items.pop() + else: + return None + + def tamano(self): + return len(self.items) + + def imprimir(self): + print(self.items) + +# Ejemplo de uso de la clase Pila +pila = Pila() +pila.apilar(1) +pila.apilar(2) +pila.apilar(3) +print("Contenido de la pila después de apilar 1, 2, 3:") +pila.imprimir() + +print("Elemento desapilado:", pila.desapilar()) +print("Contenido de la pila después de desapilar:") +pila.imprimir() + +print("Tamaño de la pila:", pila.tamano()) +print("¿La pila está vacía?", pila.esta_vacia()) + +# Ejemplo de uso de la clase Cola +cola = Cola() +cola.encolar(1) +cola.encolar(2) +cola.encolar(3) +print("Contenido de la cola después de encolar 1, 2, 3:") +cola.imprimir() + +print("Elemento desencolado:", cola.desencolar()) +print("Contenido de la cola después de desencolar:") +cola.imprimir() + +print("Tamaño de la cola:", cola.tamano()) +print("¿La cola está vacía?", cola.esta_vacia()) diff --git a/Logic/10.Herencia.py b/Logic/10.Herencia.py new file mode 100644 index 00000000..31904238 --- /dev/null +++ b/Logic/10.Herencia.py @@ -0,0 +1,62 @@ +# Implementa la jerarquia de una empresa de desarrollo formada por Empleados que pueden ser Gerentes, Gerentes de Proyectos o Programadores. +# Cada empleado tiene un identificador y un nombre +# Dependiendo de su labor, tienen propiedades y funciones exclusivas de su actividad, y almacenan los empleados a su cargo + +class Empleado: + def __init__(self, id, nombre): + self.id = id + self.nombre = nombre + + def mostrar_informacion(self): + print(f"ID: {self.id}, Nombre: {self.nombre}") + + +class Gerente(Empleado): + def __init__(self, id, nombre): + super().__init__(id, nombre) + self.empleados_a_cargo = [] + + def agregar_empleado(self, empleado): + self.empleados_a_cargo.append(empleado) + + def mostrar_empleados_a_cargo(self): + print(f"Empleados a cargo de {self.nombre}:") + for empleado in self.empleados_a_cargo: + empleado.mostrar_informacion() + + +class GerenteDeProyectos(Gerente): + def __init__(self, id, nombre, proyecto): + super().__init__(id, nombre) + self.proyecto = proyecto + + def mostrar_informacion(self): + super().mostrar_informacion() + print(f"Proyecto: {self.proyecto}") + + +class Programador(Empleado): + def __init__(self, id, nombre, lenguaje): + super().__init__(id, nombre) + self.lenguaje = lenguaje + + def mostrar_informacion(self): + super().mostrar_informacion() + print(f"Lenguaje de programación: {self.lenguaje}") + + +# Ejemplo de uso +gerente = Gerente(1, "Carlos") +programador1 = Programador(2, "Ana", "Python") +programador2 = Programador(3, "Luis", "JavaScript") + +gerente.agregar_empleado(programador1) +gerente.agregar_empleado(programador2) + +gerente.mostrar_informacion() +gerente.mostrar_empleados_a_cargo() + +gerente_proyectos = GerenteDeProyectos(4, "Marta", "Proyecto X") +gerente_proyectos.agregar_empleado(gerente) +gerente_proyectos.mostrar_informacion() +gerente_proyectos.mostrar_empleados_a_cargo() diff --git a/Logic/11.Excepciones.py b/Logic/11.Excepciones.py new file mode 100644 index 00000000..d747c702 --- /dev/null +++ b/Logic/11.Excepciones.py @@ -0,0 +1,40 @@ + +# Crea una función que sea capaz de procesar parámetros, pero que también pueda lanzar 3 tipos diferentes de excepcions +# (una de ellas tiene que corresponderse con un tipo de excepción creada por nosotros de manera personalizada, +# y debe ser lanzada de manera manual) en caso de error. +# Captura todas las excepciones desde el lugar donde llamas a la función. +# Imprime el tipo de error. +# Imprime si no se ha producido ningún error. +# Imprime que la ejecución ha finalizado. + +# 1. Definición de excepción personalizada +class CustomError(Exception): + def __init__(self, message): + super().__init__(message) + +# 2. Función que procesa parámetros +def procesar_parametro(param): + if not isinstance(param, int): + raise TypeError("El parámetro debe ser un entero") + elif param < 0: + raise ValueError("El parámetro no puede ser negativo") + elif param == 0: + raise CustomError("El parámetro no puede ser cero") # Excepción personalizada + return param * 2 + +# 3. Bloque de ejecución y manejo de excepciones +try: + resultado = procesar_parametro(0) # Prueba con diferentes valores + print(f"Resultado: {resultado}") +except CustomError as ce: + print(f"Error personalizado: {type(ce).__name__} - {ce}") +except TypeError as te: + print(f"Error de tipo: {type(te).__name__} - {te}") +except ValueError as ve: + print(f"Error de valor: {type(ve).__name__} - {ve}") +except Exception as e: + print(f"Error inesperado: {type(e).__name__} - {e}") +else: + print("No se produjeron errores") +finally: + print("Ejecución finalizada") diff --git a/Logic/12.Ficheros.py b/Logic/12.Ficheros.py new file mode 100644 index 00000000..bf80d57a --- /dev/null +++ b/Logic/12.Ficheros.py @@ -0,0 +1,113 @@ +import os + +ARCHIVO = 'ventas.txt' + +def cargar_ventas(): + try: + with open(ARCHIVO, 'r') as f: + ventas = [] + for linea in f: + nombre, cantidad, precio = linea.strip().split(',') + ventas.append({ + 'nombre': nombre.strip(), + 'cantidad': int(cantidad), + 'precio': float(precio) + }) + return ventas + except FileNotFoundError: + return [] + +def guardar_ventas(ventas): + with open(ARCHIVO, 'w') as f: + for p in ventas: + f.write(f"{p['nombre']}, {p['cantidad']}, {p['precio']}\n") + +def mostrar_menu(): + print('\n===== GESTIÓN DE VENTAS =====') + print('1. Añadir producto') + print('2. Consultar productos') + print('3. Actualizar producto') + print('4. Eliminar producto') + print('5. Total ventas') + print('6. Ventas por producto') + print('7. Salir') + +def añadir_producto(ventas): + nombre = input('Nombre del producto: ') + cantidad = int(input('Cantidad vendida: ')) + precio = float(input('Precio unitario: ')) + ventas.append({ + 'nombre': nombre, + 'cantidad': cantidad, + 'precio': precio + }) + guardar_ventas(ventas) + print('Producto añadido!') + +def listar_productos(ventas): + print('\n=== LISTADO DE PRODUCTOS ===') + for i, p in enumerate(ventas): + print(f"{i+1}. {p['nombre']} - {p['cantidad']} u. - ${p['precio']} c/u") + +def actualizar_producto(ventas): + listar_productos(ventas) + indice = int(input('Índice del producto a actualizar: ')) - 1 + if 0 <= indice < len(ventas): + p = ventas[indice] + p['cantidad'] = int(input(f"Nueva cantidad ({p['cantidad']}): ") or p['cantidad']) + p['precio'] = float(input(f"Nuevo precio ({p['precio']}): ") or p['precio']) + guardar_ventas(ventas) + print('Producto actualizado!') + else: + print('Índice inválido.') + +def eliminar_producto(ventas): + listar_productos(ventas) + indice = int(input('Índice del producto a eliminar: ')) - 1 + if 0 <= indice < len(ventas): + del ventas[indice] + guardar_ventas(ventas) + print('Producto eliminado!') + else: + print('Índice inválido.') + +def calcular_total(ventas): + total = sum(p['cantidad'] * p['precio'] for p in ventas) + print(f"\nTOTAL VENDIDO: ${total:.2f}") + +def ventas_por_producto(ventas): + nombre = input('Nombre del producto: ') + total = sum(p['cantidad'] * p['precio'] for p in ventas if p['nombre'].lower() == nombre.lower()) + print(f"TOTAL PARA {nombre}: ${total:.2f}") + +def salir(ventas): + if os.path.exists(ARCHIVO): + os.remove(ARCHIVO) + print('\nArchivo borrado. ¡Hasta luego!') + exit() + +def main(): + ventas = cargar_ventas() + while True: + mostrar_menu() + opcion = input('Seleccione opción: ') + + if opcion == '1': + añadir_producto(ventas) + elif opcion == '2': + listar_productos(ventas) + elif opcion == '3': + actualizar_producto(ventas) + elif opcion == '4': + eliminar_producto(ventas) + elif opcion == '5': + calcular_total(ventas) + elif opcion == '6': + ventas_por_producto(ventas) + elif opcion == '7': + salir(ventas) + else: + print('Opción inválida!') + +if __name__ == "__main__": + main() diff --git a/Logic/13.XML.py b/Logic/13.XML.py new file mode 100644 index 00000000..5733f9bd --- /dev/null +++ b/Logic/13.XML.py @@ -0,0 +1,116 @@ +# Desarrolla un programa capaz de crear un archivo XML que guarde los siguientes datos (sintaxis correcta en cada caso): +# Nombre, Edad, Fecha de nacimiento, Listado de lenguajes de programación +# Muestra el contenido del archivo +# Borra el archivo + +# Adicionalmente, utilizando la lógica del archivo anterior, crea un programa capaz de leer y transformar en una misma clase custom los datos alamecenados en el XML. + +import xml.etree.ElementTree as ET + +def crear_xml(data): + # Crear el elemento raíz + root = ET.Element('Persona') + + # Añadir subelementos + ET.SubElement(root, 'Nombre').text = data['Nombre'] + ET.SubElement(root, 'Edad').text = data['Edad'] + ET.SubElement(root, 'Fecha_de_nacimiento').text = data['Fecha_de_nacimiento'] + + lenguajes = ET.SubElement(root, 'Lenguajes_de_programacion') + for lenguaje in data['Lenguajes_de_programacion']: + ET.SubElement(lenguajes, 'Lenguaje').text = lenguaje + + # Crear el árbol y guardar en un archivo + tree = ET.ElementTree(root) + with open('persona.xml', 'wb') as file: + tree.write(file) + +def mostrar_contenido(): + with open('persona.xml', 'r') as file: + contenido = file.read() + return contenido + +def borrar_archivo(): + import os + if os.path.exists('persona.xml'): + os.remove('persona.xml') + return 'Archivo eliminado correctamente.' + else: + return 'El archivo no existe.' + +# Datos a guardar +data = { + 'Nombre': 'Juan Pérez', + 'Edad': '30', + 'Fecha_de_nacimiento': '1995-05-15', + 'Lenguajes_de_programacion': ['Python', 'Java', 'C++'] +} + +# Crear archivo XML +crear_xml(data) + +# Mostrar contenido +print("Contenido del archivo:") +print(mostrar_contenido()) + +# Borrar archivo +print("\nResultado al borrar el archivo:") +print(borrar_archivo()) + +import xml.etree.ElementTree as ET + +class Persona: + def __init__(self, nombre, edad, fecha_de_nacimiento, lenguajes): + self.nombre = nombre + self.edad = edad + self.fecha_de_nacimiento = fecha_de_nacimiento + self.lenguajes = lenguajes + + def __repr__(self): + return f"Persona(Nombre: {self.nombre}, Edad: {self.edad}, Fecha de nacimiento: {self.fecha_de_nacimiento}, Lenguajes: {self.lenguajes})" + +def leer_xml_y_transformar(): + # Crear nuevamente el archivo XML para leerlo + data = { + 'Nombre': 'Juan Pérez', + 'Edad': '30', + 'Fecha_de_nacimiento': '1995-05-15', + 'Lenguajes_de_programacion': ['Python', 'Java', 'C++'] + } + + root = ET.Element('Persona') + ET.SubElement(root, 'Nombre').text = data['Nombre'] + ET.SubElement(root, 'Edad').text = data['Edad'] + ET.SubElement(root, 'Fecha_de_nacimiento').text = data['Fecha_de_nacimiento'] + + lenguajes = ET.SubElement(root, 'Lenguajes_de_programacion') + for lenguaje in data['Lenguajes_de_programacion']: + ET.SubElement(lenguajes, 'Lenguaje').text = lenguaje + + tree = ET.ElementTree(root) + with open('persona.xml', 'wb') as file: + tree.write(file) + + # Leer el archivo XML + tree = ET.parse('persona.xml') + root = tree.getroot() + + # Extraer datos + nombre = root.find('Nombre').text + edad = root.find('Edad').text + fecha_de_nacimiento = root.find('Fecha_de_nacimiento').text + lenguajes = [lenguaje.text for lenguaje in root.find('Lenguajes_de_programacion')] + + # Transformar en una clase custom + persona = Persona(nombre, edad, fecha_de_nacimiento, lenguajes) + + # Borrar el archivo después de leerlo + import os + if os.path.exists('persona.xml'): + os.remove('persona.xml') + + return persona + +# Leer y transformar datos +print("\nDatos transformados en clase custom:") +print(leer_xml_y_transformar()) diff --git a/Logic/14.JSON.py b/Logic/14.JSON.py new file mode 100644 index 00000000..4498d990 --- /dev/null +++ b/Logic/14.JSON.py @@ -0,0 +1,91 @@ +# Desarrolla un programa capaz de crear un archivo JSON que guarde los siguientes datos (sintaxis correcta en cada caso): +# Nombre, Edad, Fecha de nacimiento, Listado de lenguajes de programación +# Muestra el contenido del archivo +# Borra el archivo + +# Adicionalmente, utilizando la lógica del archivo anterior, crea un programa capaz de leer y transformar en una misma clase custom los datos alamecenados en el XML. +import json + +def crear_json(data): + # Crear archivo JSON + with open('persona.json', 'w') as file: + json.dump(data, file, indent=4) + +def mostrar_contenido(): + with open('persona.json', 'r') as file: + contenido = file.read() + return contenido + +def borrar_archivo(): + import os + if os.path.exists('persona.json'): + os.remove('persona.json') + return 'Archivo eliminado correctamente.' + else: + return 'El archivo no existe.' + +# Datos a guardar +data = { + 'Nombre': 'Juan Pérez', + 'Edad': 30, + 'Fecha_de_nacimiento': '1995-05-15', + 'Lenguajes_de_programacion': ['Python', 'Java', 'C++'] +} + +# Crear archivo JSON +crear_json(data) + +# Mostrar contenido +print("Contenido del archivo:") +print(mostrar_contenido()) + +# Borrar archivo +print("\nResultado al borrar el archivo:") +print(borrar_archivo()) + +import json + +class Persona: + def __init__(self, nombre, edad, fecha_de_nacimiento, lenguajes): + self.nombre = nombre + self.edad = edad + self.fecha_de_nacimiento = fecha_de_nacimiento + self.lenguajes = lenguajes + + def __repr__(self): + return f"Persona(Nombre: {self.nombre}, Edad: {self.edad}, Fecha de nacimiento: {self.fecha_de_nacimiento}, Lenguajes: {self.lenguajes})" + +def leer_json_y_transformar(): + # Crear nuevamente el archivo JSON para leerlo + data = { + 'Nombre': 'Juan Pérez', + 'Edad': 30, + 'Fecha_de_nacimiento': '1995-05-15', + 'Lenguajes_de_programacion': ['Python', 'Java', 'C++'] + } + + with open('persona.json', 'w') as file: + json.dump(data, file, indent=4) + + # Leer el archivo JSON + with open('persona.json', 'r') as file: + datos_json = json.load(file) + + # Transformar en una clase custom + persona = Persona( + datos_json['Nombre'], + datos_json['Edad'], + datos_json['Fecha_de_nacimiento'], + datos_json['Lenguajes_de_programacion'] + ) + + # Borrar el archivo después de leerlo + import os + if os.path.exists('persona.json'): + os.remove('persona.json') + + return persona + +# Leer y transformar datos +print("\nDatos transformados en clase custom:") +print(leer_json_y_transformar()) diff --git a/Logic/15.Test.py b/Logic/15.Test.py new file mode 100644 index 00000000..62bc29c3 --- /dev/null +++ b/Logic/15.Test.py @@ -0,0 +1,52 @@ +# Crea una función que se encargue de sumar dos números y retornar su resultado +# Crea una función que se encargue de sumar dos números y retornar su resultado +def sumar_numeros(a, b): + return a + b + +# Ejemplo de uso +resultado = sumar_numeros(5, 3) +print(f"El resultado de la suma es: {resultado}") + +# Crea un test, utilizando las herramientas propias del lenguaje, que sea capaz de determinar si esa función se ejecuta correctamente. +def test_sumar_numeros(): + resultado = sumar_numeros(5, 3) + assert resultado == 8, f"El resultado esperado es 8 y se obtuvo {resultado}" + print("La función 'sumar_numeros' es correcta.") + +""" +Crea un diccionario con las siguientes calves y valores +clave: nombre, valor: Juan +clave: edad, valor: 30 +clave: fecha_nacuimiento , valor: 12/05/1980 +clave: lenguajes, valor: JavaScript, Python, Java + +Crear dos test: +- Uno que determine que existen todos los campos +- Otro que determine que los datos introducidos son correctos +""" + +# Diccionario con las claves y valores especificados +persona = { + "nombre": "Juan", + "edad": 30, + "fecha_nacimiento": "12/05/1980", + "lenguajes": ["JavaScript", "Python", "Java"] +} + +# Test para determinar que existen todos los campos +def test_existen_todos_los_campos(): + campos_requeridos = {"nombre", "edad", "fecha_nacimiento", "lenguajes"} + assert campos_requeridos.issubset(persona.keys()), "Faltan campos en el diccionario" + print("Todos los campos están presentes en el diccionario.") + +# Test para determinar que los datos introducidos son correctos +def test_datos_correctos(): + assert persona["nombre"] == "Juan", "El nombre no es correcto" + assert persona["edad"] == 30, "La edad no es correcta" + assert persona["fecha_nacimiento"] == "12/05/1980", "La fecha de nacimiento no es correcta" + assert persona["lenguajes"] == ["JavaScript", "Python", "Java"], "Los lenguajes no son correctos" + print("Todos los datos son correctos.") + +# Ejecución de los tests +test_existen_todos_los_campos() +test_datos_correctos() diff --git a/Logic/16.Fechas.py b/Logic/16.Fechas.py new file mode 100644 index 00000000..c5c15432 --- /dev/null +++ b/Logic/16.Fechas.py @@ -0,0 +1,45 @@ +from datetime import datetime + +""" +Ejercicio +""" + +now = datetime.now() +birth_date = datetime(1987, 4, 29, 12, 0, 0) + +print(now) +print(birth_date) + +difference = now - birth_date +print(type(difference)) + +print(f"Tengo {difference.days // 365} años.") + +""" +Extra +""" + +# Día, mes y año +print(birth_date.strftime("%d/%m/%y")) +print(birth_date.strftime("%d/%m/%Y")) + +# Horas, minutos y segundos +print(birth_date.strftime("%H:%M:%S")) + +# Día del año +print(birth_date.strftime("%j")) + +# Día de la semana +print(birth_date.strftime("%A")) + +# Nombre del mes +print(birth_date.strftime("%h")) +print(birth_date.strftime("%B")) + +# Representación por defecto del locale +print(birth_date.strftime("%c")) +print(birth_date.strftime("%x")) +print(birth_date.strftime("%X")) + +# AM/PM +print(birth_date.strftime("%p")) diff --git a/Logic/17.Asincronia.py b/Logic/17.Asincronia.py new file mode 100644 index 00000000..92c10c71 --- /dev/null +++ b/Logic/17.Asincronia.py @@ -0,0 +1,56 @@ +""" +Crea un programa en javascript capaz de ejecutar de manera asíncrona una función que tardará en finalizar un número concreto de segundos parametrizables. +También debes poder asignarle un nombre. +La función imprime su nombre, cuándo empieza, el tiempo que durará su ejecución y cuando finalia. +""" + +import asyncio + +async def tarea(nombre: str, duracion: int): + print(f"[{nombre}] Iniciando tarea. Duración: {duracion} segundos.") + await asyncio.sleep(duracion) + print(f"[{nombre}] Tarea finalizada tras {duracion} segundos.") + +async def main(): + # Ejecutar varias tareas asíncronas + tareas = [ + tarea("Tarea 1", 3), + tarea("Tarea 2", 5), + tarea("Tarea 3", 2) + ] + await asyncio.gather(*tareas) + +if __name__ == "__main__": + asyncio.run(main()) + +""" +Utilizando el concepto de asincronía y la función anterior, crea el siguiente programa que ejecuta en este orden +* Una función C que dura 3 segundos +* Una función B que dura 2 segundos +* Una función A que dura 1 segundo +* Una función D que dura 1 segundo +* Las funciones C, B y A se ejecutan en paralelo. +* La función D comienza su ejecución cuando las 3 anteriores han finalizado. +""" +import asyncio + +async def tarea(nombre: str, duracion: int): + print(f"[{nombre}] Iniciando tarea. Duración: {duracion} segundos.") + await asyncio.sleep(duracion) + print(f"[{nombre}] Tarea finalizada tras {duracion} segundos.") + +async def main(): + # Ejecutar C, B y A en paralelo + tareas_paralelas = [ + tarea("C", 3), + tarea("B", 2), + tarea("A", 1) + ] + await asyncio.gather(*tareas_paralelas) + + # Ejecutar D solo después de que C, B y A hayan finalizado + await tarea("D", 1) + +if __name__ == "__main__": + asyncio.run(main()) + diff --git a/Logic/18.ExpresionesRegulares.py b/Logic/18.ExpresionesRegulares.py new file mode 100644 index 00000000..c198a3f7 --- /dev/null +++ b/Logic/18.ExpresionesRegulares.py @@ -0,0 +1,33 @@ +""" +Crea 3 expresiones regulares (a tu criterio) capaces de: +* Validar un email +* Validar un número de teléfono +* Validar una url +""" +import re + +# Expresiones regulares +EMAIL_REGEX = r'^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$' +PHONE_REGEX = r'^\+?\d{1,4}[\s-]?\d{1,14}([\s-]?\d{1,13})?$' +URL_REGEX = r'^(https?:\/\/)?(www\.)?[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}([\/\w.-]*)*\/?$' + +def validar_dato(tipo: str, dato: str): + regex = { + "email": EMAIL_REGEX, + "telefono": PHONE_REGEX, + "url": URL_REGEX + }.get(tipo) + + if regex and re.match(regex, dato): + print(f"{tipo.capitalize()} válido: {dato}") + else: + print(f"{tipo.capitalize()} inválido: {dato}") + +def main(): + # Validaciones + validar_dato("email", "usuario@example.com") + validar_dato("telefono", "+34 600-123-456") + validar_dato("url", "https://www.ejemplo.com") + +main() + diff --git a/Logic/19.Iteraciones.py b/Logic/19.Iteraciones.py new file mode 100644 index 00000000..3fa40ac3 --- /dev/null +++ b/Logic/19.Iteraciones.py @@ -0,0 +1,72 @@ +""" +Escribe el mayor número de mecanismos que posee python para iterar valores. +""" +import itertools +from functools import reduce + +print("\n1. Bucle for con lista:") +for i in [1, 2, 3]: + print(i) + +print("\n2. Bucle while:") +i = 0 +while i < 3: + print(i) + i += 1 + +print("\n3. Iteración con range:") +for i in range(1, 5, 2): + print(i) + +print("\n4. Iteración sobre diccionario:") +diccionario = {"a": 1, "b": 2} +for clave, valor in diccionario.items(): + print(clave, valor) + +print("\n5. Enumerate:") +lista = ['a', 'b', 'c'] +for i, valor in enumerate(lista): + print(i, valor) + +print("\n6. Zip:") +nombres = ['Ana', 'Luis'] +edades = [25, 30] +for nombre, edad in zip(nombres, edades): + print(nombre, edad) + +print("\n7. List Comprehension:") +cuadrados = [x**2 for x in range(5)] +print(cuadrados) + +print("\n8. Set y Dict Comprehension:") +conjunto = {x for x in range(5)} +print(conjunto) +dicc = {x: x**2 for x in range(3)} +print(dicc) + +print("\n9. Iteradores y Generadores:") +lista = iter([1, 2, 3]) +print(next(lista)) +def generador(): + for i in range(3): + yield i +for valor in generador(): + print(valor) + +print("\n10. Funciones Funcionales:") +print(list(map(lambda x: x*2, [1, 2, 3]))) +print(list(filter(lambda x: x % 2 == 0, range(5)))) +print(reduce(lambda x, y: x + y, [1, 2, 3])) + +print("\n11. Itertools:") +print(list(itertools.islice(itertools.count(10, 2), 5))) +print(list(itertools.islice(itertools.cycle([1, 2, 3]), 7))) +print(list(itertools.permutations([1, 2, 3]))) + +print("\n12. Leer archivo línea por línea:") +try: + with open('archivo.txt') as f: + for linea in f: + print(linea.strip()) +except FileNotFoundError: + print("archivo.txt no encontrado, omitiendo este paso.") diff --git a/Logic/20.Conjuntos.py b/Logic/20.Conjuntos.py new file mode 100644 index 00000000..e68b76ef --- /dev/null +++ b/Logic/20.Conjuntos.py @@ -0,0 +1,56 @@ +""" +Realiza un programa python que muestre ejemplos de las siguientes operaciones con conjuntos: +* Unión +* Intersección +* Diferencia +* Diferencia simétrica +* Subconjunto +* Producto cartesiano +* Potencia de un conjunto +* Complemento de un conjunto +* Producto de conjuntos +""" +from itertools import chain, combinations, product + +# Funciones para operaciones con conjuntos +def union(setA, setB): + return setA | setB + +def interseccion(setA, setB): + return setA & setB + +def diferencia(setA, setB): + return setA - setB + +def diferencia_simetrica(setA, setB): + return setA ^ setB + +def es_subconjunto(subset, setA): + return subset.issubset(setA) + +def producto_cartesiano(setA, setB): + return set(product(setA, setB)) + +def potencia_conjunto(setA): + return set(frozenset(s) for s in chain.from_iterable(combinations(setA, r) for r in range(len(setA) + 1))) + +def complemento(setA, universo): + return universo - setA + +def producto_de_conjuntos(setA, setB): + return {a * b for a in setA for b in setB} + +# Ejemplo de uso +A = {1, 2, 3} +B = {3, 4, 5} +universo = {1, 2, 3, 4, 5, 6, 7, 8, 9} + +print("Unión:", union(A, B)) +print("Intersección:", interseccion(A, B)) +print("Diferencia A - B:", diferencia(A, B)) +print("Diferencia simétrica:", diferencia_simetrica(A, B)) +print("¿A es subconjunto de B?", es_subconjunto(A, B)) +print("Producto cartesiano:", producto_cartesiano(A, B)) +print("Potencia de A:", potencia_conjunto(A)) +print("Complemento de A:", complemento(A, universo)) +print("Producto de conjuntos:", producto_de_conjuntos(A, B)) diff --git a/Logic/21.Enumeraciones.py b/Logic/21.Enumeraciones.py new file mode 100644 index 00000000..98a20728 --- /dev/null +++ b/Logic/21.Enumeraciones.py @@ -0,0 +1,83 @@ +""" +Crea un pequeño sistema de gestión del estado de pedidos. +Implementa una clase que defina un pedido con las siguientes características: +* El pedido tiene un ID único y un estado. +* El estado es un enumerado que puede ser PENDIENTE, ENVIADO, ENTREGADO y CANCELADO. +* Implementa las funciones que sirvan para modificar el estado: + * Cambiar el estado a ENVIADO. + * Cambiar el estado a ENTREGADO. + * Cambiar el estado a CANCELADO. + * Cambiar el estado a PENDIENTE. + * Cambiar el estado a un valor inválido (debería lanzar un error). + (establece una lógica, por ejemplo, no se puede entregar si no se ha enviado, etc...) +* Implementa un método para mostrar el estado actual del pedido. +* Crea diferentes pedidos y muestra cómo se interactua con ellos. +""" +from enum import Enum, auto +import uuid + +class EstadoPedido(Enum): + PENDIENTE = auto() + ENVIADO = auto() + ENTREGADO = auto() + CANCELADO = auto() + +class Pedido: + def __init__(self): + self.id = str(uuid.uuid4()) + self.estado = EstadoPedido.PENDIENTE + + def mostrar_estado(self): + print(f"Pedido {self.id[:8]} - Estado actual: {self.estado.name}") + + def cambiar_estado(self, nuevo_estado): + if not isinstance(nuevo_estado, EstadoPedido): + raise ValueError("Estado inválido. Debe ser una instancia de EstadoPedido.") + + if nuevo_estado == EstadoPedido.ENVIADO: + if self.estado != EstadoPedido.PENDIENTE: + raise ValueError("Solo se puede enviar un pedido que esté PENDIENTE.") + + elif nuevo_estado == EstadoPedido.ENTREGADO: + if self.estado != EstadoPedido.ENVIADO: + raise ValueError("Solo se puede entregar un pedido que haya sido ENVIADO.") + + elif nuevo_estado == EstadoPedido.CANCELADO: + if self.estado == EstadoPedido.ENTREGADO: + raise ValueError("No se puede cancelar un pedido ya ENTREGADO.") + + elif nuevo_estado == EstadoPedido.PENDIENTE: + if self.estado != EstadoPedido.CANCELADO: + raise ValueError("Solo se puede volver a estado PENDIENTE desde CANCELADO.") + + self.estado = nuevo_estado + print(f"El estado del pedido {self.id[:8]} ha cambiado a: {self.estado.name}") + +# Demostración del sistema de gestión de pedidos +if __name__ == "__main__": + pedido1 = Pedido() + pedido2 = Pedido() + + pedido1.mostrar_estado() + pedido1.cambiar_estado(EstadoPedido.ENVIADO) + pedido1.cambiar_estado(EstadoPedido.ENTREGADO) + pedido1.mostrar_estado() + + pedido2.mostrar_estado() + pedido2.cambiar_estado(EstadoPedido.CANCELADO) + pedido2.mostrar_estado() + try: + pedido2.cambiar_estado(EstadoPedido.ENTREGADO) + except ValueError as e: + print("Error:", e) + + try: + pedido2.cambiar_estado("REEMBOLSADO") # Estado inválido + except ValueError as e: + print("Error:", e) + + try: + pedido2.cambiar_estado(EstadoPedido.PENDIENTE) # válido desde CANCELADO + pedido2.mostrar_estado() + except ValueError as e: + print("Error:", e) diff --git a/Logic/22.PeticionesHTTP.py b/Logic/22.PeticionesHTTP.py new file mode 100644 index 00000000..9c2be0d7 --- /dev/null +++ b/Logic/22.PeticionesHTTP.py @@ -0,0 +1,85 @@ +""" +Utilizando un mecanismo de peticiones HTTP de python, +realiza una petición a la web que tu quieras, +verifica que dicha petición fue exitosa y muestra por consola el contenido de la web. +""" +import requests + +# URL de ejemplo +url = "https://www.example.com" + +try: + response = requests.get(url) + + # Verificamos si la respuesta fue exitosa (código 200) + if response.status_code == 200: + print("✅ Petición exitosa") + print("Contenido de la página:") + print(response.text) + else: + print(f"❌ La petición falló con código de estado: {response.status_code}") + +except requests.RequestException as e: + print(f"⚠️ Error durante la petición HTTP: {e}") + +""" +Utilizando la PokéAPI (https://pokeapi.co), crea un programa por terminal al que le puedas solicitar +información de un Pokémon concreto utilizando su nombre o número. +- Muestra el nombre, id, peso, altura y tipo(s) del Pokémon. +- Si el Pokémon no existe, muestra un mensaje de error. +- Muestra el nombre de su cadena de evoluciones. +- Muestra los juegos en los que aparece. +- Controla posibles errores. +""" +#import requests + +def obtener_pokemon(nombre_o_id): + url = f"https://pokeapi.co/api/v2/pokemon/{nombre_o_id.lower()}" + try: + respuesta = requests.get(url) + if respuesta.status_code != 200: + print("\n❌ Pokémon no encontrado.") + return + + datos = respuesta.json() + + nombre = datos['name'] + id_pokemon = datos['id'] + peso = datos['weight'] + altura = datos['height'] + tipos = [tipo['type']['name'] for tipo in datos['types']] + + print(f"\n🧾 Información de {nombre.capitalize()}") + print(f"ID: {id_pokemon}") + print(f"Peso: {peso}") + print(f"Altura: {altura}") + print(f"Tipo(s): {', '.join(tipos)}") + + # Mostrar juegos donde aparece + juegos = {entry['version']['name'] for entry in datos['game_indices']} + print(f"\n🎮 Aparece en los juegos:") + for juego in sorted(juegos): + print(f"- {juego}") + + # Obtener cadena de evolución + url_especie = datos['species']['url'] + especie = requests.get(url_especie).json() + url_evoluciones = especie['evolution_chain']['url'] + cadena = requests.get(url_evoluciones).json() + + print("\n🔗 Cadena de evoluciones:") + mostrar_cadena(cadena['chain']) + + except requests.RequestException as e: + print(f"\n⚠️ Error de conexión: {e}") + +def mostrar_cadena(cadena): + actual = cadena['species']['name'] + print(f"- {actual}") + for evolucion in cadena['evolves_to']: + mostrar_cadena(evolucion) + +if __name__ == "__main__": + nombre = input("Introduce el nombre o número del Pokémon: ") + obtener_pokemon(nombre) + diff --git a/Logic/23.Callbacks.py b/Logic/23.Callbacks.py new file mode 100644 index 00000000..b66d0f8a --- /dev/null +++ b/Logic/23.Callbacks.py @@ -0,0 +1,76 @@ +""" + * EJERCICIO: + * Explora el concepto de callback en tu lenguaje creando un ejemplo + * simple (a tu elección) que muestre su funcionamiento. +""" + +def procesar_lista(lista, callback): + """Aplica una función (callback) a cada elemento de la lista.""" + resultado = [] + for elemento in lista: + resultado.append(callback(elemento)) + return resultado + +# Funciones de ejemplo para usar como callbacks +def al_cuadrado(x): + return x * x + +def al_doble(x): + return x * 2 + +# Uso +numeros = [1, 2, 3, 4, 5] + +print("Aplicando al_cuadrado:") +print(procesar_lista(numeros, al_cuadrado)) # [1, 4, 9, 16, 25] + +print("Aplicando al_doble:") +print(procesar_lista(numeros, al_doble)) # [2, 4, 6, 8, 10] + +""" + * DIFICULTAD EXTRA (opcional): + * Crea un simulador de pedidos de un restaurante utilizando callbacks. + * Estará formado por una función que procesa pedidos. + * Debe aceptar el nombre del plato, una callback de confirmación, una + * de listo y otra de entrega. + * - Debe imprimir un confirmación cuando empiece el procesamiento. + * - Debe simular un tiempo aleatorio entre 1 a 10 segundos entre + * procesos. + * - Debe invocar a cada callback siguiendo un orden de procesado. + * - Debe notificar que el plato está listo o ha sido entregado. +""" +import time +import random + +def procesar_pedido(plato, on_confirmacion, on_listo, on_entrega): + print(f"\n🔔 Recibido pedido de: {plato}") + + # Confirmación del pedido + on_confirmacion(plato) + tiempo_preparacion = random.randint(1, 10) + time.sleep(tiempo_preparacion) + + # Plato listo + on_listo(plato) + tiempo_entrega = random.randint(1, 5) + time.sleep(tiempo_entrega) + + # Plato entregado + on_entrega(plato) + +# Callbacks + +def confirmar_pedido(plato): + print(f"✅ Pedido confirmado: {plato}") + +def plato_listo(plato): + print(f"🍽️ El plato '{plato}' está listo para servir.") + +def entregar_pedido(plato): + print(f"📦 Pedido '{plato}' ha sido entregado al cliente.\n") + +# Simulación de varios pedidos +if __name__ == "__main__": + pedidos = ["Pizza Margarita", "Ensalada César", "Sushi", "Hamburguesa"] + for plato in pedidos: + procesar_pedido(plato, confirmar_pedido, plato_listo, entregar_pedido) diff --git a/Logic/24.OrdenSuperior.py b/Logic/24.OrdenSuperior.py new file mode 100644 index 00000000..88a45413 --- /dev/null +++ b/Logic/24.OrdenSuperior.py @@ -0,0 +1,126 @@ +""" + * EJERCICIO: + Explora el concepto de funciones de orden superior en python + creando ejemplos simples (a tu elección) que muestren su funcionamiento. +""" +# 1.Recibir funciones como argumentos + +def aplicar_operacion(x, y, operacion): + return operacion(x, y) + +def sumar(a, b): + return a + b + +def multiplicar(a, b): + return a * b + +# Uso: +print(aplicar_operacion(5, 3, sumar)) # 8 +print(aplicar_operacion(5, 3, multiplicar)) # 15 + +# 2.Devolver una función + +def crear_saludo(tipo): + def saludo_formal(nombre): + return f"Buenos días, {nombre}." + + def saludo_informal(nombre): + return f"¡Hey, {nombre}!" + + return saludo_formal if tipo == "formal" else saludo_informal + +# Uso: +saludo = crear_saludo("informal") +print(saludo("Ana")) # ¡Hey, Ana! + +saludo = crear_saludo("formal") +print(saludo("Carlos")) # Buenos días, Carlos. + +# 3.Combinar funciones como datos + +def procesar_lista(lista, funcion): + return [funcion(x) for x in lista] + +doble = lambda x: x * 2 +cuadrado = lambda x: x ** 2 + +nums = [1, 2, 3, 4] + +print(procesar_lista(nums, doble)) # [2, 4, 6, 8] +print(procesar_lista(nums, cuadrado)) # [1, 4, 9, 16] + + +""" + * DIFICULTAD EXTRA (opcional): + * Dada una lista de estudiantes (con sus nombres, fecha de nacimiento y + * lista de calificaciones), utiliza funciones de orden superior para + * realizar las siguientes operaciones de procesamiento y análisis: + * - Promedio calificaciones: Obtiene una lista de estudiantes por nombre + * y promedio de sus calificaciones. + * - Mejores estudiantes: Obtiene una lista con el nombre de los estudiantes + * que tienen calificaciones con un 9 o más de promedio. + * - Nacimiento: Obtiene una lista de estudiantes ordenada desde el más joven. + * - Mayor calificación: Obtiene la calificación más alta de entre todas las + * de los alumnos. + * - Una calificación debe estar comprendida entre 0 y 10 (admite decimales). + """ + +from datetime import datetime +from statistics import mean +from itertools import chain + + +# Lista de estudiantes +estudiantes = [ + { + "nombre": "Ana", + "nacimiento": "2005-06-10", + "calificaciones": [8.5, 9.0, 7.5] + }, + { + "nombre": "Luis", + "nacimiento": "2004-02-20", + "calificaciones": [9.5, 9.0, 10.0] + }, + { + "nombre": "María", + "nacimiento": "2006-11-05", + "calificaciones": [6.0, 7.0, 5.5] + }, + { + "nombre": "Pedro", + "nacimiento": "2003-09-15", + "calificaciones": [10.0, 10.0, 9.5] + } +] + +# Validación de calificaciones +for est in estudiantes: + est['calificaciones'] = list(filter(lambda x: 0 <= x <= 10, est['calificaciones'])) + +# 1. Promedio de calificaciones +promedios = list(map(lambda e: { + "nombre": e['nombre'], + "promedio": round(mean(e['calificaciones']), 2) +}, estudiantes)) + +print("\n🎓 Promedios de calificaciones:") +for p in promedios: + print(f"{p['nombre']}: {p['promedio']}") + +# 2. Mejores estudiantes (promedio >= 9) +mejores = list(filter(lambda e: mean(e['calificaciones']) >= 9, estudiantes)) +print("\n🏅 Mejores estudiantes (promedio >= 9):") +for e in mejores: + print(f"{e['nombre']}") + +# 3. Estudiantes ordenados desde el más joven +ordenados_por_edad = sorted(estudiantes, key=lambda e: datetime.strptime(e['nacimiento'], "%Y-%m-%d"), reverse=True) +print("\n📅 Estudiantes ordenados por edad (de más joven a mayor):") +for e in ordenados_por_edad: + print(f"{e['nombre']} - {e['nacimiento']}") + +# 4. Mayor calificación entre todos +todas_las_calificaciones = list(chain.from_iterable(map(lambda e: e['calificaciones'], estudiantes))) +mayor_calificacion = max(todas_las_calificaciones) +print(f"\n🏆 Mayor calificación entre todos: {mayor_calificacion}") diff --git a/Logic/25.Singleton.py b/Logic/25.Singleton.py new file mode 100644 index 00000000..7058b931 --- /dev/null +++ b/Logic/25.Singleton.py @@ -0,0 +1,53 @@ +""" + * EJERCICIO: + * Explora el patrón de diseño "singleton" y muestra cómo crearlo + * con un ejemplo genérico. +""" +class SesionUsuario: + _instancia = None + + def __new__(cls): + if cls._instancia is None: + cls._instancia = super(SesionUsuario, cls).__new__(cls) + cls._instancia.usuario = None + return cls._instancia + + def asignar_usuario(self, id, username, nombre, email): + self.usuario = { + "id": id, + "username": username, + "nombre": nombre, + "email": email + } + print(f"✅ Usuario asignado: {self.usuario['username']}") + + def obtener_usuario(self): + if self.usuario: + return self.usuario + else: + print("⚠️ No hay usuario en sesión.") + return None + + def cerrar_sesion(self): + if self.usuario: + print(f"🔒 Sesión cerrada para: {self.usuario['username']}") + self.usuario = None + else: + print("⚠️ No hay sesión activa para cerrar.") + + +# Ejemplo de uso +if __name__ == "__main__": + sesion1 = SesionUsuario() + sesion1.asignar_usuario(1, "jdoe", "John Doe", "jdoe@example.com") + + sesion2 = SesionUsuario() + print("\n📋 Datos de usuario desde otra instancia:") + print(sesion2.obtener_usuario()) + + print("\n🧪 Verificando que ambas instancias son la misma:") + print(sesion1 is sesion2) # Debe ser True + + sesion2.cerrar_sesion() + print(sesion1.obtener_usuario()) + diff --git a/Logic/26.Decorator.py b/Logic/26.Decorator.py new file mode 100644 index 00000000..876e9025 --- /dev/null +++ b/Logic/26.Decorator.py @@ -0,0 +1,46 @@ +""" + * EJERCICIO: + * Explora el concepto de "decorador" y muestra cómo crearlo + * con un ejemplo genérico. +""" +class Decorador: + def __init__(self, funcion): + self.funcion = funcion + + def __call__(self, *args, **kwargs): + print("🔄 Antes de ejecutar la función.") + resultado = self.funcion(*args, **kwargs) + print("✅ Después de ejecutar la función.") + return resultado +@Decorador +def saludar(nombre): + print(f"Hola, {nombre}!") + +# Ejemplo de uso +if __name__ == "__main__": + saludar("Juan") + print("\n🔄 Decorador aplicado a la función 'saludar'.") + +""" + * DIFICULTAD EXTRA (opcional): + * Crea un decorador que sea capaz de contabilizar cuántas veces + * se ha llamado a una función y aplícalo a una función de tu elección. +""" +class ContadorLlamadas: + def __init__(self, funcion): + self.funcion = funcion + self.contador = 0 + + def __call__(self, *args, **kwargs): + self.contador += 1 + print(f"🔄 Llamada número: {self.contador}") + return self.funcion(*args, **kwargs) +@ContadorLlamadas +def sumar(a, b): + return a + b +# Ejemplo de uso +if __name__ == "__main__": + print(sumar(3, 4)) + print(sumar(5, 6)) + print(sumar(7, 8)) + print("\n🔄 Decorador 'ContadorLlamadas' aplicado a la función 'sumar'.") \ No newline at end of file diff --git a/Logic/27.Logs.py b/Logic/27.Logs.py new file mode 100644 index 00000000..bd8829e0 --- /dev/null +++ b/Logic/27.Logs.py @@ -0,0 +1,86 @@ +""" + * EJERCICIO: + * Explora el concepto de "logging" en tu lenguaje. Configúralo y muestra + * un ejemplo con cada nivel de "severidad" disponible. +""" +import logging + +# Configuración del logging +logging.basicConfig( + level=logging.DEBUG, # Nivel mínimo a registrar + format='[%(levelname)s] %(asctime)s - %(message)s', + datefmt='%H:%M:%S' +) + +# Ejemplos por nivel +logging.debug("Este es un mensaje DEBUG: útil para desarrollo.") +logging.info("Este es un mensaje INFO: todo funciona correctamente.") +logging.warning("Este es un WARNING: algo inesperado ha ocurrido.") +logging.error("Este es un ERROR: algo ha fallado.") +logging.critical("Este es un CRITICAL: fallo crítico del sistema.") + +""" + * DIFICULTAD EXTRA (opcional): + * Crea un programa ficticio de gestión de tareas que permita añadir, eliminar + * y listar dichas tareas. + * - Añadir: recibe nombre y descripción. + * - Eliminar: por nombre de la tarea. + * Implementa diferentes mensajes de log que muestren información según la + * tarea ejecutada (a tu elección). + * Utiliza el log para visualizar el tiempo de ejecución de cada tarea. +""" +import logging +import time + +# Configuración del logging +logging.basicConfig( + level=logging.DEBUG, + format='[%(levelname)s] %(asctime)s - %(message)s', + datefmt='%H:%M:%S' +) + +# Lista de tareas +tareas = [] + +# Función para añadir tarea +def añadir_tarea(nombre, descripcion): + start_time = time.time() # Empezamos a medir el tiempo de ejecución + tareas.append({'nombre': nombre, 'descripcion': descripcion}) + end_time = time.time() # Fin de la medición del tiempo + execution_time = end_time - start_time + logging.info(f'✔️ Tarea añadida: {nombre}') + logging.debug(f'⏱ Tiempo de ejecución de añadir_tarea: {execution_time:.4f} segundos') + +# Función para eliminar tarea +def eliminar_tarea(nombre): + start_time = time.time() + tarea_encontrada = False + for tarea in tareas: + if tarea['nombre'] == nombre: + tareas.remove(tarea) + tarea_encontrada = True + break + end_time = time.time() + execution_time = end_time - start_time + if tarea_encontrada: + logging.info(f'✔️ Tarea eliminada: {nombre}') + else: + logging.warning(f'⚠️ Tarea no encontrada: {nombre}') + logging.debug(f'⏱ Tiempo de ejecución de eliminar_tarea: {execution_time:.4f} segundos') + +# Función para listar tareas +def listar_tareas(): + logging.info('📋 Listando tareas actuales:') + if tareas: + for tarea in tareas: + logging.info(f'📝 {tarea["nombre"]}: {tarea["descripcion"]}') + else: + logging.warning('⚠️ No hay tareas en la lista.') + +# Ejemplo de uso +if __name__ == '__main__': + añadir_tarea('Comprar leche', 'Ir al supermercado y comprar leche.') + añadir_tarea('Estudiar Python', 'Practicar programación en Python para mejorar habilidades.') + listar_tareas() + eliminar_tarea('Comprar leche') + listar_tareas() diff --git a/SOLID/DIP.py b/SOLID/DIP.py new file mode 100644 index 00000000..c2edd6f2 --- /dev/null +++ b/SOLID/DIP.py @@ -0,0 +1,109 @@ +""" + * EJERCICIO: + * Explora el "Principio SOLID de Inversión de Dependencias (Dependency Inversion + * Principle, DIP)" y crea un ejemplo simple donde se muestre su funcionamiento + * de forma correcta e incorrecta. +""" +# ❌ Ejemplo INCORRECTO (violando DIP) + +# Módulo de alto nivel depende directamente de un módulo de bajo nivel + +class MotorGasolina: + def encender(self): + print("Motor de gasolina encendido") + +class Coche: + def __init__(self): + self.motor = MotorGasolina() # 😬 dependencia directa + + def arrancar(self): + self.motor.encender() + + + +# ✅ Ejemplo CORRECTO (cumpliendo DIP) + +from abc import ABC, abstractmethod + +class Motor(ABC): + @abstractmethod + def encender(self): + pass + +class MotorGasolina(Motor): + def encender(self): + print("Motor de gasolina encendido") + +class MotorElectrico(Motor): + def encender(self): + print("Motor eléctrico encendido") + +class Coche: + def __init__(self, motor: Motor): + self.motor = motor # ✅ se inyecta la dependencia + + def arrancar(self): + self.motor.encender() + +# Crear coches con diferentes motores sin modificar la clase Coche +motor1 = MotorGasolina() +motor2 = MotorElectrico() + +coche1 = Coche(motor1) +coche2 = Coche(motor2) + +coche1.arrancar() # Motor de gasolina encendido +coche2.arrancar() # Motor eléctrico encendido + +""" + * DIFICULTAD EXTRA (opcional): + * Crea un sistema de notificaciones. + * Requisitos: + * 1. El sistema puede enviar Email, PUSH y SMS (implementaciones específicas). + * 2. El sistema de notificaciones no puede depender de las implementaciones específicas. + * Instrucciones: + * 1. Crea la interfaz o clase abstracta. + * 2. Desarrolla las implementaciones específicas. + * 3. Crea el sistema de notificaciones usando el DIP. + * 4. Desarrolla un código que compruebe que se cumple el principio. +""" + +from abc import ABC, abstractmethod + +class Notificador(ABC): + @abstractmethod + def enviar(self, mensaje: str): + pass + +class EmailNotificador(Notificador): + def enviar(self, mensaje: str): + print(f"[Email] Enviando: {mensaje}") + +class SMSNotificador(Notificador): + def enviar(self, mensaje: str): + print(f"[SMS] Enviando: {mensaje}") + +class PushNotificador(Notificador): + def enviar(self, mensaje: str): + print(f"[Push] Enviando: {mensaje}") + +class SistemaNotificaciones: + def __init__(self, notificador: Notificador): + self.notificador = notificador # ✅ depende de la abstracción + + def notificar(self, mensaje: str): + self.notificador.enviar(mensaje) + +# Podemos inyectar cualquier tipo de notificador sin modificar el sistema + +email = EmailNotificador() +sms = SMSNotificador() +push = PushNotificador() + +sistema_email = SistemaNotificaciones(email) +sistema_sms = SistemaNotificaciones(sms) +sistema_push = SistemaNotificaciones(push) + +sistema_email.notificar("Tu pedido ha sido enviado.") +sistema_sms.notificar("Código de verificación: 123456") +sistema_push.notificar("¡Nueva actualización disponible!") diff --git a/SOLID/ISP.py b/SOLID/ISP.py new file mode 100644 index 00000000..a7b17a75 --- /dev/null +++ b/SOLID/ISP.py @@ -0,0 +1,150 @@ +""" +EJERCICIO: + * Explora el "Principio SOLID de Segregación de Interfaces (Interface Segregation Principle, ISP)" + * y crea un ejemplo simple donde se muestre su funcionamiento de forma correcta e incorrecta. +""" +# ❌ Ejemplo INCORRECTO (Violando ISP) +from abc import ABC, abstractmethod + +class Animal(ABC): + @abstractmethod + def volar(self): + pass + + @abstractmethod + def nadar(self): + pass + +class Pato(Animal): + def volar(self): + print("El pato está volando") + + def nadar(self): + print("El pato está nadando") + +class Perro(Animal): + def volar(self): + raise NotImplementedError("¡El perro no puede volar!") + + def nadar(self): + print("El perro está nadando") + + +# ✅ Ejemplo CORRECTO (Aplicando ISP) +from abc import ABC, abstractmethod + +class Nadador(ABC): + @abstractmethod + def nadar(self): + pass + +class Volador(ABC): + @abstractmethod + def volar(self): + pass + +class Pato(Nadador, Volador): + def nadar(self): + print("El pato nada en el lago") + + def volar(self): + print("El pato vuela sobre el campo") + +class Perro(Nadador): + def nadar(self): + print("El perro nada en la piscina") + +def hacer_nadar(nadador: Nadador): + nadador.nadar() + +def hacer_volar(volador: Volador): + volador.volar() + +pato = Pato() +perro = Perro() + +hacer_nadar(pato) +hacer_volar(pato) +hacer_nadar(perro) +# hacer_volar(perro) # ❌ Esto daría error porque Perro no es un Volador + + +""" +* DIFICULTAD EXTRA (opcional): + * Crea un gestor de impresoras. + * Requisitos: + * 1. Algunas impresoras sólo imprimen en blanco y negro. + * 2. Otras sólo a color. + * 3. Otras son multifunción, pueden imprimir, escanear y enviar fax. + * Instrucciones: + * 1. Implementa el sistema, con los diferentes tipos de impresoras y funciones. + * 2. Aplica el ISP a la implementación. + * 3. Desarrolla un código que compruebe que se cumple el principio. +""" +from abc import ABC, abstractmethod + +# Interfaces segregadas según funcionalidad +class ImpresoraBlancoNegro(ABC): + @abstractmethod + def imprimir_bn(self, documento): + pass + +class ImpresoraColor(ABC): + @abstractmethod + def imprimir_color(self, documento): + pass + +class Escaner(ABC): + @abstractmethod + def escanear(self, documento): + pass + +class Fax(ABC): + @abstractmethod + def enviar_fax(self, documento): + pass + +class ImpresoraBN(ImpresoraBlancoNegro): + def imprimir_bn(self, documento): + print(f"Imprimiendo en blanco y negro: {documento}") + +class ImpresoraColorSimple(ImpresoraColor): + def imprimir_color(self, documento): + print(f"Imprimiendo en color: {documento}") + +class ImpresoraMultifuncion(ImpresoraBlancoNegro, ImpresoraColor, Escaner, Fax): + def imprimir_bn(self, documento): + print(f"[MF] Imprimiendo en blanco y negro: {documento}") + + def imprimir_color(self, documento): + print(f"[MF] Imprimiendo en color: {documento}") + + def escanear(self, documento): + print(f"[MF] Escaneando documento: {documento}") + + def enviar_fax(self, documento): + print(f"[MF] Enviando fax del documento: {documento}") + +def probar_impresora_bn(impresora: ImpresoraBlancoNegro): + impresora.imprimir_bn("Factura 001") + +def probar_impresora_color(impresora: ImpresoraColor): + impresora.imprimir_color("Informe de ventas") + +def probar_multifuncion(impresora: Fax): + impresora.enviar_fax("Contrato firmado") + +# Crear instancias +bn = ImpresoraBN() +color = ImpresoraColorSimple() +multifuncion = ImpresoraMultifuncion() + +# Probar funcionalidades +probar_impresora_bn(bn) +probar_impresora_color(color) +probar_impresora_bn(multifuncion) +probar_impresora_color(multifuncion) +probar_multifuncion(multifuncion) + +# ❌ Estas no deberían tener métodos innecesarios, y así es +# probar_impresora_color(bn) # Esto causaría error si se descomenta diff --git a/SOLID/LSP.py b/SOLID/LSP.py new file mode 100644 index 00000000..08a376ed --- /dev/null +++ b/SOLID/LSP.py @@ -0,0 +1,112 @@ +""" + * EJERCICIO: + * Explora el "Principio SOLID de Sustitución de Liskov (Liskov Substitution Principle, LSP)" + * y crea un ejemplo simple donde se muestre su funcionamiento + * de forma correcta e incorrecta. +""" +#❌ Ejemplo INCORRECTO (Violando LSP) +class Ave: + def volar(self): + print("Estoy volando") + +class Pinguino(Ave): + def volar(self): + raise Exception("¡Los pingüinos no pueden volar!") + +def hacer_volar(ave: Ave): + ave.volar() + +# Esto funciona: +hacer_volar(Ave()) + +# Pero esto rompe el principio LSP: +#hacer_volar(Pinguino()) # ❌ Error en tiempo de ejecución + +#✅ Ejemplo CORRECTO (Aplicando LSP) +from abc import ABC, abstractmethod + +class Ave(ABC): + @abstractmethod + def hacer_sonido(self): + pass + +class AveVoladora(Ave): + @abstractmethod + def volar(self): + pass + +class Aguila(AveVoladora): + def hacer_sonido(self): + print("¡Kree!") + + def volar(self): + print("El águila está volando") + +class Pinguino(Ave): + def hacer_sonido(self): + print("¡Noot noot!") + +# ✅ Ambas clases se comportan correctamente dentro de su jerarquía + +def presentar_ave(ave: Ave): + ave.hacer_sonido() + +presentar_ave(Aguila()) # ✅ +presentar_ave(Pinguino()) # ✅ + + +""" + * DIFICULTAD EXTRA (opcional): + * Crea una jerarquía de vehículos. Todos ellos deben poder acelerar y frenar, así como + * cumplir el LSP. + * Instrucciones: + * 1. Crea la clase Vehículo. + * 2. Añade tres subclases de Vehículo. + * 3. Implementa las operaciones "acelerar" y "frenar" como corresponda. + * 4. Desarrolla un código que compruebe que se cumple el LSP. +""" +from abc import ABC, abstractmethod + +# 1. Clase base +class Vehiculo(ABC): + @abstractmethod + def acelerar(self): + pass + + @abstractmethod + def frenar(self): + pass + +# 2. Subclases de Vehículo +class Coche(Vehiculo): + def acelerar(self): + print("El coche acelera suavemente.") + + def frenar(self): + print("El coche frena con ABS.") + +class Moto(Vehiculo): + def acelerar(self): + print("La moto acelera rápidamente.") + + def frenar(self): + print("La moto frena con los frenos de disco.") + +class Camion(Vehiculo): + def acelerar(self): + print("El camión acelera lentamente debido a su peso.") + + def frenar(self): + print("El camión frena con aire comprimido.") + +# 4. Función que comprueba LSP +def probar_vehiculo(vehiculo: Vehiculo): + print(f"\nProbando un {vehiculo.__class__.__name__}:") + vehiculo.acelerar() + vehiculo.frenar() + +# 🧪 Prueba del cumplimiento de LSP +if __name__ == '__main__': + vehiculos = [Coche(), Moto(), Camion()] + for v in vehiculos: + probar_vehiculo(v) diff --git a/SOLID/OCP.py b/SOLID/OCP.py new file mode 100644 index 00000000..7a8add90 --- /dev/null +++ b/SOLID/OCP.py @@ -0,0 +1,123 @@ +""" + * EJERCICIO: + * Explora el "Principio SOLID Abierto-Cerrado (Open-Close Principle, OCP)" + * y crea un ejemplo simple donde se muestre su funcionamiento + * de forma correcta e incorrecta. +""" +#❌ Ejemplo INCORRECTO (Violando OCP) +class CalculadoraDescuentos: + def calcular(self, tipo_cliente, total): + if tipo_cliente == "regular": + return total * 0.95 + elif tipo_cliente == "vip": + return total * 0.90 + elif tipo_cliente == "super_vip": + return total * 0.85 + else: + return total + +#✅ Ejemplo CORRECTO (Aplicando OCP con polimorfismo) +from abc import ABC, abstractmethod + +class EstrategiaDescuento(ABC): + @abstractmethod + def calcular_descuento(self, total): + pass + +class DescuentoRegular(EstrategiaDescuento): + def calcular_descuento(self, total): + return total * 0.95 + +class DescuentoVIP(EstrategiaDescuento): + def calcular_descuento(self, total): + return total * 0.90 + +class DescuentoSuperVIP(EstrategiaDescuento): + def calcular_descuento(self, total): + return total * 0.85 + +class CalculadoraDescuentos: + def __init__(self, estrategia: EstrategiaDescuento): + self.estrategia = estrategia + + def calcular(self, total): + return self.estrategia.calcular_descuento(total) + +cliente_vip = CalculadoraDescuentos(DescuentoVIP()) +total_con_descuento = cliente_vip.calcular(100) +print(f"Total con descuento VIP: {total_con_descuento}") + +""" + * DIFICULTAD EXTRA (opcional): + * Desarrolla una calculadora que necesita realizar diversas operaciones matemáticas. + * Requisitos: + * - Debes diseñar un sistema que permita agregar nuevas operaciones utilizando el OCP. + * Instrucciones: + * 1. Implementa las operaciones de suma, resta, multiplicación y división. + * 2. Comprueba que el sistema funciona. + * 3. Agrega una quinta operación para calcular potencias. + * 4. Comprueba que se cumple el OCP. +""" +from abc import ABC, abstractmethod + +# Interfaz para todas las operaciones +class Operacion(ABC): + @abstractmethod + def ejecutar(self, a, b): + pass + +# Operaciones básicas +class Suma(Operacion): + def ejecutar(self, a, b): + return a + b + +class Resta(Operacion): + def ejecutar(self, a, b): + return a - b + +class Multiplicacion(Operacion): + def ejecutar(self, a, b): + return a * b + +class Division(Operacion): + def ejecutar(self, a, b): + if b == 0: + raise ValueError("No se puede dividir por cero") + return a / b + +# ✅ Nueva operación: potencia (extensión sin modificar código anterior) +class Potencia(Operacion): + def ejecutar(self, a, b): + return a ** b + +# Calculadora que usa operaciones +class Calculadora: + def __init__(self): + self.operaciones = {} + + def registrar_operacion(self, nombre, operacion): + self.operaciones[nombre] = operacion + + def calcular(self, nombre, a, b): + if nombre in self.operaciones: + return self.operaciones[nombre].ejecutar(a, b) + else: + raise ValueError(f"Operación '{nombre}' no registrada") + +# 🧪 Ejemplo de uso +def main(): + calc = Calculadora() + calc.registrar_operacion("suma", Suma()) + calc.registrar_operacion("resta", Resta()) + calc.registrar_operacion("multiplicacion", Multiplicacion()) + calc.registrar_operacion("division", Division()) + calc.registrar_operacion("potencia", Potencia()) + + print("Suma:", calc.calcular("suma", 10, 5)) + print("Resta:", calc.calcular("resta", 10, 5)) + print("Multiplicacion:", calc.calcular("multiplicacion", 10, 5)) + print("Division:", calc.calcular("division", 10, 2)) + print("Potencia:", calc.calcular("potencia", 2, 3)) + +if __name__ == '__main__': + main() diff --git a/SOLID/SRP.py b/SOLID/SRP.py new file mode 100644 index 00000000..4d6322e7 --- /dev/null +++ b/SOLID/SRP.py @@ -0,0 +1,166 @@ +""" + * EJERCICIO: + * Explora el "Principio SOLID de Responsabilidad Única (Single Responsibility + * Principle, SRP)" y crea un ejemplo simple donde se muestre su funcionamiento + * de forma correcta e incorrecta. +""" +#/Ejemplo erroneo +class Usuario: + def __init__(self, nombre, email): + self.nombre = nombre + self.email = email + + def guardar_usuario(self): + # Código para guardar el usuario en la base de datos + pass + + def enviar_email(self): + # Código para enviar un email al usuario + pass +# Ejemplo OK +class Usuario: + def __init__(self, nombre, email): + self.nombre = nombre + self.email = email +class UsuarioDB: + def guardar_usuario(self, usuario): + # Código para guardar el usuario en la base de datos + pass +class EmailService: + def enviar_email(self, usuario): + # Código para enviar un email al usuario + pass +# Ejemplo de uso +usuario = Usuario("Alice", "alice@example.com") +gestor = UsuarioDB() +email_service = EmailService() + +gestor.guardar_usuario(usuario) +email_service.enviar_email(usuario) + +""" +* DIFICULTAD EXTRA (opcional): + * Desarrolla un sistema de gestión para una biblioteca. El sistema necesita + * manejar diferentes aspectos como el registro de libros, la gestión de usuarios + * y el procesamiento de préstamos de libros. + * Requisitos: + * 1. Registrar libros: El sistema debe permitir agregar nuevos libros con + * información básica como título, autor y número de copias disponibles. + * 2. Registrar usuarios: El sistema debe permitir agregar nuevos usuarios con + * información básica como nombre, número de identificación y correo electrónico. + * 3. Procesar préstamos de libros: El sistema debe permitir a los usuarios + * tomar prestados y devolver libros. + * Instrucciones: + * 1. Diseña una clase que no cumple el SRP: Crea una clase Library que maneje + * los tres aspectos mencionados anteriormente (registro de libros, registro de + * usuarios y procesamiento de préstamos). + * 2. Refactoriza el código: Separa las responsabilidades en diferentes clases + * siguiendo el Principio de Responsabilidad Única. +""" + +# ❌ Ejemplo que VIOLA el SRP +class Library: + def __init__(self): + self.libros = [] + self.usuarios = [] + self.prestamos = [] + + def registrar_libro(self, titulo, autor, copias): + self.libros.append({"titulo": titulo, "autor": autor, "copias": copias}) + + def registrar_usuario(self, nombre, id_usuario, email): + self.usuarios.append({"nombre": nombre, "id": id_usuario, "email": email}) + + def prestar_libro(self, id_usuario, titulo_libro): + libro = next((l for l in self.libros if l["titulo"] == titulo_libro and l["copias"] > 0), None) + if libro: + self.prestamos.append({"usuario": id_usuario, "libro": titulo_libro}) + libro["copias"] -= 1 + print(f"Libro '{titulo_libro}' prestado a usuario {id_usuario}") + else: + print("Libro no disponible") + + def devolver_libro(self, id_usuario, titulo_libro): + prestamo = next((p for p in self.prestamos if p["usuario"] == id_usuario and p["libro"] == titulo_libro), None) + if prestamo: + self.prestamos.remove(prestamo) + for libro in self.libros: + if libro["titulo"] == titulo_libro: + libro["copias"] += 1 + break + print(f"Libro '{titulo_libro}' devuelto por usuario {id_usuario}") + else: + print("No se encontró el préstamo") + + +# ✅ Refactorizado aplicando SRP +class Libro: + def __init__(self, titulo, autor, copias): + self.titulo = titulo + self.autor = autor + self.copias = copias + +class Usuario: + def __init__(self, nombre, id_usuario, email): + self.nombre = nombre + self.id_usuario = id_usuario + self.email = email + +class GestorLibros: + def __init__(self): + self.libros = [] + + def registrar_libro(self, titulo, autor, copias): + self.libros.append(Libro(titulo, autor, copias)) + + def buscar_libro(self, titulo): + return next((libro for libro in self.libros if libro.titulo == titulo), None) + +class GestorUsuarios: + def __init__(self): + self.usuarios = [] + + def registrar_usuario(self, nombre, id_usuario, email): + self.usuarios.append(Usuario(nombre, id_usuario, email)) + + def obtener_usuario(self, id_usuario): + return next((u for u in self.usuarios if u.id_usuario == id_usuario), None) + +class GestorPrestamos: + def __init__(self, gestor_libros, gestor_usuarios): + self.prestamos = [] + self.gestor_libros = gestor_libros + self.gestor_usuarios = gestor_usuarios + + def prestar_libro(self, id_usuario, titulo_libro): + libro = self.gestor_libros.buscar_libro(titulo_libro) + usuario = self.gestor_usuarios.obtener_usuario(id_usuario) + if libro and usuario and libro.copias > 0: + self.prestamos.append({"usuario": id_usuario, "libro": titulo_libro}) + libro.copias -= 1 + print(f"✅ '{titulo_libro}' prestado a {usuario.nombre}") + else: + print("❌ Libro no disponible o usuario no encontrado") + + def devolver_libro(self, id_usuario, titulo_libro): + prestamo = next((p for p in self.prestamos if p["usuario"] == id_usuario and p["libro"] == titulo_libro), None) + if prestamo: + self.prestamos.remove(prestamo) + libro = self.gestor_libros.buscar_libro(titulo_libro) + if libro: + libro.copias += 1 + print(f"🔄 '{titulo_libro}' devuelto por usuario {id_usuario}") + else: + print("⚠️ Préstamo no encontrado") + +# 🧪 Ejemplo de uso +if __name__ == '__main__': + libros = GestorLibros() + usuarios = GestorUsuarios() + prestamos = GestorPrestamos(libros, usuarios) + + libros.registrar_libro("1984", "George Orwell", 2) + usuarios.registrar_usuario("Alice", 1, "alice@mail.com") + + prestamos.prestar_libro(1, "1984") + prestamos.devolver_libro(1, "1984") diff --git a/abc.txt b/abc.txt new file mode 100644 index 00000000..9ee07d76 --- /dev/null +++ b/abc.txt @@ -0,0 +1 @@ +SampurneshBabu movie is Britania Bisket \ No newline at end of file diff --git a/camiseta.txt b/camiseta.txt new file mode 100644 index 00000000..3368c293 --- /dev/null +++ b/camiseta.txt @@ -0,0 +1 @@ +Ejemplo fichero para el ejercicio RAR \ No newline at end of file diff --git a/camiseta.zip b/camiseta.zip new file mode 100644 index 00000000..7abb2851 Binary files /dev/null and b/camiseta.zip differ diff --git a/demo.log b/demo.log new file mode 100644 index 00000000..924fc1a3 --- /dev/null +++ b/demo.log @@ -0,0 +1,4 @@ +01/22/2026 10:41:55AM - LoggerDemoConsoleINFO: info message +01/22/2026 10:41:55AM - LoggerDemoConsoleWARNING: warn message +01/22/2026 10:41:55AM - LoggerDemoConsoleERROR: error message +01/22/2026 10:41:55AM - LoggerDemoConsoleCRITICAL: critical message diff --git a/names.txt b/names.txt new file mode 100644 index 00000000..66b42de9 --- /dev/null +++ b/names.txt @@ -0,0 +1,4 @@ +Ramesh +Arjun +Senthil +Vignesh \ No newline at end of file diff --git a/sample_log.txt b/sample_log.txt new file mode 100644 index 00000000..c8ed6591 --- /dev/null +++ b/sample_log.txt @@ -0,0 +1,54 @@ +WARNING:root:warning Information +ERROR:root:error Information +CRITICAL:root:critical Information +WARNING:root:warning Information +ERROR:root:error Information +CRITICAL:root:critical Information +WARNING:root:warning Information +ERROR:root:error Information +CRITICAL:root:critical Information +WARNING:root:warning Information +ERROR:root:error Information +CRITICAL:root:critical Information +WARNING:root:warning Information +ERROR:root:error Information +CRITICAL:root:critical Information +WARNING:root:warning Information +ERROR:root:error Information +CRITICAL:root:critical Information +WARNING:root:warning Information +ERROR:root:error Information +CRITICAL:root:critical Information +WARNING:root:warning Information +ERROR:root:error Information +CRITICAL:root:critical Information +WARNING:root:warning Information +ERROR:root:error Information +CRITICAL:root:critical Information +WARNING:root:warning Information +ERROR:root:error Information +CRITICAL:root:critical Information +WARNING:root:warning Information +ERROR:root:error Information +CRITICAL:root:critical Information +WARNING:root:warning Information +ERROR:root:error Information +CRITICAL:root:critical Information +WARNING:root:warning Information +ERROR:root:error Information +CRITICAL:root:critical Information +WARNING:root:warning Information +ERROR:root:error Information +CRITICAL:root:critical Information +INFO:demologger:info message +WARNING:demologger:warn message +ERROR:demologger:error message +CRITICAL:demologger:critical message +INFO:LoggerDemoConsole:info message +WARNING:LoggerDemoConsole:warn message +ERROR:LoggerDemoConsole:error message +CRITICAL:LoggerDemoConsole:critical message +INFO:LoggerDemoConsole:info message +WARNING:LoggerDemoConsole:warn message +ERROR:LoggerDemoConsole:error message +CRITICAL:LoggerDemoConsole:critical message diff --git a/suscriptores.csv b/suscriptores.csv new file mode 100644 index 00000000..25fec642 --- /dev/null +++ b/suscriptores.csv @@ -0,0 +1,7 @@ +id,email,status +1,test1@example.com,activo +2,test2@example.com,inactivo +3,test3@example.com,activo +4,test4@example.com,activo +5,test5@example.com,inactivo +6,test6@example.com,activo diff --git a/test.txt b/test.txt new file mode 100644 index 00000000..4cca6162 --- /dev/null +++ b/test.txt @@ -0,0 +1,3 @@ +Welcome +to +Python diff --git a/wish.txt b/wish.txt new file mode 100644 index 00000000..e73c1a9b --- /dev/null +++ b/wish.txt @@ -0,0 +1,7 @@ +Welcome +to +python world +Welcome +to +python world +Welcome to python world \ No newline at end of file