Python coding
53 subscribers
24 files
11 links
​A technical hub dedicated to Python programming, web development, and software engineering. Learn core syntax, build full-stack projects, and master backend development.
Download Telegram
Python coding
🐍 Python Tip #37: The itertools.cycle() Function The cycle() function from Python's itertools module repeats the elements of an iterable indefinitely. It is useful when you need to continuously loop through a sequence without restarting it manually. --…
πŸš€ Python Tip #38: The itertools.repeat() Function

The repeat() function from Python's itertools module returns the same value multiple times.

It is useful when you need a constant value in loops, function calls, or data generation.

---

Importing repeat

from itertools import repeat

---

Basic Example

from itertools import repeat

for value in repeat("Python", 5):
print(value)

Output:

Python
Python
Python
Python
Python

The string "Python" is repeated exactly 5 times.

---

Creating a List

from itertools import repeat

numbers = list(repeat(10, 4))

print(numbers)

Output:

[10, 10, 10, 10]

---

Using repeat() with map()

Suppose you want to multiply every number by 2.

from itertools import repeat

numbers = [1, 2, 3, 4]

result = list(map(pow, numbers, repeat(2)))

print(result)

Output:

[1, 4, 9, 16]

Here, `repeat(2) provides the exponent 2 for every call to pow().

---

Infinite Repetition

If you omit the second argument,
repeat() repeats forever.

``
python
from itertools import repeat

counter = repeat("Hello")

for _ in range(3):
print(next(counter))

Output:

python
Hello
Hello
Hello

Since the iterator is infinite, we use `next()` or limit it with a loop.

---

Why use `repeat()`?

βœ“ Generates constant values efficiently
βœ“ Works well with `map()` and other iterators
βœ“ Avoids creating unnecessary lists
βœ“ Commonly used in functional programming and data processing

---

Challenge:

Use `itertools.repeat()` to create a list containing the word:

python
"AI"

repeated **8 times**.

Expected Output:

python
['AI', 'AI', 'AI', 'AI', 'AI', 'AI', 'AI', 'AI']
`
Python coding
πŸš€ Python Tip #38: The itertools.repeat() Function The repeat() function from Python's itertools module returns the same value multiple times. It is useful when you need a constant value in loops, function calls, or data generation. --- Importing repeat…
πŸ’‘ Python Tip #39: The itertools.takewhile() Function

The takewhile() function from Python's itertools module returns items from an iterable **as long as a condition remains True**.

Once the condition becomes False, the iteration stops immediately.

---

Importing takewhile

from itertools import takewhile

---

Basic Example

from itertools import takewhile

numbers = [2, 4, 6, 8, 9, 10, 12]

result = list(takewhile(lambda x: x % 2 == 0, numbers))

print(result)

Output:

[2, 4, 6, 8]

The iteration stops when it reaches 9 because it is not an even number.

---

Using a Numeric Condition

from itertools import takewhile

numbers = [5, 10, 15, 20, 30, 40]

result = list(takewhile(lambda x: x < 25, numbers))

print(result)

Output:

[5, 10, 15, 20]

Although 40 also doesn't satisfy the condition, the iteration already stopped at 30.

---

Working with Strings

from itertools import takewhile

words = [
"Apple",
"Ant",
"Ball",
"Cat"
]

result = list(takewhile(lambda word: word.startswith("A"), words))

print(result)

Output:

['Apple', 'Ant']

The iteration stops when "Ball" is encountered.

---

Important Note

takewhile() only checks items until the first condition fails.

It dnotot** continue searching the remaining elements.

---

Why use takewhile()?

βœ“ Stops processing as soon as a condition fails
βœ“ More efficient than checking every item
βœ“ Works with any iterable or generator
βœ“ Commonly used in data streams and lazy evaluation

---

Challenge:

Given the following list:

temperatures = [18, 20, 22, 24, 31, 28, 26]

Use `itertools.takewhile() to collect all temperatures that are **below 30**.

Expected Output:

``
python
[18, 20, 22, 24]
`
Python coding
πŸ’‘ Python Tip #39: The itertools.takewhile() Function The takewhile() function from Python's itertools module returns items from an iterable **as long as a condition remains True**. Once the condition becomes False, the iteration stops immediately. --- …
πŸš€ Python Tip #40: The itertools.dropwhile() Function

The dropwhile() function from Python's itertools module skips items from an iterable **as long as a condition is True**.

Once the condition becomes False, it returns that item and every remaining item.

---

Importing dropwhile

from itertools import dropwhile

---

Basic Example

from itertools import dropwhile

numbers = [2, 4, 6, 8, 9, 10, 12]

result = list(dropwhile(lambda x: x % 2 == 0, numbers))

print(result)

Output:

[9, 10, 12]

The even numbers at the beginning are skipped. Once 9 is encountered, all remaining values are returned.

---

Using a Numeric Condition

from itertools import dropwhile

numbers = [5, 10, 15, 20, 30, 40]

result = list(dropwhile(lambda x: x < 25, numbers))

print(result)

Output:

[30, 40]

The function skips numbers less than 25 and starts returning values from 30.

---

Working with Strings

from itertools import dropwhile

words = [
"Apple",
"Ant",
"Ball",
"Cat"
]

result = list(dropwhile(lambda word: word.startswith("A"), words))

print(result)

Output:

['Ball', 'Cat']

The words starting with "A" are skipped. After "Ball" is reached, all remaining words are returned.

---

takewhile() vs dropwhile()

from itertools import takewhile, dropwhile

numbers = [1, 2, 3, 4, 5]

print(list(takewhile(lambda x: x < 4, numbers)))
print(list(dropwhile(lambda x: x < 4, numbers)))

Output:

[1, 2, 3]
[4, 5]

- `takewhile() keeps items while the condition is True.
-
dropwhile() skips items while the condition is True.

---

Why use
dropwhile()?

βœ“ Skips unwanted items efficiently
βœ“ Stops checking once the condition becomes
False
βœ“ Works with iterators and generators
βœ“ Useful for processing logs, streams, and large datasets

---

Challenge:

Given the following list:

``
python
scores = [45, 50, 55, 60, 72, 80, 90]

Use `itertools.dropwhile()` to skip all scores below `70`.

Expected Output:

python
[72, 80, 90]
`
Python coding
πŸš€ Python Tip #40: The itertools.dropwhile() Function The dropwhile() function from Python's itertools module skips items from an iterable **as long as a condition is True**. Once the condition becomes False, it returns that item and every remaining item.…
🐍 Python Tip #41: The itertools.tee() Function

The tee() function from Python's itertools module creates multiple independent iterators from a single iterable.

This is useful when you need to iterate over the same data more than once without recreating it.

---

Importing tee

from itertools import tee

---

Basic Example

from itertools import tee

numbers = [1, 2, 3, 4]

iterator1, iterator2 = tee(numbers)

print(list(iterator1))
print(list(iterator2))

Output:

[1, 2, 3, 4]
[1, 2, 3, 4]

Both iterators contain the same data.

---

Working with Generators

tee() is especially useful with generators, which can normally be used only once.

from itertools import tee

squares = (x ** 2 for x in range(5))

it1, it2 = tee(squares)

print(list(it1))
print(list(it2))

Output:

[0, 1, 4, 9, 16]
[0, 1, 4, 9, 16]

Without tee(), the generator would be exhausted after the first iteration.

---

Creating More Than Two Iterators

You can create as many independent iterators as needed.

from itertools import tee

letters = ["A", "B", "C"]

a, b, c = tee(letters, 3)

print(next(a))
print(next(b))
print(next(c))

Output:

A
A
A

Each iterator maintains its own position independently.

---

Why use tee()?

βœ“ Creates multiple independent iterators
βœ“ Works with generators and other iterables
βœ“ Prevents data from being consumed after one iteration
βœ“ Useful in data pipelines and iterator-based programming

---

Challenge:

Create a generator that produces the numbers from 1 to 10.

Use itertools.tee() to create two independent iterators.

- Use the first iterator to print all the numbers.
- Use the second iterator to print only the first five numbers.
Python coding
🐍 Python Tip #41: The itertools.tee() Function The tee() function from Python's itertools module creates multiple independent iterators from a single iterable. This is useful when you need to iterate over the same data more than once without recreating it.…
πŸš€ Python Tip #42: The itertools.zip_longest() Function

The zip_longest() function from Python's itertools module combines multiple iterables, just like zip(). However, unlike zip(), it continues until the longest iterable is exhausted.

Missing values are filled with a specified value (or None by default).

---

Importing zip_longest

from itertools import zip_longest

---

Basic Example

from itertools import zip_longest

names = ["Ali", "Sara", "John"]
scores = [90, 85]

result = list(zip_longest(names, scores))

print(result)

Output:

[
('Ali', 90),
('Sara', 85),
('John', None)
]

Since `scores is shorter, None is used for the missing value.

---

Using a Custom Fill Value

You can replace
None with any value using the fillvalue parameter.

``
python
from itertools import zip_longest

names = ["Ali", "Sara", "John"]
scores = [90, 85]

result = list(zip_longest(names, scores, fillvalue="N/A"))

print(result)

Output:

python
[
('Ali', 90),
('Sara', 85),
('John', 'N/A')
]

---

`zip()` vs `zip_longest()`

python
from itertools import zip_longest

list1 = [1, 2, 3]
list2 = ["A", "B"]

print(list(zip(list1, list2)))
print(list(zip_longest(list1, list2)))

Output:

python
[(1, 'A'), (2, 'B')]

[(1, 'A'),
(2, 'B'),
(3, None)]

- `zip()` stops when the shortest iterable ends.
- `zip_longest()` continues until the longest iterable ends.

---

Practical Example

python
from itertools import zip_longest

products = ["Laptop", "Phone", "Tablet"]
prices = [1200, 800]

for product, price in zip_longest(products, prices, fillvalue="Unknown"):
print(product, price)

Output:

python
Laptop 1200
Phone 800
Tablet Unknown

---

Why use `zip_longest()`?

βœ“ Combines iterables of different lengths
βœ“ Prevents data loss when one iterable is shorter
βœ“ Supports custom fill values
βœ“ Useful for data cleaning, reporting, and CSV processing

---

Challenge:

Given the following lists:

python
students = [
"Ali",
"Sara",
"John",
"Mariam"
]

grades = [
"A",
"B"
]

Use `itertools.zip_longest()` with:

python
fillvalue = "Not Graded"

Expected Output:

python
[
('Ali', 'A'),
('Sara', 'B'),
('John', 'Not Graded'),
('Mariam', 'Not Graded')
]
`
Python coding
πŸš€ Python Tip #42: The itertools.zip_longest() Function The zip_longest() function from Python's itertools module combines multiple iterables, just like zip(). However, unlike zip(), it continues until the longest iterable is exhausted. Missing values are…
πŸ’‘ Python Tip #43: The collections.Counter Class

The Counter class from Python's collections module is a convenient way to count the occurrences of elements in an iterable.

It automatically creates a dictionary where the keys are the unique elements and the values are their counts.

---

Importing Counter

from collections import Counter

---

Basic Example

from collections import Counter

fruits = [
"apple",
"banana",
"apple",
"orange",
"banana",
"apple"
]

count = Counter(fruits)

print(count)

Output:

Counter({
'apple': 3,
'banana': 2,
'orange': 1
})

---

Counting Characters

from collections import Counter

text = "programming"

count = Counter(text)

print(count)

Output:

Counter({
'g': 2,
'r': 2,
'm': 2,
'p': 1,
'o': 1,
'a': 1,
'i': 1,
'n': 1
})

---

Finding the Most Common Items

Use the most_common() method.

from collections import Counter

numbers = [1, 2, 2, 3, 3, 3, 4]

count = Counter(numbers)

print(count.most_common(2))

Output:

[(3, 3), (2, 2)]

This returns the two most common elements and their frequencies.

---

Counting Words

from collections import Counter

sentence = "python is fun and python is powerful"

words = sentence.split()

count = Counter(words)

print(count)

Output:

Counter({
'python': 2,
'is': 2,
'fun': 1,
'and': 1,
'powerful': 1
})

---

Why use Counter?

βœ“ Counts elements automatically
βœ“ Eliminates manual counting loops
βœ“ Finds the most common items easily
βœ“ Commonly used in text analysis, data science, and frequency analysis

---

Challenge:

Given the following list:

votes = [
"Python",
"Java",
"Python",
"C++",
"Python",
"Java",
"Java"
]

Use `collections.Counter to:

1. Count how many votes each programming language received.
2. Display the most popular programming language using:

``
python
most_common(1)
`
Python coding
πŸ’‘ Python Tip #43: The collections.Counter Class The Counter class from Python's collections module is a convenient way to count the occurrences of elements in an iterable. It automatically creates a dictionary where the keys are the unique elements and the…
πŸš€ Python Tip #44: The collections.UserDict Class

The UserDict class from Python's collections module is a wrapper around the built-in dictionary.

It makes it easier to create custom dictionary classes by allowing you to override dictionary behavior.

---

Importing UserDict

from collections import UserDict

---

Basic Example

from collections import UserDict

class MyDictionary(UserDict):
pass

data = MyDictionary()

data["name"] = "Yehya"
data["age"] = 16

print(data)

Output:

{'name': 'Yehya', 'age': 16}

---

Customizing Dictionary Behavior

Suppose you want all keys to be stored in lowercase.

from collections import UserDict

class LowerDict(UserDict):
def __setitem__(self, key, value):
super().__setitem__(key.lower(), value)

data = LowerDict()

data["Name"] = "Ali"
data["AGE"] = 18

print(data)

Output:

{'name': 'Ali', 'age': 18}

---

Validating Values

You can also validate data before storing it.

from collections import UserDict

class PositiveNumbers(UserDict):
def __setitem__(self, key, value):
if value < 0:
raise ValueError("Only positive numbers are allowed.")
super().__setitem__(key, value)

numbers = PositiveNumbers()

numbers["a"] = 10
numbers["b"] = 20

print(numbers)

Output:

{'a': 10, 'b': 20}

Trying to store a negative number:

numbers["c"] = -5

Output:

ValueError: Only positive numbers are allowed.

---

Why use UserDict?

βœ“ Easily create custom dictionary classes
βœ“ Override dictionary behavior safely
βœ“ Add validation and custom logic
βœ“ Useful for configuration systems, caching, and data validation

---

Challenge:

Create a class named:

UpperCaseDict

using `UserDict.

Whenever a key is added, automatically convert it to uppercase.

Example:

``
python
data["name"] = "Yehya"
data["city"] = "Addis Ababa"

Expected Output:

python
{'NAME': 'Yehya', 'CITY': 'Addis Ababa'}
`
Python coding
πŸš€ Python Tip #44: The collections.UserDict Class The UserDict class from Python's collections module is a wrapper around the built-in dictionary. It makes it easier to create custom dictionary classes by allowing you to override dictionary behavior. --…
🐍 Python Tip #45: The collections.UserList Class

The UserList class from Python's collections module is a wrapper around Python's built-in list.

It makes it easier to create custom list classes with your own behavior.

---

Importing UserList

from collections import UserList

---

Basic Example

from collections import UserList

class MyList(UserList):
pass

numbers = MyList([1, 2, 3])

numbers.append(4)

print(numbers)

Output:

[1, 2, 3, 4]

---

Customizing List Behavior

Suppose you want every string added to the list to be stored in uppercase.

from collections import UserList

class UpperList(UserList):
def append(self, item):
if isinstance(item, str):
item = item.upper()
super().append(item)

words = UpperList()

words.append("python")
words.append("programming")

print(words)

Output:

['PYTHON', 'PROGRAMMING']

---

Validating Items

You can prevent invalid data from being added.

from collections import UserList

class PositiveList(UserList):
def append(self, item):
if item < 0:
raise ValueError("Only positive numbers are allowed.")
super().append(item)

numbers = PositiveList()

numbers.append(10)
numbers.append(20)

print(numbers)

Output:

[10, 20]

Trying to add a negative number:

numbers.append(-5)

Output:

ValueError: Only positive numbers are allowed.

---

Why use UserList?

βœ“ Easily create custom list classes
βœ“ Add validation before inserting items
βœ“ Customize built-in list methods
βœ“ Useful for data validation, business rules, and reusable components

---

Challenge:

Create a class named:

EvenList

using `UserList.

Whenever a number is added:

- If the number is even, add it to the list.
- If the number is odd, raise a
ValueError.

Example:

``
python
numbers.append(2)
numbers.append(8)
numbers.append(5)

Expected Output:

python
ValueError: Only even numbers are allowed.
`
Python coding
🐍 Python Tip #45: The collections.UserList Class The UserList class from Python's collections module is a wrapper around Python's built-in list. It makes it easier to create custom list classes with your own behavior. --- Importing UserList from collections…
πŸš€ Python Tip #46: The collections.UserString Class

The UserString class from Python's collections module is a wrapper around Python's built-in string.

It allows you to create custom string classes and modify string behavior while keeping all standard string features.

---

Importing UserString

from collections import UserString

---

Basic Example

from collections import UserString

class MyString(UserString):
pass

text = MyString("Hello, Python!")

print(text)
print(text.upper())

Output:

Hello, Python!
HELLO, PYTHON!

---

Customizing String Behavior

Suppose you want every string to be stored in uppercase.

from collections import UserString

class UpperString(UserString):
def __init__(self, value):
super().__init__(value.upper())

text = UpperString("python programming")

print(text)

Output:

PYTHON PROGRAMMING

---

Validating Input

You can validate data before creating the string.

from collections import UserString

class NoDigitsString(UserString):
def __init__(self, value):
if any(char.isdigit() for char in value):
raise ValueError("Numbers are not allowed.")
super().__init__(value)

text = NoDigitsString("Hello")
print(text)

Output:

Hello

Trying to create:

text = NoDigitsString("Python3")

Output:

ValueError: Numbers are not allowed.

---

Why use UserString?

βœ“ Easily create custom string classes
βœ“ Add validation or formatting automatically
βœ“ Preserve all built-in string methods
βœ“ Useful for usernames, passwords, and custom text processing

---

Challenge:

Create a class named:

TitleString

using `UserString.

Whenever a string is created, automatically convert it to title case.

Example:

``
python
text = TitleString("welcome to python programming")

print(text)

Expected Output:

python
Welcome To Python Programming
`
Python coding
πŸš€ Python Tip #46: The collections.UserString Class The UserString class from Python's collections module is a wrapper around Python's built-in string. It allows you to create custom string classes and modify string behavior while keeping all standard string…
πŸ’‘ Python Tip #47: The fractions.Fraction Class

Floating-point numbers can sometimes produce unexpected results due to precision limitations.

Python's Fraction class from the fractions module represents numbers as exact fractions.

---

Importing Fraction

from fractions import Fraction

---

Basic Example

from fractions import Fraction

fraction = Fraction(3, 4)

print(fraction)

Output:

3/4

---

Adding Fractions

from fractions import Fraction

a = Fraction(1, 2)
b = Fraction(1, 3)

result = a + b

print(result)

Output:

5/6

---

Creating Fractions from Floats

from fractions import Fraction

fraction = Fraction(0.75)

print(fraction)

Output:

3/4

You can also limit the denominator.

from fractions import Fraction

fraction = Fraction(3.14159).limit_denominator()

print(fraction)

Output:

355/113

---

Arithmetic Operations

from fractions import Fraction

a = Fraction(2, 5)
b = Fraction(3, 10)

print(a + b)
print(a - b)
print(a * b)
print(a / b)

Output:

7/10
1/10
3/25
4/3

---

Why use Fraction?

βœ“ Performs exact fraction calculations
βœ“ Avoids floating-point precision errors
βœ“ Supports all arithmetic operations
βœ“ Useful in mathematics, finance, engineering, and scientific computing

---

Challenge:

Create the following fractions:

2/3
5/6

Then calculate:

- Their sum
- Their difference
- Their product
- Their quotient

Print each result as a fraction.
Python coding
πŸ’‘ Python Tip #47: The fractions.Fraction Class Floating-point numbers can sometimes produce unexpected results due to precision limitations. Python's Fraction class from the fractions module represents numbers as exact fractions. --- Importing Fraction…
πŸš€ Python Tip #48: The decimal.Decimal Class

Floating-point numbers are not always exact. This can lead to small rounding errors, especially in financial and scientific calculations.

Python's Decimal class from the decimal module provides precise decimal arithmetic.

---

Importing Decimal

from decimal import Decimal

---

The Floating-Point Problem

print(0.1 + 0.2)

Output:

0.30000000000000004

This happens because floating-point numbers are stored in binary.

---

Using Decimal

from decimal import Decimal

result = Decimal("0.1") + Decimal("0.2")

print(result)

Output:

0.3

The calculation is exact.

---

Performing Arithmetic

from decimal import Decimal

a = Decimal("10.50")
b = Decimal("3.25")

print(a + b)
print(a - b)
print(a * b)
print(a / b)

Output:

13.75
7.25
34.1250
3.230769230769230769230769231

---

Rounding Decimals

Use the quantize() method to round decimal values.

from decimal import Decimal

price = Decimal("19.9876")

rounded = price.quantize(Decimal("0.01"))

print(rounded)

Output:

19.99

---

Why use Decimal?

βœ“ Provides precise decimal calculations
βœ“ Eliminates floating-point rounding errors
βœ“ Ideal for financial and accounting applications
βœ“ Commonly used in banking, e-commerce, and scientific computing

---

Challenge:

Using Decimal, calculate the total cost of these three items:

12.99
8.75
15.50

Then round the final result to 2 decimal places using quantize().
Python coding
πŸš€ Python Tip #48: The decimal.Decimal Class Floating-point numbers are not always exact. This can lead to small rounding errors, especially in financial and scientific calculations. Python's Decimal class from the decimal module provides precise decimal…
🐍 Python Tip #49: The datetime Module

Working with dates and times is a common task in Python.

The datetime module allows you to create, manipulate, and format dates and times with ease.

---

Importing datetime

from datetime import datetime

---

Getting the Current Date and Time

from datetime import datetime

now = datetime.now()

print(now)

Output:

2026-07-08 14:30:15.123456

(The output will depend on the current date and time.)

---

Getting Individual Components

from datetime import datetime

now = datetime.now()

print(now.year)
print(now.month)
print(now.day)
print(now.hour)
print(now.minute)
print(now.second)

Example Output:

2026
7
8
14
30
15

---

Formatting Dates

Use the strftime() method to display dates in different formats.

from datetime import datetime

now = datetime.now()

print(now.strftime("%d/%m/%Y"))
print(now.strftime("%B %d, %Y"))
print(now.strftime("%I:%M %p"))

Example Output:

08/07/2026
July 08, 2026
02:30 PM

---

Creating a Specific Date

from datetime import datetime

birthday = datetime(2009, 11, 4)

print(birthday)

Output:

2009-11-04 00:00:00

---

Why use datetime?

βœ“ Work with dates and times easily
βœ“ Format dates in different styles
βœ“ Extract year, month, day, and time components
βœ“ Commonly used in web development, automation, logging, and scheduling

---

Challenge:

Create a datetime object for:

January 1, 2030

Then print it in the following format:

01 January 2030

using the strftime() method.
Python coding
🐍 Python Tip #49: The datetime Module Working with dates and times is a common task in Python. The datetime module allows you to create, manipulate, and format dates and times with ease. --- Importing datetime from datetime import datetime --- Getting…
πŸš€ Python Tip #50: The datetime.timedelta Class

The timedelta class from Python's datetime module represents a duration or difference between two dates or times.

It makes it easy to perform date and time arithmetic.

---

Importing timedelta

from datetime import datetime, timedelta

---

Adding Days

from datetime import datetime, timedelta

today = datetime.now()

future = today + timedelta(days=7)

print(future)

Output:

2026-07-15 14:30:15.123456

(The output depends on the current date and time.)

---

Subtracting Days

from datetime import datetime, timedelta

today = datetime.now()

past = today - timedelta(days=30)

print(past)

This returns the date 30 days before today.

---

Adding Hours and Minutes

from datetime import datetime, timedelta

now = datetime.now()

later = now + timedelta(hours=2, minutes=30)

print(later)

This calculates the date and time 2 hours and 30 minutes from now.

---

Finding the Difference Between Dates

from datetime import datetime

date1 = datetime(2026, 7, 1)
date2 = datetime(2026, 7, 15)

difference = date2 - date1

print(difference)
print(difference.days)

Output:

14 days, 0:00:00
14

The result is a timedelta object representing the time difference.

---

Why use timedelta?

βœ“ Easily add or subtract dates and times
βœ“ Calculate the difference between two dates
βœ“ Supports days, hours, minutes, seconds, and weeks
βœ“ Commonly used in scheduling, reminders, logging, and automation

---

Challenge:

Create a program that:

1. Gets today's date.
2. Calculates the date 100 days from today.
3. Prints both dates.
4. Displays the number of days between them.
Python coding
πŸš€ Python Tip #50: The datetime.timedelta Class The timedelta class from Python's datetime module represents a duration or difference between two dates or times. It makes it easy to perform date and time arithmetic. --- Importing timedelta from datetime…
πŸ’‘ Python Tip #51: The uuid Module

The uuid module generates Universally Unique Identifiers (UUIDs).

UUIDs are commonly used to create unique IDs for users, orders, files, API keys, and database records.

---

Importing uuid

import uuid

---

Generating a Random UUID

import uuid

unique_id = uuid.uuid4()

print(unique_id)

Example Output:

550e8400-e29b-41d4-a716-446655440000

Your output will be different every time because each UUID is randomly generated.

---

Converting a UUID to a String

import uuid

unique_id = uuid.uuid4()

print(str(unique_id))

Output:

550e8400-e29b-41d4-a716-446655440000

This is useful when storing UUIDs in databases or sending them through APIs.

---

Generating Multiple UUIDs

import uuid

for _ in range(3):
print(uuid.uuid4())

Example Output:

9b1deb4d-3b7d-4f47-bc2b-4e7f5f36c91e
b87d6b11-5c61-4e2a-a93e-91b7ef9d82a3
7db3d59f-0ec4-4b5e-8f5f-cd28bca1e75f

Each generated UUID is unique.

---

Using UUIDs as Dictionary Keys

import uuid

users = {}

user_id = uuid.uuid4()

users[user_id] = "Yehya"

print(users)

Output:

{
UUID('550e8400-e29b-41d4-a716-446655440000'): 'Yehya'
}

---

Why use uuid?

βœ“ Generates globally unique identifiers
βœ“ Prevents ID collisions
βœ“ No need for auto-incrementing numbers
βœ“ Commonly used in web development, databases, distributed systems, and REST APIs

---

Challenge:

Create a program that:

1. Generates 5 random UUIDs.
2. Stores them in a list.
3. Prints each UUID on a separate line.
4. Verifies that all generated UUIDs are unique.
Python coding
πŸ’‘ Python Tip #51: The uuid Module The uuid module generates Universally Unique Identifiers (UUIDs). UUIDs are commonly used to create unique IDs for users, orders, files, API keys, and database records. --- Importing uuid import uuid --- Generating a…
πŸš€ Python Tip #52: The enum.Enum Class

The Enum class from Python's enum module allows you to create a set of named constant values.

Enums make your code more readable, safer, and easier to maintain.

---

Importing Enum

from enum import Enum

---

Creating an Enum

from enum import Enum

class Status(Enum):
PENDING = 1
RUNNING = 2
COMPLETED = 3

print(Status.PENDING)

Output:

Status.PENDING

---

Accessing the Name and Value

from enum import Enum

class Status(Enum):
PENDING = 1
RUNNING = 2
COMPLETED = 3

print(Status.RUNNING.name)
print(Status.RUNNING.value)

Output:

RUNNING
2

---

Comparing Enum Members

from enum import Enum

class Color(Enum):
RED = 1
GREEN = 2
BLUE = 3

if Color.RED == Color.RED:
print("They are equal.")

Output:

They are equal.

Enums should be compared with other enum members, not with integers.

---

Looping Through an Enum

from enum import Enum

class Day(Enum):
MONDAY = 1
TUESDAY = 2
WEDNESDAY = 3

for day in Day:
print(day.name, day.value)

Output:

MONDAY 1
TUESDAY 2
WEDNESDAY 3

---

Why use Enum?

βœ“ Makes code more readable
βœ“ Replaces "magic numbers" with meaningful names
βœ“ Prevents invalid constant values
βœ“ Commonly used for application states, user roles, HTTP status codes, and configuration options

---

Challenge:

Create an enum named:

TrafficLight

with the following members:

RED = 1
YELLOW = 2
GREEN = 3

Then:

1. Print the name and value of GREEN.
2. Loop through all members and print their names and values.
Python coding
πŸš€ Python Tip #52: The enum.Enum Class The Enum class from Python's enum module allows you to create a set of named constant values. Enums make your code more readable, safer, and easier to maintain. --- Importing Enum from enum import Enum --- Creating…
🐍 Python Tip #53: The secrets Module

The secrets module is designed for generating cryptographically secure random numbers, tokens, and passwords.

Unlike the random module, secrets should be used for security-related tasks.

---

Importing secrets

import secrets

---

Generating a Secure Random Number

import secrets

number = secrets.randbelow(100)

print(number)

Output:

42

The output will be a secure random integer between 0 and 99.

---

Choosing a Random Item

import secrets

colors = ["Red", "Green", "Blue", "Black"]

choice = secrets.choice(colors)

print(choice)

Output:

Green

A random item is selected securely.

---

Generating a Secure Token

import secrets

token = secrets.token_hex(16)

print(token)

Example Output:

9f8d7c2b1a4e5f6d8c9b0a1d2e3f4a5b

This creates a secure hexadecimal token with 16 random bytes.

---

Generating a Strong Password

import secrets
import string

characters = string.ascii_letters + string.digits + string.punctuation

password = "".join(
secrets.choice(characters)
for _ in range(12)
)

print(password)

Example Output:

A#7mP!2xQ9@k

A different password will be generated each time.

---

Why use secrets?

βœ“ Generates cryptographically secure random values
βœ“ More secure than the random module for sensitive data
βœ“ Ideal for passwords, API keys, authentication tokens, and session IDs
βœ“ Recommended for security-related applications

---

Challenge:

Create a program that:

1. Generates a secure password with 16 characters.
2. The password should contain:
- Uppercase letters
- Lowercase letters
- Numbers
- Special characters
3. Print the generated password.
Python coding
🐍 Python Tip #53: The secrets Module The secrets module is designed for generating cryptographically secure random numbers, tokens, and passwords. Unlike the random module, secrets should be used for security-related tasks. --- Importing secrets import…
πŸš€ Python Tip #54: The dataclasses Module

The dataclasses module helps you create classes that mainly store data without writing repetitive boilerplate code.

It automatically generates methods such as __init__(), __repr__(), and __eq__().

---

Importing dataclass

from dataclasses import dataclass

---

Creating a Data Class

from dataclasses import dataclass

@dataclass
class Student:
name: str
age: int
grade: str

student = Student("Ali", 18, "A")

print(student)

Output:

Student(name='Ali', age=18, grade='A')

Notice that Python automatically created the constructor and the string representation.

---

Accessing Attributes

from dataclasses import dataclass

@dataclass
class Student:
name: str
age: int

student = Student("Yehya", 16)

print(student.name)
print(student.age)

Output:

Yehya
16

---

Comparing Objects

Data classes automatically support equality comparison.

from dataclasses import dataclass

@dataclass
class Book:
title: str
pages: int

book1 = Book("Python", 300)
book2 = Book("Python", 300)

print(book1 == book2)

Output:

True

---

Using Default Values

from dataclasses import dataclass

@dataclass
class User:
name: str
country: str = "Ethiopia"

user = User("Yehya")

print(user)

Output:

User(name='Yehya', country='Ethiopia')

If no country is provided, "Ethiopia" is used by default.

---

Why use dataclasses?

βœ“ Eliminates repetitive boilerplate code
βœ“ Automatically generates constructors and other useful methods
βœ“ Improves code readability and maintainability
βœ“ Commonly used in APIs, configuration objects, and data models

---

Challenge:

Create a data class named:

Car

with the following fields:

brand
model
year

Then:

1. Create two identical Car objects.
2. Print one of them.
3. Check whether the two objects are equal.
Python coding
πŸš€ Python Tip #54: The dataclasses Module The dataclasses module helps you create classes that mainly store data without writing repetitive boilerplate code. It automatically generates methods such as __init__(), __repr__(), and __eq__(). --- Importing…
πŸ’‘ Python Tip #55: The pathlib Module

The pathlib module provides an object-oriented way to work with files and directories.

It is the modern replacement for using os.path in Python.

---

Importing Path

from pathlib import Path

---

Creating a Path Object

from pathlib import Path

file = Path("example.txt")

print(file)

Output:

example.txt

---

Checking if a File Exists

from pathlib import Path

file = Path("example.txt")

print(file.exists())

Output:

True

or

```python
False

depending on whether the file exists.

---

Getting File Information

python
from pathlib import Path

file = Path("report.pdf")

print(file.name)
print(file.stem)
print(file.suffix)

Output:

python
report.pdf
report
.pdf

- `name` returns the full filename.
- `stem` returns the filename without the extension.
- `suffix` returns the file extension.

---

Creating a Directory

python
from pathlib import Path

folder = Path("Projects")

folder.mkdir(exist_ok=True)

print("Folder created.")

The `exist_ok=True` argument prevents an error if the folder already exists.

---

Listing Files in a Directory

python
from pathlib import Path

folder = Path(".")

for file in folder.iterdir():
print(file)

This prints every file and folder in the current directory.

---

Why use `pathlib`?

βœ“ Modern and easy-to-read syntax
βœ“ Works across Windows, macOS, and Linux
βœ“ Simplifies file and directory operations
βœ“ Commonly used in automation, scripting, web development, and data science

---

Challenge:

Create a program that:

1. Creates a folder named:

python
PythonProjects

2. Creates a `Path` object for a file named:

python
notes.txt
`

inside that folder.

3. Print:

- The full path
- The file name
- The file extension
Python coding
πŸ’‘ Python Tip #55: The pathlib Module The pathlib module provides an object-oriented way to work with files and directories. It is the modern replacement for using os.path in Python. --- Importing Path from pathlib import Path --- Creating a Path Object…
πŸš€ Python Tip #56: The logging Module

The logging module provides a flexible way to record messages while your program is running.

Unlike print(), logging allows you to categorize messages by importance and save them to files.

---

Importing logging

import logging

---

Basic Logging

import logging

logging.basicConfig(level=logging.INFO)

logging.info("Program started.")

Output:

INFO:root:Program started.

---

Logging Levels

Python provides several logging levels.

import logging

logging.basicConfig(level=logging.DEBUG)

logging.debug("Debug message")
logging.info("Information message")
logging.warning("Warning message")
logging.error("Error message")
logging.critical("Critical error")

Output:

DEBUG:root:Debug message
INFO:root:Information message
WARNING:root:Warning message
ERROR:root:Error message
CRITICAL:root:Critical error

---

Logging to a File

Instead of displaying messages in the terminal, you can save them to a file.

import logging

logging.basicConfig(
filename="app.log",
level=logging.INFO
)

logging.info("Application started.")
logging.warning("Low disk space.")

A file named app.log will be created containing the log messages.

---

Formatting Log Messages

import logging

logging.basicConfig(
level=logging.INFO,
format="%(asctime)s - %(levelname)s - %(message)s"
)

logging.info("User logged in.")

Example Output:

2026-07-22 10:15:30 - INFO - User logged in.

---

Why use logging?

βœ“ Better than using print() for debugging
βœ“ Supports different log levels
βœ“ Can save logs to files automatically
βœ“ Essential for professional applications, APIs, and server programs

---

Challenge:

Create a program that:

1. Configures logging to save messages to a file named:

program.log

2. Logs the following messages:

INFO: Program started
WARNING: Low memory
ERROR: File not found

3. Open the log file and verify that all three messages were saved.
Python coding
πŸš€ Python Tip #56: The logging Module The logging module provides a flexible way to record messages while your program is running. Unlike print(), logging allows you to categorize messages by importance and save them to files. --- Importing logging import…
🐍 Python Tip #57: The argparse Module

The argparse module allows your Python programs to accept command-line arguments.

It is commonly used to build professional command-line applications and automation scripts.

---

Importing argparse

import argparse

---

Basic Example

import argparse

parser = argparse.ArgumentParser()

parser.add_argument("name")

args = parser.parse_args()

print(f"Hello, {args.name}!")

Running the program:

python app.py Yehya

Output:

Hello, Yehya!

---

Adding Optional Arguments

Optional arguments start with --.

import argparse

parser = argparse.ArgumentParser()

parser.add_argument("--age", type=int)

args = parser.parse_args()

print(args.age)

Run:

```bash
python app.py --age 16

Output:

python
16

---

Providing Default Values

python
import argparse

parser = argparse.ArgumentParser()

parser.add_argument("--country", default="Ethiopia")

args = parser.parse_args()

print(args.country)

Run:

bash
python app.py

Output:

python
Ethiopia

---

Displaying Help

`argparse` automatically generates a help message.

python
import argparse

parser = argparse.ArgumentParser(
description="Simple Calculator"
)

parser.add_argument("--num", type=int)

parser.parse_args()

Run:

bash
python app.py --help

Example Output:

text
usage: app.py [-h] [--num NUM]

Simple Calculator

options:
-h, --help Show this help message and exit
--num NUM Enter a number

---

Why use `argparse`?

βœ“ Makes command-line programs easy to use
βœ“ Automatically validates user input
βœ“ Generates built-in help messages
βœ“ Widely used in automation, DevOps, and professional Python tools

---

Challenge:

Create a program that accepts the following command-line arguments:

text
--name
--age
--country

Then print the information in this format:

text
Name: Yehya
Age: 16
Country: Ethiopia
`

If `--country` is not provided, use `"Unknown"` as the default value.