Mini manual de Python de cero a experto
Este programa de estudios te ayudará a aprender Python de manera estructurada, comenzando por los fundamentos e intermedio hacia temas más especializados y avanzados.
Módulo 1: Fundamentos de Python
- Introducción a Python
 - Instalación y configuración de Python
 - Variables, tipos de datos y operadores básicos
 - Estructuras de control: if, elif, else
 - Bucles: for y while
 - Funciones
 - Manejo de excepciones
 - Ejercicios y ejemplos prácticos
 
Módulo 2: Estructuras de datos en Python
- Listas
 - Tuplas
 - Conjuntos (sets)
 - Diccionarios
 - Comprensiones de listas, diccionarios y conjuntos
 - Ejercicios y ejemplos prácticos
 
Módulo 3: Programación orientada a objetos (POO) en Python
- Introducción a la POO 3.2. Clases y objetos
 - Herencia y polimorfismo
 - Encapsulamiento
 - Ejercicios y ejemplos prácticos
 
Módulo 4: Módulos y paquetes en Python
- Introducción a módulos y paquetes
 - Importación de módulos y paquetes
 - Creación de módulos y paquetes personalizados
 - Ejercicios y ejemplos prácticos
 
Módulo 5: Bibliotecas estándar de Python
- Manejo de archivos y directorios (os, shutil)
 - Expresiones regulares (re)
 - Fecha y hora (datetime)
 - Serialización y deserialización de datos (json, pickle)
 - Ejercicios y ejemplos prácticos
 
Módulo 6: Bibliotecas y aplicaciones más comunes
- Solicitudes HTTP y scraping web (requests, BeautifulSoup)
 - Automatización de tareas (selenium)
 - Manipulación y análisis de datos (numpy, pandas)
 - Visualización de datos (matplotlib, seaborn)
 - Machine Learning (scikit-learn, TensorFlow)
 - Desarrollo web (Flask, Django)
 - Ejercicios y ejemplos prácticos
 
Módulo 7: Temas avanzados y buenas prácticas
- Decoradores
 - Generadores
 - Concurrencia y paralelismo (threading, multiprocessing)
 - Programación asíncrona (asyncio, aiohttp)
 - Pruebas unitarias (unittest)
 - Integración continua y control de versiones (Git, GitHub) 7.7.
 - Ejercicios y ejemplos prácticos
 
 Módulo 1: Fundamentos de Python
1.1 Introducción a Python
Python es un lenguaje de programación de alto nivel, de propósito general y fácil de aprender. Es ideal para principiantes y utilizado en diversas áreas, como desarrollo web, análisis de datos y machine learning.
1.2 Instalación y configuración de Python Descarga e instala Python desde python.org. Verifica la instalación ejecutando python --version en la terminal.
#Instalacion en red hat y derivados yum install python #Instalación en debian y derivados apt install python
1.3. Variables, tipos de datos y operadores básicos Las variables almacenan datos. Los tipos de datos comunes incluyen int, float y str. Ejemplo:
a = 5 # int
 b = 3.14 # float
 c = "Hola" # str
 suma = a + b # 8.14
 1.4. Estructuras de control: if, elif, else Permiten la toma de decisiones basadas en condiciones. Ejemplo:
edad = 18
 if edad < 18:
 print("Menor de edad")
 elif edad == 18:
 print("Exactamente 18 años")
 else:
 print("Mayor de edad")
 1.5. Bucles: for y while Repiten acciones mientras se cumpla una condición. Ejemplo:
# for
 for i in range(3):
 print(i) # 0, 1, 2# whilecontador = 0
while contador < 3:
print(contador) # 0, 1, 2
contador += 1
1.6. Funciones Bloques de código reutilizables. Ejemplo:
def suma(a, b):
 return a + bresultado = suma(3, 4) # 71.7. Manejo de excepciones Evita que los errores detengan la ejecución. Ejemplo:
try:
 resultado = 5 / 0
 except ZeroDivisionError:
 print("No se puede dividir entre cero")
 1.8. Ejercicios y ejemplos prácticos Realiza ejercicios para aplicar lo aprendido. Por ejemplo, crea un programa que calcule el área de un triángulo con base y altura dadas.
python
def solicitar_numero(mensaje):
while True:
try:
numero = float(input(mensaje))
if numero <= 0:
print("Por favor, ingrese un número positivo.")
else:
return numero
except ValueError:
print("Por favor, ingrese un número válido.")
def calcular_area(base, altura):
return 0.5 * base * altura
def main():
base = solicitar_numero("Ingrese la base del triángulo: ")
altura = solicitar_numero("Ingrese la altura del triángulo: ")
area = calcular_area(base, altura)
print(f"El área del triángulo es: {area:.2f}")
if __name__ == "__main__":
main()Explicación del código del ejercicios y ejemplos prácticos anterior:
- La función 
solicitar_numerosolicita un número positivo al usuario y verifica que la entrada sea válida. - La función 
calcular_arearecibe la base y la altura del triángulo y devuelve su área. - La función 
maincoordina el flujo del programa, solicitando la base y la altura al usuario, calculando el área e imprimiendo el resultado. - La condición 
if __name__ == "__main__":permite ejecutar el programa principal solo si el archivo se ejecuta directamente. 
- La función 
 
Puedes utilizar este ejemplo para verificar la comprensión de los conceptos básicos de Python, como funciones, entrada de datos, manejo de excepciones y estructuras de control.
Módulo 2: Estructuras de datos en Python
2.1. Listas Colecciones ordenadas y mutables. Ejemplo:
frutas = ["manzana", "plátano", "cereza"]
 frutas.append("uva") # Añade elemento
 frutas.pop(1) # Elimina elemento en índice 1
 2.2. Tuplas Colecciones ordenadas e inmutables. Ejemplo:
coordenadas = (3, 4)
 x, y = coordenadas # Desempaquetado
 2.3. Conjuntos (sets) Colecciones no ordenadas y sin elementos duplicados. Ejemplo:
mascotas = {"perro", "gato", "pez"}
 mascotas.add("conejo") # Añade elemento
 mascotas.remove("pez") # Elimina elemento
 2.4. Diccionarios Colecciones de pares clave-valor. Ejemplo:
estudiante = {
    "nombre": "Ana",
    "edad": 21,
    "carrera": "Informática"
}
estudiante["carrera"] = "Sistemas"  # Modifica valor
2.5. Comprensiones Forma concisa de crear colecciones. Ejemplo:
# Lista
cuadrados = [x**2 for x in range(5)]  # [0, 1, 4, 9, 16]# Diccionariocapitales = {pais: capital.upper() for pais, capital in {"España": "Madrid", "Francia": "París"}.items()} # {"España": "MADRID", "Francia": "PARÍS"}# Conjuntopares = {x for x in range(10) if x % 2 == 0} # {0, 2, 4, 6, 8}2.6. Ejercicios y ejemplos prácticos Realiza ejercicios para aplicar lo aprendido. Por ejemplo, crea un programa que elimine los elementos duplicados de una lista y los guarde en un nuevo conjunto.Puedes utilizar este ejemplo para verificar la comprensión de los conceptos de estructuras de datos en Python, como listas, conjuntos y la conversión entre ellos.
def eliminar_duplicados(lista):
return set(lista)
def main():
lista_original = [1, 2, 2, 3, 4, 4, 4, 5, 6, 6, 7, 8, 9, 9, 9, 9]
print(f"Lista original: {lista_original}")
conjunto_sin_duplicados = eliminar_duplicados(lista_original)
print(f"Conjunto sin duplicados: {conjunto_sin_duplicados}")
if __name__ == "__main__":
main()Explicación del ejercicio:
- La función 
eliminar_duplicadosrecibe una lista y devuelve un conjunto con los elementos únicos de la lista. - La función 
maincoordina el flujo del programa, mostrando la lista original, llamando a la funcióneliminar_duplicadosy mostrando el conjunto sin duplicados. - La condición 
if __name__ == "__main__":permite ejecutar el programa principal solo si el archivo se ejecuta directamente. 
- La función 
 
Módulo 3: Programación orientada a objetos (POO) en Python
3.1. Introducción a la POO
La Programación Orientada a Objetos (POO) es un paradigma que organiza el código en clases y objetos para modelar entidades del mundo real.
3.2. Clases y objetos
Las clases son plantillas para crear objetos, y los objetos son instancias de clases. Ejemplo:
python
class Perro:
    def __init__(self, nombre):
        self.nombre = nombre
    def ladrar(self):
        print(f"{self.nombre} dice: ¡Guau!")
firulais = Perro("Firulais")
firulais.ladrar()  # Firulais dice: ¡Guau!
3.3. Herencia y polimorfismo
La herencia permite que una clase herede atributos y métodos de otra. El polimorfismo permite que una subclase sobrescriba o extienda métodos de la clase base. Ejemplo:
class Animal:
    def hablar(self):
        print("El animal hace un sonido")
class Gato(Animal):
    def hablar(self):
        print("El gato dice: ¡Miau!")
tom = Gato()
tom.hablar()  # El gato dice: ¡Miau!
3.4. Encapsulamiento
El encapsulamiento esconde detalles de implementación y expone solo las partes necesarias. Ejemplo:
class Coche:
    def __init__(self):
        self.__velocidad = 0
    def acelerar(self, incremento):
        self.__velocidad += incremento
    def obtener_velocidad(self):
        return self.__velocidad
mi_coche = Coche()
mi_coche.acelerar(10)
print(mi_coche.obtener_velocidad())  # 10
3.5. Ejercicios y ejemplos prácticos Realiza ejercicios para aplicar lo aprendido. Por ejemplo, crea un programa que modele una jerarquía de vehículos, como coches y bicicletas, con atributos y métodos específicos.
Ejemplo del ejercicio,
Puedes utilizar este ejemplo para verificar la comprensión de los conceptos de programación orientada a objetos en Python, como clases, objetos, herencia, polimorfismo y encapsulamiento.
class Vehiculo:
def __init__(self, marca, modelo):
self.marca = marca
self.modelo = modelo
def descripcion(self):
return f"Marca: {self.marca}, Modelo: {self.modelo}"
class Coche(Vehiculo):
def __init__(self, marca, modelo, num_puertas):
super().__init__(marca, modelo)
self.num_puertas = num_puertas
def descripcion(self):
return f"{super().descripcion()}, Número de puertas: {self.num_puertas}"
class Bicicleta(Vehiculo):
def __init__(self, marca, modelo, tipo):
super().__init__(marca, modelo)
self.tipo = tipo
def descripcion(self):
return f"{super().descripcion()}, Tipo: {self.tipo}"
def main():
mi_coche = Coche("Toyota", "Corolla", 4)
mi_bicicleta = Bicicleta("Giant", "TCR Advanced", "Carrera")
print("Coche:", mi_coche.descripcion()) # Coche: Marca: Toyota, Modelo: Corolla, Número de puertas: 4
print("Bicicleta:", mi_bicicleta.descripcion()) # Bicicleta: Marca: Giant, Modelo: TCR Advanced, Tipo: Carrera
if __name__ == "__main__":
main()En este ejemplo:
- La clase 
Vehiculoes la clase base que representa un vehículo genérico. - Las clases 
CocheyBicicletaheredan deVehiculoy agregan atributos específicos. - Los métodos 
descripcionen las subclases sobrescriben el método de la clase base y utilizansuper()para incluir información adicional. - La función 
maincrea instancias deCocheyBicicletay muestra sus descripciones. - La condición 
if __name__ == "__main__":permite ejecutar el programa principal solo si el archivo se ejecuta directamente. 
Módulo 4: Módulos y paquetes en Python
4.1. Módulos y paquetes Módulos son archivos Python que contienen funciones, clases y variables. Paquetes son colecciones de módulos organizados en directorios. Ejemplo:
mi_modulo.py
def saludo(nombre):
 print(f"Hola, {nombre}!")
 main.py
import mi_modulo
mi_modulo.saludo("Juan") # Hola, Juan!
4.2. Biblioteca estándar Python incluye una amplia biblioteca estándar con módulos útiles. Ejemplo:
import math
print(math.sqrt(16)) # 4.0
4.3. Bibliotecas de terceros Se pueden instalar y utilizar bibliotecas adicionales. Ejemplo:
pip install requests
 import requests
response = requests.get("https://api.example.com/data")
 print(response.json())
4.4. Manejo de archivos Leer y escribir archivos es fundamental en programación. Ejemplo:
# Escritura
 with open("archivo.txt", "w") as f:
 f.write("Hola, mundo!")# Lecturawith open("archivo.txt", "r") as f:
contenido = f.read()
print(contenido) # Hola, mundo!
4.5. Ejercicios y ejemplos prácticos Realiza ejercicios para aplicar lo aprendido. Por ejemplo, crea un programa que lea un archivo CSV, realice algunas operaciones sobre los datos y genere un archivo de salida en formato JSON.
Aquí tienes un ejemplo práctico para leer un archivo CSV, realizar algunas operaciones sobre los datos y generar un archivo de salida en formato JSON. Este ejemplo se puede utilizar para comprender y corregir la práctica del Módulo 4.
datos.csv (archivo de entrada)
nombre,edad,ciudad
Ana,25,Madrid
Juan,30,Barcelona
Luis,22,Valencia
convertidor_csv_json.py
import csv
import json
def leer_csv(archivo_csv):
    with open(archivo_csv, "r") as f:
        reader = csv.DictReader(f)
        datos = [row for row in reader]
    return datos
def guardar_json(datos, archivo_json):
    with open(archivo_json, "w") as f:
        json.dump(datos, f, indent=2)
def main():
    archivo_entrada = "datos.csv"
    archivo_salida = "datos.json"
    datos = leer_csv(archivo_entrada)
    for persona in datos:
        persona["edad"] = int(persona["edad"]) + 1  # Incrementar edad en 1
    guardar_json(datos, archivo_salida)
    print("Conversión realizada con éxito.")
if __name__ == "__main__":
    main()
datos.json (archivo de salida)
[
 {
 "nombre": "Ana",
 "edad": 26,
 "ciudad": "Madrid"
 },
 {
 "nombre": "Juan",
 "edad": 31,
 "ciudad": "Barcelona"
 },
 {
 "nombre": "Luis",
 "edad": 23,
 "ciudad": "Valencia"
 }
 ]
 En este ejemplo:
- La función 
leer_csvlee un archivo CSV y devuelve una lista de diccionarios. - La función 
guardar_jsonguarda los datos en formato JSON en un archivo. - La función 
maincoordina el flujo del programa, leyendo el archivo CSV, modificando los datos y guardando el archivo JSON. - La condición 
if __name__ == "__main__":permite ejecutar el programa principal solo si el archivo se ejecuta directamente. 
- La función 
 
 Módulo 5: Bibliotecas estándar de Python
5.1. Introducción a funciones avanzadas Las funciones avanzadas en Python permiten escribir código más conciso y funcional.
5.2. Funciones lambda Funciones anónimas de una sola línea. Ejemplo:
suma = lambda a, b: a + b
print(suma(3, 4))  # 7
5.3. Funciones de orden superior Funciones que toman otras funciones como argumentos o las devuelven. Ejemplo:
def aplicar_funcion(func, a, b):
    return func(a, b)
print(aplicar_funcion(lambda x, y: x * y, 3, 4))  # 12
5.4. Map, filter y reduce Funciones integradas para aplicar funciones a colecciones. Ejemplo:
numeros = [1, 2, 3, 4, 5]
# Map
cuadrados = map(lambda x: x**2, numeros)
print(list(cuadrados))  # [1, 4, 9, 16, 25]
# Filter
pares = filter(lambda x: x % 2 == 0, numeros)
print(list(pares))  # [2, 4]
# Reduce
from functools import reduce
suma_total = reduce(lambda x, y: x + y, numeros)
print(suma_total)  # 15
5.5. Decoradores Permiten extender o modificar el comportamiento de funciones o clases. Ejemplo:
def mi_decorador(func):
    def wrapper(*args, **kwargs):
        print("Antes de la función original")
        resultado = func(*args, **kwargs)
        print("Después de la función original")
        return resultado
    return wrapper
@mi_decorador
def suma(a, b):
    return a + b
print(suma(3, 4))  # Antes de la función original, Después de la función original, 7
5.6. Ejercicios y ejemplos prácticos Realiza ejercicios para aplicar lo aprendido. Por ejemplo, crea un programa que utilice decoradores para medir el tiempo de ejecución de diferentes funciones.
Puedes utilizar este ejemplo para verificar la comprensión de los conceptos avanzados de funciones en Python, como funciones lambda, funciones de orden superior, map, filter, reduce y decoradores, para corregir la práctica del Módulo 5.
temporizador.py
import time
def temporizador(func):
    def wrapper(*args, **kwargs):
        inicio = time.time()
        resultado = func(*args, **kwargs)
        fin = time.time()
        print(f"Tiempo de ejecución de {func.__name__}: {fin - inicio:.5f} segundos")
        return resultado
    return wrapper
@temporizador
def suma(a, b):
    time.sleep(0.5)
    return a + b
@temporizador
def producto(a, b):
    time.sleep(1)
    return a * b
def main():
    print("Resultado suma:", suma(3, 4))
    print("Resultado producto:", producto(3, 4))
if __name__ == "__main__":
    main()
Al ejecutar este programa, obtendrás una salida similar a la siguiente:
Tiempo de ejecución de suma: 0.50034 segundos
Resultado suma: 7
Tiempo de ejecución de producto: 1.00081 segundos
Resultado producto: 12
En este ejemplo:
- La función 
temporizadores un decorador que mide el tiempo de ejecución de cualquier función que decore. - Las funciones 
sumayproductoestán decoradas con el decoradortemporizador. - La función 
mainejecuta las funcionessumayproducto. - La condición 
if __name__ == "__main__":permite ejecutar el programa principal solo si el archivo se ejecuta directamente. 
- La función 
 
Módulo 6: Bibliotecas y aplicaciones más comunes
6.1. Conceptos básicos de pruebas Las pruebas de software ayudan a garantizar que el código funcione correctamente. En Python, se utiliza el módulo unittest para realizar pruebas unitarias.
6.2. Pruebas unitarias Pruebas que verifican el funcionamiento de unidades individuales de código. Ejemplo:
mi_modulo.py
def suma(a, b):
 return a + b
 test_mi_modulo.py
import unittest
from mi_modulo import suma
class TestMiModulo(unittest.TestCase):
    def test_suma(self):
        self.assertEqual(suma(3, 4), 7)
        self.assertEqual(suma(-1, 1), 0)
if __name__ == "__main__":
    unittest.main()
6.3. Afirmaciones (Assertions) Permiten verificar condiciones en las pruebas. Ejemplo:
self.assertEqual(a, b)  # a == b
self.assertNotEqual(a, b)  # a != b
self.assertTrue(condicion)  # condicion es True
self.assertFalse(condicion)  # condicion es False
self.assertIsNone(obj)  # obj es None
self.assertIsNotNone(obj)  # obj no es None
6.4. Organización de pruebas Las pruebas se organizan en clases y métodos. Ejemplo:
class TestSuma(unittest.TestCase):
    def test_suma_positivos(self):
        ...
    def test_suma_negativos(self):
        ...
6.5. Configuración y desmontaje (setUp y tearDown) Métodos para preparar y limpiar el entorno de prueba. Ejemplo:
class TestMiClase(unittest.TestCase):
    def setUp(self):
        self.obj = MiClase()
    def tearDown(self):
        del self.obj
    def test_metodo(self):
        ...
6.6. Ejecución de pruebas Ejecutar pruebas desde la línea de comandos o mediante un IDE. Ejemplo:
python -m unittest test_mi_modulo.py
6.7. Ejercicios y ejemplos prácticos Realiza ejercicios para aplicar lo aprendido. Por ejemplo, crea un programa que implemente funciones matemáticas y escribe pruebas unitarias para verificar su correcto funcionamiento.
Puedes utilizar este ejemplo para verificar la comprensión de los conceptos de pruebas en Python, como pruebas unitarias, afirmaciones, organización de pruebas, configuración y desmontaje, y ejecución de pruebas.
matematicas.py
def suma(a, b):
    return a + b
def resta(a, b):
    return a - b
def multiplica(a, b):
    return a * b
def divide(a, b):
    if b == 0:
        raise ValueError("División por cero")
    return a / b
test_matematicas.py
import unittest
from matematicas import suma, resta, multiplica, divide
class TestMatematicas(unittest.TestCase):
    def test_suma(self):
        self.assertEqual(suma(3, 4), 7)
        self.assertEqual(suma(-1, 1), 0)
    def test_resta(self):
        self.assertEqual(resta(5, 3), 2)
        self.assertEqual(resta(3, 5), -2)
    def test_multiplica(self):
        self.assertEqual(multiplica(3, 4), 12)
        self.assertEqual(multiplica(5, -1), -5)
    def test_divide(self):
        self.assertEqual(divide(8, 2), 4)
        self.assertRaises(ValueError, divide, 8, 0)
if __name__ == "__main__":
    unittest.main()
En este ejemplo:
- El archivo matematicas.py contiene funciones matemáticas: suma, resta, multiplica y divide.
 - El archivo test_matematicas.py contiene pruebas unitarias para cada función en matematicas.py.
 - Cada función matemática es probada usando afirmaciones (assertions) como 
assertEqualyassertRaises. - La condición 
if __name__ == "__main__":permite ejecutar las pruebas al ejecutar el archivo directamente. 
Módulo 7: Temas avanzados y buenas prácticas
7.1. Decoradores Permiten modificar o ampliar el comportamiento de funciones o clases. Ejemplo:
def mi_decorador(func):
    def wrapper():
        print("Antes de la función")
        func()
        print("Después de la función")
    return wrapper
@mi_decorador
def saludar():
    print("¡Hola!")
saludar()
7.2. Generadores Funciones que producen una secuencia de resultados utilizando la palabra clave yield. Ejemplo:
def generador_pares(n):
    for i in range(n):
        if i % 2 == 0:
            yield i
for par in generador_pares(10):
    print(par)
7.3. Concurrencia y paralelismo (threading, multiprocessing) Permiten ejecutar tareas de manera simultánea. Ejemplo:
import threading
def imprimir_numeros():
    for i in range(5):
        print(i)
t1 = threading.Thread(target=imprimir_numeros)
t2 = threading.Thread(target=imprimir_numeros)
t1.start()
t2.start()
t1.join()
t2.join()
7.4. Programación asíncrona (asyncio, aiohttp) Ejecución no bloqueante de código. Ejemplo:
import asyncio
async def tarea(nombre, segundos):
    print(f"Tarea {nombre} iniciada")
    await asyncio.sleep(segundos)
    print(f"Tarea {nombre} completada")
async def main():
    tarea1 = asyncio.create_task(tarea("A", 3))
    tarea2 = asyncio.create_task(tarea("B", 2))
    await tarea1
    await tarea2
asyncio.run(main())
7.5. Pruebas unitarias (unittest) Verificación del correcto funcionamiento de unidades de código. Ejemplo:
import unittest
def suma(a, b):
    return a + b
class TestSuma(unittest.TestCase):
    def test_suma(self):
        self.assertEqual(suma(3, 4), 7)
if __name__ == "__main__":
    unittest.main()
7.6. Integración continua y control de versiones (Git, GitHub) Permite gestionar cambios en el código fuente y colaboración. Ejemplo:
git init
git add archivo.py
git commit -m "Primer commit"
git remote add origin https://github.com/usuario/repositorio.git
git push -u origin master
7.7. Ejercicios y ejemplos prácticos Realiza ejercicios para aplicar lo aprendido. Por ejemplo, crea un programa que utilice decoradores para medir el tiempo de ejecución de funciones, genere números primos con un generador y haga uso de programación asíncrona para realizar varias tareas simultáneamente.
Ejemplo del ejercicio
Este ejemplo combina los tres conceptos en un solo programa. El decorador medir_tiempo mide el tiempo de ejecución de la función principal. La función generador_primos es un generador que produce números primos. La función imprimir_primos es una tarea asíncrona que imprime una cantidad específica de números primos después de un tiempo de espera. La función main ejecuta dos tareas de imprimir_primos de forma asíncrona y mide el tiempo de ejecución total.
import time
import asyncio
from functools import wraps
# Decorador para medir el tiempo de ejecución
def medir_tiempo(func):
@wraps(func)
def wrapper(*args, **kwargs):
start = time.perf_counter()
result = func(*args, **kwargs)
elapsed = time.perf_counter() - start
print(f"{func.__name__} tomó {elapsed:.2f} segundos")
return result
return wrapper
# Generador de números primos
def generador_primos(n):
def es_primo(num):
if num < 2:
return False
for i in range(2, num):
if num % i == 0:
return False
return True
count = 0
num = 0
while count < n:
if es_primo(num):
yield num
count += 1
num += 1
# Tarea asíncrona
async def imprimir_primos(n, segundos):
print(f"Imprimiendo {n} primeros números primos")
await asyncio.sleep(segundos)
primos = list(generador_primos(n))
print(primos)
@medir_tiempo
def main():
loop = asyncio.get_event_loop()
# Ejecuta dos tareas de impresión de primos de forma asíncrona
tareas = [
loop.create_task(imprimir_primos(10, 2)),
loop.create_task(imprimir_primos(20, 3))
]
loop.run_until_complete(asyncio.gather(*tareas))
if __name__ == "__main__":
main()