π Day 14 is here! Ready to unlock the power of Object-Oriented Programming? π§± Today, we dive deep into *Inheritance* and *Polymorphism*! Learn how to reuse code efficiently with inheritance, creating a clear "is-a" relationship between classes. Then, discover polymorphism, allowing objects of different classes to be treated through a common interface, behaving differently based on their type. Get ready to write more flexible and maintainable Python code! β¨
```python
class Animal:
def __init__(self, name):
self.name = name
def make_sound(self):
# This method is intended to be overridden by subclasses
raise NotImplementedError("Subclass must implement the make_sound method")
class Dog(Animal):
def make_sound(self):
return f"{self.name} barks! Woof! Woof!"
class Cat(Animal):
def make_sound(self):
return f"{self.name} meows! Meow!"
class Duck(Animal):
def make_sound(self):
return f"{self.name} quacks! Quack! Quack!"
# Demonstrate Polymorphism: A function that can take any 'Animal' object
def animal_sound_party(animal):
print(animal.make_sound())
print("--- Animal Sounds Party! π₯³ ---")
my_dog = Dog("Buddy")
my_cat = Cat("Whiskers")
my_duck = Duck("Daffy")
animal_sound_party(my_dog)
animal_sound_party(my_cat)
animal_sound_party(my_duck)
print("n--- Direct Calls ---")
print(my_dog.make_sound())
print(my_cat.make_sound())
```
Output example:
```
--- Animal Sounds Party! π₯³ ---
Buddy barks! Woof! Woof!
Whiskers meows! Meow!
Daffy quacks! Quack! Quack!
--- Direct Calls ---
Buddy barks! Woof! Woof!
Whiskers meows! Meow!
```
Small Challenge:
Challenge: Add a new class `Lion` π¦ that inherits from `Animal` and implements its own unique `make_sound()` method. Then, add a `lion` object to our `animal_sound_party` function! Share your mighty solution! πΎ
---
```python
class Animal:
def __init__(self, name):
self.name = name
def make_sound(self):
# This method is intended to be overridden by subclasses
raise NotImplementedError("Subclass must implement the make_sound method")
class Dog(Animal):
def make_sound(self):
return f"{self.name} barks! Woof! Woof!"
class Cat(Animal):
def make_sound(self):
return f"{self.name} meows! Meow!"
class Duck(Animal):
def make_sound(self):
return f"{self.name} quacks! Quack! Quack!"
# Demonstrate Polymorphism: A function that can take any 'Animal' object
def animal_sound_party(animal):
print(animal.make_sound())
print("--- Animal Sounds Party! π₯³ ---")
my_dog = Dog("Buddy")
my_cat = Cat("Whiskers")
my_duck = Duck("Daffy")
animal_sound_party(my_dog)
animal_sound_party(my_cat)
animal_sound_party(my_duck)
print("n--- Direct Calls ---")
print(my_dog.make_sound())
print(my_cat.make_sound())
```
Output example:
```
--- Animal Sounds Party! π₯³ ---
Buddy barks! Woof! Woof!
Whiskers meows! Meow!
Daffy quacks! Quack! Quack!
--- Direct Calls ---
Buddy barks! Woof! Woof!
Whiskers meows! Meow!
```
Small Challenge:
Challenge: Add a new class `Lion` π¦ that inherits from `Animal` and implements its own unique `make_sound()` method. Then, add a `lion` object to our `animal_sound_party` function! Share your mighty solution! πΎ
---
Which OOP principle allows objects of different classes to be treated as objects of a common superclass, enabling a single interface to represent different types?
Anonymous Quiz
0%
Inheritance
0%
Encapsulation
0%
Polymorphism
0%
Abstraction
Here's your Telegram post for Day 15!
---
**Day 15: Introduction to Python Libraries (requests)**
Day 15 is here! π Today, we're diving into the exciting world of Python libraries by exploring `requests`! π This powerful library makes interacting with web services and APIs incredibly easy. Forget complex built-in modules; `requests` simplifies making HTTP requests, fetching data, and much more. Get ready to connect your Python scripts to the vast internet! π» Let's make some web requests!
```python
import requests
# Define the URL of a public API endpoint
# This endpoint returns a sample ToDo item in JSON format
url = "https://jsonplaceholder.typicode.com/todos/1"
try:
# Make an HTTP GET request to the specified URL
response = requests.get(url)
# Check if the request was successful (status code 200)
if response.status_code == 200:
print("Request successful! π")
# Parse the JSON response
data = response.json()
print("nParsed JSON Data:")
print(f"User ID: {data['userId']}")
print(f"ID: {data['id']}")
print(f"Title: {data['title']}")
print(f"Completed: {data['completed']}")
else:
print(f"Request failed with status code: {response.status_code} π’")
print("Response text:", response.text)
except requests.exceptions.RequestException as e:
print(f"An error occurred: {e} π")
```
Output example:
Request successful! π
Parsed JSON Data:
User ID: 1
ID: 1
Title: delectus aut autem
Completed: False
Your Challenge: π§
Try changing the `url` to fetch a different ToDo item (e.g., `https://jsonplaceholder.typicode.com/todos/5`) or explore a different public API. Can you print only the `title` and `completed` status for the new item? Share your findings! π
---
---
**Day 15: Introduction to Python Libraries (requests)**
Day 15 is here! π Today, we're diving into the exciting world of Python libraries by exploring `requests`! π This powerful library makes interacting with web services and APIs incredibly easy. Forget complex built-in modules; `requests` simplifies making HTTP requests, fetching data, and much more. Get ready to connect your Python scripts to the vast internet! π» Let's make some web requests!
```python
import requests
# Define the URL of a public API endpoint
# This endpoint returns a sample ToDo item in JSON format
url = "https://jsonplaceholder.typicode.com/todos/1"
try:
# Make an HTTP GET request to the specified URL
response = requests.get(url)
# Check if the request was successful (status code 200)
if response.status_code == 200:
print("Request successful! π")
# Parse the JSON response
data = response.json()
print("nParsed JSON Data:")
print(f"User ID: {data['userId']}")
print(f"ID: {data['id']}")
print(f"Title: {data['title']}")
print(f"Completed: {data['completed']}")
else:
print(f"Request failed with status code: {response.status_code} π’")
print("Response text:", response.text)
except requests.exceptions.RequestException as e:
print(f"An error occurred: {e} π")
```
Output example:
Request successful! π
Parsed JSON Data:
User ID: 1
ID: 1
Title: delectus aut autem
Completed: False
Your Challenge: π§
Try changing the `url` to fetch a different ToDo item (e.g., `https://jsonplaceholder.typicode.com/todos/5`) or explore a different public API. Can you print only the `title` and `completed` status for the new item? Share your findings! π
---
What is the primary purpose of Python's 'requests' library?
Anonymous Quiz
0%
Performing complex mathematical calculations.
0%
Interacting with local file systems.
0%
Making HTTP requests to web servers and APIs.
0%
Building graphical user interfaces (GUIs).
Hey Python learners! π Day 17 is here, and we're diving into the world of **JSON (JavaScript Object Notation)**! π Ever wondered how web services exchange data? Often, it's through JSON β a lightweight, human-readable format. Python makes handling JSON a breeze with its built-in `json` module. Let's learn to convert Python data structures into JSON strings and parse them back! Get ready to serialize and deserialize! π
```python
import json
# A Python dictionary representing some data
person_data = {
"name": "Alice Wonderland",
"age": 30,
"isStudent": False,
"courses_taken": ["Python Basics", "Web Development"],
"contact": {
"email": "alice@example.com",
"phone": None
}
}
print("--- Original Python Dictionary ---")
print(person_data)
print(f"Type: {type(person_data)}n")
# 1. Convert Python dictionary to a JSON string (Serialization)
# The 'indent' parameter makes the output pretty-printed
json_string = json.dumps(person_data, indent=4)
print("--- Python Dictionary as JSON String ---")
print(json_string)
print(f"Type: {type(json_string)}n")
# 2. Convert JSON string back to a Python dictionary (Deserialization)
parsed_data = json.loads(json_string)
print("--- JSON String parsed back to Python Dictionary ---")
print(parsed_data)
print(f"Type: {type(parsed_data)}n")
# You can now work with the parsed_data as a regular Python dictionary
print(f"Alice's age (from parsed data): {parsed_data['age']}")
```
Output example:
```
--- Original Python Dictionary ---
{'name': 'Alice Wonderland', 'age': 30, 'isStudent': False, 'courses_taken': ['Python Basics', 'Web Development'], 'contact': {'email': 'alice@example.com', 'phone': None}}
Type: <class 'dict'>
--- Python Dictionary as JSON String ---
{
"name": "Alice Wonderland",
"age": 30,
"isStudent": false,
"courses_taken": [
"Python Basics",
"Web Development"
],
"contact": {
"email": "alice@example.com",
"phone": null
}
}
Type: <class 'str'>
--- JSON String parsed back to Python Dictionary ---
{'name': 'Alice Wonderland', 'age': 30, 'isStudent': False, 'courses_taken': ['Python Basics', 'Web Development'], 'contact': {'email': 'alice@example.com', 'phone': None}}
Type: <class 'dict'>
Alice's age (from parsed data): 30
```
### Your Challenge! π§
Can you modify the code to:
1. Save the `person_data` dictionary directly into a file named `user_profile.json` using `json.dump()`.
2. Then, in a separate part of your script (or a new script), load the data back from `user_profile.json` using `json.load()` and print its content?
---
```python
import json
# A Python dictionary representing some data
person_data = {
"name": "Alice Wonderland",
"age": 30,
"isStudent": False,
"courses_taken": ["Python Basics", "Web Development"],
"contact": {
"email": "alice@example.com",
"phone": None
}
}
print("--- Original Python Dictionary ---")
print(person_data)
print(f"Type: {type(person_data)}n")
# 1. Convert Python dictionary to a JSON string (Serialization)
# The 'indent' parameter makes the output pretty-printed
json_string = json.dumps(person_data, indent=4)
print("--- Python Dictionary as JSON String ---")
print(json_string)
print(f"Type: {type(json_string)}n")
# 2. Convert JSON string back to a Python dictionary (Deserialization)
parsed_data = json.loads(json_string)
print("--- JSON String parsed back to Python Dictionary ---")
print(parsed_data)
print(f"Type: {type(parsed_data)}n")
# You can now work with the parsed_data as a regular Python dictionary
print(f"Alice's age (from parsed data): {parsed_data['age']}")
```
Output example:
```
--- Original Python Dictionary ---
{'name': 'Alice Wonderland', 'age': 30, 'isStudent': False, 'courses_taken': ['Python Basics', 'Web Development'], 'contact': {'email': 'alice@example.com', 'phone': None}}
Type: <class 'dict'>
--- Python Dictionary as JSON String ---
{
"name": "Alice Wonderland",
"age": 30,
"isStudent": false,
"courses_taken": [
"Python Basics",
"Web Development"
],
"contact": {
"email": "alice@example.com",
"phone": null
}
}
Type: <class 'str'>
--- JSON String parsed back to Python Dictionary ---
{'name': 'Alice Wonderland', 'age': 30, 'isStudent': False, 'courses_taken': ['Python Basics', 'Web Development'], 'contact': {'email': 'alice@example.com', 'phone': None}}
Type: <class 'dict'>
Alice's age (from parsed data): 30
```
### Your Challenge! π§
Can you modify the code to:
1. Save the `person_data` dictionary directly into a file named `user_profile.json` using `json.dump()`.
2. Then, in a separate part of your script (or a new script), load the data back from `user_profile.json` using `json.load()` and print its content?
---
Which Python `json` module function is used to convert a Python dictionary into a JSON formatted *string*?
Anonymous Quiz
0%
json.load()
0%
json.dump()
0%
json.loads()
0%
json.dumps()
π Day 18: Dive into the powerful world of Regular Expressions (RegEx)! π Today, we're unlocking advanced pattern matching techniques in Python. RegEx lets you search, validate, and manipulate text based on complex patterns β a must-have skill for any developer. Get ready to transform your text processing game! β¨ Let's explore how to find specific patterns within strings with ease.
```python
import re
text = "Python is a powerful programming language. Python regular expressions are amazing for pattern matching!"
# 1. Find all occurrences of the word "Python" (case-insensitive)
pattern_python = r"[Pp]ython"
matches_python = re.findall(pattern_python, text)
print(f"Found '{pattern_python}' occurrences: {matches_python}")
# 2. Find all words that start with 'p' or 'P'
# b matches word boundaries, [Pp] matches 'P' or 'p', w* matches zero or more word characters
pattern_startswith_p = r"b[Pp]w*b"
words_starting_with_p = re.findall(pattern_startswith_p, text)
print(f"Words starting with 'P'/'p': {words_starting_with_p}")
# 3. Find all numbers (e.g., if there were any)
text_with_numbers = "I have 3 apples and 12 bananas."
pattern_numbers = r"d+" # d matches a digit, + matches one or more
numbers = re.findall(pattern_numbers, text_with_numbers)
print(f"Numbers in '{text_with_numbers}': {numbers}")
```
Output example:
```
Found '[Pp]ython' occurrences: ['Python', 'Python']
Words starting with 'P'/'p': ['Python', 'powerful', 'programming', 'Python', 'pattern']
Numbers in 'I have 3 apples and 12 bananas.': ['3', '12']
```
π‘ **Small Challenge:**
Can you write a RegEx pattern to find all words in a given string that are exactly 5 characters long? For example, in "Hello World Python", it should find "Hello" and "World".
---
```python
import re
text = "Python is a powerful programming language. Python regular expressions are amazing for pattern matching!"
# 1. Find all occurrences of the word "Python" (case-insensitive)
pattern_python = r"[Pp]ython"
matches_python = re.findall(pattern_python, text)
print(f"Found '{pattern_python}' occurrences: {matches_python}")
# 2. Find all words that start with 'p' or 'P'
# b matches word boundaries, [Pp] matches 'P' or 'p', w* matches zero or more word characters
pattern_startswith_p = r"b[Pp]w*b"
words_starting_with_p = re.findall(pattern_startswith_p, text)
print(f"Words starting with 'P'/'p': {words_starting_with_p}")
# 3. Find all numbers (e.g., if there were any)
text_with_numbers = "I have 3 apples and 12 bananas."
pattern_numbers = r"d+" # d matches a digit, + matches one or more
numbers = re.findall(pattern_numbers, text_with_numbers)
print(f"Numbers in '{text_with_numbers}': {numbers}")
```
Output example:
```
Found '[Pp]ython' occurrences: ['Python', 'Python']
Words starting with 'P'/'p': ['Python', 'powerful', 'programming', 'Python', 'pattern']
Numbers in 'I have 3 apples and 12 bananas.': ['3', '12']
```
π‘ **Small Challenge:**
Can you write a RegEx pattern to find all words in a given string that are exactly 5 characters long? For example, in "Hello World Python", it should find "Hello" and "World".
---
Which of the following RegEx metacharacters matches zero or more occurrences of the preceding character or group?
Anonymous Quiz
0%
?
0%
+
0%
*
0%
.
Here's your Telegram post for Day 19 on Virtual Environments! π
---
Hey Python learners! π Today is Day 19, and we're diving into a crucial topic: **Virtual Environments**! π Ever had project dependencies clash? Or needed a specific package version for one project but another for a different one? Virtual environments are your savior! They provide isolated spaces for your Python projects, keeping dependencies neat and tidy. No more global package chaos! β¨ Let's set up some order!
The standard way to create and manage virtual environments is using Python's built-in `venv` module. Here's a quick overview of the essential shell commands:
```bash
# 1. Create a virtual environment named 'myenv' in your project folder
python -m venv myenv
# 2. Activate it (Linux/macOS)
source myenv/bin/activate
# 2. Activate it (Windows PowerShell)
.myenvScriptsActivate.ps1
# 2. Activate it (Windows Cmd)
myenvScriptsactivate.bat
# Once activated, your terminal prompt usually changes to indicate the active env.
# Any packages you install with 'pip' now will go ONLY into this environment.
# 3. Deactivate it when you're done
deactivate
```
Now, let's look at some Python code you can run *inside* an activated virtual environment to see its effects:
```python
import sys
import os
import subprocess
print(f"Python interpreter location: {sys.executable}")
print(f"Virtual environment prefix: {sys.prefix}")
print(f"Is this a virtual environment? {hasattr(sys, 'real_prefix') or (hasattr(sys, 'base_prefix') and sys.base_prefix != sys.prefix)}")
# Try to import a common package like 'requests'
# If it's not installed in *this specific venv*, it should fail.
try:
import requests
print("nRequests package is installed in THIS environment! π")
except ImportError:
print("nRequests package is NOT installed in THIS environment. π")
print("Try installing it: pip install requests")
print("nCurrent packages in this environment (via 'pip list'):")
try:
# Running pip list as a subprocess to demonstrate package isolation
# This ensures we're checking packages relative to the active venv.
result = subprocess.run([sys.executable, '-m', 'pip', 'list', '--format=columns'],
capture_output=True, text=True, check=True)
print(result.stdout)
except FileNotFoundError:
print("Pip not found. Ensure it's correctly installed in the venv.")
except subprocess.CalledProcessError as e:
print(f"Error running pip: {e}")
```
Output example:
```
Python interpreter location: /path/to/your/project/myenv/bin/python
Virtual environment prefix: /path/to/your/project/myenv
Is this a virtual environment? True
Requests package is NOT installed in THIS environment. π
Try installing it: pip install requests
Current packages in this environment (via 'pip list'):
Package Version
---------- -------
pip 23.3.1
setuptools 68.2.2
```
*(Note: Paths and versions will vary depending on your system and Python version.)*
### Your Challenge! π
1. Create a new project folder (e.g., `my_cool_project`).
2. Inside it, create and activate a virtual environment named `my_project_env`.
3. Install the `requests` library within this activated environment (`pip install requests`).
4. Run the Python code from today's lesson inside your `my_project_env` to confirm `requests` is installed and verify the environment's prefix.
5. Deactivate your virtual environment. Now, open a *new* terminal window (or ensure your current one is deactivated) and try `python -c 'import requests'`. What happens? Why? (Hint: It should fail unless `requests` was *globally* installed!) Share your findings! π
---
---
Hey Python learners! π Today is Day 19, and we're diving into a crucial topic: **Virtual Environments**! π Ever had project dependencies clash? Or needed a specific package version for one project but another for a different one? Virtual environments are your savior! They provide isolated spaces for your Python projects, keeping dependencies neat and tidy. No more global package chaos! β¨ Let's set up some order!
The standard way to create and manage virtual environments is using Python's built-in `venv` module. Here's a quick overview of the essential shell commands:
```bash
# 1. Create a virtual environment named 'myenv' in your project folder
python -m venv myenv
# 2. Activate it (Linux/macOS)
source myenv/bin/activate
# 2. Activate it (Windows PowerShell)
.myenvScriptsActivate.ps1
# 2. Activate it (Windows Cmd)
myenvScriptsactivate.bat
# Once activated, your terminal prompt usually changes to indicate the active env.
# Any packages you install with 'pip' now will go ONLY into this environment.
# 3. Deactivate it when you're done
deactivate
```
Now, let's look at some Python code you can run *inside* an activated virtual environment to see its effects:
```python
import sys
import os
import subprocess
print(f"Python interpreter location: {sys.executable}")
print(f"Virtual environment prefix: {sys.prefix}")
print(f"Is this a virtual environment? {hasattr(sys, 'real_prefix') or (hasattr(sys, 'base_prefix') and sys.base_prefix != sys.prefix)}")
# Try to import a common package like 'requests'
# If it's not installed in *this specific venv*, it should fail.
try:
import requests
print("nRequests package is installed in THIS environment! π")
except ImportError:
print("nRequests package is NOT installed in THIS environment. π")
print("Try installing it: pip install requests")
print("nCurrent packages in this environment (via 'pip list'):")
try:
# Running pip list as a subprocess to demonstrate package isolation
# This ensures we're checking packages relative to the active venv.
result = subprocess.run([sys.executable, '-m', 'pip', 'list', '--format=columns'],
capture_output=True, text=True, check=True)
print(result.stdout)
except FileNotFoundError:
print("Pip not found. Ensure it's correctly installed in the venv.")
except subprocess.CalledProcessError as e:
print(f"Error running pip: {e}")
```
Output example:
```
Python interpreter location: /path/to/your/project/myenv/bin/python
Virtual environment prefix: /path/to/your/project/myenv
Is this a virtual environment? True
Requests package is NOT installed in THIS environment. π
Try installing it: pip install requests
Current packages in this environment (via 'pip list'):
Package Version
---------- -------
pip 23.3.1
setuptools 68.2.2
```
*(Note: Paths and versions will vary depending on your system and Python version.)*
### Your Challenge! π
1. Create a new project folder (e.g., `my_cool_project`).
2. Inside it, create and activate a virtual environment named `my_project_env`.
3. Install the `requests` library within this activated environment (`pip install requests`).
4. Run the Python code from today's lesson inside your `my_project_env` to confirm `requests` is installed and verify the environment's prefix.
5. Deactivate your virtual environment. Now, open a *new* terminal window (or ensure your current one is deactivated) and try `python -c 'import requests'`. What happens? Why? (Hint: It should fail unless `requests` was *globally* installed!) Share your findings! π
---
What is the primary purpose of using Python virtual environments?
Anonymous Quiz
0%
To isolate project dependencies, preventing conflicts between different projects.
0%
To speed up the execution of Python code.
0%
To create executable files from Python scripts.
0%
To compile Python code into a lower-level language.
Here's your Telegram post for Day 20!
---
**Day 20: Working with Dates and Times! β°ποΈ**
Time flies when you're coding! π Today, we're mastering how to handle dates and times in Python using the built-in `datetime` module. From getting the current moment to formatting dates and performing calculations, `datetime` is your go-to tool for temporal data. Let's synchronize our clocks and dive in! β¨
```python
import datetime
# Get current date and time
now = datetime.datetime.now()
print(f"Current Date and Time: {now}")
# Get current date only
today = datetime.date.today()
print(f"Current Date: {today}")
# Creating a specific date/time
specific_date = datetime.datetime(2024, 7, 15, 10, 30, 0)
print(f"Specific Date and Time: {specific_date}")
# Formatting dates using strftime()
formatted_now = now.strftime("%Y-%m-%d %H:%M:%S")
print(f"Formatted Current Time: {formatted_now}")
another_format = specific_date.strftime("Day %d of %B, %Y (%A)")
print(f"Another Format: {another_format}")
# Date arithmetic: Adding a timedelta
seven_days_later = now + datetime.timedelta(days=7)
print(f"Date 7 days from now: {seven_days_later.strftime('%Y-%m-%d')}")
two_hours_ago = now - datetime.timedelta(hours=2)
print(f"Time 2 hours ago: {two_hours_ago.strftime('%H:%M:%S')}")
```
Output example:
```
Current Date and Time: 2023-10-27 10:30:45.123456
Current Date: 2023-10-27
Specific Date and Time: 2024-07-15 10:30:00
Formatted Current Time: 2023-10-27 10:30:45
Another Format: Day 15 of July, 2024 (Monday)
Date 7 days from now: 2023-11-03
Time 2 hours ago: 08:30:45
```
**Small Challenge:** π―
Can you calculate and print the date that is **30 hours from now**, formatted as `HH:MM on DD-MM-YYYY`? π€
---
---
**Day 20: Working with Dates and Times! β°ποΈ**
Time flies when you're coding! π Today, we're mastering how to handle dates and times in Python using the built-in `datetime` module. From getting the current moment to formatting dates and performing calculations, `datetime` is your go-to tool for temporal data. Let's synchronize our clocks and dive in! β¨
```python
import datetime
# Get current date and time
now = datetime.datetime.now()
print(f"Current Date and Time: {now}")
# Get current date only
today = datetime.date.today()
print(f"Current Date: {today}")
# Creating a specific date/time
specific_date = datetime.datetime(2024, 7, 15, 10, 30, 0)
print(f"Specific Date and Time: {specific_date}")
# Formatting dates using strftime()
formatted_now = now.strftime("%Y-%m-%d %H:%M:%S")
print(f"Formatted Current Time: {formatted_now}")
another_format = specific_date.strftime("Day %d of %B, %Y (%A)")
print(f"Another Format: {another_format}")
# Date arithmetic: Adding a timedelta
seven_days_later = now + datetime.timedelta(days=7)
print(f"Date 7 days from now: {seven_days_later.strftime('%Y-%m-%d')}")
two_hours_ago = now - datetime.timedelta(hours=2)
print(f"Time 2 hours ago: {two_hours_ago.strftime('%H:%M:%S')}")
```
Output example:
```
Current Date and Time: 2023-10-27 10:30:45.123456
Current Date: 2023-10-27
Specific Date and Time: 2024-07-15 10:30:00
Formatted Current Time: 2023-10-27 10:30:45
Another Format: Day 15 of July, 2024 (Monday)
Date 7 days from now: 2023-11-03
Time 2 hours ago: 08:30:45
```
**Small Challenge:** π―
Can you calculate and print the date that is **30 hours from now**, formatted as `HH:MM on DD-MM-YYYY`? π€
---
Which `strftime` format code would you use to display the full weekday name (e.g., 'Monday', 'Tuesday')?
Anonymous Quiz
0%
%a
0%
%w
0%
%A
0%
%W
Here's your Telegram post for Day 21 on Python Decorators!
---
**Day 21: Decorators β¨ Unlocking Python Magic!**
Ready to add powerful functionality to your functions without changing their core code? Today, we're diving into Python Decorators! πͺ These amazing tools act as wrappers, allowing you to modify or enhance functionsβthink logging, authentication, or performance timingβwith a simple `@` syntax. It's a clean and elegant way to extend behavior. Let's see them in action! π
```python
def my_logger_decorator(func):
"""A simple decorator that logs function calls."""
def wrapper(*args, **kwargs):
print(f"π Calling function: {func.__name__} with args: {args}, kwargs: {kwargs}")
result = func(*args, **kwargs)
print(f"β Function {func.__name__} finished. Result: {result}")
return result
return wrapper
@my_logger_decorator
def add(a, b):
"""Adds two numbers."""
return a + b
@my_logger_decorator
def say_hello(name, greeting="Hello"):
"""Greets a person."""
print(f"{greeting}, {name}!")
return f"{greeting}, {name}!"
# Using our decorated functions
print("--- Calling add(5, 3) ---")
sum_result = add(5, 3)
print(f"Add function returned: {sum_result}n")
print("--- Calling say_hello('Alice', greeting='Hi') ---")
hello_message = say_hello('Alice', greeting='Hi')
print(f"Say_hello function returned: {hello_message}")
```
Output example:
```
--- Calling add(5, 3) ---
π Calling function: add with args: (5, 3), kwargs: {}
β Function add finished. Result: 8
Add function returned: 8
--- Calling say_hello('Alice', greeting='Hi') ---
π Calling function: say_hello with args: ('Alice',), kwargs: {'greeting': 'Hi'}
Hi, Alice!
β Function say_hello finished. Result: Hi, Alice!
Say_hello function returned: Hi, Alice!
```
**Small challenge:**
Can you create a decorator called `@timer` that measures and prints the execution time of the decorated function? β±οΈ Share your solution in the comments! π
---
---
**Day 21: Decorators β¨ Unlocking Python Magic!**
Ready to add powerful functionality to your functions without changing their core code? Today, we're diving into Python Decorators! πͺ These amazing tools act as wrappers, allowing you to modify or enhance functionsβthink logging, authentication, or performance timingβwith a simple `@` syntax. It's a clean and elegant way to extend behavior. Let's see them in action! π
```python
def my_logger_decorator(func):
"""A simple decorator that logs function calls."""
def wrapper(*args, **kwargs):
print(f"π Calling function: {func.__name__} with args: {args}, kwargs: {kwargs}")
result = func(*args, **kwargs)
print(f"β Function {func.__name__} finished. Result: {result}")
return result
return wrapper
@my_logger_decorator
def add(a, b):
"""Adds two numbers."""
return a + b
@my_logger_decorator
def say_hello(name, greeting="Hello"):
"""Greets a person."""
print(f"{greeting}, {name}!")
return f"{greeting}, {name}!"
# Using our decorated functions
print("--- Calling add(5, 3) ---")
sum_result = add(5, 3)
print(f"Add function returned: {sum_result}n")
print("--- Calling say_hello('Alice', greeting='Hi') ---")
hello_message = say_hello('Alice', greeting='Hi')
print(f"Say_hello function returned: {hello_message}")
```
Output example:
```
--- Calling add(5, 3) ---
π Calling function: add with args: (5, 3), kwargs: {}
β Function add finished. Result: 8
Add function returned: 8
--- Calling say_hello('Alice', greeting='Hi') ---
π Calling function: say_hello with args: ('Alice',), kwargs: {'greeting': 'Hi'}
Hi, Alice!
β Function say_hello finished. Result: Hi, Alice!
Say_hello function returned: Hi, Alice!
```
**Small challenge:**
Can you create a decorator called `@timer` that measures and prints the execution time of the decorated function? β±οΈ Share your solution in the comments! π
---
π Day 22: Unlocking Python's Power with Generators & Iterators! π
Today, we dive into the magic of memory-efficient data processing. Learn how **generators** allow you to create sequences on-the-fly without storing the entire sequence in memory β perfect for huge datasets! We'll explore the `yield` keyword and how **iterators** work behind the scenes to produce values one by one. Get ready to write more performant and scalable Python code! β¨
```python
def countdown_generator(n):
"""A simple generator that counts down from n."""
print(f"Starting countdown from {n}...")
while n >= 0:
yield n # Pause execution and yield a value
n -= 1
print("Countdown finished!")
# --- Using a for loop to iterate over the generator ---
print("--- Iterating with a for loop (n=3) ---")
for num in countdown_generator(3):
print(f"Current count: {num}")
print("n--- Manually iterating with next() (n=2) ---")
# --- Manually iterating using next() ---
gen = countdown_generator(2)
try:
print(f"First value: {next(gen)}")
print(f"Second value: {next(gen)}")
print(f"Third value: {next(gen)}")
# Trying to get another value after exhaustion raises StopIteration
print(f"Fourth value: {next(gen)}")
except StopIteration:
print("Caught StopIteration: Generator is exhausted.")
```
Output example:
```
--- Iterating with a for loop (n=3) ---
Starting countdown from 3...
Current count: 3
Current count: 2
Current count: 1
Current count: 0
Countdown finished!
--- Manually iterating with next() (n=2) ---
Starting countdown from 2...
First value: 2
Second value: 1
Third value: 0
Caught StopIteration: Generator is exhausted.
Countdown finished!
```
π‘ **Your Challenge:** Modify the `countdown_generator` to create a `fibonacci_generator(limit)` that yields Fibonacci numbers up to a specified `limit`! Share your solution! π
---
Today, we dive into the magic of memory-efficient data processing. Learn how **generators** allow you to create sequences on-the-fly without storing the entire sequence in memory β perfect for huge datasets! We'll explore the `yield` keyword and how **iterators** work behind the scenes to produce values one by one. Get ready to write more performant and scalable Python code! β¨
```python
def countdown_generator(n):
"""A simple generator that counts down from n."""
print(f"Starting countdown from {n}...")
while n >= 0:
yield n # Pause execution and yield a value
n -= 1
print("Countdown finished!")
# --- Using a for loop to iterate over the generator ---
print("--- Iterating with a for loop (n=3) ---")
for num in countdown_generator(3):
print(f"Current count: {num}")
print("n--- Manually iterating with next() (n=2) ---")
# --- Manually iterating using next() ---
gen = countdown_generator(2)
try:
print(f"First value: {next(gen)}")
print(f"Second value: {next(gen)}")
print(f"Third value: {next(gen)}")
# Trying to get another value after exhaustion raises StopIteration
print(f"Fourth value: {next(gen)}")
except StopIteration:
print("Caught StopIteration: Generator is exhausted.")
```
Output example:
```
--- Iterating with a for loop (n=3) ---
Starting countdown from 3...
Current count: 3
Current count: 2
Current count: 1
Current count: 0
Countdown finished!
--- Manually iterating with next() (n=2) ---
Starting countdown from 2...
First value: 2
Second value: 1
Third value: 0
Caught StopIteration: Generator is exhausted.
Countdown finished!
```
π‘ **Your Challenge:** Modify the `countdown_generator` to create a `fibonacci_generator(limit)` that yields Fibonacci numbers up to a specified `limit`! Share your solution! π
---
What is the primary benefit of using a generator function in Python compared to a regular function that returns a list for large sequences?
Anonymous Quiz
0%
Generators execute faster because they don't use loops.
0%
Generators store the entire sequence in memory at once, making access quicker.
0%
Generators produce items one at a time, saving memory by not storing the entire sequence.
0%
Generators are only used for asynchronous programming.
π Hey Python learners! Day 23 is here, and we're diving into a Python superpower: *Context Managers* using the `with` statement! π
Ever forget to close a file or release a lock? The `with` statement is your elegant solution for ensuring resources are properly managed and cleaned up automatically, even if errors occur. It makes your code safer, cleaner, and more Pythonic! Get ready to simplify resource handling. Let's explore! π
```python
# Day 23: Context Managers (with statement)
# --- Example 1: File Handling with 'with' ---
print("--- File Handling Demo ---")
try:
# 'with' ensures the file is closed automatically,
# even if an error occurs during writing/reading.
with open("my_document.txt", "w") as file_writer:
file_writer.write("Hello from Day 23!n")
file_writer.write("Context Managers are awesome!n")
print("Successfully wrote to my_document.txt")
with open("my_document.txt", "r") as file_reader:
content = file_reader.read()
print(f"Content read:n{content}")
print("File automatically closed after 'with' block.")
# --- Example 2: Demonstrating cleanup on error ---
print("n--- Error Handling Demo ---")
with open("error_test.log", "w") as log_file:
log_file.write("Starting critical operation...n")
# Simulate an error
raise ValueError("Critical operation failed!")
log_file.write("This line will not be reached.n") # Unreachable
except ValueError as e:
print(f"Caught an expected error: {e}")
# Even though an error occurred, log_file was closed
# before the exception was propagated.
print("The 'error_test.log' file was still automatically closed!")
except Exception as e:
print(f"An unexpected error occurred: {e}")
print("n--- Demo Complete ---")
```
Output example:
```
--- File Handling Demo ---
Successfully wrote to my_document.txt
Content read:
Hello from Day 23!
Context Managers are awesome!
File automatically closed after 'with' block.
--- Error Handling Demo ---
Caught an expected error: Critical operation failed!
The 'error_test.log' file was still automatically closed!
--- Demo Complete ---
```
π‘ **Your Challenge:** What happens if you try to access `file_reader` (from the example's `with open(...) as file_reader:`) *after* its `with` block has finished? For instance, try adding `print(file_reader.closed)` or `file_reader.read()` right after the first `with` block. Try it and see if you can catch the error (or the boolean value)! Share your findings! π
---
Ever forget to close a file or release a lock? The `with` statement is your elegant solution for ensuring resources are properly managed and cleaned up automatically, even if errors occur. It makes your code safer, cleaner, and more Pythonic! Get ready to simplify resource handling. Let's explore! π
```python
# Day 23: Context Managers (with statement)
# --- Example 1: File Handling with 'with' ---
print("--- File Handling Demo ---")
try:
# 'with' ensures the file is closed automatically,
# even if an error occurs during writing/reading.
with open("my_document.txt", "w") as file_writer:
file_writer.write("Hello from Day 23!n")
file_writer.write("Context Managers are awesome!n")
print("Successfully wrote to my_document.txt")
with open("my_document.txt", "r") as file_reader:
content = file_reader.read()
print(f"Content read:n{content}")
print("File automatically closed after 'with' block.")
# --- Example 2: Demonstrating cleanup on error ---
print("n--- Error Handling Demo ---")
with open("error_test.log", "w") as log_file:
log_file.write("Starting critical operation...n")
# Simulate an error
raise ValueError("Critical operation failed!")
log_file.write("This line will not be reached.n") # Unreachable
except ValueError as e:
print(f"Caught an expected error: {e}")
# Even though an error occurred, log_file was closed
# before the exception was propagated.
print("The 'error_test.log' file was still automatically closed!")
except Exception as e:
print(f"An unexpected error occurred: {e}")
print("n--- Demo Complete ---")
```
Output example:
```
--- File Handling Demo ---
Successfully wrote to my_document.txt
Content read:
Hello from Day 23!
Context Managers are awesome!
File automatically closed after 'with' block.
--- Error Handling Demo ---
Caught an expected error: Critical operation failed!
The 'error_test.log' file was still automatically closed!
--- Demo Complete ---
```
π‘ **Your Challenge:** What happens if you try to access `file_reader` (from the example's `with open(...) as file_reader:`) *after* its `with` block has finished? For instance, try adding `print(file_reader.closed)` or `file_reader.read()` right after the first `with` block. Try it and see if you can catch the error (or the boolean value)! Share your findings! π
---