Python Cookbook (2024)
Python Cookbook (2024)
Thank you for trusting our Publishing House. If you could evaluate
our work and give us a review on Amazon, we will appreciate it
very much!
Scan this code to leave an honest review:
Or go to:
https://www.amazon.com/review/create-review/?
ie=UTF8&channel=glance-detail&asin=B0D4L6V11S
Thanks (again!)
def http_status_code_message(status_code):
match status_code:
case 200:
return "OK"
case 404:
return "Not Found"
case 500:
return "Internal Server Error"
case _:
return "Unknown Status Code"
print(http_status_code_message(200)) # OK
print(http_status_code_message(404)) # Not Found
print(http_status_code_message(123)) # Unknown Status Code
print function
# Python 2 example
print "Hello, World!" # Hello, World!
print "The answer is", 42 # The answer is 42
# Using a trailing comma to avoid a newline at the end
print "Hello,",
print "World!" # Hello, World!
# Python 3 example
print("Hello, World!") # Hello, World!
print("The answer is", 42) # The answer is 42
# To avoid a newline at the end, use the end parameter
print("Hello,", end=" ")
print("World!") # Hello, World!
range function
# Python 2 example using range
numbers = range(1, 10)
print numbers # [1, 2, 3, 4, 5, 6, 7, 8, 9]
# Python 2 example using xrange
numbers = xrange(1, 10)
print numbers # xrange(1, 10)
print list(numbers) # [1, 2, 3, 4, 5, 6, 7, 8, 9]
# Python 3 example using range
numbers = range(1, 10)
print(numbers) # range(1, 10)
print(list(numbers)) # [1, 2, 3, 4, 5, 6, 7, 8, 9]
Classes
In object-oriented programming, classes are fundamental building
blocks that define the blueprint for objects. A class encapsulates
data for the object and methods to manipulate that data, promoting
modularity and code reuse.
Check for reference equality
class MyClass:
def __init__(self, value):
self.value = value
# Create two instances of MyClass
obj1 = MyClass(10)
obj2 = MyClass(10)
obj3 = obj1
# Check for reference equality using id()
print(id(obj1) == id(obj2))
# False, different objects in memory
print(id(obj1) == id(obj3))
# True, same object in memory
Constructors:
Call of the own constructor
class Person:
def __init__(self, first_name, last_name, age):
self.first_name = first_name
self.last_name = last_name
self.age = age
@classmethod
def from_full_name(cls, full_name, age):
first_name, last_name = full_name.split()
# Call the main constructor with first name and last name
extracted from full name
return cls(first_name, last_name, age)
def display_person(self):
print(f'Name: {self.first_name} {self.last_name}, Age:
{self.age}')
# Create an instance using the main constructor
person1 = Person("John", "Doe", 30)
person1.display_person()
# Output: Name: John Doe, Age: 30
# Create an instance using the alternative constructor
person2 = Person.from_full_name("Jane Smith", 25)
person2.display_person()
# Output: Name: Jane Smith, Age: 25
Call of the parent constructor
class Person:
def __init__(self, first_name, last_name, age):
self.first_name = first_name
self.last_name = last_name
self.age = age
def display_person_info(self):
print(f'Name: {self.first_name} {self.last_name}, Age:
{self.age}')
class Employee(Person):
def __init__(self, first_name, last_name, age, employee_id,
position):
# Call the parent constructor to initialize first_name,
last_name, and age
super().__init__(first_name, last_name, age)
self.employee_id = employee_id
self.position = position
def display_employee_info(self):
# Call the parent class method to display basic info
super().display_person_info()
print(f'Employee ID: {self.employee_id}, Position:
{self.position}')
# Create an instance of Person
person = Person("John", "Doe", 45)
person.display_person_info() # Output: Name: John Doe, Age: 45
# Create an instance of Employee
employee = Employee("Jane", "Smith", 30, "E123", "Software
Engineer")
employee.display_employee_info()
# Output:
# Name: Jane Smith, Age: 30
# Employee ID: E123, Position: Software Engineer
Default constructor
class Book:
def __init__(self, title="Unknown Title", author="Unknown
Author", year=0):
self.title = title
self.author = author
self.year = year
def display_info(self):
print(f'Title: {self.title}, Author: {self.author}, Year:
{self.year}')
# Create an instance using the default constructor
default_book = Book()
default_book.display_info()
# Output: Title: Unknown Title, Author: Unknown Author, Year: 0
# Create an instance with custom values
custom_book = Book("1984", "George Orwell", 1949)
custom_book.display_info()
# Output: Title: 1984, Author: George Orwell, Year: 1949
Optional parameter values
class Car:
def __init__(self, make="Unknown Make", model="Unknown
Model", year=0, color="Unknown Color"):
self.make = make
self.model = model
self.year = year
self.color = color
def display_info(self):
print(f'Make: {self.make}, Model: {self.model}, Year:
{self.year}, Color: {self.color}')
# Create an instance using the default constructor (all default
values)
default_car = Car()
default_car.display_info() # Output: Make: Unknown Make, Model:
Unknown Model, Year: 0, Color: Unknown Color
# Create an instance with some custom values
custom_car1 = Car(make="Toyota", model="Corolla")
custom_car1.display_info()
# Output: Make: Toyota, Model: Corolla, Year: 0, Color: Unknown
Color
# Create an instance with all custom values
custom_car2 = Car(make="Honda", model="Civic", year=2022,
color="Red")
custom_car2.display_info()
# Output: Make: Honda, Model: Civic, Year: 2022, Color: Red
Replacement of the parent
constructor
class Person:
def __init__(self, first_name, last_name, age):
self.first_name = first_name
self.last_name = last_name
self.age = age
def display_person_info(self):
print(f'Name: {self.first_name} {self.last_name}, Age:
{self.age}')
class Employee(Person):
def __init__(self, first_name, last_name, age, employee_id,
position):
# Call the parent constructor to initialize first_name,
last_name, and age
super().__init__(first_name, last_name, age)
# Initialize the additional attributes
self.employee_id = employee_id
self.position = position
def display_employee_info(self):
# Call the parent class method to display basic info
super().display_person_info()
print(f'Employee ID: {self.employee_id}, Position:
{self.position}')
# Create an instance of Person
person = Person("John", "Doe", 45)
person.display_person_info()
# Output: Name: John Doe, Age: 45
# Create an instance of Employee
employee = Employee("Jane", "Smith", 30, "E123", "Software
Engineer")
employee.display_employee_info()
# Output:
# Name: Jane Smith, Age: 30
# Employee ID: E123, Position: Software Engineer
With paramenters
class Rectangle:
def __init__(self, length, width):
self.length = length
self.width = width
def area(self):
return self.length * self.width
# Creating an instance of Rectangle with specific dimensions
rectangle1 = Rectangle(5, 3)
print("Area of rectangle1:", rectangle1.area())
# Output: Area of rectangle1: 15
# Creating another instance of Rectangle with different dimensions
rectangle2 = Rectangle(7, 4)
print("Area of rectangle2:", rectangle2.area())
# Output: Area of rectangle2: 28
Without any paramenters
class MyClass:
def __init__(self):
print("This is the default constructor.")
def display(self):
print("Inside MyClass.")
# Creating an instance of MyClass
obj = MyClass()
obj.display()
Create a copy of the object
import copy
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def display_info(self):
print(f'Name: {self.name}, Age: {self.age}')
# Create an instance of Person
person1 = Person("Alice", 30)
person1.display_info()
# Output: Name: Alice, Age: 30
# Create a shallow copy of person1
person2 = copy.copy(person1)
person2.display_info()
# Output: Name: Alice, Age: 30
# Modify the copy
person2.name = "Bob"
person2.display_info()
# Output: Name: Bob, Age: 30
person1.display_info()
# Output: Name: Alice, Age: 30
# Create a deep copy of person1
person3 = copy.deepcopy(person1)
person3.display_info()
# Output: Name: Alice, Age: 30
Definition and initialization
# Definition
class SomeClass:
pass
# Initialization
someClass = SomeClass()
Descriptors
class AgeDescriptor:
def __init__(self):
self._age = None
def __get__(self, instance, owner):
print("Getting age")
return self._age
def __set__(self, instance, value):
if not isinstance(value, int):
raise ValueError("Age must be an integer")
if value < 0:
raise ValueError("Age cannot be negative")
print("Setting age")
self._age = value
def __delete__(self, instance):
print("Deleting age")
self._age = None
class Person:
age = AgeDescriptor()
def __init__(self, name, age):
self.name = name
self.age = age
def display_info(self):
print(f'Name: {self.name}, Age: {self.age}')
# Create an instance of Person
person = Person("Alice", 30)
person.display_info()
# Output: Name: Alice, Age: 30
# Get the age
print(person.age)
# Output: Getting age, 30
# Set a new age
person.age = 35
# Output: Setting age
# Get the updated age
print(person.age)
# Output: Getting age, 35
# Delete the age
del person.age # Output: Deleting age
# Try to get the deleted age
print(person.age)
# Output: Getting age, None
class Circle:
def __init__(self):
self.radius = 0
@property
def area(self):
return math.pi * pow(self.radius, 2)
circle = Circle()
circle.radius = 2
# circle.area is 12.566370614359172
print(circle.area)
Read-Only properties: Stored
properties
class FilmList:
def __init__(self):
self.__count = 10
@property
def count(self):
return self.__count
filmList = FilmList()
count = filmList.count
print(count) # count is 10
Stored properties
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
# Creating an instance of Person
person = Person("Alice", 30)
# Accessing stored properties
print("Name:", person.name) # Output: Name: Alice
print("Age:", person.age) # Output: Age: 30
# Modifying stored properties
person.name = "Bob"
person.age = 25
# Displaying modified properties
print("Modified Name:", person.name)
# Output: Modified Name: Bob
print("Modified Age:", person.age)
# Output: Modified Age: 25
Type properties
class Circle:
pi = 3.14159
def __init__(self, radius):
self.radius = radius
def calculate_area(self):
return Circle.pi * self.radius ** 2
# Creating instances of Circle
circle1 = Circle(5)
circle2 = Circle(10)
# Accessing the type property
print("Value of pi:", Circle.pi) # Output: Value of pi: 3.14159
# Calculating areas using type property
print("Area of circle 1:", circle1.calculate_area())
# Output: Area of circle 1: 78.53975
print("Area of circle 2:", circle2.calculate_area())
# Output: Area of circle 2: 314.159
Subscripts (indexer methods):
With generic parameter
class MyList:
def __init__(self):
self.data = {}
def __getitem__(self, index):
return self.data[index]
def __setitem__(self, index, value):
self.data[index] = value
# Creating an instance of MyList
my_list = MyList()
# Using integer indices
my_list[0] = 'a'
my_list[1] = 'b'
print("Element at index 0:", my_list[0])
# Output: Element at index 0: a
print("Element at index 1:", my_list[1])
# Output: Element at index 1: b
# Using string keys
my_list['first'] = 10
my_list['second'] = 20
print("Element with key 'first':", my_list['first'])
# Output: Element with key 'first': 10
print("Element with key 'second':", my_list['second'])
# Output: Element with key 'second': 20
With multiple parameter
class Matrix:
def __init__(self, rows, columns):
self.rows = rows
self.columns = columns
self.data = [[0] * columns for _ in range(rows)]
def __getitem__(self, indices):
row, column = indices
return self.data[row][column]
def __setitem__(self, indices, value):
row, column = indices
self.data[row][column] = value
# Creating an instance of Matrix
matrix = Matrix(3, 3)
# Setting values using multiple indices
matrix[0, 0] = 1
matrix[1, 1] = 2
matrix[2, 2] = 3
# Getting values using multiple indices
print("Value at position (0, 0):", matrix[0, 0])
# Output: Value at position (0, 0): 1
print("Value at position (1, 1):", matrix[1, 1])
# Output: Value at position (1, 1): 2
print("Value at position (2, 2):", matrix[2, 2])
# Output: Value at position (2, 2): 3
With one parameter
class MyList:
def __init__(self, data):
self.data = data
def __getitem__(self, index):
return self.data[index]
def __setitem__(self, index, value):
self.data[index] = value
# Creating an instance of MyList
my_list = MyList([1, 2, 3, 4, 5])
# Accessing elements using single index
print("Element at index 0:", my_list[0])
# Output: Element at index 0: 1
print("Element at index 2:", my_list[2])
# Output: Element at index 2: 3
# Modifying elements using single index
my_list[1] = 10
my_list[3] = 20
print("Modified list:", my_list.data)
# Output: Modified list: [1, 10, 3, 20, 5]
Type member
class Employee:
# Class variable
company_name = "TechCorp"
employee_count = 0
def __init__(self, name, position):
self.name = name
self.position = position
Employee.employee_count += 1
# Class method
@classmethod
def set_company_name(cls, name):
cls.company_name = name
# Class method to get employee count
@classmethod
def get_employee_count(cls):
return cls.employee_count
# Accessing and modifying class variables
print("Company Name:", Employee.company_name)
# Output: Company Name: TechCorp
print("Initial Employee Count:", Employee.employee_count)
# Output: Initial Employee Count: 0
# Creating instances of Employee
emp1 = Employee("Alice", "Developer")
emp2 = Employee("Bob", "Designer")
# Accessing class variable via instance
print("Company Name (via emp1):", emp1.company_name)
# Output: Company Name (via emp1): TechCorp
print("Employee Count (via emp1):", emp1.employee_count)
# Output: Employee Count (via emp1): 2
# Using class method to set company name
Employee.set_company_name("InnoTech")
print("Updated Company Name:", Employee.company_name)
# Output: Updated Company Name: InnoTech
# Using class method to get employee count
print("Total Employees:", Employee.get_employee_count())
# Output: Total Employees: 2
Control Flow
Control flow in programming determines the order in which
instructions are executed. It encompasses decision-making, looping,
and branching mechanisms that allow a program to execute
different code paths based on conditions. Key constructs include
conditional statements (if, else if, else) for decision-making, switch
statements for handling multiple conditions, and loops (for, while,
do...while) for repeating code. Control flow also involves breaking
out of loops with "break" and skipping iterations with "continue".
These constructs are fundamental for creating dynamic and
responsive software that can adapt to various inputs and situations.
if/else statements:
Complex conditions
X = 10
Y = 20
Z = 30
if Z > X and Z > Y:
if X < Y:
print("Z is the largest and X is smaller than Y.")
else:
print("Z is the largest but X is not smaller than Y.")
else:
print("Z is not the largest.")
# Output: Z is the largest and X is smaller than Y.
Is not valid example
# Invalid example
if latitud == 0 # SyntaxError: invalid syntax
location = "Equator"
Ternary operator
n = -42
classify = "positive" if n > 0 else "negative"
print(classify) # Output: negative
Valid example
import random
def get_latitude():
return random.randint(-90, 90)
latitude = get_latitude()
location = ""
if latitude == 0:
location = "Equator"
elif latitude == 90:
location = "North Pole"
elif latitude == -90:
location = "South Pole"
else:
location = "Not at the Equator or Pole"
print(f"latitude is {latitude}")
# Example output: latitude is -57
print(f"location is \"{location}\"")
# Example output: location is "Not at the Equator or Pole"
Match statements:
Different types of values
monitor_inch_size = 24
match monitor_inch_size:
case 15:
str = "too small"
case 16 | 17 | 18:
str = "good for the past decade"
case 19 | 20 | 21 | 22 | 23:
str = "for office work"
case 24 | 25 | 26 | 27:
str = "great choice"
case _:
str = ""
print(f'str is "{str}"')
# Output: str is "great choice"
Example with a tuple
message = ("error", 404, "Not Found")
match message:
case ("error", code, description):
result = f"Error {code}: {description}"
case ("warning", description):
result = f"Warning: {description}"
case ("info", description):
result = f"Info: {description}"
case ("success", code, description):
result = f"Success {code}: {description}"
case _:
result = "Unknown message type"
print(result) # Output: Error 404: Not Found
Match if conditions
numbers = [5, -2, 0, 10, -8]
for number in numbers:
match number:
case n if n > 0:
print(f"{n} is positive")
case n if n < 0:
print(f"{n} is negative")
case 0:
print("Zero")
case _:
print("Unknown number")
Simple conditions
# Define a function to calculate the tax based on income
def calculate_tax(income):
match income:
case x if x <= 10000:
tax = x * 0.1
case x if 10000 < x <= 50000:
tax = 10000 * 0.1 + (x - 10000) * 0.2
case x if x > 50000:
tax = 10000 * 0.1 + 40000 * 0.2 + (x - 50000) * 0.3
return tax
# Test the function
print("Tax for $5000:", calculate_tax(5000))
# Tax for $5000: 500.0
print("Tax for $25000:", calculate_tax(25000))
# Tax for $25000: 4000.0
print("Tax for $75000:", calculate_tax(75000))
# Tax for $75000: 17000.0
Interruption of a control flow:
“break statement”
# Example using a while loop
number = 0
while number < 5:
print(number)
if number == 3:
break # Exit the loop when number reaches 3
number += 1
print("Loop ended")
“continue statement”
# Example using a for loop
for i in range(5):
if i == 2:
continue # Skip the rest of the loop when i is 2
print(i)
With return value
# Define a function to calculate the square of a number
def square(x):
return x ** 2 # Return the square of the input value
# Call the function and store the result in a variable
result = square(5)
# Print the result
print("Square of 5 is:", result)
With return value
# Define a function to print a message and return
def print_and_return():
print("Function execution is complete.")
return # No value is returned
# Call the function
print_and_return()
print("After function call")
Loops:
“do-while” loop
i=7
f7 = 1
while i > 1:
f7 *= i
i -= 1
print(f'f7 is {f7}')
# Output: f7 is 5040
“for in range” loop
f7 = 1
for i in range(7, 1, -1):
f7 *= i
print(f'f7 is {f7}') # Output: f7 is 5040
“for-in” loop
# Example with a list
fruits = ["apple", "banana", "cherry"]
for fruit in fruits:
print(fruit)
# apple
# banana
# cherry
“while” loop
# Initialize a counter
i=0
# Define a while loop
while i < 5:
print(i)
i += 1 # Increment the counter
#0
#1
#2
#3
#4
Endless loop
while True:
# statements
Enumerations
Enumerations, or enums, are a data type that consists of a set of
named values called elements or members. Enums are used to
represent a collection of related constants in a readable and
maintainable way. They enhance code clarity and safety by
providing meaningful names for sets of values, reducing errors from
using arbitrary numbers or strings. Enums are commonly used in
scenarios like defining states, categories, or types where a variable
can only take one out of a small set of possible values. This makes
the code more intuitive and less prone to mistakes.
Base member value
from enum import Enum
# Define an enumeration class
class Color(Enum):
RED = 1
GREEN = 2
BLUE = 3
# Access the value of an enumeration member
red_value = Color.RED.value
print("Value of RED:", red_value)
# Output: Value of RED: 1
Base type
from enum import Enum
# Define an enumeration class
class DataType(Enum):
INTEGER = 42
FLOAT = 3.14
STRING = "hello"
CUSTOM_OBJECT = {"name": "John", "age": 30}
# Accessing enumeration members and their data types
print("Integer value:", DataType.INTEGER.value, "Type:",
type(DataType.INTEGER.value))
# Integer value: 42 Type: <class 'int'>
print("Float value:", DataType.FLOAT.value, "Type:",
type(DataType.FLOAT.value))
# Float value: 3.14 Type: <class 'float'>
print("String value:", DataType.STRING.value, "Type:",
type(DataType.STRING.value))
# String value: hello Type: <class 'str'>
print("Custom object value:", DataType.CUSTOM_OBJECT.value,
"Type:", type(DataType.CUSTOM_OBJECT.value))
# Custom object value: {'name': 'John', 'age': 30} Type: <class
'dict'>
Conversion from a string
from enum import Enum
# Define an enumeration class
class Color(Enum):
RED = 1
GREEN = 2
BLUE = 3
# Convert a string to an enumeration member
def string_to_enum(string_value):
try:
enum_member = Color[string_value]
return enum_member
except KeyError:
print(f"No enum member found for {string_value}")
return None
# Test the conversion
color_string = "GREEN"
color_enum_member = string_to_enum(color_string)
if color_enum_member:
print(f"Enum member for {color_string}: {color_enum_member}")
# Enum member for GREEN: Color.GREEN
Converting to a String
from enum import Enum
# Define an enumeration class
class Color(Enum):
RED = 1
GREEN = 2
BLUE = 3
# Convert an enumeration member to a string
def enum_to_string(enum_member):
return str(enum_member) # Using str() function
# Test the conversion
color_enum_member = Color.GREEN
color_string = enum_to_string(color_enum_member)
print(f"String representation: {color_string}")
# String representation: Color.GREEN
# Alternatively, directly access the name attribute
color_string = color_enum_member.name
print(f"String representation (using name attribute): {color_string}")
# String representation (using name attribute): GREEN
Definition and initialization
from enum import Enum
class Season(Enum):
Summer, Fall, Winter, Spring = range(4)
summer = Season.Summer
winter = Season.Winter
print(summer) # Season.Summer
print(winter) # Season.Winter
Enums comparison
from enum import Enum
class Size(Enum):
xs, s, m, l, xl = range(5)
small = Size.s
large = Size.l
print("is l > s:", large.value > small.value)
# is l > s: True
Explicitly set base value
from enum import Enum
class Season(Enum):
Summer = 1
Fall = 2
Winter = 3
Spring = 4
winter = Season.Winter
baseWinter = winter.value
print(baseWinter) # 3
Get the list of values
from enum import Enum
class Season(Enum):
Summer, Fall, Winter, Spring = range(4)
values = list(Season)
print(values)
print(values[0])
# [<Season.Summer: 0>, <Season.Fall: 1>, <Season.Winter:
2>, <Season.Spring: 3>]
# Season.Summer
Initializing from a base value
from enum import Enum
class Season(Enum):
Summer = 0
Fall = 1
Winter = 2
Spring = 3
winter = Season(2)
# winter is Season.Winter
print(winter) # Season.Winter
Exceptions Handling
Exceptions handling is a programming technique used to manage
unexpected or erroneous situations that may occur during runtime.
When a program encounters an exceptional condition (e.g., division
by zero, file not found), it throws an exception, which disrupts the
normal flow of execution.
Catch all exceptions
class IsNoneException(Exception):
pass
class IsEmptyException(Exception):
pass
def throw_when_null_or_empty(data):
if data is None:
raise IsNoneException()
if len(data) == 0:
raise IsEmptyException()
try:
throw_when_null_or_empty(None)
except Exception as e:
print("Error happened " + e.__class__.__name__)
# Error happened IsNoneException
Catch the specific exception
class IsNoneException(Exception):
pass
class IsEmptyException(Exception):
pass
def throw_when_null_or_empty(data):
if data is None:
raise IsNoneException()
if len(data) == 0:
raise IsEmptyException()
try:
throw_when_null_or_empty([])
except IsNoneException:
print("list is not specified")
except IsEmptyException:
print("list is empty")
# list is empty
Define an exception type
class SimpleException(Exception):
pass
raise SimpleException("Oops!")
Guaranteed code execution
def throw_if_true(param):
try:
if param:
raise OSError("test exception")
except OSError:
print("except")
finally:
print("finally")
throw_if_true(True)
# printed: "except" and "finally"
throw_if_true(False)
# printed only "finally"
If no exception occurred
def throw_if_true(param):
try:
if param:
raise OSError("test exception")
except OSError:
print("except")
else:
print("else")
throw_if_true(True)
# printed: "except"
throw_if_true(False)
# printed only "else"
Method throwing an exception
# any method can throw an error
def method_with_exception():
raise Exception("test exception")
method_with_exception()
# Exception: test exception
Re-throw exceptions
def method_with_exception():
try:
raise Exception("test exception")
except Exception as ex:
# implementation of any partial procesing
# and send error to the calling code
raise ex
try:
method_with_exception()
except Exception as e:
print(e.args[0])
# test exception
Throw an exception
class Seller:
def __init__(self):
self.cars = []
def sell(self):
if len(self.cars) == 0:
raise Exception("No cars for sale")
seller = Seller()
try:
seller.sell()
except Exception as e:
print(e.args[0])
# e.args[0] is "No cars for sale"
Extensions
Extensions in programming languages allow developers to enhance
existing types or classes without modifying their source code. They
provide a way to add new functionality, methods, or properties to
types that are already defined.
Adding object methods
from math import *
excluded_methods = frozenset(["__module__", "__qualname__"])
def class_extend(cls):
class Meta(type):
def __new__(mcs, name, bases, attrs):
for name, value in attrs.items():
if name not in excluded_methods:
setattr(cls, name, value)
return cls
return Meta
class Point:
def __init__(self, x, y):
self.x = x
self.y = y
class Point(metaclass=class_extend(Point)):
def distance_to(self, p2):
d1 = pow(self.x - p2.x, 2)
d2 = pow(self.y - p2.y, 2)
return sqrt(d1 + d2)
point1 = Point(1, 2)
point2 = Point(2, 3)
distance = point1.distance_to(point2)
print(f"{distance = }")
# distance = 1.4142135623730951
Functions
Functions in programming are blocks of reusable code that perform
a specific task. They allow developers to encapsulate logic, promote
code reusability, and enhance readability by breaking down
complex operations into smaller, manageable parts.
Array of parameters
def get_avg(*values):
if len(values) == 0:
return 0
sum_v = 0
for value in values:
sum_v += value
return sum_v / len(values)
avg = get_avg(1, 2, 3, 4)
print(f"{avg = }") # avg is 2.5
In/Out parameters
def swap_strings(s1, s2):
tmp = s1[0]
s1[0] = s2[0]
s2[0] = tmp
s1 = ["A"]
s2 = ["B"]
swap_strings(s1, s2)
print(f"s1[0] is {s1[0]}, s2[0] is {s2[0]}")
# s1[0] is "B", s2[0] is "A"
Multiple return values
def get_first_last(ar):
if len(ar) == 0:
return -1, -1
return ar[0], ar[-1]
ar = [2, 3, 5]
first, last = get_first_last(ar)
print(f"first is {first}") # first is 2
print(f"last is {last}") # last is 5
Optional parameter values
# Using Default Parameter Values in Python
def say_goodbye(message="Goodbye!"):
print(message)
say_goodbye()
# prints "Goodbye!"
say_goodbye("See you")
# prints "See you"
# Before Using Default Parameters
def old_say_goodbye(message=None):
if message is None:
message = "Goodbye!"
print(message)
old_say_goodbye()
# prints "Goodbye!"
old_say_goodbye("See you")
# prints "See you"
Out parameters
# in Python, you can't change param reference
def get_sum(summ, n1, n2):
summ.append(n1 + n2):
ar_sum = []
get_sum(ar_sum, 5, 3)
# ar_sum is [13]
Recursion
def fibonacci(x):
return x if x <= 1 else fibonacci(x - 1) + fibonacci(x - 2)
f10 = fibonacci(10)
print(f"f10 is {f10}") # f10 is 55
Variable parameters
def print5(data):
if len(data) > 5:
data = data[0: 5]
print(data)
print5("1234567") # prints: 12345
With return value
def get_sum(n1, n2):
return n1 + n2
result = get_sum(5, 3)
print(f"{result = }") # result is 8
Without any parameters
def say_goodbye():
print("Goodbye!")
say_goodbye()
Without any return value
def add_3_and_print(value):
print(value + 3)
add_3_and_print(5) # 8
Generic Types
Generic types in programming languages allow developers to define
classes, functions, or interfaces that can work with various data
types without specifying them beforehand. This flexibility enhances
code reusability and type safety by enabling components to be more
generic and adaptable to different scenarios.
Class conformity
from typing import TypeVar, Generic
class Vehicle:
def test(self):
print(f"test: {self}")
class Car(Vehicle):
pass
class Truck:
pass
T = TypeVar('T', bound=Vehicle)
class Service(Generic[T]):
def __init__(self):
selt.v_list = list[T]()
def add(self, item: T):
self.v_list.append(item)
def test(self):
for item in self.v_list:
item.test()
service = Service[Vehicle]()
service.add(Vehicle())
service.add(Car())
# Warning: Expected type 'Vehicle'
service.add(Truck())
service.test()
Default value
from typing import TypeVar, Generic, Type T = TypeVar('T')
class Size(Generic[T]):
def __init__(self, width: T, height: T):
self.width = width
self.height = height
def reset(self):
self.width = type(self.width)()
self.height = type(self.height)()
def print(self):
print(f{[{self.width}; {self.height}]})
size_int = Size[int](5, 9)
size_int.print()
# prints: [5; 9]
size_int.reset()
size_int.print()
# prints: [0; 0]
Generic classes
from typing import TypeVar, Generic
T = TypeVar('T')
class Size(Generic[T]):
def __init__(self, width: T, height: T):
self.width = width
self.height = height
def as_text(self):
return f"[{self.width}; {self.height}]"
size_int = Size[int](5, 8)
text_int = size_int.as_text()
# text_int is "[5; 8]"
print(f"{text_int=}")
print(f"{text_float=}")
Generic collections
# List of integer
int_list = list[int]()
int_list.append(5)
print(f"{int_list = }")
# Dictionary
dic = dict[int, str]()
dic[1] = "one"
print(f"{dic = }")
# Set
set_float = set[float]()
set_float.add(3.14)
print(f"{set_float = }")
# nt_list = [5]
# dic = {1: 'one'}
# set_float = {3.14}
Generic methods
from typing import TypeVar
T = TypeVar('T')
def swap(v1: list[T], v2: list[T]):
v1[0], v2[0] = v2[0], v1[0]
n1 = [5]
n2 = [7]
swap(n1, n2)
# n1[0] is 7, n2[0] is 5
s1 = ["cat"]
s2 = ["dog"]
swap(s1, s2)
# s1[0] is "B", s2[0] is "A"
print(f'{n1 = }, {n2 = }')
print(f'{s1 = }, {s2 = }')
Interface conformity
from abc import ABC, abstractmethod
from typing import TypeVar, Generic
class Vehicle(ABC):
@abstractmethod
def test(self):
pass
class Car(Vehicle):
def test(self):
print(f"test {self}")
T = TypeVar('T', bound=Vehicle)
class Service(Generic[T]):
def __init__(self):
self.v_list = list[T]()
def add(self, item: T):
self.v_list.append(item)
def test(self):
for item in self.v_list:
item.test()
service = Service[Car]()
service.add(Car())
service.test()
Substitution principle
class Vehicle:
def test(self):
print(f"test {self}")
class Car(Vehicle):
pass
class Truck(Vehicle):
pass
lst = list[Vehicle]()
lst.append(Vehicle())
lst.append(Car())
lst.append(Truck())
for vehicle in lst:
vehicle.test()
Initializing of Types
Initializing types refers to the process of setting initial values or
states for variables, objects, or data structures in a program. This
process ensures that entities in the program start with predefined
values, which are often crucial for correct functioning and behavior.
Classes:
With a constructor
class Phone:
def __init__(self, model):
self.model = model
class Employee:
def __init__(self, first_name, last_name, phone):
self.first_name = first_name
self.last_name = last_name
self.phone = phone
# Create instances
nokia_phone = Phone("Nokia 6610")
kim = Employee("Victorya", "Kim", Phone("IPhone 11 Pro"))
# Access and print phone model
print(kim.phone.model) # Iphone 11 Pro
Without any constructor
class Phone:
pass # No explicit constructor needed
class Employee:
pass # No explicit constructor needed
kim = Employee()
kim.firstName = "Victorya"
kim.lastName = "Kim"
kim.phone = Phone()
kim.phone.model = "IPhone 5"
# list of Employee
class Employee:
def __init__(self, first_name, last_name):
self.firstName = first_name
self.lastName = last_name
def __iter__(self):
return self
def __next__(self):
if self.current > self.high
raise StopIteration
else:
result = self.current
self.current += self.step
return result
# Example usage:
point1 = Point(1, 2)
point2 = Point(2, 3)
point3 = Point(1, 2)
print(f"point1 == point2: {point1 == point2}") # False
print(f"point1 == point3: {point1 == point3}") # True
print(f"point1 < point2: {point1 < point2}") # True
print(f"point1 <= point2: {point1 <= point2}") # True
print(f"point1 > point2: {point1 > point2}") # False
print(f"point1 >= point2: {point1 >= point2}") # False
print(f"point1 != point2: {point1 != point2}") # True
Custom operators
class Vector:
def __init__(self, x, y):
self.x = x
self.y = y
def __add__(self, other):
return Vector(self.x + other.x, self.y + other.y)
def __sub__(self, other):
return Vector(self.x - other.x, self.y - other.y)
def __mul__(self, scalar):
return Vector(self.x * scalar, self.y * scalar)
def __truediv__(self, scalar):
return Vector(self.x / scalar, self.y / scalar)
def __eq__(self, other):
return self.x == other.x and self.y == other.y
def __lt__(self, other):
return (self.x ** 2 + self.y ** 2) < (other.x ** 2 + other.y
** 2)
def __le__(self, other):
return (self.x ** 2 + self.y ** 2) <= (other.x ** 2 + other.y
** 2)
def __repr__(self):
return f"Vector({self.x}, {self.y})"
# Example usage:
v1 = Vector(1, 2)
v2 = Vector(3, 4)
v3 = v1 + v2
v4 = v2 - v1
v5 = v1 * 3
v6 = v2 / 2
print(f"v1: {v1}") # v1: Vector(1, 2)
print(f"v2: {v2}") # v2: Vector(3, 4)
print(f"v1 + v2: {v3}") # v1 + v2: Vector(4, 6)
print(f"v2 - v1: {v4}") # v2 - v1: Vector(2, 2)
print(f"v1 * 3: {v5}") # v1 * 3: Vector(3, 6)
print(f"v2 / 2: {v6}") # v2 / 2: Vector(1.5, 2.0)
print(f"v1 == v2: {v1 == v2}") # v1 == v2: False
print(f"v1 < v2: {v1 < v2}") # v1 < v2: True
print(f"v1 <= v2: {v1 <= v2}") # v1 <= v2: True
Equivalence operators
class Point:
def __init__(self, x, y):
self.x = x
self.y = y
def __eq__(self, other):
if not isinstance(other, Point):
return NotImplemented
return self.x == other.x and self.y == other.y
def __ne__(self, other):
if not isinstance(other, Point):
return NotImplemented
return not self == other
def __repr__(self):
return f"Point({self.x}, {self.y})"
# Example usage:
point1 = Point(1, 2)
point2 = Point(1, 2)
point3 = Point(2, 3)
print(f"point1 == point2: {point1 == point2}") # True
print(f"point1 == point3: {point1 == point3}") # False
print(f"point1 != point2: {point1 != point2}") # False
print(f"point1 != point3: {point1 != point3}") # True
Unary operators
class Vector:
def __init__(self, x, y):
self.x = x
self.y = y
def __neg__(self):
return Vector(-self.x, -self.y)
def __pos__(self):
return Vector(+self.x, +self.y)
def __repr__(self):
return f"Vector({self.x}, {self.y})"
# Example usage:
v1 = Vector(3, 4)
v_neg = -v1
v_pos = +v1
print(f"v1: {v1}") # v1: Vector(3, 4)
print(f"-v1: {v_neg}") # -v1: Vector(-3, -4)
print(f"+v1: {v_pos}") # +v1: Vector(3, 4)
Design Patterns
Design patterns are proven solutions to common problems that arise
during software design and development. They represent best
practices and reusable templates that help developers solve
recurring design challenges effectively.
Creational patterns:
Abstract factory
import copy
# Prototype
class Shape:
def __init__(self, line_count):
self.line_count = line_count
def clone(self):
return copy.deepcopy(self)
# ConcretePrototype
class Square(Shape):
def __init__(self):
super().__init__(4)
# Client
class ShapeMaker:
def __init__(self, shape):
self._shape = shape
def make_shape(self):
return self._shape.clone()
if __name__ == "__main__":
square = Square()
maker = ShapeMaker(square)
square1 = maker.make_shape()
square2 = maker.make_shape()
print("square1.line_count is", square1.line_count)
# square1.line_count is 4
print("square2.line_count is", square2.line_count)
# square2.line_count is 4
Singleton
class Settings:
_singleton_instance = None
def __new__(cls):
if cls._singleton_instance is None:
cls._singleton_instance = super().__new__(cls)
cls._singleton_instance.port = 0
cls._singleton_instance.host = ""
return cls._singleton_instance
if __name__ == "__main__":
settings = Settings()
settings.host = "192.168.100.1"
settings.port = 33
settings1 = Settings()
# settings1.port is 33
print("settings1.port is", settings1.port)
# settings1.port is 33
Structural patterns:
Adapter (Composition)
class StringList:
def __init__(self):
self.rows = []
# SpecificRequest
def get_string(self):
return "\n".join(self.rows)
def add(self, value):
self.rows.append(value)
# Adapter
class TextAdapter:
def __init__(self, row_list):
self.row_list = row_list
# Request
def get_text(self):
return self.row_list.get_string()
def get_text_adapter():
row_list = StringList()
adapter = TextAdapter(row_list)
row_list.add("line 1")
row_list.add("line 2")
return adapter
# Client
if __name__ == "__main__":
adapter = get_text_adapter()
text = adapter.get_text()
# text: line 1
# line 2
print(text)
# line 1
# line 2
Adapter (Inheritance)
# Adaptee
class StringList:
def __init__(self):
self.rows = []
# SpecificRequest
def get_string(self):
return "\n".join(self.rows)
def add(self, value):
self.rows.append(value)
# Adapter
class TextAdapter(StringList):
def __init__(self):
super().__init__()
# Request
def get_text(self):
return self.get_string()
def get_text_adapter():
adapter = TextAdapter()
adapter.add("line 1")
adapter.add("line 2")
return adapter
# Client
if __name__ == "__main__":
adapter = get_text_adapter()
text = adapter.get_text()
# text: line 1
# line 2
print(text)
Bridge
# Implementor
class TextImp:
def __init__(self):
self._rows = []
def get_string(self):
return "\n".join(self._rows)
# RefinedAbstraction
class TextMaker:
def __init__(self, imp):
self.text_imp = imp
def get_text(self):
return self.text_imp.get_string()
def add_line(self, value):
self.text_imp.append_line(value)
# ConcreteImplementor
class HtmlBuilder(TextImp):
def __init__(self):
super().__init__()
def append_line(self, value):
self._rows.append("<span>" + value + "</span><br/>")
# Client
if __name__ == "__main__":
text_maker = TextMaker(TextImp())
text_maker.add_line("line 1")
text_maker.add_line("line 2")
text = text_maker.get_text()
html_maker = TextMaker(HtmlBuilder())
html_maker.add_line("line 1")
html_maker.add_line("line 2")
html = html_maker.get_text()
print(text)
print(html)
# line 1
# line 2
# <span>line 1</span><br/>
# <span>line 2</span><br/>
Composite
# Component
class Graphic:
def draw(self):
pass
# Leaf
class Circle(Graphic):
def draw(self):
print("Draw circle")
# Leaf
class Square(Graphic):
def draw(self):
print("Draw square")
# Composite
class CImage(Graphic):
def __init__(self):
self.graphics = []
def add(self, graphic):
self.graphics.append(graphic)
def remove(self, graphic):
self.graphics.remove(graphic)
def draw(self):
print("Draw image")
for graphic in self.graphics:
graphic.draw()
# Client
if __name__ == "__main__":
image = CImage()
image.add(Circle())
image.add(Square())
picture = CImage()
picture.add(image)
picture.add(CImage())
picture.draw()
# Output:
# Draw image
# Draw circle
# Draw square
Decorator
# Component
class Shape:
# Operation()
def get_info(self):
return "shape"
def show_info(self):
print(self.get_info())
# ConcreteComponent
class Square(Shape):
def __init__(self):
super().__init__()
# Operation()
def get_info(self):
return "square"
# Decorator
class ShapeDecorator(Shape):
def __init__(self, shape):
super().__init__()
self.shape = shape
# Operation()
def get_info(self):
return self.shape.get_info()
# ConcreteDecorator
class ColorShape(ShapeDecorator):
def __init__(self, shape, color):
super().__init__(shape)
self.color = color
def get_info(self):
return f"{self.color} {self.shape.get_info()}"
# Complex parts
class Kettle:
def turn_off(self):
print("Kettle turn off")
class Toaster:
def turn_off(self):
print("Toaster turn off")
class Refrigerator:
def turn_off(self):
print("Refrigerator turn off")
# Facade
class Kitchen:
def __init__(self, kettle, toaster, refrigerator):
self.kettle = kettle
self.toaster = toaster
self.refrigerator = refrigerator
def off(self):
self.kettle.turn_off()
self.toaster.turn_off()
self.refrigerator.turn_off()
kettle = Kettle()
toaster = Toaster()
refrigerator = Refrigerator()
kitchen = Kitchen(kettle, toaster, refrigerator)
kitchen.off()
# Kettle turn off
# Toaster turn off
# Refrigerator turn off
Flyweight
# Flyweight
class Char:
def __init__(self, c):
self._c = c
# Operation(extrinsicState)
def print_span(self, style):
span = f'<span style="{style}">{self._c}</span>'
print(span)
# FlyweightFactory
class CharFactory:
def __init__(self):
self.chars = {}
# GetFlyweight(key)
def get_char(self, c):
if c not in self.chars:
self.chars[c] = Char(c)
return self.chars[c]
# Client
factory = CharFactory()
charA = factory.get_char("A")
charA.print_span("font-size: 40pt")
charB = factory.get_char("B")
charB.print_span("font-size: 12")
charA1 = factory.get_char("A")
charA1.print_span("font-size: 12")
equal = charA is charA1
# equal is True
print(equal)
# <span style="font-size: 40pt">A</span>
# <span style="font-size: 12">B</span>
# <span style="font-size: 12">A</span>
Proxy
# Subject
class Graphic:
def __init__(self, file_name):
self._file_name = file_name
def get_file_name(self):
return self._file_name
# RealSubject
class CImage(Graphic):
def __init__(self, file_name):
super().__init__(file_name)
# Request()
def draw(self):
print("draw", self._file_name)
# Proxy
class ImageProxy(Graphic):
def __init__(self, file_name):
super().__init__(file_name)
self._image = None
def get_image(self):
if self._image is None:
self._image = CImage(self._file_name)
return self._image
def draw(self):
self.get_image().draw()
# Client
proxy = ImageProxy("1.png")
# operation without creating a RealSubject
file_name = proxy.get_file_name()
# forwarded to the RealSubject
proxy.draw()
# draw 1.png
print("file_name is", file_name)
# file_name is 1.png
Behavioral patterns:
Chain of responsibility
# Handler
class Rescuer:
def __init__(self, code, next_rescuer=None):
self._code = code
self._next_rescuer = next_rescuer
# HandleRequest()
def help(self, code):
if self._code == code:
self.to_help()
elif self._next_rescuer is not None:
self._next_rescuer.help(code)
def to_help(self):
pass
# ConcreteHandler
class Firefighter(Rescuer):
def __init__(self, next_rescuer=None):
super().__init__(1, next_rescuer)
def to_help(self):
print("call firefighters")
# ConcreteHandler
class Police(Rescuer):
def __init__(self, next_rescuer=None):
super().__init__(2, next_rescuer)
def to_help(self):
print("call the police")
# ConcreteHandler
class Ambulance(Rescuer):
def __init__(self, next_rescuer=None):
super().__init__(3, next_rescuer)
def to_help(self):
print("call on ambulance")
ambulance = Ambulance()
police = Police(ambulance)
firefighter = Firefighter(police)
firefighter.help(1)
# printed: call firefighters
firefighter.help(2)
# printed: call the police
firefighter.help(3)
# printed: call the ambulance
Command
# Invoker
class BankClient:
def __init__(self, put_command, get_command):
self._put_command = put_command
self._get_command = get_command
def put_money(self):
self._put_command.execute()
def get_money(self):
self._get_command.execute()
# Receiver
class Bank:
def give_money(self):
print("money to the client")
def receive_money(self):
print("money from the client")
# Command interface
class Command:
def execute(self):
pass
# ConcreteCommand
class PutCommand(Command):
def __init__(self, bank):
self._bank = bank
def execute(self):
self._bank.receive_money()
# ConcreteCommand
class GetCommand(Command):
def __init__(self, bank):
self._bank = bank
def execute(self):
self._bank.give_money()
# Client
bank = Bank()
put_command = PutCommand(bank)
get_command = GetCommand(bank)
client = BankClient(put_command, get_command)
client.get_money()
# printed: money to the client
client.put_money()
# printed: money from the client
Interpreter
# TerminalExpression
class DivExpression:
def __init__(self, divider):
self._divider = divider
def interpret(self, i):
return i % self._divider == 0
# NonterminalExpression
class OrExpression:
def __init__(self, exp1, exp2):
self.exp1 = exp1
self.exp2 = exp2
def interpret(self, i):
return self.exp1.interpret(i) or self.exp2.interpret(i)
# NonterminalExpression
class AndExpression:
def __init__(self, exp1, exp2):
self.exp1 = exp1
self.exp2 = exp2
def interpret(self, i):
return self.exp1.interpret(i) and self.exp2.interpret(i)
# Client
div_exp5 = DivExpression(5)
div_exp7 = DivExpression(7)
or_exp = OrExpression(div_exp5, div_exp7)
and_exp = AndExpression(div_exp5, div_exp7)
# 21 is divided by 7 or 5?
result1 = or_exp.interpret(21)
# 21 is not divided by 7 and 5
result2 = and_exp.interpret(21)
# 35 is divided by 7 and 5
result3 = and_exp.interpret(35)
print("21 is divided by 7 or 5?", result1)
# 21 is divided by 7 or 5? True
print("21 is divided by 7 and 5?", result2)
# 21 is divided by 7 and 5? False
print("35 is divided by 7 and 5?", result3)
# 35 is divided by 7 and 5? True
Iterator
# ConcreteAggregate
class PrimeNumbers:
def __init__(self):
self.numbers = [2, 3, 5, 7, 11]
def get_iterator(self):
return Iterator(self)
# ConcreteIterator
class Iterator:
def __init__(self, prime_numbers):
self.index = 0
self.numbers = prime_numbers.numbers
def first(self):
self.index = 0
def next(self):
self.index += 1
def is_done(self):
return self.index >= len(self.numbers)
def current_item(self):
return self.numbers[self.index]
# Client
numbers = PrimeNumbers()
iterator = numbers.get_iterator()
sum_result = 0
iterator.first()
while not iterator.is_done():
sum_result += iterator.current_item()
iterator.next()
print(f"sum is {sum_result}") # sum is 28
Mediator
# Mediator
class Mediator:
def __init__(self):
self._switchers = []
def add(self, switcher):
self._switchers.append(switcher)
def sync(self, switcher):
state = switcher.get_state()
for s in self._switchers:
s.set_state(state)
# Colleague
class Switcher:
def __init__(self, mediator):
self._state = False
self._mediator = mediator
self._mediator.add(self)
def sync(self):
self._mediator.sync(self)
def get_state(self):
return self._state
def set_state(self, value):
self._state = value
# ConcreteMediator
class SyncMediator(Mediator):
def __init__(self):
super().__init__()
# Client
mediator = SyncMediator()
switcher1 = Switcher(mediator)
switcher2 = Switcher(mediator)
switcher3 = Switcher(mediator)
switcher1.set_state(True)
state2 = switcher2.get_state()
# state2 is False
state3 = switcher3.get_state()
# state3 is False
print("state2 is", state2)
print("state3 is", state3)
switcher1.sync()
state2 = switcher2.get_state()
# state2 is True
state3 = switcher3.get_state()
# state3 is True
print("state2 is", state2)
print("state3 is", state3)
# state2 is False
# state3 is False
# state2 is True
# state3 is True
Memento
# State
class Point:
def __init__(self, x, y):
self.x = x
self.y = y
class Memento:
def __init__(self, m_state):
self._state = m_state
def get_state(self):
return self._state
# Originator
class Shape:
def __init__(self):
self.position = Point(0, 0)
def move(self, left, top):
self.position.x += left
self.position.y += top
def get_memento(self):
state = Point(self.position.x, self.position.y)
return Memento(state)
def set_memento(self, memento):
self.position = memento.get_state()
def show_position(self):
print(f"{self.position.x}, {self.position.y}")
# Caretaker
class ShapeHelper:
def __init__(self, h_shape):
self.stack = []
self.shape = h_shape
def move(self, left, top):
self.stack.append(self.shape.get_memento())
self.shape.move(left, top)
def undo(self):
if self.stack:
self.shape.set_memento(self.stack.pop())
shape = Shape()
helper = ShapeHelper(shape)
helper.move(2, 3)
# shape.position is (2, 3)
shape.show_position()
helper.move(-5, 4)
# shape.position is (-3, 7)
shape.show_position()
helper.undo()
# shape.position is (2, 3)
shape.show_position()
helper.undo()
# shape.position is (0, 0)
shape.show_position()
Observer
# concreteObserver
class TextObserver:
def __init__(self, o_name):
self.name = o_name
def update(self, state):
print(f"{self.name}: {state}")
# Subject
class TestSubject:
def __init__(self):
self._observers = []
def attach(self, observer):
self._observers.append(observer)
def detach(self, observer):
if observer in self._observers:
self._observers.remove(observer)
def notify(self, state):
for observer in self._observers:
observer.update(state)
# ConcreteSubject
class TextEdit(TestSubject):
def __init__(self):
super().__init__()
self.text = ""
# SetState(State)
def set_text(self, s_text):
self.text = s_text
self.notify(self.text)
def get_text(self):
return self.text
# client
observer1 = TextObserver("Observer #1")
observer2 = TextObserver("Observer #2")
text_edit = TextEdit()
text_edit.attach(observer1)
text_edit.attach(observer2)
text_edit.set_text("test text")
# printed:
# Observer #1: test text
# Observer #2: test text
State
# ConcreteState
class CloseState:
def open(self, c):
print("open the connection")
c.set_state(OpenState())
def close(self, c):
print("connection is already closed")
# ConcreteState
class OpenState:
def open(self, c):
print("connection is already open")
def close(self, c):
print("close the connection")
c.set_state(CloseState())
# Context
class Connection:
def __init__(self):
self.state = CloseState()
def open(self):
self.state.open(self)
def close(self):
self.state.close(self)
def set_state(self, s_state):
self.state = s_state
# Client
con = Connection()
# printed: open the connection
con.open()
# printed: connection is already open
con.close()
# printed: close the connection
con.close()
# printed: connection is already closed
Strategy
# ConcreteStrategy
class AddStrategy:
def do_operation(self, a, b):
return a + b
# ConcreteStrategy
class SubtractStrategy:
def do_operation(self, a, b):
return a - b
# Context
class Calc:
def __init__(self):
self.strategy = None
def execute(self, a, b):
if self.strategy is None:
return 0
return self.strategy.do_operation(a, b)
def set_strategy(self, s_strategy):
self.strategy = s_strategy
calc = Calc()
result1 = calc.execute(5, 3)
# result1 is 0
calc.set_strategy(AddStrategy())
result2 = calc.execute(5, 3)
# result2 is 8
calc.set_strategy(SubtractStrategy())
result3 = calc.execute(5, 3)
# result3 is 2
print(f"result1 is {result1}") # result1 is 0
print(f"result2 is {result2}") # result2 is 8
print(f"result3 is {result3}") # result3 is 2
Template method
value1 = True
value2 = False
print(f'value_not1 is {value_not1}')
# value_not1 is False
print(f'value_not2 is {value_not2}')
# value_not2 is True
print(f'value_and is {value_and}')
# value_and is False
print(f'value_or is {value_or}')
# value_or is True
print(f'value_xor is {value_xor}')
# value_xor is True
Character type:
Converting to a number and back
# Converting characters to numbers and back in Python
char_a = 'A'
int_value = ord(char_a)
# int_value is 65
print(f'char_a is "{char_a}"') # char_a is "A"
print(f'int_value is {int_value}') # int_value is 65
int_value += 1
char_b = chr(int_value)
# char_b is 'B'
print(f'char_b is "{char_b}"') # char_b is "B"
print(f'int_value is {int_value}') # int_value is 66
Converting to a string
# Converting characters to strings in Python
char_a = 'A'
print(f'char_a is "{char_a}"')
# char_a is "A"
str_var = "character " + char_a
# str_var is "character A"
print(f'str_var is "{str_var}"')
# str_var is "character A"
Escape characters
# Escape characters in Python
# \' for a single quote.
c1 = "'"
# \" for a double quote.
c2 = '"'
# \\ for a backslash.
c3 = "\\"
# \0 for a null character.
c4 = "\0"
# \b for a backspace.
c5 = "\b"
# \n for a new line.
c6 = "\n"
# \r for a carriage return.
c7 = "\r"
# \t for a horizontal tab.
c8 = "\t"
# \v for a vertical tab.
c9 = "\v"
# \x for a unicode character hex value. (Example: \x41 represents
'A')
c10 = "\x41"
# Printing the escape characters
print(f"c1 is '{c1}'") # c1 is '''
print(f"c2 is \"{c2}\"") # c2 is """
print(f"c3 is '{c3}'") # c3 is '\'
print(f"c4 is '{c4}'") # c4 is ''
print(f"c5 is '{c5}'") # c5 is '
print(f"c6 is '{c6}'") # c6 is '
print(f"c7 is '{c7}'") # '
# '7 is '
print(f"c8 is '{c8}'") # c8 is ' '
print(f"c9 is '{c9}'") # c9 is '
#'
print(f"c10 is '{c10}'") # c10 is 'A'
Getting from a string
# Getting characters from a string in Python
# Define a string
str = "ABC"
# Get individual characters using indexing
charA = str[0] # charA is 'A'
charB = str[1] # charB is 'B'
charC = str[2] # charC is 'C'
# Iterate through the string and build a list of characters
charList = ";".join(str) + ";"
# charList is "A;B;C;"
# Printing the characters and the character list
print(f"charA is \"{charA}\"") # charA is "A"
print(f"charB is \"{charB}\"") # charB is "B"
print(f"charC is \"{charC}\"") # charC is "C"
print(f"charList is \"{charList}\"") # charList is "A;B;C;"
Special Characters
c_ruble = '\u20BD' # ₽
c_lambda = '\u03BB' # λ
print(f"{c_ruble = }") # c_ruble = '₽'
print(f"{c_lambda = }") # c_lambda = 'λ
Date and time:
Comparison of dates
from datetime import datetime, timedelta
# Get the current date and time
now = datetime.now()
# Get yesterday's date and time
yesterday = now - timedelta(days=1)
# Compare the dates
are_equal = now == yesterday
# are_equal is False
are_later = now > yesterday
# are_later is True
are_earlier = now < yesterday
# are_earlier is False
# Print the results
print(f"are_equal is {are_equal}")
# are_equal is False
print(f"are_later is {are_later}")
# are_later is True
print(f"are_earlier is {are_earlier}")
# are_earlier is False
Conversion from a string
from datetime import datetime
# Convert the string to datetime using strptime
string_dt = "1945-05-09 01:00".replace(" ", "T")
victory_dt = datetime.fromisoformat(string_dt)
# First method
string_date = "1945-05-09"
victory_date1 = datetime.strptime(string_date, "%Y-%m-%d")
# Second method
parts = string_date.split("-")
victory_date2 = datetime(int(parts[0]), int(parts[1]), int(parts[2]))
# Print the results
print(victory_dt.strftime("%d.%m.%Y"))
# 09.05.1945
print(victory_date1.strftime("%m/%d/%Y"))
# 05/09/1945
print(victory_date2.strftime("%m/%d/%Y"))
# 05/09/1945
Converting to a string
from datetime import datetime
# Get the current datetime
now = datetime.now()
# Define formatting options
options_en = "%m/%d/%y %I:%M %p"
# For English (US) locale
options_ru = "%d.%m.%y %H:%M"
# For Russian (RU) locale
custom_format = "%Y-%m-%d"
# Custom format for date only
# Format the datetime objects
short_style_en = now.strftime(options_en)
short_style_ru = now.strftime(options_ru)
custom_style = now.strftime(custom_format)
# Print the formatted strings
print(f"shortStyleEn is \"{short_style_en}\"")
# shortStyleEn is "05/24/21 04:02 PM"
print(f"shortStyleRu is \"{short_style_ru}\"")
# shortStyleRu is "24.05.21 16:02"
print(f"customStyle is \"{custom_style}\"")
# customStyle is "2021-05-24"
Date changing
from datetime import datetime, timedelta
# Get the current datetime
now = datetime.now()
# Calculate yesterday
yesterday = now - timedelta(days=1)
# Calculate tomorrow
tomorrow = now + timedelta(days=1)
# Calculate next month
next_month = now.replace(day=1) + timedelta(days=32) # Add
32 days to ensure we move to the next month
# Calculate next year
next_year = now.replace(year=now.year + 1)
# Print the results
print(f"now is \"{now.strftime('%x')}\"")
print(f"yesterday is \"{yesterday.strftime('%x')}\"")
print(f"tomorrow is \"{tomorrow.strftime('%x')}\"")
print(f"nextMonth is \"{next_month.strftime('%x')}\"")
print(f"nextYear is \"{next_year.strftime('%x')}\"")
Date initialization
from datetime import datetime
year = 1945
month = 5
day = 9
victory_date = datetime(year, month, day)
print(victory_date.strftime("%x, %X"))
# Output: 05/09/45, 00:00:00
Getting of the current date
from datetime import datetime
now = datetime.now()
print(f"now is \"{now}\"")
# now is "2024-06-10 22:26:11.530947"
Getting of year, month, day
from datetime import datetime
now = datetime.now()
year = now.year
month = now.month
day = now.day
hour = now.hour
minute = now.minute
second = now.second
day_of_week = now.weekday() # Monday is 0, Sunday is 6
print(f"year is {year}") # year is 2023
print(f"month is {month}") # month is 5
print(f"day is {day}") # day is 30
print(f"hour is {hour}") # hour is 11
print(f"minute is {minute}") # minute is 45
print(f"second is {second}") # second is 52
print(f"day_of_week is {day_of_week}") # day_of_week is 0
The interval between the dates
from datetime import datetime
victory_date = datetime(1945, 5, 9)
now = datetime.now()
time_diff = now - victory_date
days = time_diff.days
minutes = time_diff.total_seconds() // 60
print(f"days is {days}") # days is 28691
print(f"minutes is {minutes}") # minutes is 41316446
Double and Float:
Arithmetic operations
d1 = 8.5 + 2.4
d2 = 8.5 - 2.4
d3 = 8.5 * 2
d4 = 8.5 / 2
# mod
d5 = 7.5 % 2
d6 = -7.5 % 2
# div
d7 = int(7.5 / 2)
d8 = -d7
d9 = 3.5
d9 += 1
d9 -= 1
d10 = d9
d9 += 1
d11 = d9
d9 -= 1
d12 = abs(-5.5)
print("d1 =", d1) # d1 = 10.9
print("d2 =", d2) # d2 = 6.1
print("d3 =", d3) # d3 = 17.0
print("d4 =", d4) # d4 = 4.25
print("d5 =", d5) # d5 = 1.5
print("d6 =", d6) # d6 = 0.5
print("d7 =", d7) # d7 = 3
print("d8 =", d8) # d8 = -3
print("d9 =", d9) # d9 = 5.5
print("d10 =", d10) # d10 = 4.5
print("d11 =", d11) # d11 = 6.5
print("d12 =", d12) # d12 = 5.5
Conversion from a string
# The first method
str_pi = "3.14"
pi_float = float(str_pi)
# The second method
str_exp = "2.71828"
exp = float(str_exp)
# The third method
str_half = "0,5"
half = float(str_half.replace(",", "."))
print("pi_float =", pi_float) # pi_float = 3.14
print("exp =", exp) # exp = 2.71828
print("half =", half) # half = 0.5
Converting to a string
# Given double
exp = 2.718281828
# Converting to string using str()
s1 = str(exp)
# s1 is '2.718281828'
# Converting to string with fixed decimal places using format()
s2 = format(exp, '.3f')
# s2 is '2.718'
# Converting to string with specified decimal places using format()
and locale
import locale
from babel.numbers import format_decimal
locale.setlocale(locale.LC_ALL, 'en_US.UTF-8')
s3 = format_decimal(exp * 1000000, locale='en_US',
format='#,##0.00')
# s3 is '2,718,281.83'
print("s1 =", s1) # s1 = 2.718281828
print("s2 =", s2) # s2 = 2.718
print("s3 =", s3) # s3 = 2,718,281.83
Converting to integer
# Given float
pi = 3.1415926535
# Converting to integer using int()
int_value = int(pi)
# int_value is 3
print(f"int_value is {int_value}") # int_value is 3
Getting random values
import random
# Getting random value between 0.0 and 1.0
random_value = random.random()
print(f"random is {random_value}")
# random is 0.19281624415432086
Number comparison
# Define the numbers
a = 1.0
b = 0.3 * 3 + 0.1
# Wrong way to compare
isEqual1 = a == b
# isEqual1 is False
isEqual2 = a is b
# isEqual2 is False
# Correct way to compare
delta = 0.0000000001
isEqual3 = abs(a - b) < delta
# isEqual3 is True
print("isEqual1 is", isEqual1)
print("isEqual2 is", isEqual2)
print("isEqual3 is", isEqual3)
Rounding and truncating
import math
# Define the value of pi
pi = 3.1415
# Rounding
pi_round1 = round(pi, 3)
# pi_round1 is 3.142
pi_round2 = "{:.3f}".format(pi)
# pi_round2 is 3.142
# Truncating
pi_trunc = math.trunc(pi * 1000) / 1000
# pi_trunc is 3.141
# Ceiling
pi_ceil = math.ceil(pi * 100) / 100
# pi_ceil is 3.15
print("pi_round1 =", pi_round1) # pi_round1 = 3.142
print("pi_round2 =", pi_round2) # pi_round2 = 3.142
print("pi_trunc =", pi_trunc) # pi_trunc = 3.141
print("pi_ceil =", pi_ceil) # pi_ceil = 3.15
Integer:
Arithmetic operations
d1 = 8 + 2
d2 = 8 - 2
d3 = 8 * 2
d4 = 8 / 2
d5 = 5 % 2
d6 = -5 % 2
d7 = 1
d7 += 1
d7 -= 1
d8 = d7
d7 += 1
d9 = d7
print("d1 =", d1) # d1 = 10
print("d2 =", d2) # d2 = 6
print("d3 =", d3) # d3 = 16
print("d4 =", d4) # d4 = 4.0
print("d5 =", d5) # d5 = 1
print("d6 =", d6) # d6 = 1
print("d7 =", d7) # d7 = 2
print("d8 =", d8) # d8 = 1
print("d9 =", d9) # d9 = 2
BigInteger
# Maximum safe int value is 2^53
a = 9223372036854775807
b = 255
c = 1000
a1 = a * c
a2 = (a1 + c) // b
big_int = 9007199254740991
print("big_int =", big_int)
A = 9007199254740991
B = A + 10
print("a1 =", a1) # a1 = 9223372036854775807000
print("a2 =", a2) # a2 = 36170086419038335
print("B =", B) # B = 9007199254741001
Bitwise operations
a = 5 # 0101
b = 6 # 0110
# And
c1 = a & b
# c1 is 4 (0100)
# Or
c2 = a | b
# c2 is 7 (0111)
# Xor
c3 = a ^ b
# c3 is 3 (0011)
# Shift right
c4 = a >> 1
# c4 is 2 (0010)
# Shift left
c5 = b << 1
# c5 is 12 (1100)
# Bits inversion
c6 = ~b
# c6 is -7 (-111)
print("c1 =", c1) # c1 = 4
print("c2 =", c2) # c2 = 7
print("c3 =", c3) # c3 = 3
print("c4 =", c4) # c4 = 2
print("c5 =", c5) # c5 = 12
print("c6 =", c6) # c6 = -7
Conversion from a string
str_number = "42"
# Using int() function
number1 = int(str_number)
# number1 is 42
# Using int() function with base
number2 = int(str_number, 10)
# number2 is 42
# Using the + operator
number3 = int(str_number)
# number3 is 42
print("number1 is", number1)
print("number2 is", number2)
print("number3 is", number3)
Converting to a string
number = 42
# Using str() function
s1 = str(number)
# s1 is "42"
# Using concatenation with an empty string
s2 = "" + str(number)
# s2 is "42"
# Using string formatting with zero padding
s3 = "{:03d}".format(number)
# s3 is "042"
print("s1 =", s1) # s1 = 42
print("s2 =", s2) # s2 = 42
print("s3 =", s3) # s3 = 042
Getting random values
import random
def get_random_int(min_val, max_val):
return random.randint(min_val, max_val)
random_val = get_random_int(0, 2)
print(f"random is {random_val}")
# random is 0, 1, or 2
Numeral system
# decimal number system
decimal = 42
# octal number system
octal = 0o42
# octal is 34
# hexadecimal number system
hexadecimal = 0x42
# hexadecimal is 66
# binary number system
binary = 0b1010
# binary is 10
# 42 to decimal string
s_decimal = str(decimal)
# s_decimal is "42"
# 42 to hexadecimal string
s_hexadecimal = hex(decimal)
# s_hexadecimal is "0x2a"
# 42 to binary string
s_binary = bin(decimal)
# s_binary is "0b101010"
print("octal =", octal) # octal = 34
print("hexadecimal =", hexadecimal) # hexadecimal = 66
print("binary =", binary) # binary = 10
print("s_decimal =", s_decimal) # s_decimal = 42
print("s_hexadecimal =", s_hexadecimal) # s_hexadecimal = 0x2a
print("s_binary =", s_binary) # s_binary = 0b101010
Mathematical operations:
Decimal logarithm
import math
number = 1000
result = math.log10(number)
# result is 3.0
print(f"result is {result}") # result is 3.0
Exponentiation
number = 8
power = 3
result1 = number ** power
# result1 is 512
import math
result2 = math.pow(number, power)
# result2 is 512.0
print(f"result1 is {result1}") # result1 is 512
print(f"result2 is {result2}") # result2 is 512.0
Logarithm
number = 8
power = 3
result1 = number ** power
# result1 is 512
import math
result2 = math.pow(number, power)
# result2 is 512.0
print(f"result1 is {result1}") # result1 is 512
print(f"result2 is {result2}") # result2 is 512.0
Sine, cosine and tangent
import math
sin90 = math.sin(math.pi / 2)
# sin90 is 1.0
cos180 = math.cos(math.pi)
# cos180 is -1.0
tan45 = math.tan(math.pi / 4)
# tan45 is 0.9999999999999999
print(f"sin90 is {sin90}") # sin90 is 1.0
print(f"cos180 is {cos180}") # cos180 is -1.0
print(f"tan45 is {tan45}") # tan45 is 0.9999999999999999
Square root
import math
number = 100
result = math.sqrt(number)
# result is 10.0
print(f"result is {result}") # result is 10.0
min and max values
numbers = [2, 1, 3]
min_value = min(numbers)
# min_value is 1
max_value = max(numbers)
# max_value is 3
print(f"min_value is {min_value}") # min_value is 1
print(f"max_value is {max_value}") # max_value is 3
Strings:
Change the case of characters
def get_capitalize(word):
if not word:
return word
return word[0].upper() + word[1:].lower()
str = "Lower and Upper"
lower = str.lower()
# lower is "lower and upper"
upper = str.upper()
# upper is "LOWER AND UPPER"
capitalize = get_capitalize(str)
# capitalize is "Lower and upper"
print(f"lower is \"{lower}\"")
print(f"upper is \"{upper}\"")
print(f"capitalize is \"{capitalize}\"")
# Output:
# lower is "lower and upper"
# upper is "LOWER AND UPPER"
# capitalize is "Lower and upper"
Character replacement
str_value = "1-3-2"
str_value = str_value[:2] + "2" + str_value[3:4] + "3"
# str_value is "1-2-3"
print(f"str_value is \"{str_value}\"")
Characters count
def reverse(word):
# Characters count
char_count = len(word)
result = ""
for i in range(char_count - 1, -1, -1):
result += word[i]
return result
string_reverse = reverse("string")
# string_reverse = "gnirts"
print("string_reverse is", string_reverse)
# string_reverse is gnirts
Converting to a number
# Convert string to integer
str_number = "42"
# The first method
number1 = int(str_number)
# The second method (same as first in Python)
number2 = int(str_number)
print("number1 =", number1) # number1 = 42
print("number2 =", number2) # number2 = 42
# Convert string to double/float
# The first method
str_pi = "3.14"
pi = float(str_pi)
# The second method
str_exp = "2.71828"
exp = float(str_exp)
# The third method
str_half = "0,5"
half = float(str_half.replace(",", "."))
print("pi =", pi) # pi = 3.14
print("exp =", exp) # exp = 2.71828
print("half =", half) # half = 0.5
Empty strings
# Empty strings
some_empty_string = ""
another_empty_string = ""
if not some_empty_string:
print("string is empty")
if len(another_empty_string) == 0:
print("another string is empty")
# Output:
# string is empty
# another string is empty
Escaping characters
# \t Insert a tab.
# \b Insert a backspace.
# \n Insert a newline.
# \r Insert a carriage return.
# \' or ' Insert a single quote.
# \" Insert a double quote.
# \\ Insert a backslash character.
str = 'She said "Hello!" to me.'
# str is "She said "Hello!" to me."
print(f'str is "{str}"')
# str is "She said "Hello!" to me."
Getting substring
str = "one way ticket"
way1 = str[4:7]
# way1 is "way"
way2 = str[-10:-7]
# way2 is "way"
print(f'way1 is "{way1}"') # way1 is "way"
print(f'way2 is "{way2}"') # way2 is "way"
Iterating over a string
str = "level"
# Iterating without index
for c in str:
print(c)
# Iterating with index
for i in range(len(str)):
print(f'str[{i}] = {str[i]}')
# Output:
#l
#e
#v
#e
#l
# str[0] = l
# str[1] = e
# str[2] = v
# str[3] = e
# str[4] = l
Removing spaces
str = " Spaces "
trim_str = str.strip()
# trim_str is "Spaces"
print(f'"{trim_str}"') # "Spaces"
Replace multiple characters
import re
str = "1-/[=2/]=3"
separators = re.compile(r'[=/\\[\]]')
ar_str = separators.split(str)
str = "".join(ar_str)
# str is "1-23"
print(f'str is "{str}"')
# str is "1-23"
Split into an array
str_data = "1981|Kim Victorya|engineer"
arr_data = str_data.split("|")
year = int(arr_data[0])
# year is 1981
full_name = arr_data[1]
# full_name is "Kim Victorya"
position = arr_data[2]
# position is "engineer"
print("year is", year) # year is 1981
print(f"name is '{full_name}'") # name is 'Kim Victorya'
print(f"position is '{position}'") # position is 'engineer'
String multiplication
str_val = "7" * 3
# str_val is "777"
print(f'str is "{str_val}"') # str is "777"
String padding
str_val = "123"
len_val = 10
# Pad Start
pad_start1 = str_val.rjust(len_val)
# padStart1 is ' 123'
pad_start2 = str_val.zfill(len_val)
# padStart2 is '0000000123'
# Pad End
pad_end1 = str_val.ljust(len_val)
# padEnd1 is '123 '
pad_end2 = str_val.ljust(len_val, "=*")
# padEnd2 is '123=*=*=*='
print(f"padStart1 is '{pad_start1}'")
# padStart1 is ' 123'
print(f"padStart2 is '{pad_start2}'")
# padStart2 is '0000000123'
print(f"padEnd1 is '{pad_end1}'")
# padEnd1 is '123 '
print(f"padEnd2 is '{pad_end2}'")
# padEnd2 is '123=*=*=*='
String comparison
first = "A"
second = "B"
third = "A"
# String comparison
are_equal1 = first == second
# areEqual1 is False
are_not_equal = first != second
# areNotEqual is True
are_equal2 = first == third
# areEqual2 is True
more_than = first > second
# moreThan is False
print("areEqual1 is", are_equal1)
# areEqual1 is False
print("areEqual2 is", are_equal2)
# areEqual2 is True
print("areNotEqual is", are_not_equal)
# areNotEqual is True
print("moreThan is", more_than)
# moreThan is False
String concatenating
s1 = "three"
s2 = "two"
s3 = s1 + ", " + s2
s3 += ", one"
s_go = s3 + ", " + "go!"
# s_go is "three, two, one, go!"
print(f's_go is "{s_go}"')
# s_go is "three, two, one, go!"
String interpolation
# Since Python 3.6
font_size = 14
font_family = "Arial"
style = f"font-size: {font_size}; font-family: {font_family}"
# style is "font-size: 14; font-family: Arial"
print(f"style is '{style}'")
# Since Python 3.6
ar = [1, 2, 3]
print(f"length is {len(ar)}") # length is 3
print(f"ar[1] is {ar[1]}") # ar[1] is 2
print(f"all > 0: {all(i > 0 for i in ar)}")
# all > 0: True
Strings list concatenating
numbers = ["one", "two", "three"]
number_list = "; ".join(numbers)
# number_list is "one; two; three"
print(number_list) # one; two; three
Substring index
data_string = "Substring index"
index1 = data_string.find("string")
# index1 is 3
import re
index2 = re.search("string", data_string).start()
# index2 is 3
print(f"index1 is {index1}") # index1 is 3
print(f"index2 is {index2}") # index2 is 3
Substring inserting
class CustomString(str):
def insert(self, index, string):
return self[:index] + string + self[index:]
data_string = CustomString("string")
data_string = data_string.insert(0, "Sub")
print(data_string)
# Output: "Substring"
data_string = data_string.insert(9, "!")
print(data_string)
# Output: "Substring!"
data_string = data_string.insert(10, " inserting")
print(data_string)
# Output: "Substring! inserting"
Substring removing
class CustomString(str):
def remove(self, start, end=None):
if end is None:
end = start + 1
return self[:start] + self[end:]
data_string = CustomString("Substring removing!")
# Remove substring from index 9 to index 18
data_string = data_string.remove(9, 18)
print(data_string) # Output: "Substring!"
# Remove characters from index 0 to index 2 (keeping characters
from index 3 onwards)
data_string = data_string.remove(0, 3)
print(data_string) # Output: "string!"
Substring replacement
import re
# Simple replacements
start_string = "3, 2, 1, go!"
start_string = (start_string
.replace("1", "one")
.replace("2", "two")
.replace("3", "three"))
print(start_string)
# Output: "three, two, one, go!"
# Replace all occurrences
one_string = "1 1 1"
one_string = re.sub("1", "one", one_string)
print(one_string)
# Output: "one one one"
Substring searching
data_string = "Substring search"
# Check if data_string contains "string"
if "string" in data_string:
print('data_string contains "string"')
# Check if data_string starts with "Sub"
if data_string.startswith("Sub"):
print('data_string starts with "Sub"')
# Check if data_string ends with "search"
if data_string.endswith("search"):
print('data_string ends with "search"')
Tuple
# Using a tuple
one = (1, "one")
number_one = one[0] # number_one is 1
name_one = one[1] # name_one is "one"
# Using a dictionary
two = {"number": 2, "name": "two"}
number_two = two["number"] # number_two is 2
name_two = two["name"] # name_two is "two"
print(f'nameOne is "{name_one}"') # nameOne is "one"
print(f'numberOne is {number_one}') # numberOne is 1
print(f'nameTwo is "{name_two}"') # nameTwo is "two"
print(f'numberTwo is {number_two}') # numberTwo is 2
Work with Color
Working with colors in programming often involves representing,
manipulating, and displaying colors using various formats and
operations.
Color to HTML color
orange = 0xffc80080
# Extracting the RGB part (ignoring alpha)
x = (orange >> 8) & 0xffffff
html_color = f"#{x:06x}"
print(f'style="color: {html_color}"')
# style="color: #ffc800"
# Including transparency
html_color_with_alpha = f"#{orange:08x}"
print(f'htmlColor is {html_color_with_alpha}')
# htmlColor is #ffc80080
Color to RGB
orange = 0xffc80080
red = (orange >> 24) & 0xff
green = (orange >> 16) & 0xff
blue = (orange >> 8) & 0xff
alpha = orange & 0xff
print("red is", red) # red is 255
print("green is", green) # green is 200
print("blue is", blue) # blue is 0
print("alpha is", alpha) # alpha is 128
HTML color to RGB
orange = "#FFC80080"
# Convert the hex string to an integer
x = int(orange[1:], 16)
# Extract the RGBA components
red = (x >> 24) & 0xff
green = (x >> 16) & 0xff
blue = (x >> 8) & 0xff
alpha = x & 0xff
print("red is", red) # red is 255
print("green is", green) # green is 200
print("blue is", blue) # blue is 0
print("alpha is", alpha) # alpha is 128
RGB to Color
def int_to_hex(i):
return f"{i:02x}"
red = 51
green = 255
blue = 51
alpha = 128
# Combine RGB values into a hex string
c_green = f"#{int_to_hex(red)}{int_to_hex(green)}
{int_to_hex(blue)}"
print(c_green) # Output: #33ff33
# Add the alpha value to the hex string
c_green_with_alpha = f"{c_green}{int_to_hex(alpha)}"
print(c_green_with_alpha)
# Output: #33ff3380
RGB to HTML color
red = 51
green = 255
blue = 51
alpha = 128
# Convert RGB values to an integer
value = (red << 16) + (green << 8) + blue
# Convert the integer to a hex string (without alpha)
html_color = f"{value:06x}"
print(f'style="color: #{html_color}"')
# Output: style="color: #33ff33"
# Include alpha and convert to hex string
value = (value << 8) + alpha
html_color_with_alpha = f"{value:08x}"
print(f'htmlColor is #{html_color_with_alpha}')
# Output: htmlColor is #33ff3380
Work with Database (DB)
Working with databases in software development involves
managing data storage, retrieval, and manipulation using structured
query languages (SQL) or NoSQL approaches.
Connect to the DB:
Connect to Access
# pip install pyodbc
import pyodbc
# Connection string for Access database
access_driver = '{Microsoft Access Driver (*.mdb, *.accdb)}'
access_db_file = 'path/to/your/database.accdb'
# Replace with the path to your Access database file
# Establishing a connection
try:
conn = pyodbc.connect(driver=access_driver,
dbq=access_db_file)
print("Connected to the database")
except pyodbc.Error as e:
print(f"Failed to connect to the database: {e}")
exit()
# Creating a cursor to execute SQL queries
cursor = conn.cursor()
try:
# Execute a SELECT query
cursor.execute("SELECT * FROM YourTableName")
result = cursor.fetchall()
print(result)
except pyodbc.Error as e:
print(f"Error executing query: {e}")
finally:
# Close cursor and connection
cursor.close()
conn.close()
Connect to FireBird
# pip install fdb
import fdb
options = {
'host': 'HostName',
'port': 3050,
'database': 'DbName.fdb',
'user': 'UserName',
'password': 'Password'
}
# Connect to the Firebird database
try:
conn = fdb.connect(**options)
print("Connected to the database")
except fdb.Error as e:
print(f"Failed to connect to the database: {e}")
exit()
# Create a cursor to execute SQL queries
cursor = conn.cursor()
try:
# Execute a SELECT query
cursor.execute("SELECT * FROM country")
result = cursor.fetchall()
print(result)
except fdb.Error as e:
print(f"Error executing query: {e}")
finally:
# Close cursor and connection
cursor.close()
conn.close()
Connect to MySql
# pip install mysql-connector-python
import mysql.connector
# Establishing a connection
try:
conn = mysql.connector.connect(
host="localhost",
user="root",
password="password",
database="world"
)
print("Connected to the database")
except mysql.connector.Error as e:
print(f"Failed to connect to the database: {e}")
exit()
# Creating a cursor to execute SQL queries
cursor = conn.cursor()
try:
# Execute a SELECT query
sql = "SELECT Language, Percentage FROM countrylanguage
WHERE CountryCode = 'RUS' ORDER BY Percentage DESC"
cursor.execute(sql)
result = cursor.fetchall()
print(result)
except mysql.connector.Error as e:
print(f"Error executing query: {e}")
finally:
# Close cursor and connection
cursor.close()
conn.close()
Connect to Oracle
# pip install cx_Oracle
import cx_Oracle
# Establishing a connection
try:
conn = cx_Oracle.connect(
user="UserName",
password="Password",
dsn="localhost/DataBaseName"
)
print("Connected to the database")
except cx_Oracle.DatabaseError as e:
print(f"Failed to connect to the database: {e}")
exit()
# Creating a cursor to execute SQL queries
cursor = conn.cursor()
try:
# Execute a SELECT query
sql = "SELECT * FROM tablename"
cursor.execute(sql)
result = cursor.fetchall()
print(result)
except cx_Oracle.DatabaseError as e:
print(f"Error executing query: {e}")
finally:
# Close cursor and connection
cursor.close()
conn.close()
Connect to PostgreSQL
# pip install psycopg2
import psycopg2
# Establishing a connection
try:
conn = psycopg2.connect(
user="UserName",
password="Password",
host="localhost",
port="5432",
database="DatabaseName"
)
print("Connected to the database")
except psycopg2.Error as e:
print(f"Failed to connect to the database: {e}")
exit()
# Creating a cursor to execute SQL queries
cursor = conn.cursor()
try:
# Execute a SELECT query
sql = "SELECT * FROM country"
cursor.execute(sql)
result = cursor.fetchall()
print(result)
except psycopg2.Error as e:
print(f"Error executing query: {e}")
finally:
# Close cursor and connection
cursor.close()
conn.close()
Connect to SQL Server
# pip install pyodbc
import pyodbc
# Establishing a connection
try:
conn = pyodbc.connect(
'DRIVER={SQL Server};'
'SERVER=serverName\\instanceName;'
'DATABASE=DatabaseName;'
'UID=UserName;'
'PWD=Password;'
'Trusted_Connection=no;'
)
print("Connected to the database")
except pyodbc.Error as e:
print(f"Failed to connect to the database: {e}")
exit()
# Creating a cursor to execute SQL queries
cursor = conn.cursor()
try:
# Execute a SELECT query
sql = "SELECT * FROM country"
cursor.execute(sql)
result = cursor.fetchall()
print(result)
except pyodbc.Error as e:
print(f"Error executing query: {e}")
finally:
# Close cursor and connection
cursor.close()
conn.close()
Connect to SQLite
import sqlite3
# Establishing a connection
try:
conn = sqlite3.connect('DatabaseName.db')
print("Connected to the database")
except sqlite3.Error as e:
print(f"Failed to connect to the database: {e}")
exit()
# Creating a cursor to execute SQL queries
cursor = conn.cursor()
try:
# Execute a SELECT query
sql = "SELECT * FROM countrylanguage"
cursor.execute(sql)
result = cursor.fetchall()
for row in result:
print(row)
except sqlite3.Error as e:
print(f"Error executing query: {e}")
finally:
# Close cursor and connection
cursor.close()
conn.close()
Execute SQL command
import sqlite3
# Establishing a connection
try:
conn = sqlite3.connect('DatabaseName.db')
print("Connected to the database")
except sqlite3.Error as e:
print(f"Failed to connect to the database: {e}")
exit()
# Creating a cursor to execute SQL commands
cursor = conn.cursor()
try:
# Execute the DELETE command with a parameter
sql = "DELETE FROM color WHERE green = ?"
cursor.execute(sql, (150,))
# Commit the transaction
conn.commit()
print("Rows deleted successfully!")
except sqlite3.Error as e:
print(f"Error executing command: {e}")
finally:
# Close cursor and connection
cursor.close()
conn.close()
Execute SQL query
import sqlite3
# Establishing a connection
try:
conn = sqlite3.connect('DatabaseName.db')
print("Connected to the database")
except sqlite3.Error as e:
print(f"Failed to connect to the database: {e}")
exit()
# Creating a cursor to execute SQL queries
cursor = conn.cursor()
try:
# Execute the SQL query
sql = "SELECT Language, Percentage FROM countrylanguage
WHERE CountryCode = 'USA' ORDER BY Percentage DESC"
cursor.execute(sql)
# Fetch all rows
rows = cursor.fetchall()
# Print results
for row in rows:
print(row[0], ": ", row[1])
except sqlite3.Error as e:
print(f"Error executing query: {e}")
finally:
# Close cursor and connection
cursor.close()
conn.close()
SQL query with parameters
import sqlite3
# Establishing a connection
try:
conn = sqlite3.connect('DatabaseName.db')
print("Connected to the database")
except sqlite3.Error as e:
print(f"Failed to connect to the database: {e}")
exit()
# Creating a cursor to execute SQL queries
cursor = conn.cursor()
try:
# Define the SQL query with parameters
sql = "SELECT Language, Percentage FROM countrylanguage
WHERE CountryCode = ? AND Percentage > ?"
# Execute the SQL query with parameters
cursor.execute(sql, ("USA", 0.5))
# Fetch all rows
rows = cursor.fetchall()
# Print results
for row in rows:
print(row[0], ": ", row[1])
except sqlite3.Error as e:
print(f"Error executing query: {e}")
finally:
# Close cursor and connection
cursor.close()
conn.close()
Work with Files
Working with files in software development involves various
operations related to reading, writing, and manipulating files stored
on disk.
Archives:
Packing a zip file
import zipfile
import os
source_path = "data"
zip_file = "data.zip"
zip_directory(source_path, zip_file)
Packing a zip file with a password
import os
import pyzipper
def zip_directory_with_password(directory, zip_file, password):
with pyzipper.AESZipFile(zip_file, 'w',
compression=pyzipper.ZIP_DEFLATED,
encryption=pyzipper.WZ_AES) as zipf:
zipf.setpassword(password.encode())
for root, _, files in os.walk(directory):
for file in files:
zipf.write(os.path.join(root, file),
os.path.relpath(os.path.join(root, file), directory))
source_path = "data"
zip_file = "data.zip"
password = "123"
zip_directory_with_password(source_path, zip_file, password)
Unpacking a zip file
import zipfile
def unzip(zip_file, destination):
with zipfile.ZipFile(zip_file, 'r') as zip_ref:
zip_ref.extractall(destination)
zip_file = "data.zip"
destination = "tmp"
unzip(zip_file, destination)
Basic operations:
Check if the file exists
import os
file_path = "file.txt"
# Asynchronously
if os.path.exists(file_path):
print("File exists!")
else:
print("File does not exist!")
Combining two parts of a path
import os
work_dir = os.path.dirname(os.path.abspath(__file__))
data_dir = os.path.join(work_dir, 'Data')
print("dataDir is", data_dir)
Copy a directory
import shutil
import os
source_path = "./data"
destination_path = "./data_copy"
try:
# Use shutil.copytree to copy the entire directory
shutil.copytree(source_path, destination_path,
dirs_exist_ok=True)
print("Directory copied successfully!")
except shutil.Error as e:
print("Error:", e)
except OSError as e:
print("OS error:", e)
Create a directory
// using Node.js
// npm i @types/node
const fs = require("fs");
let path = "./data";
// Asyncronously:
fs.mkdir(path, (err) => {
if (err) console.log("Error:", err);
else console.log("Sucessfully created!");
});
// Synchronously:
if (!fs.existsSync(path)) {
fs.mkdirSync(path);
}
Delete a directory
import shutil
import os
path = "./data"
# Synchronously:
if os.path.exists(path):
shutil.rmtree(path)
print("Successfully deleted!")
else:
print("Directory does not exist.")
Delete a directory with data
import shutil
import os
path = "./data"
# Synchronously:
if os.path.exists(path):
shutil.rmtree(path)
print("Successfully deleted!")
else:
print("Directory does not exist.")
Delete a file
import os
file_path = "file.txt"
try:
os.remove(file_path)
print("Deleted!")
except OSError as e:
print(f"Error: {e.strerror}")
File copying
import shutil
file_path = "file.txt"
file_path_to = "file_copy.txt"
try:
shutil.copyfile(file_path, file_path_to)
print("File copied!")
except OSError as e:
print(f"Error: {e.strerror}")
File moving
import shutil
file_path = "file.txt"
new_file_path = "file_new.txt"
try:
shutil.move(file_path, new_file_path)
print("File moved successfully!")
except OSError as e:
print(f"Error: {e.strerror}")
Get the working directory
import os
# Get the current working directory
current_working_directory = os.getcwd()
print(f"Current working directory: {current_working_directory}")
Getting file properties
import os
import stat
import time
file_path = "file.txt"
# Get file properties
file_stats = os.stat(file_path)
# File size
file_size = file_stats.st_size
# File modification date
date_changes = time.ctime(file_stats.st_mtime)
# File creation date (Note: on some Unix systems, st_ctime is the
change time)
creation_date = time.ctime(file_stats.st_ctime)
# Can read, write, and execute
can_rwe = (file_stats.st_mode & stat.S_IRWXU) == stat.S_IRWXU
# File extension
extension = os.path.splitext(file_path)[1]
# File name
file_name = os.path.basename(file_path)
# File name without extension
file_name_only = os.path.splitext(file_name)[0]
# File directory
file_dir = os.path.dirname(file_path)
print("fileSize is", file_size, "bytes")
print("dateChanges is", date_changes)
print("creationDate is", creation_date)
print("canRWE is", can_rwe)
print("extension is", extension)
print("fileName is", file_name)
print("fileNameOnly is", file_name_only)
print("fileDir is", file_dir)
List of files in the directory
import os
# Directory path
dir_path = os.getcwd()
# Synchronously
files = os.listdir(dir_path)
for file in files:
print(file)
# Asynchronously (using asyncio and aiofiles)
import asyncio
import aiofiles.os
async def list_files_async(dir_path):
files = await aiofiles.os.listdir(dir_path)
for file in files:
print(file)
# Running the async function
asyncio.run(list_files_async(dir_path))
Binary files:
Read array from a file
import struct
file_path = "file.out"
# Synchronously
try:
with open(file_path, "rb") as file:
data = file.read()
numbers = struct.unpack(f'{len(data) // 4}i', data)
print("numbers is", numbers)
except Exception as e:
print("Error:", e)
Read dictionary from a file
import json
file_path = "file.out"
# Synchronously
try:
with open(file_path, "r", encoding="utf-8") as file:
data = file.read()
map = json.loads(data)
print("map is", map)
except Exception as e:
print("Error:", e)
Reading a binary file
file_path = "file.out"
# Asynchronously (using asyncio and aiofiles)
import asyncio
import aiofiles
async def read_binary_file(file_path):
try:
async with aiofiles.open(file_path, 'rb') as file:
data = await file.read()
print("Data is", data)
bytes_array = bytearray(data)
print("bytes is", bytes_array)
except Exception as e:
print("Error:", e)
# Run the asynchronous function
asyncio.run(read_binary_file(file_path))
# Synchronously
try:
with open(file_path, 'rb') as file:
data = file.read()
print("Data is", data)
bytes_array = bytearray(data)
print("bytes is", bytes_array)
except Exception as e:
print("Error:", e)
Write array to a file
import array
numbers = [1, 2, -3]
data = array.array('i', numbers)
# 'i' indicates signed integer
file_path = "file.out"
# Asynchronously (using asyncio and aiofiles)
import asyncio
import aiofiles
async def write_binary_file(numbers, file_path):
try:
async with aiofiles.open(file_path, 'wb') as file:
file.write(numbers.tobytes())
print("Data written to file!")
except Exception as e:
print("Error:", e)
# Run the asynchronous function
asyncio.run(write_binary_file(data, file_path))
# Synchronously
with open(file_path, 'wb') as file:
file.write(data.tobytes())
print("Data written to file!")
Write a directory to a file
import json
# Define your map (equivalent to JavaScript Map)
map_data = {
1: "one",
2: "two"
}
file_path = "file.out"
# Convert map to JSON string
json_data = json.dumps(map_data)
# Write JSON string to file
with open(file_path, 'w', encoding='utf-8') as file:
file.write(json_data)
print("Data written to file:", file_path)
Writing a binary file
import array
# Data to write (equivalent to Uint8Array in JavaScript)
data = array.array('B', [120, 64, 97])
file_path = "file.out"
# Asynchronously equivalent in Python (write binary mode)
with open(file_path, 'wb') as file:
file.write(data)
print("Data written to file:", file_path)
Text files:
Append text to a file
file_path = "file.txt"
# Asynchronously equivalent in Python (append mode)
with open(file_path, 'a') as file:
file.write("\nLine 4")
print("Appended:", file_path)
# Synchronously equivalent in Python (append mode)
try:
with open(file_path, 'a') as file:
file.write("\nLine 3")
print("Text added successfully:", file_path)
except Exception as e:
print("Error:", e)
Read file line by line
file_path = "file.txt"
# Asynchronously equivalent in Node.js (read line by line)
with open(file_path, 'r') as file:
for line in file:
print("Line from file:", line.rstrip())
# rstrip() to remove newline characters
Read from a file
import asyncio
async def read_file_async(file_path):
try:
with open(file_path, 'r') as file:
text = file.read()
return text
except FileNotFoundError:
print(f"File '{file_path}' not found.")
except Exception as e:
print(f"Error reading file '{file_path}': {e}")
async def main():
file_path = "file.txt"
text = await read_file_async(file_path)
if text:
print(text)
# Run the main coroutine
asyncio.run(main())
Write to a file
import asyncio
async def write_file_async(file_path, content):
try:
with open(file_path, 'w') as file:
file.write(content)
print(f"Text written to '{file_path}' asynchronously!")
except Exception as e:
print(f"Error writing to '{file_path}': {e}")
async def main():
file_path = "file.txt"
content = "Line 1\nLine 2"
await write_file_async(file_path, content)
# Run the main coroutine
asyncio.run(main())
XML files:
Reading XML file
import xml.etree.ElementTree as ET
# XML example:
# <Lines>
# <Line Id="1">one</Line>
# <Line Id="2">two</Line>
# </Lines>
def read_xml_file(file_path):
try:
# Parse the XML file
tree = ET.parse(file_path)
root = tree.getroot()
# Access elements and attributes
for line in root.findall('Line'):
line_id = line.get('Id')
line_value = line.text
print(f"Line {line_id} value: {line_value}")
except Exception as e:
print(f"Error reading XML file '{file_path}': {e}")
# File path
file_path = "data/data.xml"
# Read the XML file
read_xml_file(file_path)
Writing XML file
from lxml import etree
# XML example:
# <Line>
# <Line Id="1">one</Line>
# <Line Id="2">two</Line>
# </Line>
lines = etree.Element("Lines")
line = etree.SubElement(lines, "Line")
line.set("Id", "1")
line.text = "one"
line = etree.SubElement(lines, "Line")
line.set("Id", "2")
line.text = "two"
xml_text = etree.tostring(
lines, pretty_print=True, xml_declaration=True,
encoding="utf-8"
).decode("utf-8")
file_name = "data.xml"
with open(file_name, "w") as text_file:
print(xml_text, file=text_file)
Thanks for reading this great book!
In every line of code, they have woven a story of
innovation and creativity. This book has been your
compass in the vast world of Python.
Close this chapter knowing that every challenge
overcome is an achievement, and every solution is a
step toward mastery.
Your code is the melody that gives life to projects.
May they continue creating and programming with
passion!
Thank you for allowing me to be part of your
journey.
With gratitude,
Hernando Abella
Author of Python Cook Book