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 #31: The functools.partial() Function Sometimes you repeatedly call a function with the same arguments. Python's partial() function allows you to "freeze" some arguments, creating a new function with predefined values. --- Importing partial…
πŸš€ Python Tip #32: The collections.OrderedDict Class

Although modern Python dictionaries preserve insertion order, the OrderedDict class provides additional features for working with ordered data.

It is available in the collections module.

---

Importing OrderedDict

from collections import OrderedDict

---

Creating an OrderedDict

from collections import OrderedDict

student = OrderedDict()

student["name"] = "Ali"
student["age"] = 18
student["grade"] = "A"

print(student)

Output:

OrderedDict([
('name', 'Ali'),
('age', 18),
('grade', 'A')
])

---

Moving an Item

You can move an existing key to the beginning or end of the dictionary.

from collections import OrderedDict

student = OrderedDict([
("name", "Ali"),
("age", 18),
("grade", "A")
])

student.move_to_end("name")

print(student)

Output:

OrderedDict([
('age', 18),
('grade', 'A'),
('name', 'Ali')
])

---

Removing the First or Last Item

The popitem() method removes items in order.

from collections import OrderedDict

student = OrderedDict([
("name", "Ali"),
("age", 18),
("grade", "A")
])

student.popitem(last=False)

print(student)

Output:

OrderedDict([
('age', 18),
('grade', 'A')
])

Using `last=False removes the first item.

---

When Should You Use
OrderedDict?

While the built-in
dict preserves insertion order in Python 3.7+, OrderedDict is still useful when you need methods like:

-
move_to_end()
-
popitem(last=False)

These features are not available with a regular dictionary.

---

Why use
OrderedDict?

βœ“ Maintains insertion order
βœ“ Easily reorder dictionary items
βœ“ Supports advanced ordering operations
βœ“ Useful for caches, queues, and ordered data processing

---

Challenge:

Create an
OrderedDict containing the following items:

``
python
{
"A": 10,
"B": 20,
"C": 30,
"D": 40
}
`

Then:

1. Move `"B"` to the end.
2. Remove the first item.
3. Print the final `OrderedDict`.
Python coding
πŸš€ Python Tip #32: The collections.OrderedDict Class Although modern Python dictionaries preserve insertion order, the OrderedDict class provides additional features for working with ordered data. It is available in the collections module. --- Importing…
🐍 Python Tip #33: The itertools.islice() Function

When working with large iterables, you may only need a portion of the data.

Python's itertools.islice() lets you slice any iterable without converting it into a list first.

---

Importing islice

from itertools import islice

---

Basic Example

from itertools import islice

numbers = range(1, 11)

result = list(islice(numbers, 5))

print(result)

Output:

[1, 2, 3, 4, 5]

---

Specifying a Start and Stop

from itertools import islice

numbers = range(1, 11)

result = list(islice(numbers, 2, 7))

print(result)

Output:

[3, 4, 5, 6, 7]

---

Using a Step

Just like normal slicing, you can specify a step value.

from itertools import islice

numbers = range(1, 21)

result = list(islice(numbers, 0, 20, 3))

print(result)

Output:

[1, 4, 7, 10, 13, 16, 19]

---

Why Use islice()?

Unlike normal list slicing, islice() works directly on iterators and generators without loading everything into memory.

Example:

from itertools import islice

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

print(list(islice(squares, 5)))

Output:

[0, 1, 4, 9, 16]

Only the required values are generated.

---

Why use itertools.islice()?

βœ“ Memory efficient
βœ“ Works with generators and iterators
βœ“ Supports start, stop, and step values
βœ“ Commonly used in data processing and large datasets

---

Challenge:

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

Then use islice() to print only:

11, 12, 13, 14, 15

without converting the entire generator into a list.
Python coding
🐍 Python Tip #33: The itertools.islice() Function When working with large iterables, you may only need a portion of the data. Python's itertools.islice() lets you slice any iterable without converting it into a list first. --- Importing islice from itertools…
⚑ Python Tip #34: The itertools.chain() Function

The chain() function from Python's itertools module allows you to combine multiple iterables into a single iterator.

It is a memory-efficient alternative to concatenating lists.

---

Importing chain

from itertools import chain

---

Basic Example

from itertools import chain

list1 = [1, 2, 3]
list2 = [4, 5, 6]

result = chain(list1, list2)

print(list(result))

Output:

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

---

Combining Multiple Iterables

from itertools import chain

letters = ["A", "B"]
numbers = [1, 2]
symbols = ["@", "#"]

result = chain(letters, numbers, symbols)

print(list(result))

Output:

['A', 'B', 1, 2, '@', '#']

---

Using chain.from_iterable()

If your iterables are stored inside another iterable, use from_iterable().

from itertools import chain

data = [
[1, 2],
[3, 4],
[5, 6]
]

result = chain.from_iterable(data)

print(list(result))

Output:

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

---

Why Use chain()?

Without chain():

list1 = [1, 2, 3]
list2 = [4, 5, 6]

result = list1 + list2

print(result)

With `chain():

``
python
from itertools import chain

result = chain(list1, list2)

print(list(result))

`chain()` avoids creating unnecessary intermediate lists, making it more memory efficient.

---

Why use `itertools.chain()`?

βœ“ Combines multiple iterables easily
βœ“ Memory efficient
βœ“ Works with lists, tuples, sets, generators, and more
βœ“ Commonly used in data processing and ETL pipelines

---

Challenge:

Given the following iterables:

python
fruits = ["Apple", "Banana"]
vegetables = ["Carrot", "Tomato"]
drinks = ["Water", "Juice"]
`

Use `itertools.chain()` to combine them into a single iterable and print all the items.
Python coding
⚑ Python Tip #34: The itertools.chain() Function The chain() function from Python's itertools module allows you to combine multiple iterables into a single iterator. It is a memory-efficient alternative to concatenating lists. --- Importing chain from…
πŸš€ Python Tip #35: The itertools.compress() Function

The compress() function from Python's itertools module filters data using a sequence of selectors.

It returns only the items whose corresponding selector is True.

---

Importing compress

from itertools import compress

---

Basic Example

from itertools import compress

letters = ["A", "B", "C", "D"]
selectors = [True, False, True, False]

result = list(compress(letters, selectors))

print(result)

Output:

['A', 'C']

Only the elements with a corresponding True value are returned.

---

Filtering Numbers

from itertools import compress

numbers = [10, 20, 30, 40, 50]
selectors = [0, 1, 0, 1, 1]

result = list(compress(numbers, selectors))

print(result)

Output:

[20, 40, 50]

In Python, 1 is treated as True and 0 as False.

---

Practical Example

Suppose you have a list of students and a list indicating who passed.

from itertools import compress

students = ["Ali", "Sara", "John", "Mariam"]
passed = [True, False, True, True]

successful = list(compress(students, passed))

print(successful)

Output:

['Ali', 'John', 'Mariam']

---

Why use compress()?

βœ“ Simple way to filter data
βœ“ Cleaner than writing manual loops
βœ“ Memory efficient
βœ“ Useful in data analysis, machine learning, and data preprocessing

---

Challenge:

Given the following lists:

products = [
"Laptop",
"Phone",
"Tablet",
"Monitor"
]

available = [
True,
False,
True,
True
]

Use `itertools.compress()` to create a list containing only the available products.
Python coding
πŸš€ Python Tip #35: The itertools.compress() Function The compress() function from Python's itertools module filters data using a sequence of selectors. It returns only the items whose corresponding selector is True. --- Importing compress from itertools…
πŸ’‘ Python Tip #36: The itertools.accumulate() Function

The accumulate() function from Python's itertools module returns cumulative results as it processes an iterable.

It is useful for calculating running totals, cumulative products, and other progressive operations.

---

Importing accumulate

from itertools import accumulate

---

Basic Example

from itertools import accumulate

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

result = list(accumulate(numbers))

print(result)

Output:

[1, 3, 6, 10, 15]

Each value is the sum of all previous values.

---

Using Multiplication

You can change the operation by providing a function.

from itertools import accumulate
import operator

numbers = [1, 2, 3, 4]

result = list(accumulate(numbers, operator.mul))

print(result)

Output:

[1, 2, 6, 24]

---

Practical Example

Calculate a running bank balance.

from itertools import accumulate

transactions = [1000, -200, 500, -150, 300]

balance = list(accumulate(transactions))

print(balance)

Output:

[1000, 800, 1300, 1150, 1450]

Each value represents the account balance after each transaction.

---

Why use accumulate()?

βœ“ Calculates running totals automatically
βœ“ Supports custom operations like multiplication and maximum
βœ“ Eliminates manual loops
βœ“ Commonly used in finance, statistics, and data analysis

---

Challenge:

Given the following daily sales:

sales = [120, 180, 150, 200, 170]

Use `itertools.accumulate() to calculate the cumulative sales after each day.

Expected Output:

``
python
[120, 300, 450, 650, 820]
`
Python coding
πŸ’‘ Python Tip #36: The itertools.accumulate() Function The accumulate() function from Python's itertools module returns cumulative results as it processes an iterable. It is useful for calculating running totals, cumulative products, and other progressive…
🐍 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.

---

Importing cycle

from itertools import cycle

---

Basic Example

from itertools import cycle

colors = cycle(["Red", "Green", "Blue"])

for _ in range(8):
print(next(colors))

Output:

Red
Green
Blue
Red
Green
Blue
Red
Green

The sequence repeats automatically.

---

Using next()

The next() function retrieves the next item from the iterator.

from itertools import cycle

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

print(next(numbers))
print(next(numbers))
print(next(numbers))
print(next(numbers))

Output:

1
2
3
1

After reaching the last item, cycle() starts again from the beginning.

---

Practical Example

Rotate through a list of servers.

from itertools import cycle

servers = cycle([
"Server A",
"Server B",
"Server C"
])

for _ in range(6):
print(next(servers))

Output:

Server A
Server B
Server C
Server A
Server B
Server C

This technique is commonly used for round-robin scheduling.

---

Why use cycle()?

βœ“ Repeats items automatically
βœ“ Eliminates manual index management
βœ“ Memory efficient
βœ“ Useful for animations, scheduling, simulations, and game development

---

Challenge:

Given the following list:

traffic_lights = [
"Red",
"Yellow",
"Green"
]

Use `itertools.cycle()` to print the traffic light sequence 10 times.
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.