What is the primary purpose of a Python decorator?
Anonymous Quiz
0%
To define a new class.
100%
To modify or enhance the behavior of a function or method without changing its source code directly.
0%
To create a loop that iterates over a list.
0%
To handle exceptions in a try-except block.
Here's your Telegram post for Day 22!
---
π Day 22 of our Python journey! Today, we unlock the power of **Generators** and **Iterators**! π‘ These aren't just fancy terms; they're essential tools for writing memory-efficient and scalable code, especially when dealing with large datasets. Forget loading everything into memory at once β generators let you produce values on the fly. Let's dive into how `yield` makes magic happen! β¨
```python
# A simple generator function
def count_up_to(n):
i = 0
print(f"Generator initialized (counting up to {n}).")
while i < n:
print(f"Yielding {i}...")
yield i # Pauses execution and returns i. Resumes from here on next() call.
i += 1
print("Generator finished.")
# Using the generator
print("--- Using next() explicitly ---")
my_counter = count_up_to(3) # This just creates the generator object, doesn't run yet
print(f"First value: {next(my_counter)}")
print(f"Second value: {next(my_counter)}")
try:
print(f"Third value: {next(my_counter)}")
print(f"Attempting fourth value: {next(my_counter)}") # This will raise StopIteration
except StopIteration:
print("Caught StopIteration! Generator is exhausted.")
print("n--- Using a for loop (the cleaner way) ---")
# Generators are iterables, so they work great with for loops
for num in count_up_to(5):
print(f"Received in loop: {num}")
# Practical example: Infinite sequence (but we'll limit it for demo)
def even_numbers():
n = 0
while True: # This would be infinite, but we'll break it
yield n
n += 2
print("n--- First 5 even numbers ---")
evens = even_numbers()
for _ in range(5):
print(next(evens))
```
Output example:
```
--- Using next() explicitly ---
Generator initialized (counting up to 3).
Yielding 0...
First value: 0
Yielding 1...
Second value: 1
Yielding 2...
Third value: 2
Generator finished.
Caught StopIteration! Generator is exhausted.
--- Using a for loop (the cleaner way) ---
Generator initialized (counting up to 5).
Yielding 0...
Received in loop: 0
Yielding 1...
Received in loop: 1
Yielding 2...
Received in loop: 2
Yielding 3...
Received in loop: 3
Yielding 4...
Received in loop: 4
Generator finished.
--- First 5 even numbers ---
0
2
4
6
8
```
π‘ **Challenge:** Create a generator function called `reverse_string_generator(s)` that takes a string `s` and yields its characters one by one in reverse order. Then, use a `for` loop to print them out! Share your elegant solution! π
---
---
π Day 22 of our Python journey! Today, we unlock the power of **Generators** and **Iterators**! π‘ These aren't just fancy terms; they're essential tools for writing memory-efficient and scalable code, especially when dealing with large datasets. Forget loading everything into memory at once β generators let you produce values on the fly. Let's dive into how `yield` makes magic happen! β¨
```python
# A simple generator function
def count_up_to(n):
i = 0
print(f"Generator initialized (counting up to {n}).")
while i < n:
print(f"Yielding {i}...")
yield i # Pauses execution and returns i. Resumes from here on next() call.
i += 1
print("Generator finished.")
# Using the generator
print("--- Using next() explicitly ---")
my_counter = count_up_to(3) # This just creates the generator object, doesn't run yet
print(f"First value: {next(my_counter)}")
print(f"Second value: {next(my_counter)}")
try:
print(f"Third value: {next(my_counter)}")
print(f"Attempting fourth value: {next(my_counter)}") # This will raise StopIteration
except StopIteration:
print("Caught StopIteration! Generator is exhausted.")
print("n--- Using a for loop (the cleaner way) ---")
# Generators are iterables, so they work great with for loops
for num in count_up_to(5):
print(f"Received in loop: {num}")
# Practical example: Infinite sequence (but we'll limit it for demo)
def even_numbers():
n = 0
while True: # This would be infinite, but we'll break it
yield n
n += 2
print("n--- First 5 even numbers ---")
evens = even_numbers()
for _ in range(5):
print(next(evens))
```
Output example:
```
--- Using next() explicitly ---
Generator initialized (counting up to 3).
Yielding 0...
First value: 0
Yielding 1...
Second value: 1
Yielding 2...
Third value: 2
Generator finished.
Caught StopIteration! Generator is exhausted.
--- Using a for loop (the cleaner way) ---
Generator initialized (counting up to 5).
Yielding 0...
Received in loop: 0
Yielding 1...
Received in loop: 1
Yielding 2...
Received in loop: 2
Yielding 3...
Received in loop: 3
Yielding 4...
Received in loop: 4
Generator finished.
--- First 5 even numbers ---
0
2
4
6
8
```
π‘ **Challenge:** Create a generator function called `reverse_string_generator(s)` that takes a string `s` and yields its characters one by one in reverse order. Then, use a `for` loop to print them out! Share your elegant solution! π
---
What is the primary keyword used to define a generator function in Python?
Anonymous Quiz
0%
return
0%
yield
0%
generate
100%
iterate
Here's your Telegram post for Day 23!
---
**Day 23: Context Managers (with statement) β¨**
Hello Python learners! π Today, we're diving into one of Python's most elegant features for resource management: **Context Managers** using the `with` statement. Ever worry about closing files or releasing resources properly? Context managers automate this cleanup, making your code safer and cleaner. π They ensure resources are acquired at the start and *always* released at the end, even if errors occur. No more forgotten `file.close()` calls!
```python
import os
# Example 1: Writing to a file safely
print("--- Writing to a file ---")
file_name = "daily_log.txt"
with open(file_name, "w") as log_file:
log_file.write("Python learning day 23!n")
log_file.write("Context managers are awesome.n")
print(f"Content written to '{file_name}'.")
# Example 2: Reading from a file safely
print("n--- Reading from the file ---")
with open(file_name, "r") as log_file:
content = log_file.read()
print("File content:")
print(content)
print(f"File '{file_name}' operations complete. The file is automatically closed.")
# Clean up the created file
try:
os.remove(file_name)
print(f"nCleaned up: '{file_name}' removed.")
except OSError as e:
print(f"Error removing file {file_name}: {e}")
```
Output example:
```
--- Writing to a file ---
Content written to 'daily_log.txt'.
--- Reading from the file ---
File content:
Python learning day 23!
Context managers are awesome.
File 'daily_log.txt' operations complete. The file is automatically closed.
Cleaned up: 'daily_log.txt' removed.
```
**Small Challenge: π€**
Can you modify the reading example to *iterate through each line* of the `daily_log.txt` file instead of reading all content at once? Print each line along with its line number (starting from 1).
---
---
**Day 23: Context Managers (with statement) β¨**
Hello Python learners! π Today, we're diving into one of Python's most elegant features for resource management: **Context Managers** using the `with` statement. Ever worry about closing files or releasing resources properly? Context managers automate this cleanup, making your code safer and cleaner. π They ensure resources are acquired at the start and *always* released at the end, even if errors occur. No more forgotten `file.close()` calls!
```python
import os
# Example 1: Writing to a file safely
print("--- Writing to a file ---")
file_name = "daily_log.txt"
with open(file_name, "w") as log_file:
log_file.write("Python learning day 23!n")
log_file.write("Context managers are awesome.n")
print(f"Content written to '{file_name}'.")
# Example 2: Reading from a file safely
print("n--- Reading from the file ---")
with open(file_name, "r") as log_file:
content = log_file.read()
print("File content:")
print(content)
print(f"File '{file_name}' operations complete. The file is automatically closed.")
# Clean up the created file
try:
os.remove(file_name)
print(f"nCleaned up: '{file_name}' removed.")
except OSError as e:
print(f"Error removing file {file_name}: {e}")
```
Output example:
```
--- Writing to a file ---
Content written to 'daily_log.txt'.
--- Reading from the file ---
File content:
Python learning day 23!
Context managers are awesome.
File 'daily_log.txt' operations complete. The file is automatically closed.
Cleaned up: 'daily_log.txt' removed.
```
**Small Challenge: π€**
Can you modify the reading example to *iterate through each line* of the `daily_log.txt` file instead of reading all content at once? Print each line along with its line number (starting from 1).
---
Here's your Telegram post for Day 24!
---
**Python Learning Series: Day 24**
π Day 24 is here! Today, we're unlocking two incredibly powerful Python features that will make your code more concise and efficient: **Lambda Functions** and **List Comprehensions**! π‘
Lambda functions are small, anonymous functions perfect for quick, single-expression tasks. List comprehensions, on the other hand, provide a clean and compact way to create lists. Get ready to write some super elegant Python! π₯ Let's dive in!
```python
# Lambda Functions: Small, anonymous functions
# Syntax: lambda arguments: expression
# Example 1: Simple lambda to double a number
double = lambda x: x * 2
print(f"Doubled 5: {double(5)}")
# Example 2: Using lambda with map() to apply a function to all items
numbers = [1, 2, 3, 4, 5]
doubled_numbers = list(map(lambda x: x * 2, numbers))
print(f"Original numbers: {numbers}")
print(f"Doubled numbers (using map + lambda): {doubled_numbers}")
# List Comprehensions: Concise way to create lists
# Example 3: Creating a list of squares
squares = [x**2 for x in range(1, 6)]
print(f"Squares from 1 to 5: {squares}")
# Example 4: Creating a list of even numbers with a condition
even_numbers = [x for x in range(10) if x % 2 == 0]
print(f"Even numbers from 0 to 9: {even_numbers}")
# Example 5: Combining transformation and filtering in a list comprehension
transformed_evens = [x * 3 for x in range(10) if x % 2 == 0]
print(f"Evens * 3 from 0 to 9: {transformed_evens}")
```
Output example:
```
Doubled 5: 10
Original numbers: [1, 2, 3, 4, 5]
Doubled numbers (using map + lambda): [2, 4, 6, 8, 10]
Squares from 1 to 5: [1, 4, 9, 16, 25]
Even numbers from 0 to 9: [0, 2, 4, 6, 8]
Evens * 3 from 0 to 9: [0, 6, 12, 18, 24]
```
π‘ **Your Challenge!**
Create a list containing the squares of all odd numbers between 1 and 20 (inclusive) using a single list comprehension. Share your solution in the comments! π
---
---
**Python Learning Series: Day 24**
π Day 24 is here! Today, we're unlocking two incredibly powerful Python features that will make your code more concise and efficient: **Lambda Functions** and **List Comprehensions**! π‘
Lambda functions are small, anonymous functions perfect for quick, single-expression tasks. List comprehensions, on the other hand, provide a clean and compact way to create lists. Get ready to write some super elegant Python! π₯ Let's dive in!
```python
# Lambda Functions: Small, anonymous functions
# Syntax: lambda arguments: expression
# Example 1: Simple lambda to double a number
double = lambda x: x * 2
print(f"Doubled 5: {double(5)}")
# Example 2: Using lambda with map() to apply a function to all items
numbers = [1, 2, 3, 4, 5]
doubled_numbers = list(map(lambda x: x * 2, numbers))
print(f"Original numbers: {numbers}")
print(f"Doubled numbers (using map + lambda): {doubled_numbers}")
# List Comprehensions: Concise way to create lists
# Example 3: Creating a list of squares
squares = [x**2 for x in range(1, 6)]
print(f"Squares from 1 to 5: {squares}")
# Example 4: Creating a list of even numbers with a condition
even_numbers = [x for x in range(10) if x % 2 == 0]
print(f"Even numbers from 0 to 9: {even_numbers}")
# Example 5: Combining transformation and filtering in a list comprehension
transformed_evens = [x * 3 for x in range(10) if x % 2 == 0]
print(f"Evens * 3 from 0 to 9: {transformed_evens}")
```
Output example:
```
Doubled 5: 10
Original numbers: [1, 2, 3, 4, 5]
Doubled numbers (using map + lambda): [2, 4, 6, 8, 10]
Squares from 1 to 5: [1, 4, 9, 16, 25]
Even numbers from 0 to 9: [0, 2, 4, 6, 8]
Evens * 3 from 0 to 9: [0, 6, 12, 18, 24]
```
π‘ **Your Challenge!**
Create a list containing the squares of all odd numbers between 1 and 20 (inclusive) using a single list comprehension. Share your solution in the comments! π
---
What is the primary characteristic of a Python `lambda` function?
Anonymous Quiz
0%
A. It can only take one argument.
100%
B. It is an anonymous function, typically used for short, single-expression operations.
0%
C. It requires a `return` statement.
0%
D. It is used exclusively for asynchronous programming.
π Day 25: Unit Testing! π
Ever wonder how to make your Python code super reliable? Today, we dive into Unit Testing! This crucial practice helps you catch bugs early, ensure individual components of your code work as expected, and makes refactoring a breeze. We'll be using Python's built-in `unittest` module to write robust tests. Let's make our code bulletproof and build confidence in every line! πͺ
```python
import unittest
# The function we want to test
def add(a, b):
"""Adds two numbers and returns the sum."""
return a + b
# Our test class, inheriting from unittest.TestCase
class TestAddFunction(unittest.TestCase):
def test_add_positive_numbers(self):
"""Test with two positive numbers."""
self.assertEqual(add(2, 3), 5)
def test_add_negative_numbers(self):
"""Test with two negative numbers."""
self.assertEqual(add(-1, -5), -6)
def test_add_mixed_numbers(self):
"""Test with a positive and a negative number."""
self.assertEqual(add(10, -3), 7)
def test_add_zero(self):
"""Test adding with zero."""
self.assertEqual(add(0, 7), 7)
self.assertEqual(add(-5, 0), -5)
# This block allows you to run the tests directly from the script
if __name__ == '__main__':
unittest.main()
```
Output example:
```
....
----------------------------------------------------------------------
Ran 4 tests in 0.000s
OK
```
π‘ Your Challenge:
Add a new test method to `TestAddFunction` that checks the addition of floating-point numbers (e.g., `add(2.5, 3.5)`). What result do you expect? Share your code snippet or just the expected outcome! π€
---
Ever wonder how to make your Python code super reliable? Today, we dive into Unit Testing! This crucial practice helps you catch bugs early, ensure individual components of your code work as expected, and makes refactoring a breeze. We'll be using Python's built-in `unittest` module to write robust tests. Let's make our code bulletproof and build confidence in every line! πͺ
```python
import unittest
# The function we want to test
def add(a, b):
"""Adds two numbers and returns the sum."""
return a + b
# Our test class, inheriting from unittest.TestCase
class TestAddFunction(unittest.TestCase):
def test_add_positive_numbers(self):
"""Test with two positive numbers."""
self.assertEqual(add(2, 3), 5)
def test_add_negative_numbers(self):
"""Test with two negative numbers."""
self.assertEqual(add(-1, -5), -6)
def test_add_mixed_numbers(self):
"""Test with a positive and a negative number."""
self.assertEqual(add(10, -3), 7)
def test_add_zero(self):
"""Test adding with zero."""
self.assertEqual(add(0, 7), 7)
self.assertEqual(add(-5, 0), -5)
# This block allows you to run the tests directly from the script
if __name__ == '__main__':
unittest.main()
```
Output example:
```
....
----------------------------------------------------------------------
Ran 4 tests in 0.000s
OK
```
π‘ Your Challenge:
Add a new test method to `TestAddFunction` that checks the addition of floating-point numbers (e.g., `add(2.5, 3.5)`). What result do you expect? Share your code snippet or just the expected outcome! π€
---
Which `unittest.TestCase` method is commonly used to verify if two values are equal in Python unit tests?
Anonymous Quiz
0%
self.assertTrue()
100%
self.assertFalse()
0%
self.assertEqual()
0%
self.assertIsNone()
Here's your Telegram post for Day 26!
---
β¨ Day 26: Basic Web Scraping (Beautiful Soup) β¨
Ready to extract data from websites? πΈοΈ Today, we dive into the exciting world of web scraping with **Beautiful Soup**! This powerful Python library helps you parse HTML and XML documents, making it easy to navigate and search the parse tree. Learn how to fetch content and extract exactly what you need. Let's turn unstructured web data into structured information! π
```python
from bs4 import BeautifulSoup
import requests # Generally used to fetch web pages, but we'll use a string for demo.
# A simple HTML string for demonstration purposes
html_doc = """
<html><head><title>The Scraped Page</title></head>
<body>
<p class="title"><b>My First Heading</b></p>
<p class="story">
Hello there! Here's some content.
<a href="http://example.com/link1" class="link">Link 1</a>
<a href="http://example.com/link2" class="link">Link 2</a>
</p>
<p class="footer">End of page.</p>
</body></html>
"""
# Parse the HTML content using BeautifulSoup
soup = BeautifulSoup(html_doc, 'html.parser')
# Print the title of the page
print("Page Title:", soup.title.string)
# Find the first paragraph with class "story"
story_paragraph = soup.find('p', class_='story')
print("Story Paragraph Text:", story_paragraph.get_text(strip=True))
# Find all anchor (<a>) tags
all_links = soup.find_all('a')
print("nAll Links:")
for link in all_links:
print(f"Text: {link.string}, Href: {link.get('href')}")
```
Output example:
```
Page Title: The Scraped Page
Story Paragraph Text: Hello there! Here's some content.Link 1Link 2
All Links:
Text: Link 1, Href: http://example.com/link1
Text: Link 2, Href: http://example.com/link2
```
**Small Challenge:**
Can you modify the code to find and print only the text inside the `<b>` tag within the `p` with class "title"? π§
---
---
β¨ Day 26: Basic Web Scraping (Beautiful Soup) β¨
Ready to extract data from websites? πΈοΈ Today, we dive into the exciting world of web scraping with **Beautiful Soup**! This powerful Python library helps you parse HTML and XML documents, making it easy to navigate and search the parse tree. Learn how to fetch content and extract exactly what you need. Let's turn unstructured web data into structured information! π
```python
from bs4 import BeautifulSoup
import requests # Generally used to fetch web pages, but we'll use a string for demo.
# A simple HTML string for demonstration purposes
html_doc = """
<html><head><title>The Scraped Page</title></head>
<body>
<p class="title"><b>My First Heading</b></p>
<p class="story">
Hello there! Here's some content.
<a href="http://example.com/link1" class="link">Link 1</a>
<a href="http://example.com/link2" class="link">Link 2</a>
</p>
<p class="footer">End of page.</p>
</body></html>
"""
# Parse the HTML content using BeautifulSoup
soup = BeautifulSoup(html_doc, 'html.parser')
# Print the title of the page
print("Page Title:", soup.title.string)
# Find the first paragraph with class "story"
story_paragraph = soup.find('p', class_='story')
print("Story Paragraph Text:", story_paragraph.get_text(strip=True))
# Find all anchor (<a>) tags
all_links = soup.find_all('a')
print("nAll Links:")
for link in all_links:
print(f"Text: {link.string}, Href: {link.get('href')}")
```
Output example:
```
Page Title: The Scraped Page
Story Paragraph Text: Hello there! Here's some content.Link 1Link 2
All Links:
Text: Link 1, Href: http://example.com/link1
Text: Link 2, Href: http://example.com/link2
```
**Small Challenge:**
Can you modify the code to find and print only the text inside the `<b>` tag within the `p` with class "title"? π§
---
What is the primary purpose of `soup.find_all('tag_name')` in Beautiful Soup?
Anonymous Quiz
0%
To find the first occurrence of a specified tag.
0%
To find all occurrences of a specified tag and return them as a list.
0%
To create a new HTML tag with the given name.
0%
To send an HTTP GET request to a website.
Here's your Telegram post for Day 27!
---
π **Day 27: Introduction to Flask/Django!** π
Today, we're taking our first steps into the exciting world of Python web development! We'll explore Flask and Django, two incredibly powerful frameworks that let you build everything from simple APIs to complex, full-featured websites. Flask is known for its lightweight, "micro-framework" approach, giving you more control. Django, on the other hand, is a "batteries-included" framework, offering a robust set of tools out-of-the-box. Let's kick things off with a super basic Flask app! β¨
```python
from flask import Flask
# Create a Flask application instance
app = Flask(__name__)
# Define a route for the home page ('/')
@app.route('/')
def home():
return 'Hello from our first Flask app! π'
# This block ensures the server runs only when the script is executed directly
if __name__ == '__main__':
# Make sure to install Flask first: pip install Flask
# Run the app in debug mode (helpful for development)
app.run(debug=True)
```
**Output example:**
When you run the script (`python your_script_name.py`), you'll see output similar to this in your terminal:
```
* Serving Flask app 'your_script_name'
* Debug mode: on
WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.
* Running on http://127.0.0.1:5000 (Press CTRL+C to quit)
```
Now, open your web browser and navigate to `http://127.0.0.1:5000`. You should see the message: `Hello from our first Flask app! π`
**Small challenge:**
Your Challenge:
Can you modify the code to add another route, `/greet/<name>`, that takes a name as a parameter (e.g., `http://127.0.0.1:5000/greet/Alice`) and returns "Hello, [name]! Welcome to Flask!"? Hint: You'll need `from flask import request` and `@app.route('/greet/<name>')`! Good luck! π©βπ»π¨βπ»
---
---
π **Day 27: Introduction to Flask/Django!** π
Today, we're taking our first steps into the exciting world of Python web development! We'll explore Flask and Django, two incredibly powerful frameworks that let you build everything from simple APIs to complex, full-featured websites. Flask is known for its lightweight, "micro-framework" approach, giving you more control. Django, on the other hand, is a "batteries-included" framework, offering a robust set of tools out-of-the-box. Let's kick things off with a super basic Flask app! β¨
```python
from flask import Flask
# Create a Flask application instance
app = Flask(__name__)
# Define a route for the home page ('/')
@app.route('/')
def home():
return 'Hello from our first Flask app! π'
# This block ensures the server runs only when the script is executed directly
if __name__ == '__main__':
# Make sure to install Flask first: pip install Flask
# Run the app in debug mode (helpful for development)
app.run(debug=True)
```
**Output example:**
When you run the script (`python your_script_name.py`), you'll see output similar to this in your terminal:
```
* Serving Flask app 'your_script_name'
* Debug mode: on
WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.
* Running on http://127.0.0.1:5000 (Press CTRL+C to quit)
```
Now, open your web browser and navigate to `http://127.0.0.1:5000`. You should see the message: `Hello from our first Flask app! π`
**Small challenge:**
Your Challenge:
Can you modify the code to add another route, `/greet/<name>`, that takes a name as a parameter (e.g., `http://127.0.0.1:5000/greet/Alice`) and returns "Hello, [name]! Welcome to Flask!"? Hint: You'll need `from flask import request` and `@app.route('/greet/<name>')`! Good luck! π©βπ»π¨βπ»
---
What is the primary purpose of Flask and Django in Python?
Anonymous Quiz
0%
A) Performing complex mathematical calculations
0%
B) Building interactive web applications and APIs
0%
C) Developing desktop applications with graphical user interfaces
0%
D) Analyzing large datasets for scientific research
π **Day 28: Diving into Asynchronous Programming with `asyncio`!** π
Hello Python learners! π Today, we're tackling one of Python's most powerful features for building high-performance, non-blocking applications: **Asynchronous Programming** using the `asyncio` library.
Asynchronous programming allows your program to perform multiple I/O-bound operations (like network requests, file operations, or waiting for external resources) concurrently without using multiple threads. This means your program can do other work while waiting for something to complete, making it much more efficient! Think faster web servers and more responsive applications. β±οΈπ§
Let's see a basic example of how `asyncio` works!
```python
import asyncio
import time
async def fetch_data(task_id, delay):
"""Simulates an I/O-bound operation."""
print(f"[{time.strftime('%H:%M:%S')}] Task {task_id}: Starting fetch (will take {delay}s)...")
await asyncio.sleep(delay) # Non-blocking wait
print(f"[{time.strftime('%H:%M:%S')}] Task {task_id}: Data fetched!")
return f"Data for task {task_id}"
async def main():
start_time = time.time()
print("Main: Kicking off multiple data fetches concurrently!")
# Run multiple coroutines concurrently
results = await asyncio.gather(
fetch_data("A", 3), # Task A takes 3 seconds
fetch_data("B", 1), # Task B takes 1 second
fetch_data("C", 2) # Task C takes 2 seconds
)
end_time = time.time()
print("nMain: All tasks completed!")
print(f"Main: Total execution time: {end_time - start_time:.2f} seconds.")
print("Main: Results received:", results)
if __name__ == "__main__":
asyncio.run(main())
```
**Output example:**
```
Main: Kicking off multiple data fetches concurrently!
[HH:MM:SS] Task A: Starting fetch (will take 3s)...
[HH:MM:SS] Task B: Starting fetch (will take 1s)...
[HH:MM:SS] Task C: Starting fetch (will take 2s)...
[HH:MM:SS] Task B: Data fetched!
[HH:MM:SS] Task C: Data fetched!
[HH:MM:SS] Task A: Data fetched!
Main: All tasks completed!
Main: Total execution time: 3.00 seconds.
Main: Results received: ['Data for task A', 'Data for task B', 'Data for task C']
```
*(Note: HH:MM:SS will be your actual current time.)*
See how all tasks started almost simultaneously, and the total execution time was determined by the *longest* task (3 seconds), not the sum of all tasks (3+1+2=6 seconds)? That's the power of `asyncio`! β¨
**Small Challenge:**
Modify the `main` function to add a fourth task, `fetch_data("D", 0.5)`. Observe how the total execution time remains the same (3.00s) because it's still less than the longest running task ("A"). Then, change Task "A" to `fetch_data("A", 4)` and see the total time increase!
---
Hello Python learners! π Today, we're tackling one of Python's most powerful features for building high-performance, non-blocking applications: **Asynchronous Programming** using the `asyncio` library.
Asynchronous programming allows your program to perform multiple I/O-bound operations (like network requests, file operations, or waiting for external resources) concurrently without using multiple threads. This means your program can do other work while waiting for something to complete, making it much more efficient! Think faster web servers and more responsive applications. β±οΈπ§
Let's see a basic example of how `asyncio` works!
```python
import asyncio
import time
async def fetch_data(task_id, delay):
"""Simulates an I/O-bound operation."""
print(f"[{time.strftime('%H:%M:%S')}] Task {task_id}: Starting fetch (will take {delay}s)...")
await asyncio.sleep(delay) # Non-blocking wait
print(f"[{time.strftime('%H:%M:%S')}] Task {task_id}: Data fetched!")
return f"Data for task {task_id}"
async def main():
start_time = time.time()
print("Main: Kicking off multiple data fetches concurrently!")
# Run multiple coroutines concurrently
results = await asyncio.gather(
fetch_data("A", 3), # Task A takes 3 seconds
fetch_data("B", 1), # Task B takes 1 second
fetch_data("C", 2) # Task C takes 2 seconds
)
end_time = time.time()
print("nMain: All tasks completed!")
print(f"Main: Total execution time: {end_time - start_time:.2f} seconds.")
print("Main: Results received:", results)
if __name__ == "__main__":
asyncio.run(main())
```
**Output example:**
```
Main: Kicking off multiple data fetches concurrently!
[HH:MM:SS] Task A: Starting fetch (will take 3s)...
[HH:MM:SS] Task B: Starting fetch (will take 1s)...
[HH:MM:SS] Task C: Starting fetch (will take 2s)...
[HH:MM:SS] Task B: Data fetched!
[HH:MM:SS] Task C: Data fetched!
[HH:MM:SS] Task A: Data fetched!
Main: All tasks completed!
Main: Total execution time: 3.00 seconds.
Main: Results received: ['Data for task A', 'Data for task B', 'Data for task C']
```
*(Note: HH:MM:SS will be your actual current time.)*
See how all tasks started almost simultaneously, and the total execution time was determined by the *longest* task (3 seconds), not the sum of all tasks (3+1+2=6 seconds)? That's the power of `asyncio`! β¨
**Small Challenge:**
Modify the `main` function to add a fourth task, `fetch_data("D", 0.5)`. Observe how the total execution time remains the same (3.00s) because it's still less than the longest running task ("A"). Then, change Task "A" to `fetch_data("A", 4)` and see the total time increase!
---
What is the primary function of `asyncio.run(main())` in the provided Python code?
Anonymous Quiz
0%
A. To define a coroutine function that can be awaited.
0%
B. To execute the top-level `async` function (`main()`) and manage the asyncio event loop.
100%
C. To pause the execution of an `await` expression until a result is ready.
0%
D. To create a new operating system thread for each asynchronous task.