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
The
It is useful when you need a constant value in loops, function calls, or data generation.
---
Importing
---
Basic Example
Output:
The string
---
Creating a List
Output:
---
Using
Suppose you want to multiply every number by 2.
Output:
Here, `repeat(2)
from itertools import repeat
counter = repeat("Hello")
for _ in range(3):
print(next(counter))
python
Hello
Hello
Hello
python
"AI"
python
['AI', 'AI', 'AI', 'AI', 'AI', 'AI', 'AI', 'AI']
itertools.repeat() FunctionThe
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
repeatfrom 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.
``pythonfrom 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
The
Once the condition becomes
---
Importing
---
Basic Example
Output:
The iteration stops when it reaches
---
Using a Numeric Condition
Output:
Although
---
Working with Strings
Output:
The iteration stops when
---
Important Note
It dnotot** continue searching the remaining elements.
---
Why use
β 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:
Use `itertools.takewhile()
[18, 20, 22, 24]
itertools.takewhile() FunctionThe
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
takewhilefrom 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
The
Once the condition becomes
---
Importing
---
Basic Example
Output:
The even numbers at the beginning are skipped. Once
---
Using a Numeric Condition
Output:
The function skips numbers less than
---
Working with Strings
Output:
The words starting with
---
Output:
- `takewhile()
scores = [45, 50, 55, 60, 72, 80, 90]
python
[72, 80, 90]
itertools.dropwhile() FunctionThe
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
dropwhilefrom 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:
``pythonscores = [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
The
This is useful when you need to iterate over the same data more than once without recreating it.
---
Importing
---
Basic Example
Output:
Both iterators contain the same data.
---
Working with Generators
Output:
Without
---
Creating More Than Two Iterators
You can create as many independent iterators as needed.
Output:
Each iterator maintains its own position independently.
---
Why use
β 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
Use
- Use the first iterator to print all the numbers.
- Use the second iterator to print only the first five numbers.
itertools.tee() FunctionThe
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
teefrom 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
The
Missing values are filled with a specified value (or
---
Importing
---
Basic Example
Output:
Since `scores
from itertools import zip_longest
names = ["Ali", "Sara", "John"]
scores = [90, 85]
result = list(zip_longest(names, scores, fillvalue="N/A"))
print(result)
python
[
('Ali', 90),
('Sara', 85),
('John', 'N/A')
]
python
from itertools import zip_longest
list1 = [1, 2, 3]
list2 = ["A", "B"]
print(list(zip(list1, list2)))
print(list(zip_longest(list1, list2)))
python
[(1, 'A'), (2, 'B')]
[(1, 'A'),
(2, 'B'),
(3, None)]
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)
python
Laptop 1200
Phone 800
Tablet Unknown
python
students = [
"Ali",
"Sara",
"John",
"Mariam"
]
grades = [
"A",
"B"
]
python
fillvalue = "Not Graded"
python
[
('Ali', 'A'),
('Sara', 'B'),
('John', 'Not Graded'),
('Mariam', 'Not Graded')
]
itertools.zip_longest() FunctionThe
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_longestfrom 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.
``pythonfrom 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
The
It automatically creates a dictionary where the keys are the unique elements and the values are their counts.
---
Importing
---
Basic Example
Output:
---
Counting Characters
Output:
---
Finding the Most Common Items
Use the
Output:
This returns the two most common elements and their frequencies.
---
Counting Words
Output:
---
Why use
β 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:
Use `collections.Counter
most_common(1)
collections.Counter ClassThe
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
Counterfrom 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:
``pythonmost_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
The
It makes it easier to create custom dictionary classes by allowing you to override dictionary behavior.
---
Importing
---
Basic Example
Output:
---
Customizing Dictionary Behavior
Suppose you want all keys to be stored in lowercase.
Output:
---
Validating Values
You can also validate data before storing it.
Output:
Trying to store a negative number:
Output:
---
Why use
β 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:
using `UserDict
data["name"] = "Yehya"
data["city"] = "Addis Ababa"
python
{'NAME': 'Yehya', 'CITY': 'Addis Ababa'}
collections.UserDict ClassThe
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
UserDictfrom 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:
``pythondata["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
The
It makes it easier to create custom list classes with your own behavior.
---
Importing
---
Basic Example
Output:
---
Customizing List Behavior
Suppose you want every string added to the list to be stored in uppercase.
Output:
---
Validating Items
You can prevent invalid data from being added.
Output:
Trying to add a negative number:
Output:
---
Why use
β 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:
using `UserList
numbers.append(2)
numbers.append(8)
numbers.append(5)
python
ValueError: Only even numbers are allowed.
collections.UserList ClassThe
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
UserListfrom 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:
``pythonnumbers.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
The
It allows you to create custom string classes and modify string behavior while keeping all standard string features.
---
Importing
---
Basic Example
Output:
---
Customizing String Behavior
Suppose you want every string to be stored in uppercase.
Output:
---
Validating Input
You can validate data before creating the string.
Output:
Trying to create:
Output:
---
Why use
β 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:
using `UserString
text = TitleString("welcome to python programming")
print(text)
python
Welcome To Python Programming
collections.UserString ClassThe
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
UserStringfrom 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:
``pythontext = 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
Floating-point numbers can sometimes produce unexpected results due to precision limitations.
Python's
---
Importing
---
Basic Example
Output:
---
Adding Fractions
Output:
---
Creating Fractions from Floats
Output:
You can also limit the denominator.
Output:
---
Arithmetic Operations
Output:
---
Why use
β 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:
Then calculate:
- Their sum
- Their difference
- Their product
- Their quotient
Print each result as a fraction.
fractions.Fraction ClassFloating-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
Fractionfrom 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
Floating-point numbers are not always exact. This can lead to small rounding errors, especially in financial and scientific calculations.
Python's
---
Importing
---
The Floating-Point Problem
Output:
This happens because floating-point numbers are stored in binary.
---
Using
Output:
The calculation is exact.
---
Performing Arithmetic
Output:
---
Rounding Decimals
Use the
Output:
---
Why use
β 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
Then round the final result to 2 decimal places using
decimal.Decimal ClassFloating-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
Decimalfrom 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
Decimalfrom 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
Working with dates and times is a common task in Python.
The
---
Importing
---
Getting the Current Date and Time
Output:
(The output will depend on the current date and time.)
---
Getting Individual Components
Example Output:
---
Formatting Dates
Use the
Example Output:
---
Creating a Specific Date
Output:
---
Why use
β 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
Then print it in the following format:
using the
datetime ModuleWorking 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
datetimefrom 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
The
It makes it easy to perform date and time arithmetic.
---
Importing
---
Adding Days
Output:
(The output depends on the current date and time.)
---
Subtracting Days
This returns the date 30 days before today.
---
Adding Hours and Minutes
This calculates the date and time 2 hours and 30 minutes from now.
---
Finding the Difference Between Dates
Output:
The result is a
---
Why use
β 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.
datetime.timedelta ClassThe
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
timedeltafrom 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
The
UUIDs are commonly used to create unique IDs for users, orders, files, API keys, and database records.
---
Importing
---
Generating a Random UUID
Example Output:
Your output will be different every time because each UUID is randomly generated.
---
Converting a UUID to a String
Output:
This is useful when storing UUIDs in databases or sending them through APIs.
---
Generating Multiple UUIDs
Example Output:
Each generated UUID is unique.
---
Using UUIDs as Dictionary Keys
Output:
---
Why use
β 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.
uuid ModuleThe
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
uuidimport 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
The
Enums make your code more readable, safer, and easier to maintain.
---
Importing
---
Creating an Enum
Output:
---
Accessing the Name and Value
Output:
---
Comparing Enum Members
Output:
Enums should be compared with other enum members, not with integers.
---
Looping Through an Enum
Output:
---
Why use
β 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:
with the following members:
Then:
1. Print the name and value of
2. Loop through all members and print their names and values.
enum.Enum ClassThe
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
Enumfrom 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
The
Unlike the
---
Importing
---
Generating a Secure Random Number
Output:
The output will be a secure random integer between
---
Choosing a Random Item
Output:
A random item is selected securely.
---
Generating a Secure Token
Example Output:
This creates a secure hexadecimal token with 16 random bytes.
---
Generating a Strong Password
Example Output:
A different password will be generated each time.
---
Why use
β Generates cryptographically secure random values
β More secure than the
β 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.
secrets ModuleThe
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
secretsimport 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
The
It automatically generates methods such as
---
Importing
---
Creating a Data Class
Output:
Notice that Python automatically created the constructor and the string representation.
---
Accessing Attributes
Output:
---
Comparing Objects
Data classes automatically support equality comparison.
Output:
---
Using Default Values
Output:
If no country is provided,
---
Why use
β 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:
with the following fields:
Then:
1. Create two identical
2. Print one of them.
3. Check whether the two objects are equal.
dataclasses ModuleThe
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
dataclassfrom 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
The
It is the modern replacement for using
---
Importing
---
Creating a Path Object
Output:
---
Checking if a File Exists
Output:
or
```python
False
python
from pathlib import Path
file = Path("report.pdf")
print(file.name)
print(file.stem)
print(file.suffix)
python
report.pdf
report
.pdf
python
from pathlib import Path
folder = Path("Projects")
folder.mkdir(exist_ok=True)
print("Folder created.")
python
from pathlib import Path
folder = Path(".")
for file in folder.iterdir():
print(file)
python
PythonProjects
python
notes.txt
inside that folder.
3. Print:
- The full path
- The file name
- The file extension
pathlib ModuleThe
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
Pathfrom 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
- `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
The
Unlike
---
Importing
---
Basic Logging
Output:
---
Logging Levels
Python provides several logging levels.
Output:
---
Logging to a File
Instead of displaying messages in the terminal, you can save them to a file.
A file named
---
Formatting Log Messages
Example Output:
---
Why use
β Better than using
β 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:
2. Logs the following messages:
3. Open the log file and verify that all three messages were saved.
logging ModuleThe
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
loggingimport 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
The
It is commonly used to build professional command-line applications and automation scripts.
---
Importing
---
Basic Example
Running the program:
Output:
---
Adding Optional Arguments
Optional arguments start with
Run:
```bash
python app.py --age 16
python
16
python
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("--country", default="Ethiopia")
args = parser.parse_args()
print(args.country)
bash
python app.py
python
Ethiopia
python
import argparse
parser = argparse.ArgumentParser(
description="Simple Calculator"
)
parser.add_argument("--num", type=int)
parser.parse_args()
bash
python app.py --help
text
usage: app.py [-h] [--num NUM]
Simple Calculator
options:
-h, --help Show this help message and exit
--num NUM Enter a number
text
--name
--age
--country
text
Name: Yehya
Age: 16
Country: Ethiopia
If `--country` is not provided, use `"Unknown"` as the default value.
argparse ModuleThe
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
argparseimport 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.