Fundamentos de Programación y Python

1

¿Por qué aprender Python?

2

Introducción a Python

3

Conceptos Básicos de Programación

4

Práctica: Te doy la bienvenida a los ejercicios interactivos

5

Manipulación de Cadenas de Texto en Python

6

Enteros, Flotantes y Booleanos

7

Todo lo que Debes Saber sobre print en Python

8

Operaciones Matemáticas en Python

9

Operaciones de Entrada/Salida en Consola

Colección y Procesamiento de Datos en Python

10

Listas

11

Método slice

12

Listas de más dimensiones y Tuplas

13

Aplicación de Matrices

14

Diccionarios

15

Comprehension Lists en Python (CLASE NUEVA)

Control de Flujo en Python

16

Estructuras condicionales

17

Bucles y Control de Iteraciones

18

Generadores e Iteradores

Funciones y Manejo de Excepciones en Python

19

Uso de Funciones en Python

20

Funciones Lambda y Programación Funcional en Python

21

¿Cómo realizar una función recursiva en Python?

22

Manejo de Excepciones y Uso de Pass (CLASE NUEVA)

Programación Orientada a Objetos en Python

23

Fundamentos de Programación Orientada a Objetos en Python

24

Ejercicio Biblioteca con POO

25

Herencia en POO con Python

26

Objetos heredados

27

Los 4 pilares de la programacion orientada a objetos

28

Uso de super() en Python (CLASE NUEVA)

29

Superando los Fundamentos de Programación Orientada a Objetos en Python

Lectura y escritura de archivos

30

Manejo de Archivos .TXT (CLASE NUEVA)

31

Manejo de Archivos CSV (CLASE NUEVA)

32

Manejo de Archivos JSON (CLASE NUEVA)

Biblioteca estándar de Python

33

Biblioteca estándar en Python (CLASE NUEVA)

34

Librería Os, Math y Random (CLASE NUEVA)

35

Librería Statistics y Análisis Estadístico (CLASE NUEVA)

36

Proyecto final: Guerra naval

Conceptos avanzados de Python

37

Recapitulación de lo aprendido hasta ahora

38

Escribir código Pythonico y profesional

39

Comentarios y Docstrings en Python

40

Scope y closures: variables locales y globales

41

Anotaciones de tipo

42

Validación de tipos en métodos

43

Librería Collections y Enumeraciones

Decoradores

44

Decoradores en Python

45

Decoradores anidados y con parámetros

46

Uso de Decoradores en clases y métodos

Métodos y estructura de clases en Python

47

Métodos mágicos

48

Sobrecarga de operadores

49

Implementación de `if __name__ == "__main__":`

50

Metaprogramación en Python

51

Uso de *args y **kwargs

52

Métodos privados y protegidos

53

Gestión avanzada de propiedades

54

Métodos estáticos y de clase avanzados

Programación concurrente y asíncrona

55

Introducción a la concurrencia y paralelismo

56

Threading y multiprocessing en Python

57

Asincronismo con asyncio

58

Asincronismo y concurrencia

Creación de módulos y paquetes

59

Creación de módulos en Python

60

Gestión de paquetes

61

Publicación de paquetes en PyPI

Proyecto final

62

Implementación de un sistema completo

63

Implementación de un Sistema Completo

No tienes acceso a esta clase

¡Continúa aprendiendo! Únete y comienza a potenciar tu carrera

Curso de Python

Curso de Python

Carli Code

Carli Code

Asincronismo y concurrencia

58/63
Recursos

Aportes 10

Preguntas 2

Ordenar por:

¿Quieres ver más aportes, preguntas y respuestas de la comunidad?

![](https://static.platzi.com/media/user_upload/image-5bccdd8d-1ad1-4b30-b2ce-e0200d2ff805.jpg)![](https://static.platzi.com/media/user_upload/image-fe0607fb-3bfc-4748-a3cc-392069675961.jpg)
En este código solo agregue una función logger que ayuda a visualizar mejor cada proceso por orden. ![](https://static.platzi.com/media/user_upload/image-379ca717-3f98-4f40-b863-ae1d84e22261.jpg) ```js import asyncio, multiprocessing, time, random from enum import Enum class Status(Enum): START = 'START 🔘' PENDING = 'PENDING 🚧' CANCELED = 'CANCELED ❌' FINISHED = 'FINISHED 🎉' def logger(order_id: int, status: Status, message: str): print(f'[order_id: {order_id}], status: {status.value}, message: {message}') async def check_inventory(order_id, item): logger(order_id, Status.START, f'Verificado Inventario para item {item}') await asyncio.sleep(random.randint(3,6)) logger(order_id, Status.START, f'Inventario verificado para {item}') print("------------------------------------------------------------------------------------") #simulando disponibilidad return [item, random.choice([True, False])] async def process_payment(order_id): logger(order_id, Status.PENDING, 'Enviando a procesar pago') await asyncio.sleep(random.randint(2,3)) logger(order_id, Status.FINISHED, 'Pago procesado correctamente') print("------------------------------------------------------------------------------------") return True #Funcion intensiva en CPU para calcular el costo total del pedido def calculate_total(order_id, items): logger(order_id, Status.START, f'Calculado el costo total para {len(items)} articulos..') time.sleep(5) total = sum(item['price'] for item in items) logger(order_id, Status.START, f'Costo total de la orden es: {total}') print("------------------------------------------------------------------------------------") return total async def process_order(order_id, items): print(f'[order_id: {order_id}], status: START, message: iniciando proceso') logger(order_id, Status.START, 'Iniciando proceso') inventory_checks = [check_inventory(order_id, item['name']) for item in items] inventory_result = await asyncio.gather(*inventory_checks) result = [item for item in inventory_result if item[1] == False] if result: logger(order_id, Status.CANCELED, f'Productos {result[0][0]} no disponibles') return with multiprocessing.Pool() as pool: total = pool.apply(calculate_total, (order_id, items,)) #procesar pago payment_result = await process_payment(order_id) if payment_result: logger(order_id, Status.FINISHED, f'Procesado correctamente total {total}') else: logger(order_id, Status.CANCELED, f'El pago no puedo ser completado') print("------------------------------------------------------------------------------------") async def main(): orders = [ {'order_id': 1, 'items': [{'name': 'Laptop', 'price': 1000}, {'name': 'Mouse', 'price': 50}]}, {'order_id': 2, 'items': [{'name': 'Teclado', 'price': 80}, {'name': 'Monitor', 'price': 300}]}, {'order_id': 3, 'items': [{'name': 'Smartphone', 'price': 700}, {'name': 'Funda', 'price': 20}]} ] #Procesar múltiples órdenes concurrentemente tasks = [process_order(order['order_id'], order['items']) for order in orders] await asyncio.gather(*tasks) ## creación de event loop if __name__ == '__main__': asyncio.run(main()) ```
El error que estás encontrando sugiere que hay un problema al intentar usar `multiprocessing.Pool` en un contexto asíncrono. `multiprocessing` no se puede usar directamente con `asyncio`. Para resolver esto, debes asegurarte de que estás utilizando `await` con funciones asíncronas. Alternativamente, si deseas ejecutar tareas en paralelo con `asyncio`, considera usar `asyncio.create_task()` o `asyncio.gather()` sin la necesidad de `multiprocessing`. Asegúrate de que tu código esté estructurado para utilizar solo una de estas dos herramientas correctamente.
Me parece que hay un error en la funcion "process\_order" ya que si la orden es cancelada por no disponibilidad de inventario, igual calcula el costo y procesa el pago.
Como no quedaron claros los conceptos explicados en las últimas clases, decidí hacer la siguiente nota con ayuda de IA. **Ejecución Secuencial vs. Concurrencia** #### **1. Ejecución Secuencial** * Las tareas se ejecutan una tras otra, sin superposición ni interrupciones. * **Ejemplo**: Un programa lee un archivo, procesa su contenido y escribe el resultado de forma secuencial. Cada paso espera a que el anterior termine antes de comenzar. **Concepto Erróneo**: La ejecución secuencial es siempre ineficiente. En realidad, para tareas simples o dependientes del cómputo, puede ser perfectamente adecuada. #### **2. Concurrencia** * La concurrencia es la capacidad de gestionar múltiples tareas intercalando su ejecución. Esto no significa necesariamente que las tareas se ejecuten al mismo tiempo; pueden alternarse. * La concurrencia puede lograrse en un procesador de un solo núcleo dividiendo el tiempo entre las tareas o en sistemas multicore ejecutando hilos o procesos concurrentemente. * Los núcleos lógicos (habilitados por tecnologías como Hyper-Threading) permiten que un único núcleo físico ejecute múltiples hilos concurrentemente al utilizar recursos inactivos. **Concepto Erróneo**: La concurrencia siempre significa que las tareas se ejecutan al mismo tiempo. Se trata de la gestión de tareas, no de la ejecución simultánea. #### **3. Asincronismo** * La programación asíncrona permite que las tareas continúen sin esperar a que otras terminen. Se utiliza comúnmente para operaciones dependientes de E/S donde, de lo contrario, la CPU permanecería inactiva. * Opera principalmente en un solo hilo utilizando un **bucle de eventos** para gestionar operaciones no bloqueantes (por ejemplo, en `asyncio` de Python o JavaScript). **Concepto Erróneo**: El asincronismo siempre involucra múltiples hilos. Aunque los hilos pueden mejorar el rendimiento asíncrono, no son un requisito. > **Nota al margen**: **¿Qué es un bucle de eventos?** Un bucle de eventos es un constructo de programación que espera y distribuye eventos o mensajes. En la programación asíncrona, gestiona tareas y callbacks de manera no bloqueante. #### **4. Multitarea** * La multitarea implica gestionar múltiples hilos o procesos, intercalando su ejecución. En procesadores de un solo núcleo, esto se logra cambiando rápidamente entre tareas (división del tiempo). * En procesadores multicore, los hilos pueden ejecutarse en paralelo en diferentes núcleos físicos o lógicos. **Concepto Erróneo**: La multitarea siempre mejora el rendimiento. Cambiar entre tareas conlleva una sobrecarga, por lo que una multitarea mal diseñada puede ralentizar la ejecución. #### **5. Paralelismo** * El paralelismo implica ejecutar múltiples tareas o hilos simultáneamente en múltiples núcleos físicos. * Ideal para tareas dependientes del cómputo como simulaciones, procesamiento de datos o aprendizaje automático. **Concepto Erróneo**: El paralelismo siempre es mejor que la concurrencia. Algunas cargas de trabajo se benefician más de una intercalación eficiente de tareas que de la verdadera ejecución paralela. > **Nota al margen**: **Núcleos físicos vs. núcleos lógicos*** Un **núcleo físico** es un núcleo de hardware real en un procesador. > * Un **núcleo lógico** (vía Hyper-Threading) permite que un núcleo físico maneje múltiples hilos utilizando recursos inactivos dentro del núcleo. ### **Tabla Resumen: Tipos de Concurrencia** **|Tipo|Descripción|Casos de Uso|Diferencias|Similitudes|** **|---|---|---|---|---|---|** **|Asincronismo|**Monohilo, no bloqueante, utiliza bucles de eventos para manejar tareas.Tareas dependientes de E/S como archivos/red.|No requiere múltiples hilos; se basa en callbacks/promesas y bucles de eventos.|Tanto el asincronismo como la multitarea permiten manejar múltiples tareas eficientemente.| |**Multitarea|**Gestiona múltiples tareas intercalando (división del tiempo) o ejecutándolas en paralelo.Ejecutar múltiples aplicaciones, capacidad de respuesta de GUI.|Puede implicar división del tiempo en procesadores de un solo núcleo o ejecución paralela en multicore.|Tanto la multitarea como el paralelismo pueden usar hilos o procesos para la concurrencia.| |**Paralelismo|**Ejecuta múltiples tareas simultáneamente en múltiples núcleos. Tareas dependientes del cómputo como simulaciones, modelos de ML. |Requiere múltiples núcleos; logra verdadera ejecución simultánea. |Tanto el paralelismo como la multitarea manejan múltiples tareas y pueden beneficiarse de sistemas multicore.| ### **Explicación Gráfica** Aquí hay una representación visual de los conceptos: 1. **Ejecución Secuencial**:Tarea A: \[-----] Tarea B: \[-----] `Tarea C: [-----]` 2. **Concurrencia (Un Solo Núcleo)**:Tarea A: \[--]\[--]\[--] Tarea B: \[--]\[--]\[--] `Tarea C: [--][--]` 3. **Paralelismo (Múltiples Núcleos)**:Núcleo 1 (Tarea A): \[-----] Núcleo 2 (Tarea B): \[-----] `Núcleo 3 (Tarea C): [-----]` ### **Ejemplos de Código en Python** #### **1. Ejecución Secuencial** import time def tarea(nombre, duracion): print(f"Iniciando {nombre}") time.sleep(duracion) print(f"Finalizado {nombre}") \# Tareas ejecutadas una tras otra tarea("Tarea 1", 2) tarea("Tarea 2", 2) `tarea("Tarea 3", 2)` #### **2. Concurrencia (Asyncio)** ```js import time def tarea(nombre, duracion): print(f"Iniciando {nombre}") time.sleep(duracion) print(f"Finalizado {nombre}") # Tareas ejecutadas una tras otra tarea("Tarea 1", 2) tarea("Tarea 2", 2) tarea("Tarea 3", 2) ``` #### **3. Multitarea (Threading)** ```js import threading import time def tarea(nombre, duracion): print(f"Iniciando {nombre}") time.sleep(duracion) print(f"Finalizado {nombre}") hilos = [] # Crear hilos para cada tarea for i in range(1, 4): hilo = threading.Thread(target=tarea, args=(f"Tarea {i}", 2)) hilos.append(hilo) hilo.start() # Esperar a que todos los hilos terminen for hilo in hilos: hilo.join() ``` **4. Paralelismo (Multiprocessing)** ```js import multiprocessing import time def tarea(nombre, duracion): print(f"Iniciando {nombre}") time.sleep(duracion) print(f"Finalizado {nombre}") if __name__ == "__main__": procesos = [] # Crear procesos para cada tarea for i in range(1, 4): proceso = multiprocessing.Process(target=tarea, args=(f"Tarea {i}", 2)) procesos.append(proceso) proceso.start() # Esperar a que todos los procesos terminen for proceso in procesos: proceso.join() ``` ### Resumen * **Secuencial**: Simple pero puede ser ineficiente para cargas de trabajo dependientes de E/S. * **Asincronismo**: Eficiente para tareas dependientes de E/S, se basa en bucles de eventos. * **Multitarea**: Intercala tareas, adecuada para cargas que toler
hola chicos ya he revisado el codigo lo he comparado con el de la clase, y he preguntado a la ia y no he podido encontrar el porque del siguiente errer al usar multiprocessing, les agradeceria si pudieran explicarme a que se refiere con context manager ```js File "/home/dan/PLATZI/data/python_Fundamentals/asyncrhonic/UserManagementSystemSimulation.py", line 28, in processOrder with multiprocessing.Pool as pool: TypeError: 'method' object does not support the context manager protocol (base) dan@DESKTOP-KH1GPVK:~ ``` File "/home/dan/PLATZI/data/python\_Fundamentals/asyncrhonic/UserManagementSystemSimulation.py", line 28, in processOrder with multiprocessing.Pool as pool: TypeError: 'method' object does not support the context manager protocol (base) dan@DESKTOP-KH1GPVK:~
asyncio.run(main()) ^^^^^^^^^^^ AttributeError: module 'asyncio' has no attribute 'run' ¿por qué tengo este error?
Traceback (most recent call last): File "/Users/rcarrca/FundamentoPython/Concurrente\_Asincrona/pedidos\_online.py", line 70, in \<module> asyncio.run(main()) File "/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.9/lib/python3.9/asyncio/runners.py", line 44, in run return loop.run\_until\_complete(main) File "/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.9/lib/python3.9/asyncio/base\_events.py", line 642, in run\_until\_complete return future.result() File "/Users/rcarrca/FundamentoPython/Concurrente\_Asincrona/pedidos\_online.py", line 65, in main await asyncio.gather(\*tasks) File "/Users/rcarrca/FundamentoPython/Concurrente\_Asincrona/pedidos\_online.py", line 43, in process\_order with multiprocessing.Pool() as pool: AttributeError: module 'multiprocessing' has no attribute 'Pool'
### Sistema de Gestión de Usuarios: ```python import asyncio import threading # Simulación de una base de datos en memoria usuarios_db = {} # Función asíncrona para crear un usuario async def crear_usuario(usuario_id, nombre): await asyncio.sleep(1) # Simula una operación de E/S usuarios_db[usuario_id] = nombre print(f"Usuario {usuario_id} creado: {nombre}") # Función asíncrona para actualizar un usuario async def actualizar_usuario(usuario_id, nuevo_nombre): await asyncio.sleep(1) # Simula una operación de E/S if usuario_id in usuarios_db: usuarios_db[usuario_id] = nuevo_nombre print(f"Usuario {usuario_id} actualizado a: {nuevo_nombre}") else: print(f"Usuario {usuario_id} no encontrado") # Función para manejar tareas concurrentes usando threading def manejar_tareas_concurrentes(): loop = asyncio.new_event_loop() asyncio.set_event_loop(loop) tareas = [ crear_usuario(1, "Alice"), crear_usuario(2, "Bob"), actualizar_usuario(1, "Alicia"), actualizar_usuario(3, "Charlie") ] loop.run_until_complete(asyncio.gather(*tareas)) loop.close() # Crear un hilo para manejar las tareas concurrentes hilo = threading.Thread(target=manejar_tareas_concurrentes) hilo.start() hilo.join() print("Operaciones de gestión de usuarios completadas.") print("Estado final de la base de datos:", usuarios_db) ```
1. **Base de Datos Simulada**: * `usuarios_db` es un diccionario que simula una base de datos en memoria para almacenar usuarios. 2. **Funciones Asíncronas**: * `crear_usuario`: Simula la creación de un usuario con un retraso de 1 segundo. * `actualizar_usuario`: Simula la actualización de un usuario con un retraso de 1 segundo. 3. **Manejo de Tareas Concurrentes**: * `manejar_tareas_concurrentes`: Crea un nuevo bucle de eventos (`event loop`) y ejecuta varias tareas asíncronas de manera concurrente usando `asyncio.gather`. 4. **Uso de** `threading`: * Se crea un hilo (`hilo`) para ejecutar `manejar_tareas_concurrentes`, permitiendo que las tareas asíncronas se ejecuten en paralelo con otras posibles operaciones en el programa principal.