├── 001_Abre_esta_carpeta ├── iformacion_del_curso.md └── preguntas_resueltas_aquí.md ├── 01_basic ├── 01_print.py ├── 02_types.py ├── 03_cast.py ├── 04_variables.py ├── 05_input.py ├── exercises.py └── soluciones.py ├── 02_flow_control ├── 01_if.py ├── 01_if_solutions.py ├── 02_booleans.py ├── 03_list.py ├── 03_list_solutions.py ├── 04_list_methods.py └── 04_list_methods_solutions.py ├── 03_loops ├── 01_loop_while.py ├── 01_loop_while_solutions.py ├── 02_loop_for.py ├── 02_loop_for_solutions.py ├── 03_range.py ├── 03_range_solutions.py └── 04_functions.py ├── 04_logic ├── 01_challenge_fantastic_four.py ├── 02_challenge_jurassic_park.py ├── 03_challenge_find_first_sum.py ├── 04_dictionaries.py └── 05_challenge_battle.py ├── 05_regex ├── 01_re.py ├── 02_metachars.py ├── 03_quantifiers.py └── 04_sets.py ├── 06_request_ai_dates ├── 01_dates.py ├── 02_requests.py └── 03_clases.py ├── 07_scraping ├── 01_basic.py ├── 02_beautiful.py ├── 03_wiki_scraper.py ├── 04_seo_cli.py ├── 05_playwright.py └── 06_playwright_scraping.py ├── LICENSE ├── README.md └── test.py /001_Abre_esta_carpeta/iformacion_del_curso.md: -------------------------------------------------------------------------------- 1 | # **¡Bienvenido@ al Curso de Python! 🐍🚀** 2 | 3 | En esta sección, te guiaremos en todo lo que necesitas saber para comenzar tu **emocionante** viaje en el mundo de la programación con Python. No importa si nunca has programado antes, este curso comienza desde cero, respondiendo **TODAS** las preguntas que puedas tener. Te ayudaremos a resolver tus dudas de forma independiente, y esto lo podrás ver en el siguiente archivo llamado: **preguntas_resueltas_aquí.md**. 📄✨ 4 | 5 | ## **Plataformas y Acceso al Curso 🌐🔓** 6 | 7 | ### **Dónde Ver las Clases 📺** 8 | 9 | Las clases se transmitirán en vivo en [Twitch](https://www.twitch.tv/midudev) y permanecerán almacenadas allí. Por ahora, no se subirán a YouTube, pero en el futuro, una vez completadas todas las sesiones, estarán disponibles en dicha plataforma. 10 | 11 | Las clases se impartirán todos los **miércoles**, con una duración de **1 hora y media a 2 horas** como máximo. Este calendario se mantendrá al menos un mes y medio, es decir, hasta aproximadamente **marzo de 2025**. Posteriormente, podríamos ampliar el contenido hacia temas como Django, Inteligencia Artificial, entre otros, si vemos que el curso es bien recibido. Así que dale una estrella ⭐ a este repositorio y ¡compártelo con tus amigos! 12 | 13 | ### **Recursos que Tendrás a tu Disposición 📚🔧** 14 | 15 | - **Academia de Midu:** ¡Sí, como lo lees! 🎉 Tenemos abierta la academia donde encontrarás una **gran cantidad** de cursos, incluyendo este mismo curso de Python. Aquí encontrarás mejoras en las explicaciones con código, por minuto, por tema, realizaremos proyectos, y quizás en un futuro certificados y muchas cosas más. Solo entra a [midu.dev](https://midu.dev/). 🚀 16 | 17 | - **Nota:** Solo los suscriptores de Twitch tienen acceso gratuito a la academia. Si tu suscripción en [Twitch](https://www.twitch.tv/midudev) expira y no la renuevas, también se cerrará tu acceso a la academia. Y buenas noticias: no importa si eres suscriptor con sub regalada o con Prime, solo basta que tengas una suscripción en Twitch, te logueas con esa cuenta y tienes acceso a la academia. 👍✨ 18 | 19 | - **Temario - Página Oficial del Curso 📋⏳:** Si quieres ver todos los temas que abordaremos por el momento, visita el siguiente enlace. Además de mostrarte el temario, tiene cuentas regresivas y anuncios de la próxima clase, además de poder guardar el evento en Discord: [cursopython.dev](https://www.cursopython.dev/). 🗓️🔔 20 | 21 | - **Repositorio de Código 💻📂:** 22 | 23 | Todo el código, ejercicios y materiales estarán disponibles en este [repositorio de GitHub](https://github.com/midudev/curso-python). 📂✨ Te recomendamos leer el archivo `README.md` 📖🔍 donde encontrarás enlaces a las clases y más información útil. Además, revisa la última modificación del repositorio 🕒🔄 para estar al tanto de las actualizaciones, como soluciones a ejercicios y mejoras en los comentarios. Por ejemplo, el archivo [01_basic](https://github.com/midudev/curso-python/tree/main/01_basic) fue actualizado una semana y media después de su primera versión. Próximamente, en cada archivo encontrarás enlaces directos al minuto exacto de la clase donde se aborda ese tema, facilitando así tu repaso rápido. ¡Mantente atento! 🚀🔗 24 | 25 | ## **Comunidad y Soporte 🤝💬** 26 | 27 | ¿Quieres una comunidad que te ayude con tus dudas de forma **amigable**? ¿Que te ayude a resolver tus preguntas y a encontrar gente con la que colaborar en proyectos? Pues únete a nuestra **comunidad en Discord** [aquí](https://discord.com/invite/midudev) para resolver dudas, compartir conocimientos y colaborar con otros estudiantes. Dentro de Discord, encontrarás una sección dedicada exclusivamente a Python 🐍💬, donde podrás recibir y brindar apoyo, así como otras secciones que te pueden interesar. No pierdas esta oportunidad para sacar el **máximo provecho** de este curso. 🌟🤗 28 | 29 | ## **¿Tienes Más Dudas? 🤔❓** 30 | 31 | Si te preguntas qué requisitos necesitas, como hemos comentado, mira el [README](https://github.com/midudev/curso-python/blob/main/README.md) 📄🔗. Allí encontrarás enlaces a las clases, así sabrás cuántas clases hemos tenido. Además, en esas clases desde la primera explicamos los requisitos, configuración, instalación de Python, historia de Python y mucho más. También en el README te enseñamos cómo clonar o descargar todo el código de este repositorio 🖥️⬇️, y mucho más. 32 | 33 | ¡Ayúdanos a mejorar! 🌟💬 Coméntanos tus dudas en las transmisiones de las próximas clases y tus sugerencias. Como podrás ver en el archivo llamado **preguntas_resueltas_aquí.md** 📄✨, leemos todas tus preguntas, por muy básicas que sean, y se te responderán. Así que si tienes alguna duda, ¡no dudes en comentarla! Y si tienes alguna sugerencia, curiosidad o si ya sabes algo de programación y quieres saber más, como la configuración de VSCode de Midudev 🖥️⚙️, atajos de teclado ⌨️, herramientas para depurar código en Python 🐍🔍, documentación oficial de Python 📚🖋️, o más recursos de aprendizaje 📖🚀, no dudes en mencionarlas durante las transmisiones de las futuras clases. Aunque no se te responda inmediatamente, seguramente se abordará en esta carpeta que has ingresado. 📁✅ 34 | 35 | --- 36 | 37 | ✨ **¡Estamos emocionados de comenzar este viaje contigo!** Si tienes alguna pregunta o necesitas asistencia, no dudes en unirte a nuestra comunidad en [Discord](https://discord.com/invite/midudev) o visitar nuestra [página del curso](https://www.cursopython.dev/). 🎉🐍 38 | -------------------------------------------------------------------------------- /001_Abre_esta_carpeta/preguntas_resueltas_aquí.md: -------------------------------------------------------------------------------- 1 | # Dudas de Python 2 | --- 3 | 4 | ## Resuelve tus dudas de Python de forma rápida y sencilla 5 | 6 | Durante las transmisiones en vivo surgen numerosas preguntas que, por limitaciones de tiempo, no siempre podemos responder en el momento. Por esta razón, hemos creado este **repositorio de dudas**, donde recopilamos todas las preguntas realizadas en el chat durante las clases de Python. 7 | 8 | Reconocemos que hay personas que están iniciándose en la programación o que desconocen las mejores herramientas para buscar información de manera autónoma. ¡No te preocupes! Aquí te ayudamos a resolver tus dudas de manera eficiente. 9 | 10 | --- 11 | 12 | ### Cómo buscar una pregunta rápidamente 13 | Para encontrar una respuesta en esta sección, utiliza el buscador de tu navegador: 14 | 15 | - **Windows**: `Ctrl + F` 16 | - **Mac**: `Command (⌘) + F` 17 | - **Linux**: `Ctrl + F` 18 | 19 | Simplemente escribe una palabra clave relacionada con tu duda y accede a la información en segundos. 20 | 21 | --- 22 | 23 | ### Antes de continuar, recuerda 24 | Como programadores, es fundamental desarrollar la **habilidad de buscar soluciones por nosotros mismos**. Esto implica leer, investigar y formular preguntas de manera efectiva. A continuación, algunas herramientas clave para mejorar tu aprendizaje: 25 | 26 | - **Inteligencia Artificial**: Utiliza herramientas como [ChatGPT](https://chat.openai.com/) de manera responsable para obtener respuestas rápidas y explicaciones detalladas. 27 | - **YouTube**: Busca tutoriales con frases como _"Cómo configurar mi terminal en VS Code en Windows"_. 28 | - **Google (u otro buscador de tu preferencia)**: Escribe consultas específicas como _"Instalar Python en Windows paso a paso"_. 29 | 30 | **Otros recursos útiles**: 31 | - [Documentación oficial de Python](https://docs.python.org/es/) 32 | - [Stack Overflow: Preguntas y respuestas de programadores](https://stackoverflow.com/) 33 | 34 | --- 35 | 36 | En esta sección, encontrarás **preguntas y respuestas de las primeras clases**. Dado que son muchas, es imposible cubrirlas todas en las transmisiones en vivo. **Si no encuentras lo que buscas, utiliza las herramientas mencionadas anteriormente y continúa practicando.** Si observas algún error, infórmanos; estamos trabajando para mejorar la experiencia de este curso. 37 | 38 | ¡Explora, aprende y sigue creciendo como programador! 39 | 40 | ## Índice 41 | 42 | 1. [Básica](#basica) 43 | 2. [Intermedia](#intermedia) 44 | 45 | --- 46 | 47 | ## Básica 48 | 49 | ### Dudas de las clases de Python [Curso Python de midudev](https://github.com/midudev/curso-python/tree/main/01_basic) 50 | 51 | 1. **Pregunta:** ¿Cómo le hiciste para tener la terminal a la izquierda? 52 | **Respuesta:** Lo explico en el siguiente enlace: [Video](https://www.twitch.tv/videos/2366925887?t=0h58m8s) 53 | 54 | 2. **Pregunta:** ¿Qué versión de Python usaremos? ¿Podemos usar una versión anterior? 55 | **Respuesta:** Sí, puedes usar una versión anterior, siempre y cuando no sea demasiado antigua, como las versiones anteriores a Python 3. Se recomienda utilizar la **última versión estable de Python**. Sin embargo, puedes continuar trabajando con la versión que tienes; si en algún momento encuentras algún error, puedes [actualizar Python](https://www.python.org/) desde su página oficial. 56 | 57 | 3. **Pregunta:** ¿Cómo configuramos `Cmd + Enter` para ejecutar el código de Python en VS Code sin tener que hacer clic en ejecutar? 58 | **Respuesta:** 59 | 1. **Instala la extensión [Code Runner](https://marketplace.visualstudio.com/items?itemName=formulahendry.code-runner)**. 60 | 2. Siempre hay un ícono para compilar código que dice "Ejecutar". Al pasar el cursor sobre él, puedes ver si tiene un atajo de teclado. 61 | 3. Te recomendamos ver el siguiente video: [Tutorial](https://youtu.be/rQ6JQxMio2Q?si=dT3ZS6bndqATu7-8). 62 | 4. Según tu sistema operativo, puedes buscar más información en videos de YouTube o consultar una herramienta de inteligencia artificial. 63 | 64 | 4. **Pregunta:** ¿Qué terminal usa midudev? 65 | **Respuesta:** Midudev utiliza la **terminal de Warp**, que puedes encontrar [aquí](https://www.warp.dev/). En VS Code, puedes usar la terminal integrada, que puede ser `PowerShell`, `cmd`, `Git Bash` o `WSL` según la configuración. Para abrir tu terminal, consulta [este video](https://www.youtube.com/watch?v=gXVI3PxFajU). 66 | 67 | 5. **Pregunta:** ¿Por qué se autocompletan los comentarios? 68 | **Respuesta:** VS Code cuenta con funcionalidades de **autocompletado** y extensiones como **Python IntelliSense** que ayudan a completar automáticamente código y comentarios. Además, midudev utiliza un asistente llamado **Supermaven**, que puedes encontrar [aquí](https://supermaven.com/). 69 | 70 | 6. **Pregunta:** No entendí cómo se abre la consola y se muestra el mensaje. 71 | **Respuesta:** Consulta el siguiente [video](https://www.youtube.com/watch?v=xuuVY52sjdo). Si no funciona, puedes buscar más información en videos de YouTube o utilizar ChatGPT. 72 | 73 | 7. **Pregunta:** Si tenemos Visual Studio, ¿podemos usar Python igual o es necesario usar VS Code? 74 | **Respuesta:** Si te refieres a Visual Studio (el IDE de Microsoft), puedes usarlo para programar en Python. Sin embargo, **Visual Studio Code (VS Code)** es más ligero y está **recomendado para Python**. De todas formas, te dejamos un [enlace](https://youtu.be/oUwz2mc4BFA?si=ArsENSojSvSzf5ty) para que puedas usar Python en ese IDE. 75 | 76 | 8. **Pregunta:** ¿Dónde se ve la configuración de Python? ¿De type checking en VS Code? 77 | **Respuesta:** En VS Code, puedes configurar el type checking siguiendo las instrucciones que explico en el siguiente enlace: [video](https://www.twitch.tv/videos/2354087841?t=1h32m53s). Para acceder a las configuraciones: 78 | 1. Abre VS Code y haz clic en el menú superior que dice Archivo. 79 | 2. Selecciona Preferencias y luego Configuración. 80 | 81 | 9. **Pregunta:** ¿Se puede tener muchas versiones de Python instaladas? 82 | **Respuesta:** Sí, puedes tener varias versiones de Python instaladas y gestionarlas con herramientas como `pyenv`, `conda` o configurando correctamente las rutas de Python en tu sistema. Puedes buscar más información en videos de YouTube como [este](https://www.youtube.com/watch?v=aF0Ml39oRrE) o utilizar una herramienta de inteligencia artificial. 83 | 84 | 10. **Pregunta:** ¿PIP o Conda? 85 | **Respuesta:** Depende de tus necesidades: 86 | - **`pip`**: Gestor de paquetes oficial de Python que funciona con el repositorio de PyPI. 87 | - **`conda`**: Gestor de paquetes y entornos más avanzado, usado en ciencia de datos y desarrollo en Python. 88 | 89 | 11. **Pregunta:** ¿Se pueden concatenar `end` y `sep` en `print()`? 90 | **Respuesta:** Sí, ambos parámetros pueden combinarse en `print()`. 91 | - **`sep`** define cómo se separan los valores. 92 | - **`end`** define qué se imprime al final. 93 | 94 | **Ejemplo:** 95 | ```python 96 | print("Hola", "Mundo", sep=" ", end="!") 97 | ``` 98 | Esto imprimirá: `Hola Mundo!` 99 | 100 | 12. **Pregunta:** Si utilizamos `"""`, ¿podemos imprimir muchas líneas con una sola cadena? 101 | **Respuesta:** Sí, las triples comillas (`"""` o `'''`) permiten definir **cadenas multilínea**. 102 | 103 | 13. **Pregunta:** ¿Se puede cambiar la terminal de VS Code para Python? 104 | **Respuesta:** Sí, en `Archivo > Preferencias > Configuración`, busca `"terminal.integrated.defaultProfile"` y cambia la terminal predeterminada. Si tienes problemas, puedes consultar [ChatGPT](https://chatgpt.com/). 105 | 106 | 14. **Pregunta:** ¿Se puede usar backticks en Python? 107 | **Respuesta:** No, Python no utiliza backticks para definir cadenas como en JavaScript. En Python, se usan comillas simples (`'`), dobles (`"`), o triples (`'''` o `"""`). Para interpolación, se utilizan **f-strings** (`f""` o `f''`). 108 | 109 | 15. **Pregunta:** ¿Qué otros parámetros tiene `print()`? 110 | **Respuesta:** Algunos parámetros útiles son: 111 | - **`sep`**: Define el separador entre valores. 112 | - **`end`**: Define lo que se imprime al final de la línea. 113 | - **`file`**: Permite escribir en un archivo en lugar de la consola. 114 | - **`flush`**: Si es `True`, fuerza la impresión inmediata en la salida. 115 | 116 | 16. **Pregunta:** ¿`end` permite continuar en la misma línea si el `print` es demasiado largo? 117 | **Respuesta:** Sí, `end` permite que el siguiente `print()` continúe en la misma línea sin salto de línea. 118 | 119 | **Pregunta adicional:** ¿Por qué no escribir directamente en la misma línea? 120 | **Respuesta adicional:** Usar los parámetros `end` y `sep` en `print()` permite **controlar cómo se muestran los valores** sin necesidad de escribir todo manualmente en una sola línea. 121 | 122 | **Ejemplos:** 123 | - **Barra de progreso:** 124 | ```python 125 | import time 126 | 127 | for i in range(1, 6): 128 | print(f"\rCargando: {i * 20}%", end="", flush=True) 129 | time.sleep(0.5) 130 | ``` 131 | 132 | - **Formato con separadores:** 133 | ```python 134 | print("Python", "JavaScript", "C++", sep=" | ") 135 | # Output: Python | JavaScript | C++ 136 | ``` 137 | 138 | 17. **Pregunta:** Si no quiero que haya espacio entre valores, ¿qué hago? 139 | **Respuesta:** Usa `sep=""` en `print()`, por ejemplo: 140 | ```python 141 | print("Hola", "Mundo", sep="") 142 | ``` 143 | Imprimirá: `HolaMundo`. 144 | 145 | 18. **Pregunta:** ¿Podemos pasar variables a nuestro `print()`? ¿Cuál es la diferencia entre método y función? 146 | **Respuesta:** 147 | - **Sí**, puedes pasar variables en `print()`. 148 | ```python 149 | nombre = "Juan" 150 | print("Hola,", nombre) 151 | ``` 152 | - **Método vs Función:** 153 | - Un **método** es una función asociada a un objeto. 154 | - Una **función** es un bloque de código independiente. 155 | 156 | **Ejemplo:** 157 | ```python 158 | # Función independiente 159 | print("Hola", "Mundo", sep=", ") # Output: Hola, Mundo 160 | 161 | # Método de un objeto 162 | lista = [1, 2, 3] 163 | lista.append(4) # append() es un método de listas 164 | print(lista) # Output: [1, 2, 3, 4] 165 | ``` 166 | Aquí, `print()` es una **función**, mientras que `.append()` es un **método** de la lista `lista`. 167 | 168 | 19. **Pregunta:** ¿Existe la función `printF` como en Groovy? 169 | **Respuesta:** No existe `printF` en Python, pero puedes usar **f-strings** para formatear texto: 170 | ```python 171 | nombre = "Juan" 172 | print(f"Hola, {nombre}") 173 | ``` 174 | 175 | 20. **Pregunta:** ¿En algunos casos se pueden usar backticks? 176 | **Respuesta:** No, en Python los backticks no se usan como en JavaScript. En su lugar, se utilizan **f-strings** (`f""`) para interpolación y **comillas triples** (`"""` o `'''`) para cadenas multilínea. 177 | 178 | 21. **Pregunta:** ¿Cuál es la diferencia entre comillas dobles y simples? 179 | **Respuesta:** No hay diferencia funcional, pero: 180 | - Usa `"` cuando la cadena contiene `'`. 181 | - Usa `'` cuando la cadena contiene `"`. 182 | - Para cadenas multilínea, usa `"""` o `'''`. 183 | 184 | 22. **Pregunta:** ¿Se puede colorear la salida? ¿Tiene alguna propiedad de error/warning similar a `console.log()`? 185 | **Respuesta:** `print()` por sí solo no colorea, pero puedes usar **`colorama`**: 186 | ```python 187 | from colorama import Fore 188 | print(Fore.RED + "Esto es rojo") 189 | ``` 190 | 191 | 23. **Pregunta:** ¿Cómo se manejan los caracteres especiales (tildes en las cadenas, por ejemplo)? 192 | **Respuesta:** Python maneja **UTF-8** por defecto, así que puedes usar tildes sin problemas: 193 | ```python 194 | print("¡Hola, cómo estás!") 195 | ``` 196 | 197 | 24. **Pregunta:** ¿Realmente tiene uso? 198 | **Respuesta:** Sí, los parámetros `sep` y `end` en `print()` son muy útiles para controlar el formato de la salida sin concatenar manualmente. 199 | 200 | **Ejemplo útil: Registro en tiempo real** 201 | ```python 202 | import time 203 | 204 | print("Progreso:", end=" ") 205 | for i in range(1, 6): 206 | print(f"{i * 20}%", end=" ", flush=True) 207 | time.sleep(0.5) 208 | 209 | # Output en la misma línea: Progreso: 20% 40% 60% 80% 100% 210 | ``` 211 | 212 | 25. **Pregunta:** ¿Para imprimir una variable, simplemente se coloca después de las comillas? 213 | **Respuesta:** No, debes usar una coma o **f-strings**: 214 | ```python 215 | edad = 25 216 | print("Mi edad es", edad) # O usando f-string: 217 | print(f"Mi edad es {edad}") 218 | ``` 219 | 220 | 26. **Pregunta:** ¿También se pueden usar números en `print()`? 221 | **Respuesta:** Sí, puedes imprimir números directamente: 222 | ```python 223 | print(42) 224 | ``` 225 | 226 | 27. **Pregunta:** ¿Existen templates en Python? 227 | **Respuesta:** Sí, puedes usar **f-strings** o **`str.format()`**. 228 | 229 | 28. **Pregunta:** ¿Se pueden usar valores `chr` como parámetros? 230 | **Respuesta:** Sí, `chr()` convierte números en caracteres Unicode: 231 | ```python 232 | print(chr(65)) # Imprime 'A' 233 | ``` 234 | 235 | 29. **Pregunta:** ¿Hay tipos y constructores para los tipos aquí también? 236 | **Respuesta:** Sí, Python tiene tipos y constructores como `int()`, `float()`, `str()`, etc. 237 | 238 | 30. **Pregunta:** ¿Cómo ver la información de un método? 239 | **Respuesta:** Usa `help()` o `dir()`: 240 | ```python 241 | help(print) 242 | ``` 243 | O simplemente pasa el cursor sobre la función `print()` o la que te interese en tu editor de código. 244 | 245 | 31. **Pregunta:** ¿Cómo hago para que el resultado aparezca en la terminal? 246 | **Respuesta:** Consulta [este video](https://www.youtube.com/watch?v=xuuVY52sjdo) o, en caso de no funcionar, utiliza [ChatGPT](https://chatgpt.com/). 247 | 248 | 32. **Pregunta:** ¿Por qué se usa "def" para definir funciones? ¿De qué significa? 249 | **Respuesta:** `def` proviene de **"define"** en inglés y se utiliza para definir funciones en Python. 250 | 251 | ### Más Dudas 252 | 253 | 1. **Pregunta:** No necesitas inicializarlas, solo nombras y asignas, ¿no? 254 | **Respuesta:** Correcto, en Python no necesitas declarar o inicializar variables antes de usarlas. Simplemente asignas un valor a un nombre de variable. 255 | ```python 256 | x = 10 257 | y = "Hola" 258 | ``` 259 | 260 | 2. **Pregunta:** ¿No crea confusión que se reemplace la variable? 261 | **Respuesta:** Puede causar confusión si reutilizas nombres de variables de manera inconsistente. Es una buena práctica usar nombres descriptivos y evitar reutilizar nombres para diferentes propósitos en el mismo ámbito. 262 | 263 | 3. **Pregunta:** ¿Tipado fuerte y tipado dinámico? 264 | **Respuesta:** Python es un lenguaje **tipado dinámico** y **tipado fuerte**. 265 | - **Tipado dinámico:** No necesitas declarar el tipo de una variable, el tipo se determina en tiempo de ejecución. 266 | - **Tipado fuerte:** Las operaciones entre tipos incompatibles (como sumar un `str` y un `int`) no se realizan automáticamente y generan errores. 267 | 268 | 4. **Pregunta:** ¿Y qué ventaja da eso? 269 | **Respuesta:** 270 | - **Tipado dinámico:** Facilita la escritura de código más rápido y flexible, sin necesidad de declarar tipos explícitamente. 271 | - **Tipado fuerte:** Previene errores sutiles al evitar conversiones implícitas de tipos que podrían llevar a comportamientos inesperados. 272 | 273 | 5. **Pregunta:** ¿Afecta la indentación al tipado? 274 | **Respuesta:** La indentación en Python no afecta el tipado, pero es crucial para definir bloques de código y estructuras de control como bucles y condicionales. Una indentación incorrecta puede causar errores de sintaxis. 275 | 276 | 6. **Pregunta:** Si cambio el valor de una variable a un tipo diferente y hago `print`, ¿debería causar un error? 277 | **Respuesta:** No debería causar error. En Python, puedes reasignar variables a diferentes tipos sin problemas. 278 | ```python 279 | x = "Hola" 280 | x = 10 281 | print(x) # Output: 10 282 | ``` 283 | 284 | 7. **Pregunta:** ¿Se puede forzar un tipado estático en Python? 285 | **Respuesta:** Python es dinámico por naturaleza, pero puedes usar **anotaciones de tipo** para indicar tipos de variables y funciones. Herramientas como **mypy** pueden verificar tipos estáticamente, pero esto es opcional y no cambia el comportamiento en tiempo de ejecución. 286 | 287 | **Ejemplo:** 288 | ```python 289 | def suma(a: int, b: int) -> int: 290 | return a + b 291 | ``` 292 | 293 | 8. **Pregunta:** ¿Por qué no se recomienda usar camelCase u otros estilos de nomenclatura en Python y solo se usa snake_case como convención de nombres? 294 | **Respuesta:** 295 | En Python, se prefiere usar **snake_case** para variables, funciones y métodos siguiendo las guías de estilo [PEP 8](https://pep8.org/). Esto mejora la **legibilidad** y **consistencia** del código dentro de la comunidad de Python. 296 | 297 | 9. **Pregunta:** ¿Y el camelCase? ¿No sirve? ¿Se usa camelCase? 298 | **Respuesta:** En Python, la convención es usar **snake_case** para variables y funciones, y **CamelCase** para nombres de clases. Aunque puedes usar camelCase, no es la convención estándar y puede disminuir la legibilidad para otros desarrolladores. 299 | 300 | **Ejemplo:** 301 | ```python 302 | # Convención de Python 303 | nombre_variable = "valor" 304 | 305 | class MiClase: 306 | pass 307 | ``` 308 | 309 | 10. **Pregunta:** ¿Cómo obtuviste la lista de palabras reservadas? 310 | **Respuesta:** Si te refieres a las palabras reservadas, puedes obtener una lista usando el módulo `keyword`. 311 | ```python 312 | import keyword 313 | print(keyword.kwlist) 314 | ``` 315 | 316 | 11. **Pregunta:** ¿Cómo se llama el proceso de convertir un tipo de dato a otro, parsear? 317 | **Respuesta:** Cuando conviertes un tipo de dato a otro, se le llama **casting** o **conversión de tipos**. El término "parsear" generalmente se refiere a analizar una cadena de texto para extraer información o convertirla en otra estructura de datos. 318 | 319 | 12. **Pregunta:** ¿Por qué concatenar con `+` y no con comas? 320 | **Respuesta:** Al usar el operador `+` para concatenar cadenas (`str`), estás uniendo los contenidos de las cadenas directamente. Usar comas en `print` separa los argumentos con espacios por defecto y no requiere que conviertas tipos de datos a cadenas. 321 | 322 | **Ejemplo:** 323 | ```python 324 | a = "Hola" 325 | b = "Mundo" 326 | print(a + b) # Output: HolaMundo 327 | print(a, b) # Output: Hola Mundo 328 | ``` 329 | 330 | 13. **Pregunta:** ¿Qué sucede si convierto `None` a booleano con `bool(None)`? 331 | **Respuesta:** Convertir `None` a booleano usando `bool(None)` devuelve `False`. 332 | ```python 333 | print(bool(None)) # Output: False 334 | ``` 335 | 336 | 14. **Pregunta:** ¿Cómo se manejan los números hexadecimales? 337 | **Respuesta:** En Python, puedes trabajar con números hexadecimales utilizando el prefijo `0x` o `0X`. Puedes convertir hexadecimales a enteros y viceversa. 338 | 339 | **Ejemplo:** 340 | ```python 341 | hex_num = 0x1A # 26 en decimal 342 | print(hex_num) # Output: 26 343 | print(hex(hex_num)) # Output: '0x1a' 344 | ``` 345 | 346 | --- 347 | 348 | ## Intermedia 349 | 350 | ### Más dudas 351 | 352 | 1. **Pregunta:** ¿Existe algún límite para números enteros? Si usan 32, 64 bits, ¿habrá algún límite? 353 | **Respuesta:** 354 | En Python, los enteros (`int`) tienen **precisión ilimitada**, ya que Python ajusta automáticamente el tamaño según sea necesario. A diferencia de otros lenguajes que limitan los enteros a 32 o 64 bits, en Python no hay un límite práctico más allá de la memoria disponible en el sistema. 355 | 356 | **Ejemplos relacionados:** 357 | 358 | - **Precisión de números flotantes:** 359 | ```python 360 | print(0.1 + 0.2 == 0.3) # Output: False 361 | ``` 362 | Los números de punto flotante (`float`) en Python pueden tener pequeñas imprecisiones debido a su representación binaria. 363 | 364 | 2. **Pregunta:** ¿Existe un linter para Python? 365 | **Respuesta:** Sí, existen varios linters para Python que ayudan a mantener un código limpio y libre de errores. Uno de ellos es: 366 | - **[Pylint](https://marketplace.visualstudio.com/items?itemName=ms-python.pylint):** Analiza el código en busca de errores y mejora la calidad del código. 367 | 368 | 3. **Pregunta:** ¿El número complejo es equivalente a los doubles? 369 | **Respuesta:** No, los números complejos y los números de punto flotante (`float` o `double`) son tipos de datos diferentes en Python. 370 | - **Números de punto flotante (`float`):** Representan números reales con decimales. 371 | - **Números complejos (`complex`):** Tienen una parte real y una parte imaginaria, representados como `a + bj`. 372 | 373 | **Ejemplo:** 374 | ```python 375 | real = 3.14 # float 376 | complejo = 2 + 3j # complex 377 | ``` 378 | 379 | 4. **Pregunta:** ¿Qué pasa si sumo un string y un entero `"1" + 1`? 380 | **Respuesta:** Intentar sumar un string y un entero directamente (`"1" + 1`) resultará en un error de tipo (`TypeError`) en Python, ya que no se pueden concatenar directamente diferentes tipos de datos. 381 | 382 | **Ejemplo:** 383 | ```python 384 | "1" + 1 # TypeError: can only concatenate str (not "int") to str 385 | ``` 386 | 387 | **Solución:** Convertir el entero a string o viceversa según la necesidad. 388 | ```python 389 | "1" + str(1) # Resultado: "11" 390 | str(1) + "1" # Resultado: "11" 391 | 1 + int("1") # Resultado: 2 392 | ``` 393 | 394 | 5. **Pregunta:** ¿No existen valores "truthy" o "falsy"? 395 | **Respuesta:** En Python, sí existen valores "truthy" y "falsy". Estos determinan cómo se evalúan las expresiones en contextos booleanos, como en sentencias `if`. 396 | 397 | - **Valores "falsy":** Se consideran como `False` en contextos booleanos. 398 | - `None` 399 | - `False` 400 | - Cero de cualquier tipo (`0`, `0.0`, `0j`, etc.) 401 | - Secuencias y colecciones vacías (`""`, `[]`, `{}`, `()`, etc.) 402 | 403 | - **Valores "truthy":** Todos los demás valores que no son "falsy". 404 | 405 | **Ejemplo:** 406 | ```python 407 | if []: 408 | print("Truthy") 409 | else: 410 | print("Falsy") # Se imprimirá "Falsy" 411 | 412 | if [1, 2, 3]: 413 | print("Truthy") # Se imprimirá "Truthy" 414 | ``` 415 | 416 | 6. **Pregunta:** ¿Qué pasa si hago `print(True * False)`? 417 | **Respuesta:** En Python, `True` se interpreta como `1` y `False` como `0`. Al multiplicarlos: 418 | ```python 419 | print(True * False) # Resultado: 0 420 | ``` 421 | 422 | 7. **Pregunta:** ¿El tipo complejo solo funciona con la letra "j"? 423 | **Respuesta:** Sí, en Python, la unidad imaginaria se representa con la letra minúscula `j` o `J`. No se usan otras letras para denotar la parte imaginaria. 424 | 425 | **Ejemplo:** 426 | ```python 427 | z1 = 3 + 4j 428 | z2 = 5 - 2J 429 | ``` 430 | 431 | 8. **Pregunta:** ¿Los booleanos siempre están capitalizados? 432 | **Respuesta:** Sí, en Python los valores booleanos se escriben con la primera letra en mayúscula: 433 | - `True` 434 | - `False` 435 | 436 | Es importante respetar la capitalización, ya que `true` y `false` en minúsculas no son reconocidos como booleanos y resultarán en un error. 437 | ```python 438 | print(True) # Correcto 439 | print(true) # Error 440 | ``` 441 | 442 | 9. **Pregunta:** ¿Qué sucede si uso `1 > 2j`? 443 | **Respuesta:** Intentar comparar un número entero con un número complejo (`1 > 2j`) resultará en un error de tipo (`TypeError`) en Python, ya que no hay una definición clara para comparar estos tipos. 444 | 445 | **Ejemplo:** 446 | ```python 447 | 1 > 2j # TypeError: '>' not supported between instances of 'int' and 'complex' 448 | ``` 449 | 450 | 10. **Pregunta:** ¿Para qué sirve el `None`? 451 | **Respuesta:** `None` es un objeto especial en Python que representa la ausencia de un valor o un valor nulo. Se utiliza comúnmente para: 452 | - Indicar que una variable no tiene un valor asignado. 453 | - Funciones que no retornan explícitamente un valor retornan `None` por defecto. 454 | - Parámetros por defecto en funciones. 455 | 456 | **Ejemplo:** 457 | ```python 458 | def sin_retorno(): 459 | pass 460 | 461 | resultado = sin_retorno() 462 | print(resultado) # Output: None 463 | ``` 464 | 465 | 11. **Pregunta:** ¿Para qué se usa el `NoneType`? 466 | **Respuesta:** `NoneType` es el tipo de dato de `None`. Se utiliza principalmente para: 467 | - Verificar si una variable es `None`. 468 | - Tipar funciones que pueden retornar `None`. 469 | 470 | **Ejemplo:** 471 | ```python 472 | x = None 473 | if isinstance(x, type(None)): 474 | print("x es None") 475 | ``` 476 | 477 | 12. **Pregunta:** ¿Cómo comento un párrafo completo? 478 | **Respuesta:** En Python, no hay una sintaxis específica para comentarios multilínea como en otros lenguajes. Sin embargo, puedes utilizar comillas triples (`'''` o `"""`) para crear cadenas de texto que no se asignan a ninguna variable, lo que efectivamente actúa como comentarios. 479 | 480 | **Ejemplo:** 481 | ```python 482 | """ 483 | Este es un comentario 484 | de múltiples líneas 485 | """ 486 | ``` 487 | 488 | También puedes usar el carácter `#` al inicio de cada línea: 489 | ```python 490 | # Este es un comentario 491 | # de múltiples líneas 492 | ``` 493 | 494 | 13. **Pregunta:** ¿`None` es igual a `null`? ¿Qué da `"" == None`? 495 | **Respuesta:** En Python, `None` es similar a `null` en otros lenguajes, representando la ausencia de valor. Sin embargo, no es lo mismo que una cadena vacía `""`. 496 | 497 | - **Comparación:** 498 | ```python 499 | None == None # True 500 | "" == None # False 501 | ``` 502 | - **Explicación:** `None` representa la ausencia de un valor, mientras que `""` es una cadena vacía, que es un valor válido. 503 | 504 | 14. **Pregunta:** ¿Existe `null` en Python? 505 | **Respuesta:** En Python, no existe `null`. En su lugar, se utiliza `None` para representar la ausencia de valor. 506 | 507 | 15. **Pregunta:** ¿Un caso práctico para usar `NoneType` en un proyecto? 508 | **Respuesta:** Un caso común es cuando una función puede no retornar un valor significativo y quieres indicar explícitamente que no hay resultado. 509 | 510 | **Ejemplo:** 511 | ```python 512 | def buscar_usuario(usuario_id): 513 | usuario = base_de_datos.obtener(usuario_id) 514 | if not usuario: 515 | return None 516 | return usuario 517 | 518 | resultado = buscar_usuario(10) 519 | if resultado is None: 520 | print("Usuario no encontrado") 521 | else: 522 | print("Usuario encontrado:", resultado) 523 | ``` 524 | 525 | 16. **Pregunta:** ¿"none" indica ausencia de parámetro o ausencia de valor? 526 | **Respuesta:** En Python, `None` (con mayúscula) se utiliza para indicar la ausencia de un valor. Usar la cadena `"none"` (en minúsculas) es simplemente una cadena de texto y no tiene el mismo significado que `None`. 527 | 528 | **Ejemplo:** 529 | ```python 530 | def funcion(param=None): 531 | if param is None: 532 | print("No se proporcionó un parámetro") 533 | else: 534 | print(f"Parametro: {param}") 535 | 536 | funcion() # Output: No se proporcionó un parámetro 537 | funcion("none") # Output: Parametro: none 538 | ``` 539 | 540 | 17. **Pregunta:** ¿`NoneType` es como `null`? 541 | **Respuesta:** Sí, en Python, `NoneType` es el tipo de dato de `None`, que es equivalente a `null` en otros lenguajes. Representa la ausencia de un valor. 542 | 543 | 18. **Pregunta:** ¿Se usa `None` frecuentemente en sentencias `if`? 544 | **Respuesta:** Sí, es común utilizar `None` en sentencias `if` para verificar si una variable tiene un valor asignado o no. 545 | 546 | **Ejemplo:** 547 | ```python 548 | usuario = obtener_usuario(id_usuario) 549 | if usuario is None: 550 | print("Usuario no encontrado") 551 | else: 552 | print("Usuario:", usuario) 553 | ``` 554 | 555 | 19. **Pregunta:** ¿Se usan backticks al usar `print` en Python? 556 | **Respuesta:** No, en Python los backticks no se utilizan para formatear salidas en `print`. Para la interpolación de cadenas, se usan **f-strings** (`f""`), comillas simples (`'`), dobles (`"`), o comillas triples (`'''` o `"""`). 557 | 558 | **Ejemplo con f-strings:** 559 | ```python 560 | nombre = "Juan" 561 | print(f"Hola, {nombre}!") # Output: Hola, Juan! 562 | ``` 563 | 564 | 20. **Pregunta:** ¿Para qué sirve `None` en el contexto de usuarios sin datos en su cuenta? 565 | **Respuesta:** Usar `None` es útil para representar la ausencia de datos, como en el caso de un usuario que no tiene información registrada aún. 566 | 567 | **Ejemplo:** 568 | ```python 569 | class Usuario: 570 | def __init__(self, nombre, edad=None): 571 | self.nombre = nombre 572 | self.edad = edad 573 | 574 | nuevo_usuario = Usuario("Ana") 575 | if nuevo_usuario.edad is None: 576 | print("Edad no especificada") 577 | ``` 578 | 579 | 21. **Pregunta:** ¿Cuál es la diferencia entre `double` y `float` en Python? 580 | **Respuesta:** En Python, no existen los tipos `double` y `float` como en otros lenguajes. Python utiliza el tipo `float` para representar números de punto flotante, que generalmente corresponden a los `double` de precisión doble en otros lenguajes. 581 | 582 | **Ejemplo:** 583 | ```python 584 | numero = 3.141592653589793 # float en Python, equivalente a double en otros lenguajes 585 | ``` 586 | 587 | 22. **Pregunta:** ¿Qué tipo de dato usar para trabajar con dinero debido a la precisión? 588 | **Respuesta:** Para manejar dinero y evitar problemas de precisión con números de punto flotante, es recomendable usar el módulo `decimal` de Python, que ofrece aritmética de punto decimal con precisión exacta. 589 | 590 | **Ejemplo:** 591 | ```python 592 | from decimal import Decimal 593 | 594 | precio = Decimal('19.99') 595 | impuesto = Decimal('0.07') 596 | total = precio + (precio * impuesto) 597 | print(total) # Output: 21.39 598 | ``` 599 | 600 | 23. **Pregunta:** ¿Qué sucede si hago `print(print("Hola"))`? 601 | **Respuesta:** En Python, la función `print()` retorna `None`. Si haces un `print` de un `print`, se ejecutará el primer `print` mostrando el contenido, y luego el segundo `print` mostrará `None`. 602 | 603 | **Ejemplo:** 604 | ```python 605 | resultado = print("Hola Mundo") # Output: Hola Mundo 606 | print(resultado) # Output: None 607 | ``` 608 | 609 | 24. **Pregunta:** ¿Se pueden agregar comas en el `float`? 610 | **Respuesta:** Si te refieres a formatear números de punto flotante con comas como separadores de miles, sí, se puede hacer utilizando formateo de cadenas. 611 | 612 | **Ejemplo usando f-strings:** 613 | ```python 614 | numero = 1234567.89 615 | print(f"{numero:,}") # Output: 1,234,567.89 616 | ``` 617 | 618 | **Ejemplo usando `format`:** 619 | ```python 620 | numero = 1234567.89 621 | print("{:,}".format(numero)) # Output: 1,234,567.89 622 | ``` 623 | 624 | **Nota:** El separador de miles por defecto es la coma `,`. Si necesitas otro separador, puedes especificarlo: 625 | ```python 626 | numero = 1234567.89 627 | print(f"{numero:_}") # Output: 1_234_567.89 628 | ``` 629 | 630 | --- 631 | -------------------------------------------------------------------------------- /01_basic/01_print.py: -------------------------------------------------------------------------------- 1 | ### 2 | # 01 - print() 3 | # El módulo print() es el módulo que nos permite imprimir en consola 4 | # Sirve para mostrar información en consola y te va a acompañar 5 | # TODA TU VIDA. Desde hoy hasta el fin de los tiempos 6 | ### 7 | 8 | # Podemos importar módulos de Python para usarlos en nuestros programas. 9 | # En este caso, importamos el módulo "os" que nos da acceso a funciones 10 | # relacionadas con el sistema operativo 11 | from os import system 12 | 13 | # system() nos permite ejecutar un comando en la terminal. 14 | # En este caso, lo hacemos para limpiar la pantalla tanto 15 | # en MacOS/Linux usando "clear" como en Windows con "cls" 16 | if system("clear") != 0: system("cls") 17 | 18 | # Este es un ejemplo básico de cómo imprimir un texto en consola 19 | print("¡Hola, Twitch!") 20 | 21 | # También puedes usar comillas simples para imprimir texto 22 | print('Esto también funciona con una comilla') 23 | 24 | # Puedes imprimir múltiples elementos separados por un espacio 25 | print("Python", "es", "genial") 26 | 27 | # El parámetro 'sep' permite definir cómo se separan los elementos impresos 28 | print("Python", "es", "brutal", sep = "-") 29 | 30 | # El parámetro 'end' define lo que se imprime al final de la línea 31 | print("Esto se imprime", end = "\n") # Aquí, el 'end' tiene un salto de línea explícito 32 | print("en una línea") # Esto se imprime en la línea siguiente 33 | 34 | # También se pueden imprimir números directamente 35 | print(42) 36 | 37 | # Ejemplo de cómo imprimir el símbolo de pulgadas (") 38 | # Si usamos comillas dobles dentro de un string con comillas dobles, se produce un error: 39 | # print("Esto es una "pulgada"") # ❌ Esto generaría un error de sintaxis 40 | 41 | # ✅ Solución 1: Usar comillas simples para encerrar la cadena 42 | print('Esto es una "pulgada" dentro de un string con comillas simples') 43 | 44 | # ✅ Solución 2: Usar el carácter de escape \ para incluir comillas dobles dentro de un string con comillas dobles 45 | print("Esto es una \"pulgada\" dentro de un string con comillas dobles") 46 | 47 | # ✅ Solución 3: Usar triple comillas para definir el string 48 | print("""Esto es una "pulgada" dentro de un string con triple comillas""") -------------------------------------------------------------------------------- /01_basic/02_types.py: -------------------------------------------------------------------------------- 1 | ### 2 | # 02 - types() 3 | # Python tiene varios tipos de datos 4 | # int, float, complex, str, bool, NoneType, list, tuple, dict, range, set... 5 | ### 6 | 7 | from os import system 8 | if system("clear") != 0: system("cls") 9 | 10 | """ 11 | El comando `type()` devuelve el tipo de un objeto en Python 12 | """ 13 | print("int:") # Enteros (números sin parte decimal) 14 | print(type(10)) # Número entero positivo 15 | print(type(0)) # El número cero también es un entero 16 | print(type(-5)) # Número entero negativo 17 | print(type(7238424723784278934789239874)) # Python permite enteros de gran tamaño 18 | 19 | print("float:") # Números decimales (de punto flotante) 20 | print(type(3.14)) # Número con punto decimal 21 | print(type(1.0)) # También es considerado un float, aunque sea un número entero con punto decimal 22 | print(type(1e3)) # Notación científica (equivalente a 1000.0) 23 | 24 | print("complex:") # Números complejos (con parte real e imaginaria) 25 | print(type(1 + 2j)) # Un número complejo en Python (1 es la parte real, 2j es la parte imaginaria) 26 | 27 | print("str:") # Cadenas de texto (strings) 28 | print(type("Hola")) # Un string con texto 29 | print(type("")) # Un string vacío 30 | print(type("123")) # Aunque parezca un número, está entre comillas, por lo que es un string 31 | print(type(""" 32 | Multilinea 33 | """)) # Un string que abarca varias líneas usando triple comillas 34 | 35 | print("bool:") # Valores booleanos (True o False) 36 | print(type(True)) # Valor booleano verdadero 37 | print(type(False)) # Valor booleano falso 38 | print(type(1 < 2)) # Comparación que devuelve un booleano (True) 39 | 40 | print("NoneType:") # Representa la ausencia de valor 41 | print(type(None)) # `None` es un tipo especial en Python que representa "sin valor" o "nulo" -------------------------------------------------------------------------------- /01_basic/03_cast.py: -------------------------------------------------------------------------------- 1 | ### 2 | # 03 - casting de types 3 | # Transformar un tipo de un valor a otro 4 | ### 5 | 6 | from os import system 7 | if system("clear") != 0: system("cls") 8 | 9 | print("Conversión de tipos") 10 | 11 | # Convertir una cadena que contiene un número a un entero y sumarlo con otro entero 12 | print(2 + int("100")) # Convierte "100" a entero y suma 2. Resultado: 102 13 | 14 | # Convertir un entero a cadena para concatenarlo con otra cadena 15 | print("100" + str(2)) # Convierte el número 2 a cadena y lo concatena. Resultado: "1002" 16 | 17 | # Convertir una cadena con un número decimal a tipo float 18 | print(type(float("3.1416"))) # Convierte "3.1416" a float y muestra su tipo. Resultado: 19 | 20 | # Convertir un número decimal a entero (se trunca la parte decimal) 21 | print(int(3.1416)) # Convierte 3.1416 a 3 eliminando la parte decimal. Resultado: 3 22 | 23 | # Evaluar valores numéricos como booleanos 24 | print(bool(3)) # Cualquier número distinto de 0 es True. Resultado: True 25 | print(bool(0)) # 0 es False. Resultado: False 26 | print(bool(-1)) # Números negativos también son True. Resultado: True 27 | 28 | # Evaluar cadenas como booleanos 29 | print(bool("")) # Una cadena vacía es False. Resultado: False 30 | print(bool(" ")) # Una cadena con espacios es True. Resultado: True 31 | print(bool("False")) # Una cadena con texto, aunque sea "False", es True. Resultado: True 32 | 33 | # Redondear un número decimal 34 | print(round(2.51)) # Redondea 2.51 al entero más cercano. Resultado: 3 35 | 36 | # Este genera un error y se comenta para evitar conflicto en la ejecución 37 | # print(int("Hola mundo")) # ❌ Esto generaría un ValueError porque "Hola mundo" no es un número -------------------------------------------------------------------------------- /01_basic/04_variables.py: -------------------------------------------------------------------------------- 1 | ## 2 | # 04 - Variables 3 | # Las variables sirven para guardar datos en memoria. 4 | # Python es un lenguaje de tipado dinámico y de tipado fuerte. 5 | ### 6 | 7 | from os import system 8 | if system("clear") != 0: system("cls") 9 | 10 | # Para asignar una variable solo hace falta poner el nombre de la variable y asignarle un valor 11 | my_name = "midudev" 12 | print(my_name) # Imprime el valor de la variable my_name 13 | 14 | age = 32 15 | print(age) # Imprime el valor de la variable age) 16 | 17 | # Reasignar un nuevo valor a una variable existente 18 | age = 39 19 | print(age) # Ahora la variable age tiene el valor 39 20 | 21 | # Tipado dinámico: el tipo de dato se determine en tiempo de ejecución 22 | # No es necesario declarar explícitamente el tipo de variable 23 | name = "midudev" 24 | print(type(name)) # Muestra el tipo de dato de la variable name (str) 25 | 26 | name = 32 27 | print(type(name)) # Ahora la variable tiene un número entero (int) 28 | 29 | # Tipado fuerte: Python no realiza conversione de tipo automáticas 30 | # Esto generará un error porque no se puede sumar un número con una cadena 31 | # print(10 + "2") # ❌ TypeError: unsupported operand type(s) for +: 'int' and 'str' 32 | 33 | # f-string (literal de cadena de formato) 34 | # desde la versión Python 3.6 35 | print(f"Hola {my_name}, tengo {age + 5} años") 36 | 37 | # No recomendada forma de asignar variables 38 | name, age, city = "midudev", 32, "Bogotá" 39 | 40 | # Convenciones de nombres de variables 41 | mi_nombre_de_variable = "ok" # snake_case 42 | nombre = "ok" 43 | 44 | miNombreDeVariable = "no-recomendado" # camelCase 45 | MiNombreDeVariable = "no-recomendado" # PascalCase 46 | minombredevariable = "no-recomendado" # todojunto 47 | 48 | mi_nombre_de_variable_123 = "ok" 49 | 50 | MI_CONSTANTE = 3.14 # UPPER_CASE -> constantes 51 | 52 | # Nombres NO válidos de variables (esto generaría errores) 53 | # 123123_variable = "ko" # ❌ No puede comenzar con un número 54 | # mi-variable = "ko" # ❌ No puede contener guiones (-), usa guion bajo (_) 55 | # mi variable = "ko" # ❌ No puede contener espacios 56 | # True = False # ❌ No puedes sobrescribir palabras reservadas 57 | 58 | # Palabras reservadas en Python (no se pueden usar como nombres de variables) 59 | 60 | # ['False', 'None', 'True', 'and', 'as', 'assert', 61 | # 'async', 'await', 'break', 'class', 'continue', 62 | # 'def', 'del', 'elif', 'else', 'except', 'finally', 63 | # 'for', 'from', 'global', 'if', 'import', 'in', 'is', 64 | # 'lambda', 'nonlocal', 'not', 'or', 'pass', 'raise', 65 | # 'return', 'try', 'while', 'with', 'yield'] 66 | 67 | # Anotaciones de tipo (opcional, para mayor claridad en el código) 68 | is_user_logged_in: bool = True # Indica que la variable es un booleano 69 | print(is_user_logged_in) 70 | 71 | name: str = "midudev" # Indica que la variable es una cadena de texto 72 | print(name) 73 | 74 | -------------------------------------------------------------------------------- /01_basic/05_input.py: -------------------------------------------------------------------------------- 1 | ### 2 | # 05 - Entrada de usuario (input()) - Versión simplificada 3 | # La función input() permite obtener datos del usuario a través de la consola. 4 | ### 5 | 6 | from os import system 7 | if system("clear") != 0: system("cls") 8 | 9 | # Para obtener datos del usuario se usa la función input() 10 | # La función input() recibe un mensaje que se muestra al usuario 11 | # y devuelve el valor introducido por el usuario 12 | nombre = input("Hola, ¿cómo te llamas?\n") 13 | print(f"Hola {nombre}, encantado de conocerte") 14 | 15 | # Ten en cuenta que la función input() devuelve un string 16 | # Así que si queremos obtener un número se debe convertir el string a un número 17 | age = input("¿Cuántos años tienes?\n") 18 | age = int(age) 19 | print(f"Tienes {age} años") 20 | 21 | # La función input() también puede devolver múltiples valores 22 | # Para hacerlo, el usuario debe separar los valores con una coma 23 | print("Obtener múltiples valores a la vez") 24 | country, city = input("¿En qué país y ciudad vives?\n").split() 25 | 26 | print(f"Vives en {country}, {city}") -------------------------------------------------------------------------------- /01_basic/exercises.py: -------------------------------------------------------------------------------- 1 | ### 2 | # exercises.py 3 | # Ejercicios para practicar los conceptos aprendidos en las lecciones. 4 | ### 5 | 6 | from os import system 7 | if system("clear") != 0: system("cls") 8 | 9 | print("\nEjercicio 1: Imprimir mensajes") 10 | print("Escribe un programa que imprima tu nombre y tu ciudad en líneas separadas.") 11 | 12 | ### Completa aquí 13 | 14 | print("--------------") 15 | 16 | print("\nEjercicio 2: Muestra los tipos de datos de las siguientes variables:") 17 | print("Usa el comando 'type()' para determinar el tipo de datos de cada variable.") 18 | a = 15 19 | b = 3.14159 20 | c = "Hola mundo" 21 | d = True 22 | e = None 23 | 24 | ### Completa aquí 25 | 26 | print("--------------") 27 | 28 | print("\nEjercicio 3: Casting de tipos") 29 | print("Convierte la cadena \"12345\" a un entero y luego a un float.") 30 | print("Convierte el float 3.99 a un entero. ¿Qué ocurre?") 31 | 32 | ### Completa aquí 33 | 34 | print("--------------") 35 | 36 | print("\nEjercicio 4: Variables") 37 | print("Crea variables para tu nombre, edad y altura.") 38 | print("Usa f-strings para imprimir una presentación.") 39 | 40 | # "Hola! Me llamo midudev y tengo 39 años, mido 1.70 metros" 41 | 42 | ### Completa aquí 43 | 44 | print("--------------") 45 | 46 | print("\nEjercicio 5: Números") 47 | print("1. Crea una variable con el número PI (sin asignar una variable)") 48 | print("2. Redondea el número con round()") 49 | print("3. Haz la división entera entre el número que te salió y el número 2") 50 | print("4. El resultado debería ser 1") -------------------------------------------------------------------------------- /01_basic/soluciones.py: -------------------------------------------------------------------------------- 1 | ### 2 | # soluciones.py 3 | # Soluciones a los ejercicios del archivo exercises.py 4 | ### 5 | 6 | print("\nEjercicio 1: Imprimir mensajes") 7 | print("Escribe un programa que imprima tu nombre y tu ciudad en líneas separadas.") 8 | 9 | # Solución: 10 | nombre = "Carlos" # Reemplázalo con tu nombre 11 | ciudad = "Buenos Aires" # Reemplázalo con tu ciudad 12 | 13 | print(nombre) 14 | print(ciudad) 15 | 16 | print("--------------") 17 | 18 | print("\nEjercicio 2: Muestra los tipos de datos de las siguientes variables:") 19 | print("Usa el comando 'type()' para determinar el tipo de datos de cada variable.") 20 | 21 | # Variables dadas en el enunciado 22 | a = 15 23 | b = 3.14159 24 | c = "Hola mundo" 25 | d = True 26 | e = None 27 | 28 | # Solución: 29 | print("Tipo de a:", type(a)) 30 | print("Tipo de b:", type(b)) 31 | print("Tipo de c:", type(c)) 32 | print("Tipo de d:", type(d)) 33 | print("Tipo de e:", type(e)) 34 | 35 | print("--------------") 36 | 37 | print("\nEjercicio 3: Casting de tipos") 38 | print("Convierte la cadena '12345' a un entero y luego a un float.") 39 | print("Convierte el float 3.99 a un entero. ¿Qué ocurre?") 40 | 41 | # Solución: 42 | cadena = "12345" 43 | numero_entero = int(cadena) # Convertir cadena a entero 44 | numero_float = float(numero_entero) # Convertir entero a float 45 | 46 | print("Número entero:", numero_entero) 47 | print("Número como float:", numero_float) 48 | 49 | float_num = 3.99 50 | entero_convertido = int(float_num) # Se trunca el decimal 51 | 52 | print("Float original:", float_num) 53 | print("Float convertido a entero (se trunca la parte decimal):", entero_convertido) 54 | 55 | print("--------------") 56 | 57 | print("\nEjercicio 4: Variables") 58 | print("Crea variables para tu nombre, edad y altura.") 59 | print("Usa f-strings para imprimir una presentación.") 60 | 61 | # Solución: 62 | nombre = "midudev" 63 | edad = 18 64 | altura = 1.90 65 | 66 | # Imprimir presentación con f-string 67 | print(f"Hola! Me llamo {nombre} y tengo {edad} años, mido {altura} metros") 68 | 69 | print("--------------") 70 | 71 | print("\nEjercicio 5: Números") 72 | print("1. Crea una variable con el número PI (sin asignar una variable)") 73 | print("2. Redondea el número con round()") 74 | print("3. Haz la división entera entre el número que te salió y el número 2") 75 | print("4. El resultado debería ser 1") 76 | 77 | # Solución: 78 | # Redondeamos directamente el valor de pi sin almacenarlo en una variable 79 | resultado = int(round(3.1416) / 2) 80 | print("Valor de PI (aproximado):", 3.1416) 81 | print("PI redondeado:", round(3.1416)) 82 | print("División entera de PI redondeado entre 2:", resultado) 83 | -------------------------------------------------------------------------------- /02_flow_control/01_if.py: -------------------------------------------------------------------------------- 1 | ### 2 | # 01 - Sentencias condicionales (if, elif, else) 3 | # Permiten ejecutar bloques de código solo si se cumplen ciertas condiciones. 4 | ### 5 | 6 | from os import system 7 | if system("clear") != 0: system("cls") 8 | 9 | print("\n Sentencia simple condicional") 10 | # Podemos usar la palabra clave "if" para ejecutar un bloque de código 11 | # solo si se cumple una condición. 12 | edad = 18 13 | if edad >= 18: 14 | print("Eres mayor de edad") 15 | print("¡Felicidades!") 16 | 17 | # Si no se cumple la condición, no se ejecuta el bloque de código 18 | edad = 15 19 | if edad >= 18: 20 | print("Eres mayor de edad") 21 | print("¡Felicidades!") 22 | 23 | # Podemos usar el comando "else" para ejecutar un bloque de código 24 | # si no se cumple la condición anterior del if 25 | print("\n Sentencia condicional con else") 26 | edad = 15 27 | if edad >= 18: 28 | print("Eres mayor de edad") 29 | else: 30 | print("Eres menor de edad") 31 | 32 | print("\n Sentencia condicional con elif") 33 | nota = 5 34 | 35 | # Además de usar "if" y "else", podemos usar "elif" para determinar 36 | # múltiples condiciones, ten en cuenta que sólo se ejecutará el primer bloque 37 | # de código que cumpla la condición (o la del else, si está presente) 38 | if nota >= 9: 39 | print("¡Sobresaliente!") 40 | elif nota >= 7: 41 | print("Notable!") 42 | elif nota >= 5: 43 | print("¡Aprobado!") 44 | else: 45 | print("¡No está calificado!") 46 | 47 | print("\n Condiciones múltiples") 48 | edad = 16 49 | tiene_carnet = True 50 | 51 | # Los operadores lógicos en Python son: 52 | # and: True si ambos operandos son verdaderos 53 | # or: True si al menos uno de los operandos es verdadero 54 | # En JavaScript: 55 | # && sería and 56 | # || sería or 57 | 58 | # En el caso que seas mayor de edad y tengas carnet... 59 | # entonces podrás conducir 60 | if edad >= 18 and tiene_carnet: 61 | print("Puedes conducir 🚗") 62 | else: 63 | print("POLICIA 🚔!!!1!!!") 64 | 65 | # En un pueblo de Isla Margarita son más laxos y 66 | # te dejan conducir si eres mayor de edad O tienes carnet 67 | if edad >= 18 or tiene_carnet: 68 | print("Puedes conducir en la Isla Margarita 🚗") 69 | else: 70 | print("Paga al policía y te deja conducir!!!") 71 | 72 | # También tenemos el operador lógico "not" 73 | # que nos permite negar una condición 74 | es_fin_de_semana = False 75 | # JavaScript -> ! 76 | if not es_fin_de_semana: 77 | print("¡midu, venga que hay que streamear!") 78 | 79 | # Podemos anidar condicionales, uno dentro del otro 80 | # para determinar múltiples condiciones aunque 81 | # siempre intentaremos evitar esto para simplificar 82 | print("\n Anidar condicionales") 83 | edad = 20 84 | tiene_dinero = True 85 | 86 | if edad >= 18: 87 | if tiene_dinero: 88 | print("Puedes ir a la discoteca") 89 | else: 90 | print("Quédate en casa") 91 | else: 92 | print("No puedes entrar a la disco") 93 | 94 | # Más fácil sería: 95 | # if edad < 18: 96 | # print("No puedes entrar a la disco") 97 | # elif tiene_dinero: 98 | # print("Puedes ir a la discoteca") 99 | # else: 100 | # print("Quédate en casa") 101 | 102 | # Ten en cuenta que hay valores que al usarlos como condiciones 103 | # en Python son evaluados como verdaderos o falsos 104 | # por ejemplo, el número 5, es True 105 | numero = 5 106 | if numero: # True 107 | print("El número no es cero") 108 | 109 | # Pero el número 0 se evalúa como False 110 | numero = 0 111 | if numero: # False 112 | print("Aquí no entrará nunca") 113 | 114 | # También el valor vacío "" se evalúa como False 115 | nombre = "" 116 | if nombre: 117 | print("El nombre no es vacío") 118 | 119 | # ¡Ten cuidado con no confundir la asignación = con la comparación ==! 120 | numero = 3 # asignación 121 | es_el_tres = numero == 3 # comparación 122 | 123 | if es_el_tres: 124 | print("El número es 3") 125 | 126 | # A veces podemos crear condicionales en una sola línea usando 127 | # las ternarias, es una forma concisa de un if-else en una línea de código 128 | print("\nLa condición ternaria:") 129 | # [código si cumple la condición] if [condicion] else [codigo si no cumple] 130 | 131 | edad = 17 132 | mensaje = "Es mayor de edad" if edad >= 18 else "Es menor de edad" 133 | print(mensaje) 134 | 135 | ### 136 | # EJERCICIOS 137 | ### 138 | 139 | # Ejercicio 1: Determinar el mayor de dos números 140 | # Pide al usuario que introduzca dos números y muestra un mensaje 141 | # indicando cuál es mayor o si son iguales 142 | 143 | # Ejercicio 2: Calculadora simple 144 | # Pide al usuario dos números y una operación (+, -, *, /) 145 | # Realiza la operación y muestra el resultado (maneja la división entre zero) 146 | 147 | # Ejercicio 3: Año bisiesto 148 | # Pide al usuario que introduzca un año y determina si es bisiesto. 149 | # Un año es bisiesto si es divisible por 4, excepto si es divisible por 100 pero no por 400. 150 | 151 | # Ejercicio 4: Categorizar edades 152 | # Pide al usuario que introduzca una edad y la clasifique en: 153 | # - Bebé (0-2 años) 154 | # - Niño (3-12 años) 155 | # - Adolescente (13-17 años) 156 | # - Adulto (18-64 años) 157 | # - Adulto mayor (65 años o más) -------------------------------------------------------------------------------- /02_flow_control/01_if_solutions.py: -------------------------------------------------------------------------------- 1 | ### 2 | # EJERCICIOS 3 | ### 4 | 5 | # Ejercicio 1: Determinar el mayor de dos números 6 | # Pide al usuario que introduzca dos números y muestra un mensaje 7 | # indicando cuál es mayor o si son iguales 8 | print("\nEjercicio 1:") 9 | num1 = int(input("Introduce el primer número: ")) 10 | num2 = int(input("Introduce el segundo número: ")) 11 | 12 | if num1 > num2: 13 | print(f"{num1} es mayor que {num2}") 14 | elif num2 > num1: 15 | print(f"{num2} es mayor que {num1}") 16 | else: 17 | print("Los números son iguales") 18 | 19 | # Ejercicio 2: Calculadora simple 20 | # Pide al usuario dos números y una operación (+, -, *, /) 21 | # Realiza la operación y muestra el resultado (maneja la división entre zero) 22 | print("\nEjercicio 2:") 23 | num1 = float(input("Introduce el primer número: ")) 24 | num2 = float(input("Introduce el segundo número: ")) 25 | operacion = input("Introduce la operación (+, -, *, /): ") 26 | 27 | if operacion == "+": 28 | resultado = num1 + num2 29 | elif operacion == "-": 30 | resultado = num1 - num2 31 | elif operacion == "*": 32 | resultado = num1 * num2 33 | elif operacion == "/": 34 | if num2 == 0: 35 | print("Error: No se puede dividir por cero.") 36 | else: 37 | resultado = num1 / num2 38 | else: 39 | print("Operación no válida.") 40 | 41 | if 'resultado' in locals(): #Comprueba si la variable resultado existe. 42 | print(f"El resultado es: {resultado}") 43 | 44 | # Ejercicio 3: Año bisiesto 45 | # Pide al usuario que introduzca un año y determina si es bisiesto. 46 | # Un año es bisiesto si es divisible por 4, excepto si es divisible por 100 pero no por 400. 47 | print("\nEjercicio 3:") 48 | anio = int(input("Introduce un año: ")) 49 | 50 | if (anio % 4 == 0 and anio % 100 != 0) or anio % 400 == 0: 51 | print(f"{anio} es un año bisiesto.") 52 | else: 53 | print(f"{anio} no es un año bisiesto.") 54 | 55 | # Ejercicio 4: Categorizar edades 56 | # Pide al usuario que introduzca una edad y la clasifique en: 57 | # - Bebé (0-2 años) 58 | # - Niño (3-12 años) 59 | # - Adolescente (13-17 años) 60 | # - Adulto (18-64 años) 61 | # - Adulto mayor (65 años o más) 62 | print("\nEjercicio 4:") 63 | edad = int(input("Introduce una edad: ")) 64 | 65 | if 0 <= edad <= 2: 66 | print("Bebé") 67 | elif 3 <= edad <= 12: 68 | print("Niño") 69 | elif 13 <= edad <= 17: 70 | print("Adolescente") 71 | elif 18 <= edad <= 64: 72 | print("Adulto") 73 | elif edad >= 65: 74 | print("Adulto mayor") 75 | else: 76 | print("Edad no válida.") -------------------------------------------------------------------------------- /02_flow_control/02_booleans.py: -------------------------------------------------------------------------------- 1 | ### 2 | # 02 - Booleanos 3 | # Valores lógicos: True (verdadero) y False (falso). 4 | # Fundamentales para el control de flujo y la lógica en programación. 5 | ### 6 | 7 | from os import system 8 | if system("clear") != 0: system("cls") 9 | 10 | # Los booleanos representan valores de verdad: True o False. 11 | print("\nValores booleanos básicos:") 12 | print(True) 13 | print(False) 14 | 15 | # Operadores de comparación: devuelven un valor booleano. 16 | print("\nOperadores de comparación:") 17 | print("5 > 3:", 5 > 3) # True 18 | print("5 < 3:", 5 < 3) # False 19 | print("5 == 5:", 5 == 5) # True (igualdad) 20 | print("5 != 3:", 5 != 3) # True (desigualdad) 21 | print("5 >= 5:", 5 >= 5) # True (mayor o igual que) 22 | print("5 <= 3:", 5 <= 3) # False (menor o igual que) 23 | 24 | print("\nComparación de cadenas:") 25 | print("'manzana' < 'pera':", "manzana" < "pera") # True 26 | print("'Hola' == 'hola'", "Hola" == "hola") # False 27 | 28 | # Operadores lógicos: and, or, not 29 | print("\nOperadores lógicos:") 30 | print("True and True:", True and True) # True 31 | print("True and False:", True and False) # False 32 | print("True or False:", True or False) # True 33 | print("False or False:", False or False) # False 34 | print("not True:", not True) # False 35 | print("not False:", not False) # True 36 | 37 | # Tablas de verdad (para referencia): 38 | print("\nTablas de verdad:") 39 | print("\nand:") 40 | print("A B A and B") 41 | print("True True ", True and True) 42 | print("True False", True and False) 43 | print("False True ", False and True) 44 | print("False False", False and False) 45 | 46 | print("\n or:") 47 | print("A B A or B") 48 | print("True True ", True or True) 49 | print("True False", True or False) 50 | print("False True ", False or True) 51 | print("False False", False or False) 52 | 53 | print("\n not:") 54 | print("A not A") 55 | print("True ", not True) 56 | print("False", not False) -------------------------------------------------------------------------------- /02_flow_control/03_list.py: -------------------------------------------------------------------------------- 1 | ### 2 | # 03 - Listas 3 | # Secuencias mutables de elementos. 4 | # Pueden contener elementos de diferentes tipos. 5 | ### 6 | 7 | from os import system 8 | if system("clear") != 0: system("cls") 9 | 10 | # Creación de listas 11 | print("\nCrear listas") 12 | lista1 = [1, 2, 3, 4, 5] # lista de enteros 13 | lista2 = ["manzanas", "peras", "plátanos"] # lista de cadenas 14 | lista3 = [1, "hola", 3.14, True] # lista de tipos mixtos 15 | 16 | lista_vacia = [] 17 | lista_de_listas = [[1, 2], ['calcetin', 4]] 18 | matrix = [[1, 2], [2, 3], [4, 5]] 19 | 20 | print(lista1) 21 | print(lista2) 22 | print(lista3) 23 | print(lista_vacia) 24 | print(lista_de_listas) 25 | print(matrix) 26 | 27 | # Acceso a elementos por índice 28 | print("\nAcceso a elementos por índice") 29 | print(lista2[0]) # manzanas 30 | print(lista2[1]) # peras 31 | print(lista2[-1]) # plátanos 32 | print(lista2[-2]) # peras 33 | 34 | print(lista_de_listas[1][0]) 35 | 36 | # Slicing (rebanado) de listas 37 | lista1 = [1, 2, 3, 4, 5] 38 | print(lista1[1:4]) # [2, 3, 4] 39 | print(lista1[:3]) # [1, 2, 3] 40 | print(lista1[3:]) # [4, 5] 41 | print(lista1[:]) # [1, 2, 3, 4, 5] 42 | 43 | # El tercer parámetro es el paso (step) 44 | lista1 = [1, 2, 3, 4, 5, 6, 7, 8] 45 | print(lista1[::2]) # para devolver índices pares 46 | print(lista1[::-1]) # para devolver índices inversos 47 | 48 | # Modificar una lista 49 | lista1[0] = 20 50 | print(lista1) 51 | 52 | # Añadir elementos a una lista 53 | lista1 = [1, 2, 3] 54 | 55 | # forma larga y menos eficiente 56 | lista1 = lista1 + [4, 5, 6] 57 | print(lista1) 58 | 59 | # forma corta y más eficiente 60 | lista1 += [7, 8, 9] 61 | print(lista1) 62 | 63 | # Recuperar longitud de una lista 64 | print("Longitud de la lista", len(lista1)) 65 | 66 | ### 67 | # EJERCICIOS 68 | ### 69 | 70 | # Ejercicio 1: El mensaje secreto 71 | # Dada la siguiente lista: 72 | # mensaje = ["C", "o", "d", "i", "g", "o", " ", "s", "e", "c", "r", "e", "t", "o"] 73 | # Utilizando slicing y concatenación, crea una nueva lista que contenga solo el mensaje "secreto". 74 | 75 | # Ejercicio 2: Intercambio de posiciones 76 | # Dada la siguiente lista: 77 | # numeros = [10, 20, 30, 40, 50] 78 | # Intercambia la primera y la última posición utilizando solo asignación por índice. 79 | 80 | # Ejercicio 3: El sándwich de listas 81 | # Dadas las siguientes listas: 82 | # pan = ["pan arriba"] 83 | # ingredientes = ["jamón", "queso", "tomate"] 84 | # pan_abajo = ["pan abajo"] 85 | # Crea una lista llamada sandwich que contenga el pan de arriba, los ingredientes y el pan de abajo, en ese orden. 86 | 87 | # Ejercicio 4: Duplicando la lista 88 | # Dada una lista: 89 | # lista = [1, 2, 3] 90 | # Crea una nueva lista que contenga los elementos de la lista original duplicados. 91 | # Ejemplo: [1, 2, 3] -> [1, 2, 3, 1, 2, 3] 92 | 93 | # Ejercicio 5: Extrayendo el centro 94 | # Dada una lista con un número impar de elementos, extrae el elemento que se encuentra en el centro de la lista utilizando slicing. 95 | # Ejemplo: lista = [10, 20, 30, 40, 50] -> El centro es 30 96 | 97 | # Ejercicio 6: Reversa parcial 98 | # Dada una lista, invierte solo la primera mitad de la lista (utilizando slicing y concatenación). 99 | # Ejemplo: lista = [1, 2, 3, 4, 5, 6] -> Resultado: [3, 2, 1, 4, 5, 6] 100 | -------------------------------------------------------------------------------- /02_flow_control/03_list_solutions.py: -------------------------------------------------------------------------------- 1 | ### 2 | # SOLUCIONES 3 | ### 4 | 5 | # Ejercicio 1: El mensaje secreto 6 | # Dada la siguiente lista: 7 | # mensaje = ["C", "o", "d", "i", "g", "o", " ", "s", "e", "c", "r", "e", "t", "o"] 8 | # Utilizando slicing y concatenación, crea una nueva lista que contenga solo el mensaje "secreto". 9 | print("\nEjercicio 1:") 10 | mensaje = ["C", "o", "d", "i", "g", "o", " ", "s", "e", "c", "r", "e", "t", "o"] 11 | secreto = mensaje[7:] 12 | print(secreto) 13 | 14 | # Ejercicio 2: Intercambio de posiciones 15 | # Dada la siguiente lista: 16 | # numeros = [10, 20, 30, 40, 50] 17 | # Intercambia la primera y la última posición utilizando solo asignación por índice. 18 | print("\nEjercicio 2:") 19 | numeros = [10, 20, 30, 40, 50] 20 | numeros[0], numeros[-1] = numeros[-1], numeros[0] # Intercambio en una sola línea. 21 | print(numeros) 22 | 23 | # Ejercicio 3: El sándwich de listas 24 | # Dadas las siguientes listas: 25 | # pan = ["pan arriba"] 26 | # ingredientes = ["jamón", "queso", "tomate"] 27 | # pan_abajo = ["pan abajo"] 28 | # Crea una lista llamada sandwich que contenga el pan de arriba, los ingredientes y el pan de abajo, en ese orden. 29 | print("\nEjercicio 3:") 30 | pan = ["pan arriba"] 31 | ingredientes = ["jamón", "queso", "tomate"] 32 | pan_abajo = ["pan abajo"] 33 | sandwich = pan + ingredientes + pan_abajo 34 | print(sandwich) 35 | 36 | # Ejercicio 4: Duplicando la lista 37 | # Dada una lista: 38 | # lista = [1, 2, 3] 39 | # Crea una nueva lista que contenga los elementos de la lista original duplicados. 40 | # Ejemplo: [1, 2, 3] -> [1, 2, 3, 1, 2, 3] 41 | print("\nEjercicio 4:") 42 | lista = [1, 2, 3] 43 | lista_duplicada = lista + lista 44 | print(lista_duplicada) 45 | 46 | # Ejercicio 5: Extrayendo el centro 47 | # Dada una lista con un número impar de elementos, extrae el elemento que se encuentra en el centro de la lista utilizando slicing. 48 | # Ejemplo: lista = [10, 20, 30, 40, 50] -> El centro es 30 49 | print("\nEjercicio 5:") 50 | lista = [10, 20, 30, 40, 50] 51 | centro = len(lista) // 2 52 | print(lista[centro]) 53 | 54 | # Ejercicio 6: Reversa parcial 55 | # Dada una lista, invierte solo la primera mitad de la lista (utilizando slicing y concatenación). 56 | # Ejemplo: lista = [1, 2, 3, 4, 5, 6] -> Resultado: [3, 2, 1, 4, 5, 6] 57 | print("\nEjercicio 6:") 58 | lista = [1, 2, 3, 4, 5, 6] 59 | mitad = len(lista) // 2 60 | lista_invertida = lista[:mitad][::-1] + lista[mitad:] 61 | print(lista_invertida) -------------------------------------------------------------------------------- /02_flow_control/04_list_methods.py: -------------------------------------------------------------------------------- 1 | ### 2 | # 04 - Listas Métodos 3 | # Los métodos más importantes para trabajar con listas 4 | ### 5 | 6 | from os import system 7 | if system("clear") != 0: system("cls") 8 | 9 | # Creamos una lista con valores 10 | lista1 = ['a', 'b', 'c', 'd'] 11 | 12 | # Añadir o insertar elementos a la lista 13 | lista1.append('e') # Añade un elemento al final 14 | print(lista1) 15 | 16 | lista1.insert(1, '@') # Inserta un elemento en la posición que le indiquemos como primer argumento 17 | print(lista1) 18 | 19 | lista1.extend(['😃', '😍']) # Agrega elementos al final de la lista 20 | print(lista1) 21 | 22 | # Eliminar elementos de la lista 23 | lista1.remove('@') # Eliminar la primera aparición de la cadena de texto @ 24 | print(lista1) 25 | 26 | ultimo = lista1.pop() # Eliminar el último elemento de la lista y además te lo devuelve 27 | print(ultimo) 28 | print(lista1) 29 | 30 | lista1.pop(1) # Eliminar el segundo elemento de la lista (es el índice 1) 31 | print(lista1) 32 | 33 | # Eliminar por lo bestia un índice 34 | del lista1[-1] 35 | print(lista1) 36 | 37 | lista1.clear() # Eliminar todos los elementos de la lista 38 | print(lista1) 39 | 40 | # Eliminar un rango de elementos 41 | lista1 = ['🐼', '🐨', '🐶', '😿', '🐹'] 42 | del lista1[1:3] # eliminamos los elementos del índice 1 al 3 (no incluye el índice 3) 43 | print(lista1) 44 | 45 | # Más métodos útiles 46 | print('Ordenar listas modificando la original') 47 | numbers = [3, 10, 2, 8, 99, 101] 48 | numbers.sort() 49 | print(numbers) 50 | 51 | print('Ordenar listas creando una nueva lista') 52 | numbers = [3, 10, 2, 8, 99, 101] 53 | sorted_numbers = sorted(numbers) 54 | print(sorted_numbers) 55 | 56 | print("Ordenar una lista de cadenas de texto (todo minúscula)") 57 | frutas = ['manzana', 'pera', 'limón', 'manzana', 'pera', 'limón'] 58 | sorted_frutas = sorted(frutas) 59 | print(sorted_frutas) 60 | 61 | print("Ordenar una lista de cadenas de texto (mezclas mayúscula y minúscula)") 62 | frutas = ['manzana', 'Pera', 'Limón', 'manzana', 'pera', 'limón'] 63 | frutas.sort(key=str.lower) 64 | print(frutas) 65 | 66 | # Más cositas útiles 67 | animals = ['🐶', '🐼', '🐨', '🐶'] 68 | print(len(animals)) # Tamaño de la listas -> 4 69 | print(animals.count('🐶')) # Cuantas veces aparece el elemento '🐶' -> 2 70 | print('🐼' in animals) # Comprueba si hay un '🐼' en la lista -> True 71 | print('🐹' in animals) # -> False 72 | 73 | ### 74 | # EJERCICIOS 75 | # Usa siempre que puedas los métodos que has aprendido 76 | ### 77 | 78 | # Ejercicio 1: Añadir y modificar elementos 79 | # Crea una lista con los números del 1 al 5. 80 | # Añade el número 6 al final usando append(). 81 | # Inserta el número 10 en la posición 2 usando insert(). 82 | # Modifica el primer elemento de la lista para que sea 0. 83 | 84 | # Ejercicio 2: Combinar y limpiar listas 85 | # Crea dos listas: 86 | # lista_a = [1, 2, 3] 87 | # lista_b = [4, 5, 6, 1, 2] 88 | # Extiende lista_a con lista_b usando extend(). 89 | # Elimina la primera aparición del número 1 en lista_a usando remove(). 90 | # Elimina el elemento en el índice 3 de lista_a usando pop(). Imprime el elemento eliminado. 91 | # Limpia completamente lista_b usando clear(). 92 | 93 | # Ejercicio 3: Slicing y eliminación con del 94 | # Crea una lista con los números del 1 al 10. 95 | # Utiliza slicing y del para eliminar los elementos desde el índice 2 hasta el 5 (sin incluir el 5). 96 | # Imprime la lista resultante. 97 | 98 | # Ejercicio 4: Ordenar y contar 99 | # Crea una lista con los siguientes números: [5, 2, 8, 1, 9, 4, 2]. 100 | # Ordena la lista de forma ascendente usando sort(). 101 | # Cuenta cuántas veces aparece el número 2 en la lista usando count(). 102 | # Comprueba si el número 7 está en la lista usando in. 103 | 104 | # Ejercicio 5: Copia vs. Referencia 105 | # Crea una lista llamada original con los números [1, 2, 3]. 106 | # Crea una copia de la lista original llamada copia_1 usando slicing. 107 | # Crea otra copia llamada copia_2 usando copy(). 108 | # Crea una referencia a la lista original llamada referencia. 109 | # Modifica el primer elemento de la lista referencia a 10. 110 | # Imprime las cuatro listas (original, copia_1, copia_2, referencia) y observa los cambios. 111 | 112 | # Ejercicio 6: Ordenar strings sin diferenciar mayúsculas y minúsculas. 113 | # Crea una lista con las siguientes cadenas: ["Manzana", "pera", "BANANA", "naranja"]. 114 | # Ordena la lista sin diferenciar entre mayúsculas y minúsculas. -------------------------------------------------------------------------------- /02_flow_control/04_list_methods_solutions.py: -------------------------------------------------------------------------------- 1 | ### 2 | # EJERCICIOS 3 | ### 4 | 5 | # Ejercicio 1: Añadir y modificar elementos 6 | # Crea una lista con los números del 1 al 5. 7 | # Añade el número 6 al final usando append(). 8 | # Inserta el número 10 en la posición 2 usando insert(). 9 | # Modifica el primer elemento de la lista para que sea 0. 10 | print("\nEjercicio 1:") 11 | lista = [1, 2, 3, 4, 5] 12 | lista.append(6) 13 | lista.insert(2, 10) 14 | lista[0] = 0 15 | print(lista) # Output: [0, 2, 10, 3, 4, 5, 6] 16 | 17 | # Ejercicio 2: Combinar y limpiar listas 18 | # Crea dos listas: 19 | # lista_a = [1, 2, 3] 20 | # lista_b = [4, 5, 6, 1, 2] 21 | # Extiende lista_a con lista_b usando extend(). 22 | # Elimina la primera aparición del número 1 en lista_a usando remove(). 23 | # Elimina el elemento en el índice 3 de lista_a usando pop(). Imprime el elemento eliminado. 24 | # Limpia completamente lista_b usando clear(). 25 | print("\nEjercicio 2:") 26 | lista_a = [1, 2, 3] 27 | lista_b = [4, 5, 6, 1, 2] 28 | lista_a.extend(lista_b) 29 | lista_a.remove(1) 30 | elemento_eliminado = lista_a.pop(3) 31 | print(f"Elemento eliminado: {elemento_eliminado}") #Output: Elemento eliminado: 5 32 | lista_b.clear() 33 | print("Lista a:", lista_a) #Output: Lista a: [2, 3, 4, 6, 1, 2] 34 | print("Lista b:", lista_b) #Output: Lista b: [] 35 | 36 | # Ejercicio 3: Slicing y eliminación con del 37 | # Crea una lista con los números del 1 al 10. 38 | # Utiliza slicing y del para eliminar los elementos desde el índice 2 hasta el 5 (sin incluir el 5). 39 | # Imprime la lista resultante. 40 | print("\nEjercicio 3:") 41 | lista = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] 42 | del lista[2:5] 43 | print(lista) # Output: [1, 2, 6, 7, 8, 9, 10] 44 | 45 | # Ejercicio 4: Ordenar y contar 46 | # Crea una lista con los siguientes números: [5, 2, 8, 1, 9, 4, 2]. 47 | # Ordena la lista de forma ascendente usando sort(). 48 | # Cuenta cuántas veces aparece el número 2 en la lista usando count(). 49 | # Comprueba si el número 7 está en la lista usando in. 50 | print("\nEjercicio 4:") 51 | lista = [5, 2, 8, 1, 9, 4, 2] 52 | lista.sort() 53 | cantidad_dos = lista.count(2) 54 | esta_el_siete = 7 in lista 55 | print(f"Lista ordenada: {lista}") #Output: Lista ordenada: [1, 2, 2, 4, 5, 8, 9] 56 | print(f"Cantidad de 2: {cantidad_dos}") #Output: Cantidad de 2: 2 57 | print(f"¿Está el 7?: {esta_el_siete}") #Output: ¿Está el 7?: False 58 | 59 | # Ejercicio 5: Copia vs. Referencia 60 | # Crea una lista llamada original con los números [1, 2, 3]. 61 | # Crea una copia de la lista original llamada copia_1 usando slicing. 62 | # Crea otra copia llamada copia_2 usando copy(). 63 | # Crea una referencia a la lista original llamada referencia. 64 | # Modifica el primer elemento de la lista referencia a 10. 65 | # Imprime las cuatro listas (original, copia_1, copia_2, referencia) y observa los cambios. 66 | print("\nEjercicio 5:") 67 | original = [1, 2, 3] 68 | copia_1 = original[:] 69 | copia_2 = original.copy() 70 | referencia = original 71 | referencia[0] = 10 72 | print(f"Original: {original}") # Output: Original: [10, 2, 3] 73 | print(f"Copia 1 (slicing): {copia_1}") # Output: Copia 1 (slicing): [1, 2, 3] 74 | print(f"Copia 2 (copy()): {copia_2}") # Output: Copia 2 (copy()): [1, 2, 3] 75 | print(f"Referencia: {referencia}") # Output: Referencia: [10, 2, 3] 76 | 77 | # Ejercicio 6: Ordenar strings sin diferenciar mayúsculas y minúsculas. 78 | # Crea una lista con las siguientes cadenas: ["Manzana", "pera", "BANANA", "naranja"]. 79 | # Ordena la lista sin diferenciar entre mayúsculas y minúsculas. 80 | print("\nEjercicio 6:") 81 | strings = ["Manzana", "pera", "BANANA", "naranja"] 82 | strings.sort(key=str.lower) 83 | print(strings) # Output: ['BANANA', 'Manzana', 'naranja', 'pera'] -------------------------------------------------------------------------------- /03_loops/01_loop_while.py: -------------------------------------------------------------------------------- 1 | ### 2 | # 01 - Bucles (while) 3 | # Permiten ejecutar un bloque de código repetidamente mientras se cumpla una condición 4 | ### 5 | 6 | from os import system 7 | if system("clear") != 0: system("cls") 8 | 9 | print("\n Bucle while:") 10 | 11 | # Bucle con una simple condición 12 | contador = 0 13 | 14 | while contador <= 5: 15 | print(contador) 16 | contador += 1 # es super importante para evitar un bucle infinito 17 | 18 | # utilizando la palabra break, para romper el bucle 19 | print("\n Bucle while con break:") 20 | contador = 0 21 | 22 | while True: 23 | print(contador) 24 | contador += 1 25 | if contador == 5: 26 | break # sale del bucle 27 | 28 | # continue, que lo hace es saltar esa iteración en concreto 29 | # y continuar con el bucle 30 | print("\n Bucle con continue") 31 | contador = 0 32 | while contador < 10: 33 | contador += 1 34 | 35 | if contador % 2 == 0: 36 | continue 37 | 38 | print(contador) 39 | 40 | # else, esta condición cuando se ejecuta? 41 | print("\n Bucle while con else:") 42 | contador = 0 43 | while contador < 5: 44 | print(contador) 45 | contador += 1 46 | else: 47 | print("El bucle ha terminado") 48 | 49 | # else, esta condición cuando se ejecuta? 50 | print("\n Bucle while con else:") 51 | contador = 0 52 | while contador < 5: 53 | print(contador) 54 | contador += 1 55 | else: 56 | print("El bucle ha terminado") 57 | 58 | # pedirle al usuario un número que tiene 59 | # que ser positivo si no, no le dejamos en paz 60 | numero = -1 61 | while numero < 0: 62 | numero = int(input("Escribe un número positivo: ")) 63 | if numero < 0: 64 | print("El número debe ser positivo. Intenta otra vez, majo o maja.") 65 | 66 | print(f"El número que has introducido es {numero}") 67 | 68 | numero = -1 69 | while numero < 0: 70 | try: 71 | numero = int(input("Escribe un número positivo: ")) 72 | if numero < 0: 73 | print("El número debe ser positivo. Intenta otra vez, majo o maja.") 74 | except: 75 | print("Lo que introduces debe ser un número, que si no peta!") 76 | 77 | print(f"El número que has introducido es {numero}") 78 | 79 | ### 80 | # EJERCICIOS (while) 81 | ### 82 | 83 | # Ejercicio 1: Cuenta atrás 84 | # Imprime los números del 10 al 1 usando un bucle while. 85 | print("\nEjercicio 1:") 86 | 87 | # Ejercicio 2: Suma de números pares (while) 88 | # Calcula la suma de los números pares entre 1 y 20 (inclusive) usando un bucle while. 89 | print("\nEjercicio 2:") 90 | 91 | # Ejercicio 3: Factorial de un número 92 | # Pide al usuario que introduzca un número entero positivo. 93 | # Calcula su factorial usando un bucle while. 94 | # El factorial de un número entero positivo es el producto de todos los números del 1 al ese número. Por ejemplo, el factorial de 5 95 | # 5! = 5 x 4 x 3 x 2 x 1 = 120. 96 | print("\nEjercicio 3:") 97 | 98 | # Ejercicio 4: Validación de contraseña 99 | # Pide al usuario que introduzca una contraseña. 100 | # La contraseña debe tener al menos 8 caracteres. 101 | # Usa un bucle while para seguir pidiendo la contraseña hasta que cumpla con los requisitos. 102 | # Si la contraseña es válida, imprime "Contraseña válida". 103 | print("\nEjercicio 4:") 104 | 105 | # Ejercicio 5: Tabla de multiplicar 106 | # Pide al usuario que introduzca un número. 107 | # Imprime la tabla de multiplicar de ese número (del 1 al 10) usando un bucle while. 108 | print("\nEjercicio 5:") 109 | 110 | # Ejercicio 6: Números primos hasta N 111 | # Pide al usuario que introduzca un número entero positivo N. 112 | # Imprime todos los números primos menores o iguales que N usando un bucle while. 113 | print("\nEjercicio 6:") -------------------------------------------------------------------------------- /03_loops/01_loop_while_solutions.py: -------------------------------------------------------------------------------- 1 | ### 2 | # EJERCICIOS (while) 3 | ### 4 | 5 | # Ejercicio 1: Cuenta atrás 6 | # Imprime los números del 10 al 1 usando un bucle while. 7 | print("\nEjercicio 1:") 8 | numero = 10 9 | while numero >= 1: 10 | print(numero) 11 | numero -= 1 12 | 13 | # Ejercicio 2: Suma de números pares (while) 14 | # Calcula la suma de los números pares entre 1 y 20 (inclusive) usando un bucle while. 15 | print("\nEjercicio 2:") 16 | numero = 1 17 | suma_pares = 0 18 | while numero <= 20: 19 | if numero % 2 == 0: 20 | suma_pares += numero 21 | numero += 1 22 | 23 | print(f"La suma de los números pares hasta 20 es: {suma_pares}") 24 | 25 | # Ejercicio 3: Factorial de un número 26 | # Pide al usuario que introduzca un número entero positivo. 27 | # Calcula su factorial usando un bucle while. 28 | # El factorial de un número entero positivo es el producto de todos los números del 1 al ese número. Por ejemplo, el factorial de 5 29 | # 5! = 5 x 4 x 3 x 2 x 1 = 120. 30 | print("\nEjercicio 3:") 31 | 32 | numero = int(input("Introduce un número entero positivo: ")) 33 | factorial = 1 34 | contador = 1 35 | 36 | while contador <= numero: 37 | factorial *= contador 38 | contador += 1 39 | 40 | print(f"El factorial de {numero} es: {factorial}") 41 | 42 | # Ejercicio 4: Validación de contraseña 43 | # Pide al usuario que introduzca una contraseña. 44 | # La contraseña debe tener al menos 8 caracteres. 45 | # Usa un bucle while para seguir pidiendo la contraseña hasta que cumpla con los requisitos. 46 | # Si la contraseña es válida, imprime "Contraseña válida". 47 | print("\nEjercicio 4:") 48 | 49 | contrasena = "" 50 | while len(contrasena) < 8: 51 | contrasena = input("Introduce una contraseña (al menos 8 caracteres): ") 52 | if len(contrasena) < 8: 53 | print("La contraseña debe tener al menos 8 caracteres. Inténtalo de nuevo.") 54 | 55 | print("Contraseña válida") 56 | 57 | # Ejercicio 5: Tabla de multiplicar 58 | # Pide al usuario que introduzca un número. 59 | # Imprime la tabla de multiplicar de ese número (del 1 al 10) usando un bucle while. 60 | print("\nEjercicio 5:") 61 | 62 | numero = int(input("Introduce un número: ")) 63 | multiplicador = 1 64 | 65 | while multiplicador <= 10: 66 | resultado = numero * multiplicador 67 | print(f"{numero} x {multiplicador} = {resultado}") 68 | multiplicador += 1 69 | 70 | # Ejercicio 6: Números primos hasta N 71 | # Pide al usuario que introduzca un número entero positivo N. 72 | # Imprime todos los números primos menores o iguales que N usando un bucle while. 73 | # Un número es primo si es divisible por sólo uno de los números enteros entre 1 y él mismo, incluido. 74 | 75 | print("\nEjercicio 6:") 76 | n = int(input("Introduce un número entero positivo N: ")) 77 | 78 | numero = 2 79 | while numero <= n: 80 | es_primo = True # Asumimos que el número es primo hasta que se demuestre lo contrario 81 | divisor = 2 82 | while divisor * divisor <= numero: # Optimizamos: no es necesario probar divisores hasta numero 83 | if numero % divisor == 0: 84 | es_primo = False # Si encontramos un divisor, no es primo 85 | break # Salimos del bucle interior 86 | divisor += 1 87 | if es_primo: 88 | print(numero) 89 | 90 | numero += 1 -------------------------------------------------------------------------------- /03_loops/02_loop_for.py: -------------------------------------------------------------------------------- 1 | ### 2 | # 02 - Bucles (for) 3 | # Permiten ejecutar un bloque de código repetidamente mientras ITERA un iterable o una lista 4 | ### 5 | 6 | from os import system 7 | if system("clear") != 0: system("cls") 8 | 9 | print("\nBucle for:") 10 | 11 | # Iterar una lista 12 | frutas = ["manzana", "pera", "mandarina"] 13 | for fruta in frutas: 14 | print(fruta) 15 | 16 | # Iterar sobre cualquier cosa que sea iterable 17 | cadena = "midudev" 18 | for caracter in cadena: 19 | print(caracter) 20 | 21 | # enumerate() 22 | frutas = ["manzana", "pera", "mandarina"] 23 | for idx, value in enumerate(frutas): 24 | print(f"El índice es {idx} y la fruta es {value}") 25 | 26 | # bucles anidados 27 | letras = ["A", "B", "C"] 28 | numeros = [1, 2, 3] 29 | 30 | for letra in letras: 31 | for numero in numeros: 32 | print(f"{letra}{numero}") 33 | 34 | 35 | # break 36 | print("\nbreak:") 37 | animales = ["perro", "gato", "raton", "loro", "pez", "canario"] 38 | for idx, animal in enumerate(animales): 39 | print(animal) 40 | if animal == "loro": 41 | print(f"El loro está escondido en el índice {idx}") 42 | break 43 | 44 | # continue 45 | print("\ncontinue:") 46 | animales = ["perro", "gato", "raton", "loro", "pez", "canario"] 47 | for idx, animal in enumerate(animales): 48 | if animal == "loro": continue 49 | 50 | print(animal) 51 | 52 | # Comprensión de listas (list comprehension) 53 | animales = ["perro", "gato", "raton", "loro", "pez", "canario"] 54 | animales_mayus = [animal.upper() for animal in animales] 55 | print(animales_mayus) 56 | 57 | # Muestra los números pares de una lista 58 | pares = [num for num in [1, 2, 3, 4, 5, 6] if num % 2 == 0] 59 | print(pares) 60 | 61 | ### 62 | # EJERCICIOS (for) 63 | ### 64 | 65 | # Ejercicio 1: Imprimir números pares 66 | # Imprime todos los números pares del 2 al 20 (inclusive) usando un bucle for. 67 | print("\nEjercicio 1:") 68 | 69 | # Ejercicio 2: Calcular la media de una lista 70 | # Dada la siguiente lista de números: 71 | # numeros = [10, 20, 30, 40, 50] 72 | # Calcula la media de los números usando un bucle for. 73 | print("\nEjercicio 2:") 74 | 75 | # Ejercicio 3: Buscar el máximo de una lista 76 | # Dada la siguiente lista de números: 77 | # numeros = [15, 5, 25, 10, 20] 78 | # Encuentra el número máximo en la lista usando un bucle for. 79 | print("\nEjercicio 3:") 80 | 81 | # Ejercicio 4: Filtrar cadenas por longitud 82 | # Dada la siguiente lista de palabras: 83 | # palabras = ["casa", "arbol", "sol", "elefante", "luna"] 84 | # Crea una nueva lista que contenga solo las palabras con más de 5 letras 85 | # usando un bucle for y list comprehension. 86 | print("\nEjercicio 4:") 87 | 88 | # Ejercicio 5: Contar palabras que empiezan con una letra 89 | # Dada la siguiente lista de palabras: 90 | # palabras = ["casa", "arbol", "sol", "elefante", "luna", "coche"] 91 | # Pide al usuario que introduzca una letra. 92 | # Cuenta cuántas palabras en la lista empiezan con esa letra (sin diferenciar mayúsculas/minúsculas). 93 | print("\nEjercicio 5:") -------------------------------------------------------------------------------- /03_loops/02_loop_for_solutions.py: -------------------------------------------------------------------------------- 1 | ### 2 | # EJERCICIOS (for) 3 | ### 4 | 5 | # Ejercicio 1: Imprimir números pares 6 | # Imprime todos los números pares del 2 al 20 (inclusive) usando un bucle for. 7 | print("\nEjercicio 1:") 8 | for numero in range(2, 21, 2): # range(inicio, fin, paso) 9 | print(numero) 10 | 11 | # Ejercicio 2: Calcular la media de una lista 12 | # Dada la siguiente lista de números: 13 | # numeros = [10, 20, 30, 40, 50] 14 | # Calcula la media de los números usando un bucle for. 15 | print("\nEjercicio 2:") 16 | numeros = [10, 20, 30, 40, 50] 17 | suma = 0 18 | for numero in numeros: 19 | suma += numero 20 | media = suma / len(numeros) 21 | print(f"La media es: {media}") 22 | 23 | # Ejercicio 3: Buscar el máximo de una lista 24 | # Dada la siguiente lista de números: 25 | # numeros = [15, 5, 25, 10, 20] 26 | # Encuentra el número máximo en la lista usando un bucle for. 27 | print("\nEjercicio 3:") 28 | numeros = [15, 5, 25, 10, 20] 29 | maximo = numeros[0] # Inicializamos con el primer elemento 30 | for numero in numeros: 31 | if numero > maximo: 32 | maximo = numero 33 | print(f"El número máximo es: {maximo}") 34 | 35 | # Ejercicio 4: Filtrar cadenas por longitud 36 | # Dada la siguiente lista de palabras: 37 | # palabras = ["casa", "arbol", "sol", "elefante", "luna"] 38 | # Crea una nueva lista que contenga solo las palabras con más de 5 letras 39 | # usando un bucle for y list comprehension. 40 | print("\nEjercicio 4:") 41 | palabras = ["casa", "arbol", "sol", "elefante", "luna"] 42 | palabras_largas = [palabra for palabra in palabras if len(palabra) > 5] 43 | print(palabras_largas) 44 | 45 | # Ejercicio 5: Contar palabras que empiezan con una letra 46 | # Dada la siguiente lista de palabras: 47 | # palabras = ["casa", "arbol", "sol", "elefante", "luna", "coche"] 48 | # Pide al usuario que introduzca una letra. 49 | # Cuenta cuántas palabras en la lista empiezan con esa letra (sin diferenciar mayúsculas/minúsculas). 50 | print("\nEjercicio 5:") 51 | palabras = ["casa", "arbol", "sol", "elefante", "luna", "coche"] 52 | letra = input("Introduce una letra: ").lower() # Convertimos la letra a minúscula 53 | contador = 0 54 | for palabra in palabras: 55 | if palabra.lower().startswith(letra): # Comparamos en minúsculas 56 | contador += 1 57 | print(f"Hay {contador} palabras que empiezan con la letra {letra}") -------------------------------------------------------------------------------- /03_loops/03_range.py: -------------------------------------------------------------------------------- 1 | ### 2 | # 03 - range() 3 | # Permite crear una secuencia de números. Puede ser útil para for, pero no solo para eso 4 | ### 5 | 6 | from os import system 7 | if system("clear") != 0: system("cls") 8 | 9 | print("\nrange():") 10 | 11 | # Generado una secuencia de números del 0 al 9 12 | for num in range(10): 13 | print(num) 14 | 15 | # range(inicio, fin) 16 | for num in range(5, 10): 17 | print(num) 18 | 19 | # range(inicio, fin, paso) 20 | for num in range(0, 1000, 5): 21 | print(num) 22 | 23 | for num in range(-5, 0): 24 | print(num) 25 | 26 | for num in range(10, 0, -1): 27 | print(num) 28 | 29 | for num in range(0, 444): 30 | print(num) 31 | 32 | nums = range(10) 33 | list_of_nums = list(nums) 34 | print(list_of_nums) 35 | 36 | # seria para hacerlo cinco veces 37 | for _ in range(5): 38 | print("hacer cinco veces algo") 39 | 40 | ### 41 | # EJERCICIOS (range) 42 | ### 43 | 44 | # Ejercicio 1: Imprimir números del 1 al 10 45 | # Imprime los números del 1 al 10 (inclusive) usando un bucle for y range(). 46 | print("\nEjercicio 1:") 47 | 48 | # Ejercicio 2: Imprimir números impares del 1 al 20 49 | # Imprime todos los números impares entre 1 y 20 (inclusive) usando un bucle for y range(). 50 | print("\nEjercicio 2:") 51 | 52 | # Ejercicio 3: Imprimir múltiplos de 5 53 | # Imprime los múltiplos de 5 desde 5 hasta 50 (inclusive) usando un bucle for y range(). 54 | print("\nEjercicio 3:") 55 | 56 | # Ejercicio 4: Imprimir números en orden inverso 57 | # Imprime los números del 10 al 1 (inclusive) en orden inverso usando un bucle for y range(). 58 | print("\nEjercicio 4:") 59 | 60 | # Ejercicio 5: Suma de números en un rango 61 | # Calcula la suma de los números del 1 al 100 (inclusive) usando un bucle for y range(). 62 | print("\nEjercicio 5:") 63 | 64 | # Ejercicio 6: Tabla de multiplicar 65 | # Pide al usuario que introduzca un número. 66 | # Imprime la tabla de multiplicar de ese número (del 1 al 10) usando un bucle for y range(). 67 | print("\nEjercicio 6:") -------------------------------------------------------------------------------- /03_loops/03_range_solutions.py: -------------------------------------------------------------------------------- 1 | ### 2 | # EJERCICIOS (range) 3 | ### 4 | 5 | # Ejercicio 1: Imprimir números del 1 al 10 6 | # Imprime los números del 1 al 10 (inclusive) usando un bucle for y range(). 7 | print("\nEjercicio 1:") 8 | for i in range(1, 11): # Recuerda que range no incluye el límite superior 9 | print(i) 10 | 11 | # Ejercicio 2: Imprimir números impares del 1 al 20 12 | # Imprime todos los números impares entre 1 y 20 (inclusive) usando un bucle for y range(). 13 | print("\nEjercicio 2:") 14 | for i in range(1, 21, 2): # El paso 2 asegura que solo se generen impares 15 | print(i) 16 | 17 | # Ejercicio 3: Imprimir múltiplos de 5 18 | # Imprime los múltiplos de 5 desde 5 hasta 50 (inclusive) usando un bucle for y range(). 19 | print("\nEjercicio 3:") 20 | for i in range(5, 51, 5): # El paso 5 genera los múltiplos de 5 21 | print(i) 22 | 23 | # Ejercicio 4: Imprimir números en orden inverso 24 | # Imprime los números del 10 al 1 (inclusive) en orden inverso usando un bucle for y range(). 25 | print("\nEjercicio 4:") 26 | for i in range(10, 0, -1): # Paso negativo para orden inverso 27 | print(i) 28 | 29 | # Ejercicio 5: Suma de números en un rango 30 | # Calcula la suma de los números del 1 al 100 (inclusive) usando un bucle for y range(). 31 | print("\nEjercicio 5:") 32 | suma = 0 33 | for i in range(1, 101): 34 | suma += i 35 | print(f"La suma de los números del 1 al 100 es: {suma}") 36 | 37 | # Ejercicio 6: Tabla de multiplicar 38 | # Pide al usuario que introduzca un número. 39 | # Imprime la tabla de multiplicar de ese número (del 1 al 10) usando un bucle for y range(). 40 | print("\nEjercicio 6:") 41 | numero = int(input("Introduce un número para la tabla de multiplicar: ")) 42 | for i in range(1, 11): 43 | print(f"{numero} x {i} = {numero * i}") -------------------------------------------------------------------------------- /03_loops/04_functions.py: -------------------------------------------------------------------------------- 1 | ### 2 | # 04 - Funciones 3 | # Bloques de código reutilizables y parametrizables para hacer tareas especificas 4 | ### 5 | 6 | from os import system 7 | if system("clear") != 0: system("cls") 8 | 9 | # """ Definición de una función 10 | 11 | # def nombre_de_la_funcion(parametro1, parametro2, ...): 12 | # # docstring 13 | # # cuerpo de la función 14 | # return valor_de_retorno # opcional 15 | 16 | # """ 17 | 18 | # # Ejemplo de una función para imprimir algo en consola 19 | # def saludar(): 20 | # print("¡Hola!") 21 | 22 | # # Ejemplo de una función con parámetro 23 | # def saludar_a(nombre): 24 | # print(f"¡Hola {nombre}!") 25 | 26 | # saludar_a("midudev") 27 | # saludar_a("madeval") 28 | # saludar_a("pheralb") 29 | # saludar_a("felixicaza") 30 | # saludar_a("Carmen Ansio") 31 | 32 | # # Funciones con más parámetros 33 | # def sumar(a, b): 34 | # suma = a + b 35 | # return suma 36 | 37 | # result = sumar(2, 3) 38 | # print(result) 39 | 40 | # # Documentar las funciones con docstring 41 | # def restar(a, b): 42 | # """Resta dos números y devuelve el resultado""" 43 | # return a - b 44 | 45 | # parámetros por defecto 46 | # def multiplicar(a, b = 2): 47 | # return a * b 48 | 49 | # print(multiplicar(2)) 50 | # print(multiplicar(2, 3)) 51 | 52 | # Argumentos por posición 53 | def describir_persona(nombre: str, edad: int, sexo: str): 54 | print(f"Soy {nombre}, tengo {edad} años y me identifico como {sexo}") 55 | 56 | # parámetros son posicionales 57 | describir_persona(1, 25, "gato") 58 | describir_persona("midudev", 25, "gato") 59 | describir_persona("hombre", "madeval", 39) 60 | 61 | # Argumentos por clave 62 | # parámetros nombrados 63 | describir_persona(sexo="gato", nombre="midudev", edad=25) 64 | describir_persona(sexo="hombre", nombre="madeval", edad=21) 65 | 66 | # Argumentos de longitud de variable (*args): 67 | def sumar_numeros(*args): 68 | suma = 0 69 | for numero in args: 70 | suma += numero 71 | return suma 72 | 73 | print(sumar_numeros(1, 2, 3, 4, 5)) 74 | print(sumar_numeros(1, 2)) 75 | print(sumar_numeros(1, 2,3 ,4, 5, 6, 7, 8, 9, 10)) 76 | 77 | # Argumentos de clave-valor variable (**kwargs): 78 | def mostrar_informacion_de(**kwargs): 79 | for clave, valor in kwargs.items(): 80 | print(f"{clave}: {valor}") 81 | 82 | mostrar_informacion_de(nombre="midudev", edad=25, sexo="gato") 83 | print("\n") 84 | mostrar_informacion_de(name="madeval", edad=21, country="Uruguay") 85 | print("\n") 86 | mostrar_informacion_de(nick="pheralb", es_sub=True, is_rich=True) 87 | print("\n") 88 | mostrar_informacion_de(super_name="felixicaza", es_modo=True, gatos=40) 89 | 90 | # Ejercicios 91 | # Volver a los ejercicios anteriores 92 | # y convertirlos en funciones 93 | # e intentar utilizar todos los casos y conceptos 94 | # que hemos visto hasta ahora -------------------------------------------------------------------------------- /04_logic/01_challenge_fantastic_four.py: -------------------------------------------------------------------------------- 1 | """ 2 | ¿Está en Equilibrio la Alianza entre Reed Richards y Johnny Storm? 3 | 4 | En el universo de los 4 Fantásticos, la unión y el equilibrio entre los poderes es fundamental para enfrentar cualquier desafío. En este problema, nos centraremos en dos de sus miembros: 5 | 6 | Reed Richards (Mr. Fantastic), representado por la letra R. 7 | Johnny Storm (La Antorcha Humana), representado por la letra J. 8 | 9 | Objetivo: 10 | 11 | Crea una función en Python que reciba una cadena de texto. Esta función debe contar cuántas veces aparece la letra R (para Reed Richards) y cuántas veces aparece la letra J (para Johnny Storm) en la cadena. 12 | 13 | - Si la cantidad de R y la cantidad de J son iguales, se considera que la alianza entre la mente y el fuego está en equilibrio y la función debe retornar True. 14 | - Si las cantidades no son iguales, la función debe retornar False. 15 | - En el caso de que no aparezca ninguna de las dos letras en la cadena, se entiende que el equilibrio se mantiene (0 = 0), por lo que la función debe retornar True. 16 | """ 17 | 18 | from os import system 19 | if system("clear") != 0: system("cls") 20 | 21 | text = "RRRRJJJjjjrrr" 22 | 23 | def check_is_balanced(text): 24 | text = text.upper() 25 | 26 | # contar facilmente el número de veces que aparece una letra 27 | count_r = text.count("R") # Reed Richards 28 | count_j = text.count("J") # Johnny Storm 29 | 30 | print(f"count_r: {count_r} count_j: {count_j}") 31 | 32 | # if count_r == count_j: 33 | # return True 34 | # else: 35 | # return False 36 | 37 | return count_r == count_j 38 | 39 | print(check_is_balanced("RRJJ")) 40 | print(check_is_balanced("RRRRJJ")) 41 | print(check_is_balanced("RRJJJJJJ")) 42 | print(check_is_balanced("awwwaqAQAQA")) -------------------------------------------------------------------------------- /04_logic/02_challenge_jurassic_park.py: -------------------------------------------------------------------------------- 1 | """ 2 | En Jurassic Park, se ha observado que los dinosaurios carnívoros, como el temible T-Rex, depositan un número par de huevos. Imagina que tienes una lista de números enteros en la que cada número representa la cantidad de huevos puestos por un dinosaurio en el parque. 3 | 4 | Importante: Solo se consideran los huevos de los dinosaurios carnívoros (T-Rex) aquellos números que son pares. 5 | 6 | Objetivo: 7 | Escribe una función en Python que reciba una lista de números enteros y devuelva la suma total de los huevos que pertenecen a los dinosaurios carnívoros (es decir, la suma de todos los números pares en la lista). 8 | """ 9 | 10 | from os import system 11 | if system("clear") != 0: system("cls") 12 | 13 | # Para ver si un número es par 14 | # siempre usamos el módulo % 15 | # nos da el resto de la división: eggs % 2 == 2 16 | 17 | def count_carnivore_dinosaur_eggs(egg_list) -> int: 18 | """ 19 | Esta función recibe una lista de numeros enteros que representan la cantidad de huevos que han puesto diferentes dinosaurios en el parque jurásico y los de número par son de carnívoros. Devuelve un número con la suma de todos los huevos de carnívoros. 20 | """ 21 | total_carnivore_eggs = 0 22 | 23 | for eggs in egg_list: 24 | if eggs % 2 == 0: 25 | total_carnivore_eggs += eggs 26 | 27 | # esta forma más corta: 28 | # total_carnivore_eggs = sum(filter(lambda x: x % 2 == 0, egg_list)) 29 | 30 | return total_carnivore_eggs 31 | 32 | egg_list = [3, 4, 7, 5, 8] 33 | print(count_carnivore_dinosaur_eggs(egg_list)) # 12 -------------------------------------------------------------------------------- /04_logic/03_challenge_find_first_sum.py: -------------------------------------------------------------------------------- 1 | """ 2 | Dado un array de números y un número goal, encuentra los dos primeros números del array que sumen el número goal y devuelve sus índices. Si no existe tal combinación, devuelve None. 3 | 4 | nums = [4, 5, 6, 2] 5 | goal = 8 6 | 7 | find_first_sum(nums, goal) # [2, 3] 8 | """ 9 | 10 | from os import system 11 | if system("clear") != 0: system("cls") 12 | 13 | # def find_first_sum(nums, goal): 14 | # # early return, una validación rápida 15 | # if len(nums) == 0: return None 16 | 17 | # for i in range(len(nums)): 18 | # for j in range(i + 1, len(nums)): 19 | # if nums[i] + nums[j] == goal: 20 | # return [i, j] 21 | 22 | # return None # no se encontró ninguna combinación 23 | 24 | def find_first_sum(nums, goal): 25 | seen = {} # diccionario para guardar el numero y su índice 26 | 27 | for index, value in enumerate(nums): 28 | missing = goal - value 29 | if missing in seen: return [seen[missing], index] 30 | seen[value] = index # guardar el número actual a los vistos, porque no hemos encontrado la combinación 31 | 32 | return None 33 | 34 | nums = [4, 5, 6, 2] 35 | goal = 8 36 | result = find_first_sum(nums, goal) # [2, 3] 37 | print(result) -------------------------------------------------------------------------------- /04_logic/04_dictionaries.py: -------------------------------------------------------------------------------- 1 | ### 2 | # 04 - Dictionaries 3 | # Los diccionarios son colecciones de pares clave-valor. 4 | # Sirven para almacenar datos relacionados. 5 | ### 6 | 7 | from os import system 8 | if system("clear") != 0: system("cls") 9 | 10 | # ejemplo tipico de diccionario 11 | persona = { 12 | "nombre": "midudev", 13 | "edad": 25, 14 | "es_estudiante": True, 15 | "calificaciones": [7, 8, 9], 16 | "socials": { 17 | "twitter": "@midudev", 18 | "instagram": "@midudev", 19 | "facebook": "midudev" 20 | } 21 | } 22 | 23 | # para acceder a los valores 24 | print(persona["nombre"]) 25 | print(persona["calificaciones"][2]) 26 | print(persona["socials"]["twitter"]) 27 | 28 | # cambiar valores al acceder 29 | persona["nombre"] = "madeval" 30 | persona["calificaciones"][2] = 10 31 | 32 | # eliminar completamente una propiedad 33 | del persona["edad"] 34 | # print(persona) 35 | 36 | es_estudiante = persona.pop("es_estudiante") 37 | print(f"es_estudiante: {es_estudiante}") 38 | print(persona) 39 | 40 | # sobreescribir un diccionario con otro diccionario 41 | a = { "name": "miduev", "age": 25 } 42 | b = { "name": "madeval", "es_estudiante": True } 43 | 44 | a.update(b) 45 | print(a) 46 | 47 | # comprobar si existe una propiedad 48 | print("name" in persona) # False 49 | print("nombre" in persona) # True 50 | 51 | # obtener todas las claves 52 | print("\nkeys:") 53 | print(persona.keys()) 54 | 55 | # obtener todas los valores 56 | print("\nvalues:") 57 | print(persona.values()) 58 | 59 | # obtener tanto clave como valor 60 | print("\nitems:") 61 | print(persona.items()) 62 | 63 | for key, value in persona.items(): 64 | print(f"{key}: {value}") -------------------------------------------------------------------------------- /04_logic/05_challenge_battle.py: -------------------------------------------------------------------------------- 1 | """ 2 | Tienes dos listas de números, lista_a y lista_b, ambas de la misma longitud. 3 | 4 | Cada número en lista_a se "enfrenta" al número en la misma posición en lista_b. 5 | 6 | - Si el número en lista_a es mayor, su valor se suma al siguiente número en lista_a. 7 | - Si el número en lista_b es mayor, su valor se suma al siguiente número en lista_b. 8 | - Si los dos números son iguales, ambos se eliminan y no afectan al siguiente par. 9 | 10 | Debes simular estos enfrentamientos y devolver el resultado final: 11 | - Si al final queda un número en lista_a, devuelve ese número seguido de la letra "a" (por ejemplo, "3a"). 12 | - Si al final queda un número en lista_b, devuelve ese número seguido de la letra "b" (por ejemplo, "2b"). 13 | - En caso de empate, devuelve la letra "x". 14 | 15 | lista_a = [2, 4, 2] 16 | lista_b = [3, 3, 4] 17 | 18 | resultado = battle(lista_a, lista_b) # -> "2b" 19 | 20 | # Explicación: 21 | # - 2 vs 3: gana 3 (+1) 22 | # - 4 vs 3+1: empate 23 | # - 2 vs 4: gana 4 (+2) 24 | # Resultado: "2b" 25 | 26 | lista_a = [4, 4, 4] 27 | lista_b = [2, 8, 2] 28 | 29 | resultado = battle(lista_a, lista_b) # -> "x" 30 | 31 | # Explicación: 32 | # - 4 vs 2: gana 4 (+2) 33 | # - 4+2 vs 8: gana 8 (+2) 34 | # - 4 vs 2+2: empate 35 | # Resultado: "x" 36 | """ 37 | 38 | from os import system 39 | if system("clear") != 0: system("cls") 40 | 41 | # Fuerza bruta: buscar la solución A SACO. 42 | # Algoritmos ocultos o cálculos o fórmulas 43 | # Programación dinámica: buscar una solución mas eficiente 44 | 45 | 46 | def battle(lista_a, lista_b): 47 | puntos_a = sum(lista_a) 48 | puntos_b = sum(lista_b) 49 | return f"{puntos_a - puntos_b}a" if puntos_a > puntos_b else f"{puntos_b - puntos_a}b" if puntos_b > puntos_a else "x" 50 | 51 | 52 | lista_a = [4, 4, 4] 53 | lista_b = [2, 8, 2] 54 | winner = battle(lista_a, lista_b) 55 | print(winner) 56 | -------------------------------------------------------------------------------- /05_regex/01_re.py: -------------------------------------------------------------------------------- 1 | ## 2 | # 01 - Expresiones regulares 3 | # 4 | 5 | """ Las expresiones regulares son una secuencia de caracteres que forman un patrón de búsqueda. 6 | Se utilizan para la búsqueda de cadenas de texto, validación de datos, etc. """ 7 | 8 | 9 | """ ¿Por qué aprender Regex? 10 | 11 | - Búsqueda avanzada: Encontrar patrones específicos en textos grandes de forma rápida y precisa. (un editor de Markdown sólo usando Regex) 12 | 13 | - Validación de datos: Asegurarte que los datos que ingresa un usuario como el email, teléfono, etc. son correctos. 14 | 15 | - Manipulación del texto: Extraer, reemplazar y modificar partes de la cadena de texto fácilmente 16 | """ 17 | 18 | # 1. Importar el módulo de expresiones regulares "re" 19 | import re 20 | # 2. Crear un patrón, que es una cadena de texto que describe lo que queremos encontrar 21 | pattern = "Hola" 22 | # 3. El texto donde queremos buscar 23 | text = "Hola mundo" 24 | # 4. Usar la función de búsqueda de "re" 25 | result = re.search(pattern, text) 26 | 27 | if result: 28 | print("He encontrado el patrón en el texto") 29 | else: 30 | print("No he encontrado el patrón en el texto") 31 | 32 | # .group() devuelve la cadena que coincide con el pattern 33 | print(result.group()) 34 | 35 | # .start() devolver la posición inicial de la coincidencia 36 | print(result.start()) 37 | 38 | # .end() devolver la posición final de la coincidencia 39 | print(result.end()) 40 | 41 | # EJERCICIO 01 42 | # Encuentra la primera ocurrencia de la palabra "IA" en el siguiente texto 43 | # e indica en que posición empieza y termina la coincidencia. 44 | text = "Todo el mundo dice que la IA nos va a quitar el trabajo. Pero solo hace falta ver cómo la puede cagar con las Regex para ir con cuidado" 45 | pattern = "IA" 46 | found_ia = re.search(pattern, text) 47 | 48 | if found_ia: 49 | print(f"He encontrado el patrón en el texto en la posición {found_ia.start()} y termina en la posición {found_ia.end()}") 50 | else: 51 | print("No he encontrado el patrón en el texto") 52 | 53 | # ----------------------- 54 | 55 | ### Encontrar todas las coincidencias de un patrón 56 | # .findall() devuelve una lista con todas las coincidencias 57 | 58 | text = "Me gusta Python. Python es lo máximo. Aunque Python no es tan difícil, ojo con Python" 59 | pattern = "Python" 60 | 61 | matches = re.findall(pattern, text) 62 | 63 | print(len(matches)) 64 | 65 | # ------------------------- 66 | 67 | # iter() devuelve un iterador que contiene todos los resultados de la búsqueda 68 | 69 | text = "Me gusta Python. Python es lo máximo. Aunque Python no es tan difícil, ojo con Python" 70 | pattern = "Python" 71 | 72 | matches = re.finditer(pattern, text) 73 | 74 | for match in matches: 75 | print(match.group(), match.start(), match.end()) 76 | 77 | # EJERCICIO 02 78 | # Encuentra todas las ocurrencias de la palabra "midu" en el siguiente texto e indica en que posición empieza y termina cada coincidencia y cuantas veces se encontró. 79 | text = "Este es el curso de Python de midudev. ¡Suscríbete a midudev si te gusta este contenido! midu" 80 | 81 | ### Modificadores 82 | 83 | # Los modificadores son opciones que se pueden agregar a un patrón para cambiar su comportamiento 84 | 85 | # re.IGNORECASE: Ignora las mayúsculas y minúsculas 86 | 87 | text = "Todo el mundo dice que la IA nos va a quitar el trabajo. Pero la ia no es tan mala. ¡Viva la Ia!" 88 | pattern = "IA" 89 | found = re.findall(pattern, text, re.IGNORECASE) 90 | 91 | if found: print(found) 92 | 93 | # EJERCICIO 03 94 | # Encuentra todas las ocurrencias de la palabra "python" en el siguiente texto, sin distinguir entre mayúsculas y minúsculas. 95 | text = "Este es el curso de Python de midudev. ¡Suscríbete a python si te gusta este contenido! PYTHON" 96 | 97 | ### Reemplazar el texto 98 | 99 | # .sub() reemplaza todas las coincidencias de un patrón en un texto 100 | 101 | text = "Hola, mundo! Hola de nuevo. Hola otra vez." 102 | pattern = "hola" 103 | replacement = "Adiós" 104 | 105 | new_text = re.sub(pattern, replacement, text, flags=re.IGNORECASE) 106 | print(new_text) -------------------------------------------------------------------------------- /05_regex/02_metachars.py: -------------------------------------------------------------------------------- 1 | ### 2 | # 02 - Meta caracteres 3 | # Los metacaracteres son simbolos especiales con significados especificos en las expresiones regulares 4 | ### 5 | 6 | import re 7 | 8 | # 1. El punto (.) 9 | # Coincidir con cualquier caracter excepto una nueva linea 10 | 11 | text = "Hola mundo, H0la de nuevo, H$la otra vez" 12 | pattern = "H.la" # Hola, H0la, H$la 13 | 14 | found = re.findall(pattern, text) 15 | 16 | if (found): 17 | print(found) 18 | else: 19 | print("No se ha encontrado el patrón") 20 | 21 | 22 | text = "casa caasa cosa cisa cesa causa" 23 | pattern = "c.sa" 24 | 25 | matches = re.findall(pattern, text) 26 | print(matches) 27 | 28 | # -------------------- 29 | 30 | text = "Hola mundo, H0la de nuevo, H$la otra vez" 31 | pattern = r"H.la" # Hola, H0la, H$la 32 | 33 | found = re.findall(pattern, text) 34 | 35 | if (found): 36 | print(found) 37 | else: 38 | print("No se ha encontrado el patrón") 39 | 40 | 41 | # Cómo usar la barra invertida para anular el significado especial de un símbolo 42 | text = "Mi casa es blanca. Y el coche es negro." 43 | pattern = r"\." 44 | 45 | matches = re.findall(pattern, text) 46 | 47 | print(matches) 48 | 49 | # \d: coincide con cualquier dígito (0-9) 50 | 51 | text = "El número de teléfono es 123456789" 52 | found = re.findall(r'\d{9}', text) 53 | 54 | print(found) 55 | 56 | # Ejercicio: Detectar si hay un número de España en el texto gracias al prefijo +34 57 | 58 | text = "Mi número de teléfono es +34 688999999 apúntalo vale?" 59 | pattern = r"\+34 \d{9}" 60 | found = re.search(pattern, text) 61 | if found: print(f"Encontré el número de teléfono {found.group()}") 62 | 63 | # \w: Coincide con cualquier caracter alfanumerico (a-z, A-Z, 0-9, _) 64 | 65 | text = "el_rubius_69" 66 | pattern = r"\w" 67 | found = re.findall(pattern, text) 68 | print(found) 69 | 70 | # \s: Coincide con cualqueir espacio en blanco (espacio, tabulación, salto de línea) 71 | text = "Hola mundo\n¿Cómo estás?\t" 72 | pattern = r"\s" 73 | matches = re.findall(pattern, text) 74 | print(matches) 75 | 76 | # ^: Coincide con el principio de una cadena 77 | username = "423_name%22" 78 | pattern = r"^\w" # validar nombre de usuario 79 | 80 | valid = re.search(pattern, username) 81 | 82 | if valid: print("El nombre de usuario es válido") 83 | else: print("El nombre de usuario no es válido") 84 | 85 | phone = "+34 688999999" 86 | pattern = r"^\+\d{1,3} " 87 | 88 | valid = re.search(pattern, phone) 89 | 90 | if valid: print("El número de teléfono es válido") 91 | else: print("El número de teléfono no es válido") 92 | 93 | # $: Coincide con el final de una cadena 94 | text = "Hola mundo." 95 | pattern = r"mundo$" 96 | 97 | valid = re.search(pattern, text) 98 | 99 | if valid: print("La cadena es válida") 100 | else: print("La cadena no es válida") 101 | 102 | # EJERCICIO 103 | # Valida que un correo sea de gmail 104 | text = "miduga@hotmail.com" 105 | pattern = r"@gmail.com$" 106 | valid = re.search(pattern, text) 107 | 108 | if valid: print("El correo es gmail válido") 109 | else: print("El correo no es válido") 110 | 111 | # EJERCICIO: 112 | # Tenemos una lista de archivos, necesitamos saber los nombres de los ficheros con extension .txt 113 | files = "file1.txt file2.pdf midu-of.webp secret.txt" 114 | 115 | # \b: Coincide con el principio o final de una palabra 116 | text = "casa casada cosa cosas casado casa" 117 | pattern = r"\bc.sa\b" 118 | 119 | found = re.findall(pattern, text) 120 | print(found) 121 | 122 | # |: Coincidr con una opción u otra 123 | fruits = "platano, piña, manzana, aguacate, palta, pera, aguacate, aguacate" 124 | pattern = r"palta|aguacate|p..a|\b\w{7}\b" 125 | 126 | matches = re.findall(pattern, fruits) 127 | print(matches) -------------------------------------------------------------------------------- /05_regex/03_quantifiers.py: -------------------------------------------------------------------------------- 1 | ### 2 | # 03 - Quantifiers 3 | # Los cuantificadores se utilizan para especificar cuántas ocurrencias de un carácter o grupo de caracteres se deben encontrar en una cadena. 4 | ### 5 | 6 | import re 7 | 8 | # *: Puede aparecer 0 o más veces 9 | text = "aaaba" 10 | pattern = "a*" 11 | matches = re.findall(pattern, text) 12 | print(matches) 13 | 14 | # Ejercicio 1: 15 | # ¿Cuantas palabras tienen de 0 a más "a" y después una b? 16 | 17 | # +: Una a más veces 18 | text = "dddd aaa ccc a bb aa casa" 19 | pattern = "a+" 20 | matches = re.findall(pattern, text) 21 | print(matches) 22 | 23 | # ?: Cero o una vez 24 | text = "aaabacb" 25 | pattern = "a?b" 26 | matches = re.findall(pattern, text) 27 | print(matches) 28 | 29 | # Ejercicio: Haz opcional que aparezca un +34 en el siguiente texto 30 | phone = "+34 688999999" 31 | 32 | # {n}: Exactamente n veces 33 | text = "aaaaaa aa aaaa" 34 | pattern = "a{3}" 35 | matches = re.findall(pattern, text) 36 | 37 | print(matches) 38 | 39 | # {n, m}: De n a m veces 40 | text = "u uu uuu u" 41 | pattern = r"\w{2,3}" 42 | matches = re.findall(pattern, text) 43 | print(matches) 44 | 45 | # Ejercicio: 46 | # Encuentra las palabras de 4 a 6 letras en el siguiente texto 47 | words = "ala casa árbol león cinco murcielago" 48 | pattern = r"\b\w{4,6}\b" 49 | matches = re.findall(pattern, words) 50 | print(matches) 51 | 52 | # Ejercicio 53 | # Encuentra las palabras de más de 6 letras 54 | words = "ala fantastico casa árbol león cinco murcielago" 55 | pattern = r"\b\w{6,}\b" 56 | matches = re.findall(pattern, words) 57 | print(matches) -------------------------------------------------------------------------------- /05_regex/04_sets.py: -------------------------------------------------------------------------------- 1 | import re 2 | 3 | # [:] Coincide con cualquier caracter dentro de los corchetes 4 | 5 | username = "rub.$ius_69+" 6 | pattern = r"^[\w._%+-]+$" 7 | 8 | match = re.search(pattern, username) 9 | if match: 10 | print("El nombre de usuario es válido: ", match.group()) 11 | else: 12 | print("El nombre de usuario no es válido") 13 | 14 | 15 | # Buscar todas las vocales de una palabra 16 | text = "Hola mundo" 17 | pattern = r"[aeiou]" 18 | matches = re.findall(pattern, text) 19 | print(matches) 20 | 21 | # Una Regex para encontrar las palabras man, fan y ban 22 | # pero ignora el resto 23 | text = "man ran fan ñan ban" 24 | pattern = r"[mfb]an" 25 | 26 | matches = re.findall(pattern, text) 27 | print(matches) 28 | 29 | # Ejercicio: 30 | # Nos han complicado el asunto, porque ahora hay palabras que encajan pero no empiezan por esas letras. 31 | # Solo queremos las palabras man, fan y ban 32 | text = "omniman fanatico man bandana" 33 | # \b 34 | 35 | text = "22" 36 | pattern = r"[4-9]" 37 | 38 | matches = re.findall(pattern, text) 39 | print(matches) 40 | 41 | 42 | # Ejercicio final con todo lo aprendido 43 | # Mejorar esto: https://www.computerhope.com/jargon/r/regular-expression.png 44 | 45 | ## Buscar corner cases que no pasa y arreglarlo: 46 | "lo.que+sea@shopping.online" 47 | "michael@gov.co.uk" 48 | 49 | # [^]: Coincide con cualquier caracter que no esté dentro de los corchetes 50 | text = "Hola mundo" 51 | pattern = r"[^aeiou]" 52 | matches = re.findall(pattern, text) 53 | print(matches) -------------------------------------------------------------------------------- /06_request_ai_dates/01_dates.py: -------------------------------------------------------------------------------- 1 | # Trabajando con fechas y horas en Python 2 | 3 | from datetime import datetime, timedelta 4 | import locale 5 | 6 | # 1. Obtener la fecha y hora actual 7 | now = datetime.now() 8 | print(f"Fecha y hora actual: {now}") 9 | 10 | # 2. Crear una fecha y hora específica 11 | specific_date = datetime(2025, 2, 12, 15, 30, 0) 12 | print(f"Fecha y hora específica: {specific_date}") 13 | 14 | # 3. Formatear fechas 15 | # método strftime() para formatear fechas 16 | # pasarle el objeto datetime y el formato especificado 17 | # formato: 18 | import locale 19 | locale.setlocale(locale.LC_TIME, 'es_ES.UTF-8') 20 | 21 | format_date = now.strftime("%A %B %Y %H:%M:%S") 22 | print(f"Fecha formateada: {format_date}") 23 | 24 | # 4. Operaciones con fechas (sumar/restar dias, minutos, horas, meses) 25 | yesterday = datetime.now() - timedelta(days=1) 26 | print(f"Ayer: {yesterday}") 27 | 28 | tomorrow = datetime.now() + timedelta(days=1) 29 | print(f"Mañana: {tomorrow}") 30 | 31 | one_hour_after = datetime.now() + timedelta(hours=1) 32 | print(f"Una hora después: {one_hour_after}") 33 | 34 | # 5. Obtener componentes individuales de una fecha 35 | year = now.year 36 | print(year) 37 | 38 | month = now.month 39 | print(month) 40 | 41 | # 6. Calcular la diferencia entre 2 fechas 42 | date1 = datetime.now() 43 | date2 = datetime(2025, 2, 12, 15, 30, 0) 44 | difference = date2 - date1 45 | print(f"Diferencia entre las fechas: {difference}") 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | -------------------------------------------------------------------------------- /06_request_ai_dates/02_requests.py: -------------------------------------------------------------------------------- 1 | # Cómo hacer peticiones a APIs con Python 2 | # con y sin dependencias 3 | 4 | # 1. Sin dependencias (díficil y sin dependencias) 5 | import urllib.request 6 | import json 7 | 8 | DEEPSEEK_API_KEY = "xxx" 9 | 10 | api_posts = "https://jsonplaceholder.typicode.com/posts/" 11 | 12 | try: 13 | response = urllib.request.urlopen(api_posts) 14 | data = response.read() 15 | json_data = json.loads(data.decode('utf-8')) 16 | print(json_data) 17 | response.close() 18 | except urllib.error.URLError as e: 19 | print(f"Error en la solicitud: {e}") 20 | 21 | 22 | # 2. Con dependencia (requests) 23 | import requests 24 | 25 | print("\nGET:") 26 | api_posts = "https://jsonplaceholder.typicode.com/posts/" 27 | response = requests.get(api_posts) 28 | response_json = response.json() 29 | 30 | # 3. Un POST 31 | print("\nPOST:") 32 | try: 33 | response = requests.post( 34 | "https://jsonplaceholder.typicode.com/posts", 35 | json={ 36 | "title": "foo", 37 | "body": "bar", 38 | "userId": 1 39 | }) 40 | print(response.status_code) 41 | except requests.exceptions.RequestException as e: 42 | print(f"Error en la solicitud: {e}") 43 | 44 | # 4. Un PUT 45 | print("\nPUT:") 46 | try: 47 | response = requests.put( 48 | "https://jsonplaceholder.typicode.com/posts/1", 49 | json={ 50 | "title": "foo", 51 | "body": "bar", 52 | "userId": 1, 53 | }) 54 | 55 | print(response.status_code) 56 | except requests.exceptions.RequestException as e: 57 | print(f"Error en la solicitud: {e}") 58 | 59 | # Usar la API de GPT-4o de OpenAI 60 | # Ref: https://platform.openai.com/docs/api-reference/making-requests 61 | 62 | OPENAI_KEY = "sk-XXXXXXXX" 63 | 64 | import json 65 | 66 | def call_openai_gpt(api_key, prompt): 67 | url = "https://api.openai.com/v1/chat/completions" 68 | headers = { 69 | "Content-Type": "application/json", 70 | "Authorization": f"Bearer {api_key}" 71 | } 72 | data = { 73 | "model": "gpt-4o-mini", 74 | "messages": [{"role": "user", "content": prompt}] 75 | } 76 | 77 | response = requests.post(url, json=data, headers=headers) 78 | return response.json() 79 | 80 | api_response = call_openai_gpt(OPENAI_KEY, "Escribe un breve poema sobre la programación") 81 | 82 | # print(json.dumps(api_response, indent=2)) 83 | 84 | print(api_response["choices"][0]["message"]["content"]) 85 | 86 | # Llamar a la API de DEEPSEEK 87 | 88 | import json 89 | 90 | def call_deepseek(api_key, prompt): 91 | url = "https://api.deepseek.com/chat/completions" 92 | headers = { 93 | "Content-Type": "application/json", 94 | "Authorization": f"Bearer {api_key}" 95 | } 96 | data = { 97 | "model": "deepseek-chat", 98 | "messages": [{"role": "user", "content": prompt}] 99 | } 100 | 101 | response = requests.post(url, json=data, headers=headers) 102 | print(response.json()) 103 | return response.json() 104 | 105 | api_response = call_deepseek(DEEPSEEK_API_KEY, "Escribe un breve poema sobre la programación") 106 | 107 | # print(json.dumps(api_response, indent=2)) 108 | 109 | print(api_response["choices"][0]["message"]["content"]) -------------------------------------------------------------------------------- /06_request_ai_dates/03_clases.py: -------------------------------------------------------------------------------- 1 | # 1. Introducción a las Clases en Python 2 | # Las clases son plantillas para crear objetos. Un objeto es una instancia de una clase. 3 | # Nos permite agrupar datos (atributos o propiedades) y funciones (métodos) en un solo lugar. 4 | 5 | OPENAI_KEY = "" 6 | DEEPSEEK_API_KEY = "" 7 | 8 | # Ejemplo básico de una clase 9 | class Coche: 10 | # atributo de clase (comparte todas las instancias) 11 | tipo = "vehículo de cuatro ruedas" 12 | ruedas = 4 13 | 14 | # método especial que es el que construye el objeto 15 | # se llama automáticamente este método cuando creas la instancia 16 | def __init__(self, marca, modelo, color): 17 | # atributos de la instancia 18 | self.marca = marca 19 | self.modelo = modelo 20 | self.color = color 21 | 22 | def arrancar(self): 23 | print(f"El coche {self.marca} {self.modelo} arrancó! 🚗") 24 | 25 | 26 | mi_coche = Coche("Toyota", "Corolla", "rojo") 27 | mi_coche.arrancar() 28 | 29 | print(mi_coche.marca) 30 | 31 | coche_de_pheralb = Coche("Ford", "Fiesta", "azul") 32 | coche_de_pheralb.arrancar() 33 | 34 | print(coche_de_pheralb.marca) 35 | 36 | # Encapsulación: es ocultar los detalles internos de una clase y exponer solo la interfaz pública 37 | 38 | # Crear una clase para llamar a la AI de OpenAI, DeepSeek O LO QUE SEA 39 | 40 | import requests 41 | 42 | class AI_API: 43 | def __init__(self, api_key, url, model): 44 | self.api_key = api_key 45 | self.url = url 46 | self.model = model 47 | 48 | def call(self, prompt): 49 | headers = { 50 | "Content-Type": "application/json", 51 | "Authorization": f"Bearer {self.api_key}" 52 | } 53 | data = { 54 | "model": self.model, 55 | "messages": [{"role": "user", "content": prompt}] 56 | } 57 | 58 | try: 59 | response = requests.post(self.url, json=data, headers=headers) 60 | res_json = response.json() 61 | print(res_json["choices"][0]["message"]["content"]) 62 | except requests.exceptions.RequestException as e: 63 | print(f"Error en la solicitud: {e}") 64 | return None 65 | 66 | print("\nOPEN_AI:") 67 | openai_api = AI_API(OPENAI_KEY, "https://api.openai.com/v1/chat/completions", "gpt-4o-mini") 68 | 69 | openai_api.call("Escribe un breve poema sobre la programación") 70 | 71 | print("\nDEEPSEEK:") 72 | deepseek_api = AI_API(DEEPSEEK_API_KEY, "https://api.deepseek.com/chat/completions", "deepseek-chat") 73 | 74 | deepseek_api.call("Escribe un breve poema sobre la programación") -------------------------------------------------------------------------------- /07_scraping/01_basic.py: -------------------------------------------------------------------------------- 1 | # pip3 install requests -> instalas la dependencia para hacer peticiones 2 | 3 | import requests 4 | import re 5 | 6 | url = 'https://www.apple.com/es/shop/buy-mac/macbook-air/' 7 | 8 | response = requests.get(url) 9 | 10 | if response.status_code == 200: 11 | print('La petición fue exitosa') 12 | 13 | html = response.text 14 | print(html) 15 | 16 | # regular expression para encontrar el precio 17 | price_pattern = r'(.*?)' 18 | match = re.search(price_pattern, html) 19 | 20 | if match: 21 | print(f"El precio del producto es: {match.group(1)}") 22 | 23 | # get the title if the patter is found 24 | title_pattern = r'(.*?)' 25 | match = re.search(title_pattern, html) 26 | 27 | if match: 28 | print(f"El título de la web es: {match.group(1)}") 29 | -------------------------------------------------------------------------------- /07_scraping/02_beautiful.py: -------------------------------------------------------------------------------- 1 | from bs4 import BeautifulSoup 2 | import requests 3 | 4 | url = 'https://www.apple.com/es/shop/buy-mac/macbook-air/' 5 | headers = { 6 | 'User-Agent': 'Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko; compatible; Googlebot/2.1; +http://www.google.com/bot.html) Chrome/131.0.0 Safari/537.36' 7 | } 8 | response = requests.get(url, headers=headers) 9 | 10 | if response.status_code == 200: 11 | print('La petición fue exitosa') 12 | 13 | soup = BeautifulSoup(response.text, 'html.parser') 14 | 15 | # print(soup.prettify()) 16 | title_tag = soup.title 17 | if title_tag: 18 | print(f"El título de la web es: {title_tag.text}") 19 | 20 | # find price using bs 21 | # price_span = soup.find('span', class_='rc-prices-fullprice') 22 | # if price_span: 23 | # print(f"El precio del producto es: {price_span.text}") 24 | 25 | # find all the prices 26 | # prices_span = soup.find_all(class_='rc-prices-fullprice') 27 | # for price in prices_span: 28 | # print(f"El precio del producto es: {price.text}") 29 | 30 | # find each product and get the name and the price 31 | products = soup.find_all(class_='rc-productselection-item') 32 | for product in products: 33 | name = product.find(class_="list-title").text 34 | price = product.find(class_="rc-prices-fullprice").attrs 35 | print(f"El producto con las características:\n {name}\nPrecio de {price}\n\n") -------------------------------------------------------------------------------- /07_scraping/03_wiki_scraper.py: -------------------------------------------------------------------------------- 1 | from bs4 import BeautifulSoup 2 | from urllib.parse import urljoin 3 | import requests 4 | 5 | def scrape_url(url: str): 6 | headers = { 7 | 'User-Agent': 'Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko; compatible; Googlebot/2.1; +http://www.google.com/bot.html) Chrome/131.0.0 Safari/537.36' 8 | } 9 | response = requests.get(url, headers=headers) 10 | 11 | if response.status_code == 200: 12 | print('La petición fue exitosa') 13 | 14 | soup = BeautifulSoup(response.text, 'html.parser') 15 | 16 | # Extraer todos los 17 | titulos = [titulo.string for titulo in soup.find_all('h1')] 18 | # print(titulos) 19 | 20 | # Extraer todos los enlaces 21 | enlaces = [urljoin(url, enlace.get('href')) for enlace in soup.find_all('a')] 22 | # print(enlaces) 23 | 24 | # extraer todo el contenido de la página de texto 25 | # all_text = soup.get_text() 26 | # print(all_text) 27 | 28 | # extraer el texto del elemento main 29 | # main_text = soup.find('main').get_text() 30 | # print(main_text) 31 | 32 | # extraer de la id mw-content-text 33 | # content_text = soup.find('div', {'id': 'mw-content-text'}).get_text() 34 | # print(content_text) 35 | 36 | # extrar el open graph si existe 37 | # og_image = soup.find('meta', {'property': 'og:image'}) 38 | 39 | og_image = soup.find('meta', property='og:image') 40 | if og_image: 41 | print(og_image['content']) 42 | else: 43 | print('No se encontró la imagen') 44 | 45 | scrape_url('https://midu.dev') -------------------------------------------------------------------------------- /07_scraping/04_seo_cli.py: -------------------------------------------------------------------------------- 1 | import requests 2 | import argparse 3 | 4 | from bs4 import BeautifulSoup 5 | from urllib.parse import urljoin 6 | 7 | parser = argparse.ArgumentParser(description="Web scraping to check SEO for a given URL") 8 | parser.add_argument('url', type=str, help='The URL of the site you want to scrape and check') 9 | args = parser.parse_args() 10 | url = args.url 11 | 12 | headers = { 13 | 'User-Agent': 'Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko; compatible; Googlebot/2.1; +http://www.google.com/bot.html) Chrome/131.0.0 Safari/537.36' 14 | } 15 | response = requests.get(url, headers=headers) 16 | 17 | if response.status_code == 200: 18 | print('La petición fue exitosa') 19 | 20 | soup = BeautifulSoup(response.text, 'html.parser') 21 | 22 | print(f"\033[34mRevisando la página: {url}\033[0m") 23 | print("\nSEO básico:") 24 | 25 | titulo_pagina = soup.title.string 26 | 27 | if titulo_pagina: 28 | print(f"\033[46mEl título de la página es: {titulo_pagina}\033[0m") 29 | if len(titulo_pagina) < 70: 30 | print("\033[32m✅ El título de la página tiene una longitud adecuada\033[0m") 31 | else: 32 | print("⚠️ El título de la página es DEMASIADO largo") 33 | 34 | # extrae todos los titulos h1 35 | titulos = [titulo.text for titulo in soup.find_all('h1')] 36 | if not titulos: 37 | print("\033[31m❌ No se encontraron títulos h1 en la página\033[0m") 38 | elif len(titulos) > 1: 39 | print("\033[31m❌ Hay más de un título h1 en la página\033[0m") 40 | for titulo in titulos: 41 | print(titulo) 42 | else: 43 | print("\033[32m✅ Hay un título h1 en la página\033[0m") -------------------------------------------------------------------------------- /07_scraping/05_playwright.py: -------------------------------------------------------------------------------- 1 | import re # regular expression 2 | from playwright.sync_api import Page, expect 3 | 4 | def test_has_title(page: Page): 5 | page.goto("https://playwright.dev/") 6 | 7 | # Expect a title "to contain" a substring. 8 | expect(page).to_have_title(re.compile("Playwright")) 9 | 10 | def test_get_started_link(page: Page): 11 | page.goto("https://playwright.dev/") 12 | 13 | # Click the get started link. 14 | page.get_by_role("link", name="Get started").click() 15 | 16 | # Expects page to have a heading with the name of Installation. 17 | expect(page.get_by_role("heading", name="Installation")).to_be_visible() -------------------------------------------------------------------------------- /07_scraping/06_playwright_scraping.py: -------------------------------------------------------------------------------- 1 | from playwright.sync_api import sync_playwright 2 | 3 | url = 'https://midu.dev' 4 | 5 | with sync_playwright() as p: 6 | browser = p.chromium.launch(headless=False, slow_mo=2000) 7 | page = browser.new_page() 8 | page.goto(url) 9 | 10 | first_article_anchor = page.locator('article a').first 11 | print(first_article_anchor.text_content()) 12 | first_article_anchor.click() 13 | 14 | page.wait_for_load_state() 15 | 16 | curso_content_container = page.locator('text="Contenido del curso"') 17 | curso_content_sibling = curso_content_container.locator('xpath=./div/') 18 | 19 | browser.close() -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | # Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International 2 | 3 | Creative Commons Corporation (“Creative Commons”) is not a law firm and does not provide legal services or legal advice. Distribution of Creative Commons public licenses does not create a lawyer-client or other relationship. Creative Commons makes its licenses and related information available on an “as-is” basis. Creative Commons gives no warranties regarding its licenses, any material licensed under their terms and conditions, or any related information. Creative Commons disclaims all liability for damages resulting from their use to the fullest extent possible. 4 | 5 | **Using Creative Commons Public Licenses** 6 | 7 | Creative Commons public licenses provide a standard set of terms and conditions that creators and other rights holders may use to share original works of authorship and other material subject to copyright and certain other rights specified in the public license below. The following considerations are for informational purposes only, are not exhaustive, and do not form part of our licenses. 8 | 9 | * __Considerations for licensors:__ Our public licenses are intended for use by those authorized to give the public permission to use material in ways otherwise restricted by copyright and certain other rights. Our licenses are irrevocable. Licensors should read and understand the terms and conditions of the license they choose before applying it. Licensors should also secure all rights necessary before applying our licenses so that the public can reuse the material as expected. Licensors should clearly mark any material not subject to the license. This includes other CC-licensed material, or material used under an exception or limitation to copyright. [More considerations for licensors](http://wiki.creativecommons.org/Considerations_for_licensors_and_licensees#Considerations_for_licensors). 10 | 11 | * __Considerations for the public:__ By using one of our public licenses, a licensor grants the public permission to use the licensed material under specified terms and conditions. If the licensor’s permission is not necessary for any reason–for example, because of any applicable exception or limitation to copyright–then that use is not regulated by the license. Our licenses grant only permissions under copyright and certain other rights that a licensor has authority to grant. Use of the licensed material may still be restricted for other reasons, including because others have copyright or other rights in the material. A licensor may make special requests, such as asking that all changes be marked or described. Although not required by our licenses, you are encouraged to respect those requests where reasonable. [More considerations for the public](http://wiki.creativecommons.org/Considerations_for_licensors_and_licensees#Considerations_for_licensees). 12 | 13 | ## Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International Public License 14 | 15 | By exercising the Licensed Rights (defined below), You accept and agree to be bound by the terms and conditions of this Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International Public License ("Public License"). To the extent this Public License may be interpreted as a contract, You are granted the Licensed Rights in consideration of Your acceptance of these terms and conditions, and the Licensor grants You such rights in consideration of benefits the Licensor receives from making the Licensed Material available under these terms and conditions. 16 | 17 | ### Section 1 – Definitions. 18 | 19 | a. __Adapted Material__ means material subject to Copyright and Similar Rights that is derived from or based upon the Licensed Material and in which the Licensed Material is translated, altered, arranged, transformed, or otherwise modified in a manner requiring permission under the Copyright and Similar Rights held by the Licensor. For purposes of this Public License, where the Licensed Material is a musical work, performance, or sound recording, Adapted Material is always produced where the Licensed Material is synched in timed relation with a moving image. 20 | 21 | b. __Copyright and Similar Rights__ means copyright and/or similar rights closely related to copyright including, without limitation, performance, broadcast, sound recording, and Sui Generis Database Rights, without regard to how the rights are labeled or categorized. For purposes of this Public License, the rights specified in Section 2(b)(1)-(2) are not Copyright and Similar Rights. 22 | 23 | e. __Effective Technological Measures__ means those measures that, in the absence of proper authority, may not be circumvented under laws fulfilling obligations under Article 11 of the WIPO Copyright Treaty adopted on December 20, 1996, and/or similar international agreements. 24 | 25 | f. __Exceptions and Limitations__ means fair use, fair dealing, and/or any other exception or limitation to Copyright and Similar Rights that applies to Your use of the Licensed Material. 26 | 27 | h. __Licensed Material__ means the artistic or literary work, database, or other material to which the Licensor applied this Public License. 28 | 29 | i. __Licensed Rights__ means the rights granted to You subject to the terms and conditions of this Public License, which are limited to all Copyright and Similar Rights that apply to Your use of the Licensed Material and that the Licensor has authority to license. 30 | 31 | h. __Licensor__ means the individual(s) or entity(ies) granting rights under this Public License. 32 | 33 | i. __NonCommercial__ means not primarily intended for or directed towards commercial advantage or monetary compensation. For purposes of this Public License, the exchange of the Licensed Material for other material subject to Copyright and Similar Rights by digital file-sharing or similar means is NonCommercial provided there is no payment of monetary compensation in connection with the exchange. 34 | 35 | j. __Share__ means to provide material to the public by any means or process that requires permission under the Licensed Rights, such as reproduction, public display, public performance, distribution, dissemination, communication, or importation, and to make material available to the public including in ways that members of the public may access the material from a place and at a time individually chosen by them. 36 | 37 | k. __Sui Generis Database Rights__ means rights other than copyright resulting from Directive 96/9/EC of the European Parliament and of the Council of 11 March 1996 on the legal protection of databases, as amended and/or succeeded, as well as other essentially equivalent rights anywhere in the world. 38 | 39 | l. __You__ means the individual or entity exercising the Licensed Rights under this Public License. __Your__ has a corresponding meaning. 40 | 41 | ### Section 2 – Scope. 42 | 43 | a. ___License grant.___ 44 | 45 | 1. Subject to the terms and conditions of this Public License, the Licensor hereby grants You a worldwide, royalty-free, non-sublicensable, non-exclusive, irrevocable license to exercise the Licensed Rights in the Licensed Material to: 46 | 47 | A. reproduce and Share the Licensed Material, in whole or in part, for NonCommercial purposes only; and 48 | 49 | B. produce and reproduce, but not Share, Adapted Material for NonCommercial purposes only. 50 | 51 | 2. __Exceptions and Limitations.__ For the avoidance of doubt, where Exceptions and Limitations apply to Your use, this Public License does not apply, and You do not need to comply with its terms and conditions. 52 | 53 | 3. __Term.__ The term of this Public License is specified in Section 6(a). 54 | 55 | 4. __Media and formats; technical modifications allowed.__ The Licensor authorizes You to exercise the Licensed Rights in all media and formats whether now known or hereafter created, and to make technical modifications necessary to do so. The Licensor waives and/or agrees not to assert any right or authority to forbid You from making technical modifications necessary to exercise the Licensed Rights, including technical modifications necessary to circumvent Effective Technological Measures. For purposes of this Public License, simply making modifications authorized by this Section 2(a)(4) never produces Adapted Material. 56 | 57 | 5. __Downstream recipients.__ 58 | 59 | A. __Offer from the Licensor – Licensed Material.__ Every recipient of the Licensed Material automatically receives an offer from the Licensor to exercise the Licensed Rights under the terms and conditions of this Public License. 60 | 61 | B. __No downstream restrictions.__ You may not offer or impose any additional or different terms or conditions on, or apply any Effective Technological Measures to, the Licensed Material if doing so restricts exercise of the Licensed Rights by any recipient of the Licensed Material. 62 | 63 | 6. __No endorsement.__ Nothing in this Public License constitutes or may be construed as permission to assert or imply that You are, or that Your use of the Licensed Material is, connected with, or sponsored, endorsed, or granted official status by, the Licensor or others designated to receive attribution as provided in Section 3(a)(1)(A)(i). 64 | 65 | b. ___Other rights.___ 66 | 67 | 1. Moral rights, such as the right of integrity, are not licensed under this Public License, nor are publicity, privacy, and/or other similar personality rights; however, to the extent possible, the Licensor waives and/or agrees not to assert any such rights held by the Licensor to the limited extent necessary to allow You to exercise the Licensed Rights, but not otherwise. 68 | 69 | 2. Patent and trademark rights are not licensed under this Public License. 70 | 71 | 3. To the extent possible, the Licensor waives any right to collect royalties from You for the exercise of the Licensed Rights, whether directly or through a collecting society under any voluntary or waivable statutory or compulsory licensing scheme. In all other cases the Licensor expressly reserves any right to collect such royalties, including when the Licensed Material is used other than for NonCommercial purposes. 72 | 73 | ### Section 3 – License Conditions. 74 | 75 | Your exercise of the Licensed Rights is expressly made subject to the following conditions. 76 | 77 | a. ___Attribution.___ 78 | 79 | 1. If You Share the Licensed Material, You must: 80 | 81 | A. retain the following if it is supplied by the Licensor with the Licensed Material: 82 | 83 | i. identification of the creator(s) of the Licensed Material and any others designated to receive attribution, in any reasonable manner requested by the Licensor (including by pseudonym if designated); 84 | 85 | ii. a copyright notice; 86 | 87 | iii. a notice that refers to this Public License; 88 | 89 | iv. a notice that refers to the disclaimer of warranties; 90 | 91 | v. a URI or hyperlink to the Licensed Material to the extent reasonably practicable; 92 | 93 | B. indicate if You modified the Licensed Material and retain an indication of any previous modifications; and 94 | 95 | C. indicate the Licensed Material is licensed under this Public License, and include the text of, or the URI or hyperlink to, this Public License. 96 | 97 | For the avoidance of doubt, You do not have permission under this Public License to Share Adapted Material. 98 | 99 | 2. You may satisfy the conditions in Section 3(a)(1) in any reasonable manner based on the medium, means, and context in which You Share the Licensed Material. For example, it may be reasonable to satisfy the conditions by providing a URI or hyperlink to a resource that includes the required information. 100 | 101 | 3. If requested by the Licensor, You must remove any of the information required by Section 3(a)(1)(A) to the extent reasonably practicable. 102 | 103 | ### Section 4 – Sui Generis Database Rights. 104 | 105 | Where the Licensed Rights include Sui Generis Database Rights that apply to Your use of the Licensed Material: 106 | 107 | a. for the avoidance of doubt, Section 2(a)(1) grants You the right to extract, reuse, reproduce, and Share all or a substantial portion of the contents of the database for NonCommercial purposes only and provided You do not Share Adapted Material; 108 | 109 | b. if You include all or a substantial portion of the database contents in a database in which You have Sui Generis Database Rights, then the database in which You have Sui Generis Database Rights (but not its individual contents) is Adapted Material; and 110 | 111 | c. You must comply with the conditions in Section 3(a) if You Share all or a substantial portion of the contents of the database. 112 | 113 | For the avoidance of doubt, this Section 4 supplements and does not replace Your obligations under this Public License where the Licensed Rights include other Copyright and Similar Rights. 114 | 115 | ### Section 5 – Disclaimer of Warranties and Limitation of Liability. 116 | 117 | a. __Unless otherwise separately undertaken by the Licensor, to the extent possible, the Licensor offers the Licensed Material as-is and as-available, and makes no representations or warranties of any kind concerning the Licensed Material, whether express, implied, statutory, or other. This includes, without limitation, warranties of title, merchantability, fitness for a particular purpose, non-infringement, absence of latent or other defects, accuracy, or the presence or absence of errors, whether or not known or discoverable. Where disclaimers of warranties are not allowed in full or in part, this disclaimer may not apply to You.__ 118 | 119 | b. __To the extent possible, in no event will the Licensor be liable to You on any legal theory (including, without limitation, negligence) or otherwise for any direct, special, indirect, incidental, consequential, punitive, exemplary, or other losses, costs, expenses, or damages arising out of this Public License or use of the Licensed Material, even if the Licensor has been advised of the possibility of such losses, costs, expenses, or damages. Where a limitation of liability is not allowed in full or in part, this limitation may not apply to You.__ 120 | 121 | c. The disclaimer of warranties and limitation of liability provided above shall be interpreted in a manner that, to the extent possible, most closely approximates an absolute disclaimer and waiver of all liability. 122 | 123 | ### Section 6 – Term and Termination. 124 | 125 | a. This Public License applies for the term of the Copyright and Similar Rights licensed here. However, if You fail to comply with this Public License, then Your rights under this Public License terminate automatically. 126 | 127 | b. Where Your right to use the Licensed Material has terminated under Section 6(a), it reinstates: 128 | 129 | 1. automatically as of the date the violation is cured, provided it is cured within 30 days of Your discovery of the violation; or 130 | 131 | 2. upon express reinstatement by the Licensor. 132 | 133 | For the avoidance of doubt, this Section 6(b) does not affect any right the Licensor may have to seek remedies for Your violations of this Public License. 134 | 135 | c. For the avoidance of doubt, the Licensor may also offer the Licensed Material under separate terms or conditions or stop distributing the Licensed Material at any time; however, doing so will not terminate this Public License. 136 | 137 | d. Sections 1, 5, 6, 7, and 8 survive termination of this Public License. 138 | 139 | ### Section 7 – Other Terms and Conditions. 140 | 141 | a. The Licensor shall not be bound by any additional or different terms or conditions communicated by You unless expressly agreed. 142 | 143 | b. Any arrangements, understandings, or agreements regarding the Licensed Material not stated herein are separate from and independent of the terms and conditions of this Public License. 144 | 145 | ### Section 8 – Interpretation. 146 | 147 | a. For the avoidance of doubt, this Public License does not, and shall not be interpreted to, reduce, limit, restrict, or impose conditions on any use of the Licensed Material that could lawfully be made without permission under this Public License. 148 | 149 | b. To the extent possible, if any provision of this Public License is deemed unenforceable, it shall be automatically reformed to the minimum extent necessary to make it enforceable. If the provision cannot be reformed, it shall be severed from this Public License without affecting the enforceability of the remaining terms and conditions. 150 | 151 | c. No term or condition of this Public License will be waived and no failure to comply consented to unless expressly agreed to by the Licensor. 152 | 153 | d. Nothing in this Public License constitutes or may be interpreted as a limitation upon, or waiver of, any privileges and immunities that apply to the Licensor or You, including from the legal processes of any jurisdiction or authority. 154 | 155 | > Creative Commons is not a party to its public licenses. Notwithstanding, Creative Commons may elect to apply one of its public licenses to material it publishes and in those instances will be considered the “Licensor.” The text of the Creative Commons public licenses is dedicated to the public domain under the CC0 Public Domain Dedication. The text of the Creative Commons public licenses is dedicated to the public domain under the [CC0 Public Domain Dedication](https://creativecommons.org/publicdomain/zero/1.0/legalcode). Except for the limited purpose of indicating that material is shared under a Creative Commons public license or as otherwise permitted by the Creative Commons policies published at [creativecommons.org/policies](http://creativecommons.org/policies), Creative Commons does not authorize the use of the trademark “Creative Commons” or any other trademark or logo of Creative Commons without its prior written consent including, without limitation, in connection with any unauthorized modifications to any of its public licenses or any other arrangements, understandings, or agreements concerning use of licensed material. For the avoidance of doubt, this paragraph does not form part of the public licenses. 156 | > 157 | > Creative Commons may be contacted at [creativecommons.org](http://creativecommons.org). -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |
2 | 3 | # Curso Python desde Cero 🐍 4 | 5 | [![Python Version](https://img.shields.io/badge/Python-3.x-blue.svg)](https://www.python.org/) 6 | [![Estado](https://img.shields.io/badge/Estado-En%20emisión-yellow)](https://twitch.tv/midudev) 7 | [![CC License](https://img.shields.io/badge/license-CC--BY--NC--ND-green.svg)](https://github.com/midudev/curso-python/blob/main/LICENSE) 8 | 9 | Curso práctico y gratuito de Python desde cero. Emitido en directo en [twitch.tv/midudev](https://twitch.tv/midudev). 10 | 11 |
12 | 13 | GitHub 14 | 15 | 16 | Twitter 17 | 18 | 19 | Twitch 20 | 21 | 22 | YouTube 23 | 24 |
25 | 26 |
27 | 28 |
29 | portada python 30 |
31 | 32 | ## 🤔 ¿Por qué deberías ver este curso? 33 | 34 | - 🎯 **Aprenderás el lenguaje de programación del momento.** 35 | - 📅 **Nuevas clases todos los miércoles.** 36 | - 🚀 Ideal para principiantes: comienza **desde cero** y avanza paso a paso. 37 | - 🛠️ **Curso práctico** con ejercicios para que puedas practicar lo aprendido. 38 | - 📝 **Código abierto**: lo que te permitirá clonar el proyecto y tener acceso completo a todo lo que se muestra. 39 | > [!TIP] 40 | > **¿Sabías que puedes acceder a todas las clases desde la [Academia de midudev](https://midu.dev/)?** Si eres suscriptor en [Twitch](https://www.twitch.tv/midudev), ¡ya tienes acceso! 41 | 42 | ## 🕐 Horario por países 43 | 44 | | Hora | Países | 45 | |------|------------------------------------------| 46 | | 18H | 🇪🇸 España | 47 | | 17H | 🇮🇨 Islas Canarias | 48 | | 14H | 🇺🇾 Uruguay 🇦🇷 Argentina 🇨🇱 Chile 🇵🇾 Paraguay | 49 | | 13H | 🇧🇴 Bolivia 🇻🇪 Venezuela 🇩🇴 República Dominicana 🇵🇷 Puerto Rico | 50 | | 12H | 🇨🇴 Colombia 🇵🇪 Perú 🇪🇨 Ecuador 🇨🇺 Cuba 🇵🇦 Panamá | 51 | | 11H | 🇲🇽 México 🇨🇷 Costa Rica 🇳🇮 Nicaragua 🇸🇻 El Salvador 🇭🇳 Honduras | 52 | 53 | ## 📺¿Dónde puedo ver el curso? 54 | Mira los cursos y participa en vivo en 55 | [twitch.tv/midudev](https://twitch.tv/midudev) 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | ## 📄 Contenido Actual 65 | | Clase | Código | Video | 66 | |-----------------|-----------------|----------------------------------| 67 | |**1. Hola Mundo, Tipos de Datos, Conversión de tipos y Variables** | [![github](https://img.shields.io/badge/github-black?style=for-the-badge&logo=github&logoColor=white)](https://github.com/midudev/curso-python/tree/main/01_basic) | [![twitch](https://img.shields.io/badge/twitch-572364?style=for-the-badge&logo=twitch&logoColor=white)](https://www.twitch.tv/videos/2354087841) | 68 | |**2. Condicionales y listas + ejercicios** | [![github](https://img.shields.io/badge/github-black?style=for-the-badge&logo=github&logoColor=white)](https://github.com/midudev/curso-python/tree/main/02_flow_control) | [![twitch](https://img.shields.io/badge/twitch-572364?style=for-the-badge&logo=twitch&logoColor=white)](https://www.twitch.tv/videos/2360535344) | 69 | |**3. Bucles while, for y funciones** | [![github](https://img.shields.io/badge/github-black?style=for-the-badge&logo=github&logoColor=white)](https://github.com/midudev/curso-python/tree/main/03_loops) | [![twitch](https://img.shields.io/badge/twitch-572364?style=for-the-badge&logo=twitch&logoColor=white)](https://www.twitch.tv/videos/2366925887) | 70 | |**4. Lógica de Programación + Diccionarios** | [![github](https://img.shields.io/badge/github-black?style=for-the-badge&logo=github&logoColor=white)](https://github.com/midudev/curso-python/tree/main/04_logic) | [![twitch](https://img.shields.io/badge/twitch-572364?style=for-the-badge&logo=twitch&logoColor=white)](https://www.twitch.tv/videos/2373204722) | 71 | |**5. Expresiones Regulares** | [![github](https://img.shields.io/badge/github-black?style=for-the-badge&logo=github&logoColor=white)](https://github.com/midudev/curso-python/tree/main/05_regex) | [![twitch](https://img.shields.io/badge/twitch-572364?style=for-the-badge&logo=twitch&logoColor=white)](https://www.twitch.tv/videos/2385556729) | 72 | |**6. Fetching de Datos + Fechas + Clases** | [![github](https://img.shields.io/badge/github-black?style=for-the-badge&logo=github&logoColor=white)](https://github.com/midudev/curso-python/tree/main/06_request_ai_dates) | [![twitch](https://img.shields.io/badge/twitch-572364?style=for-the-badge&logo=twitch&logoColor=white)](https://www.twitch.tv/videos/2397854000) | 73 | |**7. Scraping de datos** | [![github](https://img.shields.io/badge/github-black?style=for-the-badge&logo=github&logoColor=white)](https://github.com/midudev/curso-python/tree/main/07_scraping) | [![twitch](https://img.shields.io/badge/twitch-572364?style=for-the-badge&logo=twitch&logoColor=white)](https://www.twitch.tv/videos/2409874203) | 74 | 75 | > [!NOTE] 76 | > El curso está actualmente en emisión. Nuevas clases todos los miércoles a las 18:00h (hora española). 77 | 78 |
79 | 📚 Temario Completo Planificado 80 | 81 | 1. Introducción ✓ 82 | 2. Variables y Funciones Incorporadas ✓ 83 | 3. Operadores ✓ 84 | 4. Strings ✓ 85 | 5. Listas ✓ 86 | 6. Tuplas ✓ 87 | 8. Diccionarios ✓ 88 | 9. Condicionales ✓ 89 | 10. Bucles ✓ 90 | 11. Funciones ✓ 91 | 12. Errores de Tipos en Python ✓ 92 | 13. Python Date time ✓ 93 | 14. Manejo de Excepciones ✓ 94 | 15. Expresiones Regulares ✓ 95 | 16. Web Scraping ✓ 96 | 17. Clases y Objetos ✓ 97 | 18. Sets 98 | 19. Módulos 99 | 20. List Comprehension 100 | 21. Funciones de Orden Superior 101 | 22. Manejo de Archivos 102 | 23. Python Package Manager 103 | 24. Entorno Virtual 104 | 25. Estadísticas 105 | 26. Python para la Web + Django 106 | 27. Python con MongoDB 107 | 28. APIs desde cero 108 | 29. Pandas 109 | 110 |
111 | 112 | ## ⚙️ Requisitos 113 | 114 | > [!IMPORTANT] 115 | > Necesitarás: 116 | > - Python 3.x 117 | > - Editor de código (recomendado VS Code) 118 | > - Conexión a internet para las clases en vivo 119 | 120 | ## 💻 Instalación 121 | 122 | ```bash 123 | # Verifica tu versión de Python 124 | python --version 125 | 126 | # En algunos sistemas operativos el ejecutable es otro 127 | python3 --version 128 | 129 | # Clona el repositorio 130 | git clone https://github.com/midudev/curso-python 131 | 132 | # Accede al directorio 133 | cd curso-python 134 | ``` 135 | 136 | > [!TIP] 137 | > Si no quieres instalar nada, puedes usar editores online como: 138 | > - [OnlineGDB](https://www.onlinegdb.com/online_python_compiler) 139 | > - [Python Sandbox](https://pythonsandbox.io/) 140 | > - [Google Colab](https://colab.research.google.com/) 141 | 142 | --- 143 | 144 | ## 💻 Configuración del Entorno 145 | 146 | > Usa **Visual Studio Code (VS Code)** para escribir y ejecutar código Python localmente. 147 | 148 | 1. Descarga [VS Code](https://code.visualstudio.com/) 149 | 2. Instala las extensiones recomendadas: 150 | - [Python](https://marketplace.visualstudio.com/items?itemName=ms-python.python) 151 | - [Pylance](https://marketplace.visualstudio.com/items?itemName=ms-python.vscode-pylance) 152 | - [Python Debugger](https://marketplace.visualstudio.com/items?itemName=ms-python.debugpy) 153 | 154 | ## 🛠️ Requisitos Técnicos 155 | 156 | - Python 3.x instalado 157 | - VS Code + extensiones 158 | - Conexión a internet 159 | - No requiere experiencia previa 160 | 161 | ## 📚 Recursos Adicionales 162 | 163 | - [cursopython.dev](https://cursopython.dev) - Portal oficial del curso 164 | - [Documentación de Python](https://docs.python.org/es/) - Documentación oficial en español 165 | - [Ejercicios resueltos](link-ejercicios) - Soluciones a los ejercicios del curso 166 | 167 | ## 🔗 Enlaces 168 | 169 | - 🌐 [cursopython.dev](https://cursopython.dev) - Portal del curso 170 | - 📚 [Documentación Python](https://docs.python.org/es/) - Docs oficial 171 | - ⭐ [GitHub](https://github.com/midudev/curso-python) - Código fuente 172 | 173 | ## 👥 Comunidad 174 | 175 | [![Discord](https://img.shields.io/discord/741237973663612969?style=for-the-badge&logo=discord&logoColor=white&label=Discord)](https://discord.gg/midudev) 176 | 177 | Únete a nuestra comunidad para: 178 | - 💬 Compartir dudas y soluciones 179 | - 🤝 Conectar con otros estudiantes 180 | - 📢 Recibir anuncios de nuevas clases 181 | - 🎉 Participar en eventos especiales 182 | 183 | ## ⚖️ Licencia 184 | 185 | Este curso usa la licencia [CC-BY-NC-ND](https://github.com/midudev/curso-python/blob/main/LICENSE) que permite: 186 | - ✅ Compartir el material 187 | - ✅ Usar el contenido para uso personal 188 | - ❌ Uso comercial 189 | - ❌ Modificación del material 190 | - ⚠️ Requiere atribución al autor 191 | 192 | ## 👨‍💻 Autor 193 | 194 | [@midudev](https://www.github.com/midudev) 195 | -------------------------------------------------------------------------------- /test.py: -------------------------------------------------------------------------------- 1 | inventario_dinosaurios = [ 2 | ("Rexy", "Tyrannosaurus Rex", 1, "Saludable"), 3 | ("Blue", "Velociraptor", 2, "Saludable"), 4 | ("Charlie", "Velociraptor", 2, "Necesita Atención"), 5 | ("Delta", "Velociraptor", 2, "Saludable"), 6 | ("Echo", "Velociraptor", 2, "Saludable"), 7 | ("Braquiosaurio_1", "Braquiosaurio", 3, "Saludable"), 8 | ("Triceratops_1", "Triceratops", 4, "Saludable"), 9 | ("Spino", "Spinosaurus", 5, "Necesita Atención"), 10 | ("Pterodáctilo_1", "Pterodáctilo", 6, "Saludable"), 11 | ("Rexy_Junior", "Tyrannosaurus Rex", 1, "Necesita Atención"), 12 | ] 13 | 14 | print("--- Informe del Inventario de Dinosaurios de Jurassic Park ---") 15 | 16 | # 1. Contar el número total de dinosaurios 17 | total_dinosaurios = 0 18 | for dinosaurio in inventario_dinosaurios: 19 | total_dinosaurios += 1 # Incrementa el contador por cada dinosaurio en la lista 20 | print(f"\nNúmero total de dinosaurios en el parque: {total_dinosaurios}") 21 | 22 | # 2. Identificar y listar los nombres de todos los Velociraptors 23 | velociraptors_list = [] 24 | for dinosaurio in inventario_dinosaurios: 25 | if dinosaurio[1] == "Velociraptor": # Comprueba si la especie (índice 1) es "Velociraptor" 26 | velociraptors_list.append(dinosaurio[0]) # Añade el nombre (índice 0) a la lista 27 | print(f"\n--- Listado de Velociraptors ---") 28 | print(f"Velociraptors encontrados: {velociraptors_list}") 29 | 30 | # 3. Determinar cuántos dinosaurios necesitan atención médica 31 | dinosaurios_necesitan_atencion = 0 32 | for dinosaurio in inventario_dinosaurios: 33 | if dinosaurio[3] == "Necesita Atención": # Comprueba si el estado de salud (índice 3) es "Necesita Atención" 34 | dinosaurios_necesitan_atencion += 1 # Incrementa el contador 35 | print(f"\n--- Dinosaurios que necesitan atención médica ---") 36 | print(f"Número de dinosaurios que necesitan atención médica: {dinosaurios_necesitan_atencion}") 37 | 38 | # 4. Simular una "inspección de recinto" para el Recinto 2 39 | def inspeccionar_recinto(recinto_numero): 40 | print(f"\n--- Inspección del Recinto {recinto_numero} ---") 41 | print(f"Dinosaurios en el Recinto {recinto_numero}:") 42 | for dinosaurio in inventario_dinosaurios: 43 | if dinosaurio[2] == recinto_numero: # Comprueba si el recinto (índice 2) coincide con el recinto_numero dado 44 | print(f"- Nombre: {dinosaurio[0]}, Estado: {dinosaurio[3]}") 45 | 46 | inspeccionar_recinto(2) # Llama a la función para inspeccionar el Recinto 2 --------------------------------------------------------------------------------