Python Set and Collection Operations
Python Set and Collection Operations
difference(b)
{1, 2, 3}
symmetric_diff = a ^ b # or a.symmetric_difference(b)
{1, 2, 3, 6, 7, 8}
Subset/superset checking
is_subset = {1, 2}.issubset(a) # True
is_superset = [Link]({1, 2}) # True
numbers = [1, 2, 2, 3, 3, 3, 4, 5, 5]
unique = remove_duplicates(numbers)
print(unique) # [1, 2, 3, 4, 5]
**Definition:** The `collections` module provides specialized container datatypes that extend built-in types with additional fu
**Why Use It:** Solves common problems efficiently, provides optimized data structures, and simplifies complex operations
**Example:**
```````````python
from collections import Counter, defaultdict, deque, OrderedDict, namedtuple, ChainMap
print(dict(by_length))
# {5: ['apple'], 3: ['pie'], 6: ['banana', 'cherry'], 4: ['date']}
# Queue operations
queue = deque(['a', 'b', 'c'])
[Link]('d') # Add to right
[Link]('z') # Add to left
right = [Link]() # Remove from right
left = [Link]() # Remove from left
def get_recent(self):
return list([Link])
history = RecentHistory(3)
for i in range(5):
[Link](f"Item {i}")
print(history.get_recent()) # ['Item 2', 'Item 3', 'Item 4']
ordered = OrderedDict()
ordered['first'] = 1
ordered['second'] = 2
ordered['third'] = 3
# Move to end
ordered.move_to_end('first')
print(list([Link]())) # ['second', 'third', 'first']
---
## 13. Comprehensions
**Definition:** List comprehensions provide a concise way to create lists by applying an expression to each item in an iterabl
**Why Use It:** More readable than loops, faster execution, Pythonic style, and reduces code verbosity.
**Example:**
```````````python
# Basic list comprehension
squares = [x**2 for x in range(10)]
print(squares) # [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
# Traditional equivalent
squares = []
for x in range(10):
[Link](x**2)
# Multiple conditions
result = [x for x in range(50) if x % 2 == 0 if x % 5 == 0]
print(result) # [0, 10, 20, 30, 40]
# If-else in comprehension
labels = ['even' if x % 2 == 0 else 'odd' for x in range(10)]
print(labels) # ['even', 'odd', 'even', 'odd', ...]
# Nested list comprehension
matrix = [[i*j for j in range(1, 4)] for i in range(1, 4)]
print(matrix)
# [[1, 2, 3], [2, 4, 6], [3, 6, 9]]
# String manipulation
words = ['hello', 'world', 'python']
upper_words = [[Link]() for word in words]
print(upper_words) # ['HELLO', 'WORLD', 'PYTHON']
# Cartesian product
colors = ['red', 'blue']
sizes = ['S', 'M', 'L']
combinations = [(color, size) for color in colors for size in sizes]
print(combinations)
# [('red', 'S'), ('red', 'M'), ('red', 'L'), ('blue', 'S'), ('blue', 'M'), ('blue', 'L')]
```````````
---
**Definition:** Dictionary comprehensions create dictionaries in a concise way by iterating over an iterable and constructing
**Why Use It:** Creates dictionaries elegantly, filters and transforms data simultaneously, and improves code readability.
**Example:**
```````````python
# Basic dictionary comprehension
squares = {x: x**2 for x in range(6)}
print(squares) # {0: 0, 1: 1, 2: 4, 3: 9, 4: 16, 5: 25}
# With condition
numbers = {x: x**2 for x in range(10) if x % 2 == 0}
print(numbers) # {0: 0, 2: 4, 4: 16, 6: 36, 8: 64}
# Filter dictionary
scores = {'Alice': 85, 'Bob': 92, 'Charlie': 78, 'Diana': 95}
high_scores = {name: score for name, score in [Link]() if score >= 90}
print(high_scores) # {'Bob': 92, 'Diana': 95}
text = "hello"
freq = char_frequency(text)
print(freq) # {'h': 1, 'e': 1, 'l': 2, 'o': 1}
# Group by property
words = ['apple', 'banana', 'apricot', 'blueberry', 'cherry']
by_first_letter = {}
for word in words:
by_first_letter.setdefault(word[0], []).append(word)
---
**Definition:** Set comprehensions create sets using a syntax similar to list comprehensions, automatically removing duplica
**Why Use It:** Creates unique collections efficiently, combines filtering with transformation, and leverages set performance
**Example:**
```````````python
# Basic set comprehension
squares = {x**2 for x in range(10)}
print(squares) # {0, 1, 4, 9, 16, 25, 36, 49, 64, 81}
# With condition
even_squares = {x**2 for x in range(10) if x % 2 == 0}
print(even_squares) # {0, 4, 16, 36, 64}
---
**Definition:** Generator expressions are similar to list comprehensions but create generators (lazy evaluation) instead of list
**Why Use It:** Memory efficient for large datasets, faster for single-pass operations, and ideal when you don't need all valu
**Example:**
```````````python
# Generator expression
squares_gen = (x**2 for x in range(10))
print(type(squares_gen)) # <class 'generator'>
# Consume generator
for square in squares_gen:
print(square, end=' ')
# Output: 0 1 4 9 16 25 36 49 64 81
# Memory comparison
import sys
# With condition
even_sum = sum(x for x in range(100) if x % 2 == 0)
print(even_sum)
# String processing
text = "The quick brown fox jumps over the lazy dog"
word_lengths = (len(word) for word in [Link]())
avg_length = sum(word_lengths) / len([Link]())
print(f"Average word length: {avg_length}")
```````````
---
**Definition:** Lambda functions are small, anonymous functions defined with the `lambda` keyword, limited to a single exp
**Why Use It:** Provides concise syntax for simple functions, useful for short-lived operations, perfect for higher-order func
**Example:**
```````````python
# Basic lambda
add = lambda x, y: x + y
print(add(5, 3)) # Output: 8
# Traditional function equivalent
def add_traditional(x, y):
return x + y
# Single parameter
square = lambda x: x**2
print(square(5)) # Output: 25
# No parameters
get_pi = lambda: 3.14159
print(get_pi()) # Output: 3.14159
# Conditional in lambda
max_value = lambda x, y: x if x > y else y
print(max_value(10, 20)) # Output: 20
---
**Definition:** Lambda functions are commonly used with built-in functions like `map()`, `filter()`, and `sorted()` for data tra
**Why Use It:** Eliminates need for separate function definitions, makes code more concise, and is idiomatic Python for sim
**Example:**
```````````python
# map() - apply function to all items
numbers = [1, 2, 3, 4, 5]
doubled = list(map(lambda x: x * 2, numbers))
print(doubled) # [2, 4, 6, 8, 10]
---
**Definition:** `reduce()` from `functools` applies a function cumulatively to items in an iterable, reducing it to a single valu
**Why Use It:** Performs cumulative operations, aggregates data, and implements custom reduction logic.
**Example:**
```````````python
from functools import reduce
# How it works:
# ((((1 + 2) + 3) + 4) + 5) = 15
# Find maximum
maximum = reduce(lambda x, y: x if x > y else y, numbers)
print(maximum) # 5
print(factorial(5)) # 120
# Merge dictionaries
dicts = [{'a': 1}, {'b': 2}, {'c': 3}]
merged = reduce(lambda x, y: {**x, **y}, dicts)
print(merged) # {'a': 1, 'b': 2, 'c': 3}
```````````
---
**Definition:** Lambda functions can be stored in data structures like dictionaries and lists to create callable collections.
**Why Use It:** Creates function mappings, implements simple dispatching, and provides flexible callback systems.
**Example:**
```````````python
# Dictionary of operations
operations = {
'add': lambda x, y: x + y,
'subtract': lambda x, y: x - y,
'multiply': lambda x, y: x * y,
'divide': lambda x, y: x / y if y != 0 else None
}
# Use operations
result = operations['add'](10, 5)
print(result) # 15
result = operations['multiply'](10, 5)
print(result) # 50
# List of validators
validators = [
lambda x: len(x) >= 8,
lambda x: any([Link]() for c in x),
lambda x: any([Link]() for c in x)
]
def validate_password(password):
"""Check if password meets all criteria"""
return all(validator(password) for validator in validators)
# Event handlers
event_handlers = {
'click': lambda: print("Button clicked!"),
'hover': lambda: print("Mouse over"),
'keypress': lambda: print("Key pressed")
}
def trigger_event(event_name):
handler = event_handlers.get(event_name)
if handler:
handler()
# Sorting configurations
sort_options = {
'name': lambda item: item['name'],
'age': lambda item: item['age'],
'score': lambda item: item['score']
}
data = [
{'name': 'Alice', 'age': 30, 'score': 85},
{'name': 'Bob', 'age': 25, 'score': 92},
{'name': 'Charlie', 'age': 35, 'score': 78}
]
sorted_by_score = sorted(data, key=sort_options['score'], reverse=True)
for item in sorted_by_score:
print(item['name'], item['score'])
```````````
---
**Definition:** Python provides built-in functions for common mathematical operations without requiring imports.
**Why Use It:** Convenient for basic math operations, optimized for performance, and universally available.
**Example:**
```````````python
# abs() - absolute value
print(abs(-10)) # 10
print(abs(3.14)) # 3.14
print(abs(-5.7)) # 5.7
---
**Definition:** Functions that convert values from one data type to another.
**Why Use It:** Essential for data processing, user input handling, and type compatibility.
**Example:**
```````````python
# int() - convert to integer
print(int("123")) # 123
print(int(3.14)) # 3 (truncates)
print(int("FF", 16)) # 255 (hexadecimal)
print(int("1010", 2)) # 10 (binary)
result = calculate(5, 3)
print(calculate.__name__) # Output: calculate
print(calculate.__doc__) # Output: Add two numbers
```````````
---
**Definition:** Decorators that modify or enhance entire classes, similar to function decorators but operating on class definiti
**Why Use It:** Adds functionality to all class instances, implements singleton patterns, adds automatic registration, or modi
**Example:**
```````````python
# Basic class decorator
def add_greeting(cls):
"""Add greeting method to class"""
[Link] = lambda self: f"Hello from {[Link]}"
return cls
@add_greeting
class Person:
def __init__(self, name):
[Link] = name
person = Person("Alice")
print([Link]()) # Output: Hello from Alice
return get_instance
@singleton
class Database:
def __init__(self):
print("Database initialized")
[Link] = "Connected"
def register_plugin(name):
"""Register class as a plugin"""
def decorator(cls):
REGISTERED_PLUGINS[name] = cls
return cls
return decorator
@register_plugin("csv_processor")
class CSVProcessor:
def process(self, data):
return f"Processing CSV: {data}"
@register_plugin("json_processor")
class JSONProcessor:
def process(self, data):
return f"Processing JSON: {data}"
---
**Definition:** Python provides built-in decorators like `@property`, `@staticmethod`, `@classmethod` for common patterns
**Why Use It:** Leverages Python's standard functionality, makes code more Pythonic, and follows established patterns.
**Example:**
```````````python
# @property decorator
class Temperature:
def __init__(self, celsius):
self._celsius = celsius
@property
def celsius(self):
"""Get temperature in Celsius"""
return self._celsius
@property
def fahrenheit(self):
"""Get temperature in Fahrenheit"""
return (self._celsius * 9/5) + 32
temp = Temperature(25)
print([Link]) # Output: 25
print([Link]) # Output: 77.0
@staticmethod
def add(a, b):
"""Static method - no self or cls"""
return a + b
@classmethod
def circle_area(cls, radius):
"""Class method - receives cls"""
return [Link] * radius ** 2
@lru_cache(maxsize=128)
def fibonacci(n):
"""Cached Fibonacci calculation"""
if n < 2:
return n
return fibonacci(n-1) + fibonacci(n-2)
---
**Definition:** Context managers handle setup and cleanup of resources automatically using the `with` statement, ensuring p
**Why Use It:** Prevents resource leaks, guarantees cleanup even on errors, makes code cleaner and more reliable.
**Example:**
```````````python
# File handling with context manager
with open('[Link]', 'w') as file:
[Link]("Hello, World!")
# File automatically closed here
lock = [Link]()
def safe_operation():
with lock:
# Critical section - only one thread at a time
print("Performing thread-safe operation")
# Lock automatically released
---
**Definition:** Create custom context managers by implementing `__enter__()` and `__exit__()` methods in a class.
**Why Use It:** Encapsulates resource management logic, provides reusable resource handling, and follows Python best prac
**Example:**
```````````python
# File manager with logging
class FileManager:
"""Context manager for file operations"""
def __enter__(self):
"""Setup - open file"""
print(f"Opening {[Link]}")
[Link] = open([Link], [Link])
return [Link]
class Timer:
"""Context manager to measure execution time"""
def __enter__(self):
[Link] = [Link]()
return self
# Using timer
with Timer():
# Some time-consuming operation
total = sum(range(1000000))
# Output: Elapsed time: 0.0234 seconds
class TemporaryDirectory:
"""Context manager for temporary directory"""
def __enter__(self):
self.temp_dir = [Link]()
print(f"Created temporary directory: {self.temp_dir}")
return self.temp_dir
---
**Definition:** Use the `@contextmanager` decorator from `contextlib` to create context managers using generator functions
**Why Use It:** Simpler syntax than class-based approach, perfect for straightforward resource management, more concise c
**Example:**
```````````python
from contextlib import contextmanager
with simple_context():
print("Inside context")
# Output:
# Entering context
# Inside context
# Exiting context
@contextmanager
def change_directory(path):
"""Temporarily change working directory"""
original_dir = [Link]()
try:
[Link](path)
yield
finally:
[Link](original_dir)
print(f"Current: {[Link]()}")
with change_directory('/tmp'):
print(f"Inside with: {[Link]()}")
print(f"After with: {[Link]()}")
# Usage
class FakeConnection:
pass
---
### Suppressing Exceptions with Context Managers
**Definition:** The `[Link]` context manager allows you to ignore specific exceptions without try-except blocks
**Why Use It:** Cleaner code for expected exceptions, improves readability, and reduces boilerplate error handling.
**Example:**
```````````python
from contextlib import suppress
import os
# Without suppress
try:
[Link]('file_that_might_not_exist.txt')
except FileNotFoundError:
pass
# Old way
try:
del config['missing_key']
except KeyError:
pass
# New way
with suppress(KeyError):
del config['missing_key']
---
**Definition:** Regular expressions (regex) are patterns used to match character combinations in strings, providing powerful
**Why Use It:** Validates input formats, extracts data from text, searches complex patterns, and performs sophisticated text r
**Example:**
```````````python
import re
# Basic search
text = "My phone number is 123-456-7890"
pattern = r'\d{3}-\d{3}-\d{4}' # Pattern for phone number
# Match at beginning
text = "Python is awesome"
if [Link](r'Python', text):
print("Text starts with Python")
# Full match
if [Link](r'\d{3}-\d{4}', '123-4567'):
print("Exact match found")
## Table of Contents
---
### Variables
**Definition:** Variables are named containers that store data values in memory. Python is dynamically typed, meaning you d
**Why Use It:** Variables allow you to store and manipulate data throughout your program, making code reusable and maint
**Example:**
``````````python
# Simple variable assignment
name = "Alice" # String variable
age = 30 # Integer variable
height = 5.7 # Float variable
is_student = False # Boolean variable
# Multiple assignment
x, y, z = 1, 2, 3 # Assign multiple values at once
a = b = c = 10 # Assign same value to multiple variables
---
**Definition:** Data types define the kind of value a variable can hold. Python has several built-in data types.
**Why Use It:** Different data types are optimized for different operations. Using the right type improves performance and p
**Example:**
``````````python
# Integer
count = 100
print(type(count)) # <class 'int'>
# Float
price = 19.99
print(type(price)) # <class 'float'>
# String
message = "Hello, World!"
print(type(message)) # <class 'str'>
# Boolean
is_active = True
print(type(is_active)) # <class 'bool'>
# Complex numbers
complex_num = 3 + 4j
print(type(complex_num)) # <class 'complex'>
# None type
result = None
print(type(result)) # <class 'NoneType'>
``````````
---
**Definition:** Type checking verifies the data type of a variable. Type conversion transforms data from one type to another.
**Why Use It:** Ensures data integrity, prevents errors, and allows operations between different types.
**Example:**
``````````python
# Type checking
age = 25
print(isinstance(age, int)) # True - checks if age is an integer
print(isinstance(age, str)) # False
---
## 2. Control Flow
**Why Use It:** Allows your program to make decisions and execute different paths of code based on conditions, making pro
**Example:**
``````````python
# Grade calculator
score = 85
print(f"Your grade is: {grade}") # Output: Good job! Your grade is: B
``````````
---
**Why Use It:** Makes code more readable and compact for simple conditional assignments.
**Example:**
``````````python
# Traditional if-else
age = 20
if age >= 18:
status = "Adult"
else:
status = "Minor"
---
**Definition:** A loop that iterates over a sequence (list, tuple, string, range) and executes a block of code for each item.
**Why Use It:** Automates repetitive tasks, processes collections of data, and eliminates the need for manual repetition.
**Example:**
``````````python
# Basic for loop with range
for i in range(5):
print(f"Count: {i}")
# Output: Count: 0, Count: 1, Count: 2, Count: 3, Count: 4
---
**Why Use It:** Useful when you don't know in advance how many iterations are needed, or when waiting for a specific con
**Example:**
``````````python
# Basic while loop
count = 0
while count < 5:
print(f"Count is: {count}")
count += 1
---
**Definition:**
- **break**: Exits the loop entirely
- **continue**: Skips the current iteration and moves to the next one
**Why Use It:** Provides fine control over loop execution, allowing you to skip unwanted iterations or exit early when condi
**Example:**
``````````python
# Break - exit loop when condition met
for i in range(10):
if i == 5:
break # Stop loop when i equals 5
print(i) # Output: 0, 1, 2, 3, 4
---
**Definition:** A structural pattern matching statement that compares a value against multiple patterns, similar to switch-case
**Why Use It:** Provides cleaner, more readable code than multiple if-elif statements, especially for complex pattern matchin
**Example:**
``````````python
# HTTP status code handler
def handle_response(status_code):
match status_code:
case 200:
return "Success"
case 404:
return "Not Found"
case 500 | 502 | 503: # Multiple values
return "Server Error"
case code if 400 <= code < 500: # With condition
return "Client Error"
case _: # Default case
return "Unknown Status"
---
## 3. Functions
**Definition:** A reusable block of code that performs a specific task. Functions are defined using the `def` keyword.
**Why Use It:** Promotes code reusability, organization, and maintainability. Breaks complex problems into smaller, manage
**Example:**
``````````python
# Simple function
def greet(name):
"""Greets a person by name"""
return f"Hello, {name}!"
message = greet("Alice")
print(message) # Output: Hello, Alice!
result = calculate_area(5, 3)
print(f"Area: {result}") # Output: Area: 15
---
**Definition:** Parameters that have default values assigned, making them optional when calling the function.
**Why Use It:** Makes functions more flexible and reduces the need for multiple function definitions for similar tasks.
**Example:**
``````````python
# Function with default parameter
def power(base, exponent=2):
"""Raises base to the power of exponent (default: 2)"""
return base ** exponent
# Multiple defaults
def create_profile(name, age=18, country="USA"):
return {
'name': name,
'age': age,
'country': country
}
---
**Definition:** Allows a function to accept any number of positional arguments, which are collected into a tuple.
**Why Use It:** Makes functions flexible when you don't know in advance how many arguments will be passed.
**Example:**
``````````python
# Function accepting any number of arguments
def sum_all(*args):
"""Sums all provided numbers"""
total = 0
for num in args:
total += num
return total
---
**Definition:** Allows a function to accept any number of keyword arguments, which are collected into a dictionary.
**Why Use It:** Provides flexibility for functions that need to handle varying named parameters, useful for configuration and
**Example:**
``````````python
# Function accepting keyword arguments
def print_info(**kwargs):
"""Prints all key-value pairs"""
for key, value in [Link]():
print(f"{key}: {value}")
---
**Definition:** Optional metadata that specifies the expected types of function parameters and return values.
**Why Use It:** Improves code documentation, enables static type checking with tools like mypy, and makes code more mai
**Example:**
``````````python
# Function with type hints
def add_numbers(x: int, y: int) -> int:
"""Adds two integers and returns an integer"""
return x + y
result = add_numbers(5, 3)
print(result) # Output: 8
---
**Definition:** A closure is a function that remembers values from its enclosing scope even after that scope has finished exec
**Why Use It:** Enables data encapsulation, creates function factories, and allows for elegant callback patterns.
**Example:**
``````````python
# Basic closure
def outer_function(x):
"""Outer function that returns an inner function"""
def inner_function(y):
"""Inner function that remembers x"""
return x + y
return inner_function
# Create a closure
add_5 = outer_function(5)
print(add_5(10)) # Output: 15 (remembers x=5)
print(add_5(20)) # Output: 25
def increment():
nonlocal count # Modify outer scope variable
count += 1
return count
return increment
counter1 = make_counter()
counter2 = make_counter()
print(counter1()) # Output: 1
print(counter1()) # Output: 2
print(counter2()) # Output: 1 (separate counter)
# Multiplier factory
def make_multiplier(n):
"""Creates a function that multiplies by n"""
def multiply(x):
return x * n
return multiply
times_3 = make_multiplier(3)
times_5 = make_multiplier(5)
print(times_3(10)) # Output: 30
print(times_5(10)) # Output: 50
``````````
---
## 4. Object-Oriented Programming
**Definition:** A class is a blueprint for creating objects. Objects are instances of classes that combine data (attributes) and b
**Why Use It:** Organizes code into reusable components, models real-world entities, and implements encapsulation, inherit
**Example:**
``````````python
# Basic class definition
class Dog:
"""Represents a dog"""
# Constructor (initializer)
def __init__(self, name, age):
"""Initialize a new dog"""
[Link] = name # Instance attribute
[Link] = age
# Instance method
def bark(self):
"""Make the dog bark"""
return f"{[Link]} says Woof!"
def get_info(self):
"""Return dog information"""
return f"{[Link]} is {[Link]} years old"
---
**Definition:** Special methods with double underscores (e.g., `__init__`, `__str__`) that define how objects behave with bui
**Why Use It:** Allows custom classes to work seamlessly with Python's built-in functions and operators, making objects be
**Example:**
``````````python
class Book:
"""Represents a book"""
def __str__(self):
"""String representation for users"""
return f"'{[Link]}' by {[Link]}"
def __repr__(self):
"""String representation for developers"""
return f"Book(title='{[Link]}', author='{[Link]}', pages={[Link]})"
def __len__(self):
"""Return number of pages"""
return [Link]
def __str__(self):
return f"Vector({self.x}, {self.y})"
v1 = Vector(2, 3)
v2 = Vector(4, 5)
v3 = v1 + v2 # Uses __add__
v4 = v1 * 3 # Uses __mul__
---
### Inheritance
**Definition:** A mechanism where a new class (child/subclass) derives properties and methods from an existing class (paren
**Why Use It:** Promotes code reuse, creates hierarchical relationships, and allows for polymorphism (same interface, differ
**Example:**
``````````python
# Parent class
class Animal:
"""Base class for all animals"""
def speak(self):
"""Generic speak method"""
return "Some sound"
def info(self):
return f"{[Link]} is {[Link]} years old"
# Child class
class Dog(Animal):
"""Dog class inherits from Animal"""
class Cat(Animal):
"""Cat class inherits from Animal"""
def speak(self):
return "Meow!"
def scratch(self):
return f"{[Link]} is scratching"
---
**Definition:**
- **Class methods**: Methods that receive the class as the first parameter (cls), not an instance
- **Static methods**: Methods that don't receive class or instance, just regular functions within class namespace
**Why Use It:** Class methods are useful for factory methods and alternative constructors. Static methods are utility function
**Example:**
``````````python
class Date:
"""Represents a date"""
@classmethod
def from_string(cls, date_string):
"""Factory method: Create Date from string"""
year, month, day = map(int, date_string.split('-'))
return cls(year, month, day) # Returns new instance
@classmethod
def today(cls):
"""Factory method: Create Date for today"""
import datetime
today = [Link]()
return cls([Link], [Link], [Link])
@staticmethod
def is_leap_year(year):
"""Utility function: Check if year is leap year"""
return year % 4 == 0 and (year % 100 != 0 or year % 400 == 0)
def __str__(self):
return f"{[Link]}-{[Link]:02d}-{[Link]:02d}"
@classmethod
def from_fahrenheit(cls, fahrenheit):
"""Create Temperature from Fahrenheit"""
celsius = (fahrenheit - 32) * 5/9
return cls(celsius)
@staticmethod
def celsius_to_fahrenheit(celsius):
"""Convert Celsius to Fahrenheit"""
return (celsius * 9/5) + 32
def __str__(self):
return f"{[Link]}°C"
temp1 = Temperature(25)
temp2 = Temperature.from_fahrenheit(77)
---
### Properties
**Definition:** Properties allow you to define methods that can be accessed like attributes, providing controlled access to cla
**Why Use It:** Enables encapsulation, data validation, computed attributes, and maintains a clean interface while adding log
**Example:**
``````````python
class Circle:
"""Represents a circle"""
@property
def radius(self):
"""Getter for radius"""
return self._radius
@[Link]
def radius(self, value):
"""Setter with validation"""
if value < 0:
raise ValueError("Radius cannot be negative")
self._radius = value
@property
def diameter(self):
"""Computed property"""
return self._radius * 2
@property
def area(self):
"""Computed property"""
import math
return [Link] * (self._radius ** 2)
@property
def circumference(self):
"""Computed property"""
import math
return 2 * [Link] * self._radius
# Using properties
circle = Circle(5)
# Validation works
try:
[Link] = -5
except ValueError as e:
print(f"Error: {e}") # Output: Error: Radius cannot be negative
@[Link]
def celsius(self, value):
if value < -273.15:
raise ValueError("Temperature below absolute zero!")
if value > 100:
print("Warning: Very high temperature!")
self._celsius = value
@property
def fahrenheit(self):
"""Convert to Fahrenheit on the fly"""
return (self._celsius * 9/5) + 32
@[Link]
def fahrenheit(self, value):
"""Set temperature in Fahrenheit"""
[Link] = (value - 32) * 5/9
thermostat = Thermostat()
print(f"Current: {[Link]}°C") # Output: Current: 20°C
print(f"In Fahrenheit: {[Link]}°F") # Output: In Fahrenheit: 68.0°F
---
**Definition:** Modules are Python files containing functions, classes, and variables. Importing allows you to use code from
**Why Use It:** Organizes code into logical units, promotes code reuse, and provides access to Python's extensive standard l
**Example:**
``````````python
# Different ways to import
current_dir = [Link]()
print(f"Current directory: {current_dir}")
def save_log(message):
"""Save timestamped log message"""
log_entry = {
'timestamp': [Link]().isoformat(),
'message': message
}
print([Link](log_entry, indent=2))
save_log("Application started")
``````````
---
**Why Use It:** Organizes your code into reusable components, separates concerns, and makes large projects manageable.
**Example:**
PI = 3.14159
def circle_area(radius):
"""Calculate circle area"""
return PI * radius ** 2
def circle_circumference(radius):
"""Calculate circle circumference"""
return 2 * PI * radius
def square_area(side):
"""Calculate square area"""
return side ** 2
class Calculator:
"""Simple calculator class"""
@staticmethod
def add(a, b):
return a + b
@staticmethod
def multiply(a, b):
return a * b
``````````
---
**Definition:** `__name__` is a special variable that equals `"__main__"` when the file is run directly, or the module name w
**Why Use It:** Allows you to write code that runs only when the file is executed directly, not when imported. Essential for c
**Example:**
``````````python
# [Link]
"""Utility functions"""
def process_data(data):
"""Process data"""
return [x * 2 for x in data]
def validate_input(value):
"""Validate input"""
return value > 0
test_data = [1, 2, 3, 4, 5]
result = process_data(test_data)
print(f"Test result: {result}")
---
## 6. File Handling
**Definition:** File reading operations allow you to access and read content from files stored on disk.
**Why Use It:** Essential for data processing, configuration loading, log analysis, and working with persistent data.
**Example:**
``````````python
# Method 1: Read entire file
with open('[Link]', 'r') as file:
content = [Link]()
print(content)
---
**Definition:** File writing operations allow you to create new files or modify existing ones by writing data to disk.
**Why Use It:** Saves program output, creates logs, generates reports, and persists data between program runs.
**Example:**
``````````python
# Write mode ('w') - overwrites existing file
with open('[Link]', 'w') as file:
[Link]("Hello, World!\n")
[Link]("This is line 2\n")
**Definition:** The `with` statement automatically handles resource setup and cleanup, ensuring files are properly closed eve
**Why Use It:** Prevents resource leaks, ensures proper cleanup, and makes code more readable and reliable.
**Example:**
``````````python
# Without context manager (not recommended)
file = open('[Link]', 'r')
try:
content = [Link]()
print(content)
finally:
[Link]() # Must remember to close
print(process_file('[Link]'))
``````````
---
### Binary Files
**Definition:** Binary mode reads/writes files as raw bytes rather than text, used for non-text files like images, videos, and ex
**Why Use It:** Required for working with binary file formats, preserves exact byte content, and prevents text encoding issu
**Example:**
``````````python
# Reading binary file
with open('[Link]', 'rb') as file:
image_data = [Link]()
print(f"Image size: {len(image_data)} bytes")
---
## 7. Exception Handling
**Definition:** Exception handling allows you to gracefully handle errors that occur during program execution, preventing cr
**Why Use It:** Makes programs robust, provides user-friendly error messages, and allows recovery from errors.
**Example:**
``````````python
# Basic exception handling
try:
result = 10 / 0
except ZeroDivisionError:
print("Cannot divide by zero!")
result = None
---
### Try-Except-Else-Finally
**Definition:**
- **else**: Runs if no exception occurred
- **finally**: Always runs, regardless of exceptions (cleanup code)
**Why Use It:** Provides precise control over exception handling flow, ensures cleanup code runs, and separates success log
**Example:**
``````````python
# Complete exception handling structure
try:
file = open('[Link]', 'r')
data = [Link]()
number = int(data)
except FileNotFoundError:
print("File not found")
except ValueError:
print("File contains invalid data")
else:
# Runs only if no exception occurred
print(f"Successfully read number: {number}")
finally:
# Always runs (cleanup)
if 'file' in locals():
[Link]()
print("File closed")
def connect(self):
print("Connecting to database...")
def close(self):
print("Closing database connection")
def run_query(query):
"""Execute query with proper cleanup"""
db = DatabaseConnection()
try:
[Link]()
[Link](query)
except ValueError as e:
print(f"Query error: {e}")
return False
else:
print("Query executed successfully")
return True
finally:
[Link]()
---
**Definition:** You can manually trigger exceptions using the `raise` keyword to signal error conditions.
**Why Use It:** Enforces business logic, validates inputs, and creates clear error boundaries in your code.
**Example:**
``````````python
# Raise built-in exception
def calculate_percentage(value, total):
"""Calculate percentage"""
if total == 0:
raise ZeroDivisionError("Total cannot be zero")
if value < 0 or total < 0:
raise ValueError("Values must be non-negative")
return (value / total) * 100
# Re-raising exceptions
def process_data(data):
"""Process data with logging"""
try:
result = int(data)
return result * 2
except ValueError:
print("Logging error...")
raise # Re-raise the same exception
# Using validation
try:
valid_age = set_age(25)
print(f"Age set to: {valid_age}")
invalid_age = set_age(-5)
except ValueError as e:
print(f"Validation error: {e}")
``````````
---
**Definition:** You can create your own exception classes by inheriting from the `Exception` class or its subclasses.
**Why Use It:** Creates domain-specific errors, provides better error context, and makes error handling more precise and me
**Example:**
``````````python
# Simple custom exception
class InsufficientFundsError(Exception):
"""Raised when account has insufficient funds"""
pass
class BankAccount:
"""Bank account with custom exception handling"""
if amount <= 0:
raise ValueError("Withdrawal amount must be positive")
[Link] -= amount
return [Link]
def lock(self):
"""Lock the account"""
[Link] = True
try:
[Link]()
[Link](100)
except AccountLockedError as e:
print(f"Cannot process: {e}")
return True
try:
validate_user_registration("AB", "invalidemail", 16)
except ValidationError as e:
print(f"Registration failed - {e}")
``````````
---
### Iterators
**Definition:** An iterator is an object that implements the iterator protocol (`__iter__()` and `__next__()` methods), allowin
**Why Use It:** Provides a standard way to loop through data, enables lazy evaluation, and allows custom iteration behavior
**Example:**
``````````python
# Basic iterator usage
my_list = [1, 2, 3, 4, 5]
iterator = iter(my_list)
print(next(iterator)) # Output: 1
print(next(iterator)) # Output: 2
print(next(iterator)) # Output: 3
def __iter__(self):
return self
def __next__(self):
if [Link] <= 0:
raise StopIteration
[Link] -= 1
return [Link] + 1
def __iter__(self):
[Link] = open([Link], 'r')
self.line_count = 0
return self
def __next__(self):
if self.line_count >= self.max_lines:
[Link]()
raise StopIteration
line = [Link]()
if not line:
[Link]()
raise StopIteration
self.line_count += 1
return [Link]()
---
### Generators
**Definition:** Generators are functions that use `yield` to produce a sequence of values lazily, one at a time, instead of retur
**Why Use It:** Memory efficient for large datasets, creates infinite sequences, simplifies iterator creation, and enables pipel
**Example:**
``````````python
# Basic generator function
def simple_generator():
"""Yields three values"""
print("First yield")
yield 1
print("Second yield")
yield 2
print("Third yield")
yield 3
# Using generator
gen = simple_generator()
print(next(gen)) # Output: First yield, then 1
print(next(gen)) # Output: Second yield, then 2
def square_numbers(numbers):
"""Square each number"""
for num in numbers:
yield num ** 2
# Chain generators
numbers = range(10)
evens = filter_even(numbers)
squared = square_numbers(evens)
print(list(squared)) # Output: [0, 4, 16, 36, 64]
``````````
---
**Definition:** A concise way to create generators using syntax similar to list comprehensions, but with parentheses instead o
**Why Use It:** More memory efficient than list comprehensions, perfect for one-time iterations, and cleaner syntax for simp
**Example:**
``````````python
# List comprehension (creates entire list in memory)
squares_list = [x**2 for x in range(1000000)] # Uses lots of memory
# Memory comparison
import sys
**Definition:** `yield from` delegates part of generator operations to another generator, simplifying code that chains generato
**Why Use It:** Makes generator delegation cleaner, flattens nested iterations, and improves code readability.
**Example:**
``````````python
# Without yield from (verbose)
def chain_generators_old(*iterables):
"""Chain iterables the old way"""
for iterable in iterables:
for item in iterable:
yield item
# Create tree
root = TreeNode(1, [
TreeNode(2, [TreeNode(4), TreeNode(5)]),
TreeNode(3, [TreeNode(6)])
])
# Traverse
for value in [Link]():
print(value, end=' ') # Output: 1 2 4 5 3 6
``````````
---
## 9. Decorators
**Definition:** Decorators are functions that modify or enhance other functions without changing their source code. They "w
**Why Use It:** Adds reusable functionality (logging, timing, authentication), separates concerns, and keeps code DRY (Don
**Example:**
``````````python
# Basic decorator
def my_decorator(func):
"""Simple decorator that wraps a function"""
def wrapper():
print("Something before the function")
func()
print("Something after the function")
return wrapper
@my_decorator
def say_hello():
print("Hello!")
say_hello()
# Output:
# Something before the function
# Hello!
# Something after the function
@timing_decorator
def slow_function():
import time
[Link](1)
return "Done"
result = slow_function()
# Output: slow_function took 1.0001 seconds
print(f"Calling {func.__name__}({all_args})")
result = func(*args, **kwargs)
print(f"{func.__name__} returned {result!r}")
return result
return wrapper
@log_function_call
def add(a, b):
return a + b
result = add(5, 3)
# Output:
# Calling add(5, 3)
# add returned 8
``````````
---
**Definition:** Decorators that accept arguments, requiring an extra layer of function nesting to configure behavior.
**Why Use It:** Allows customization of decorator behavior, makes decorators more flexible and reusable.
**Example:**
``````````python
# Decorator factory (decorator with parameters)
def repeat(times):
"""Repeat function execution N times"""
def decorator(func):
def wrapper(*args, **kwargs):
result = None
for _ in range(times):
result = func(*args, **kwargs)
return result
return wrapper
return decorator
@repeat(3)
def greet(name):
print(f"Hello, {name}!")
greet("Alice")
# Output:
# Hello, Alice!
# Hello, Alice!
# Hello, Alice!
@validate_range(0, 100)
def set_percentage(value):
return f"Percentage set to {value}%"
print(set_percentage(50)) # Works
# print(set_percentage(150)) # Raises ValueError
def decorator(func):
def wrapper(*args, **kwargs):
for attempt in range(1, max_attempts + 1):
try:
return func(*args, **kwargs)
except Exception as e:
if attempt == max_attempts:
print(f"Failed after {max_attempts} attempts")
raise
print(f"Attempt {attempt} failed: {e}. Retrying...")
[Link](delay)
return wrapper
return decorator
@retry(max_attempts=3, delay=0.5)
def unreliable_function():
import random
if [Link]() < 0.7:
raise ConnectionError("Network error")
return "Success!"
``````````
---
**Definition:** Using `[Link]` preserves the original function's metadata (name, docstring) when creating decorator
**Why Use It:** Maintains proper function introspection, documentation, and debugging information.
**Example:**
``````````python
from functools import wraps
def original_function():
"""This is the original function"""
pass
@bad_decorator
def bad_wrapped():
"""Original docstring"""
pass
@good_decorator
def good_wrapped():
"""Original docstring"""
pass
def my_decorator(func):
"""Decorator template with proper metadata preservation"""
@wraps(func)
def wrapper(*args, **kwargs):
# Before function
print(f"Calling {func.__name__}")
# Call function
result = func(*args, **kwargs)
# After function
print(f"Finished {func.__name__}")
return result
return wrapper
@my_decorator
def calculate(x, y):
"""
return bool([Link](pattern, username))
print(validate_username("john_doe")) # True
print(validate_username("ab")) # False (too short)
print(validate_username("user@name")) # False (invalid char)
``````````
---
**Definition:** Groups capture parts of matched patterns using parentheses, allowing extraction of specific portions of text.
**Why Use It:** Extracts specific data from matches, creates reusable patterns, and enables complex replacements.
**Example:**
``````````python
import re
# Basic groups
text = "John Smith, Age: 30"
pattern = r'(\w+)\s+(\w+),\s+Age:\s+(\d+)'
---
**Definition:** Replace matched patterns in strings using `[Link]()`, which can use captured groups in the replacement.
**Why Use It:** Transforms text based on patterns, cleans data, reformats strings, and performs intelligent replacements.
**Example:**
``````````python
import re
# Simple substitution
text = "I love cats and cats are great"
new_text = [Link](r'cats', 'dogs', text)
print(new_text) # Output: I love dogs and dogs are great
# Limit replacements
new_text = [Link](r'cats', 'dogs', text, count=1)
print(new_text) # Output: I love dogs and cats are great
# Format dates
text = "Dates: 03/15/2024 and 12/25/2024"
pattern = r'(\d{2})/(\d{2})/(\d{4})'
replacement = r'\3-\1-\2' # Change to YYYY-MM-DD
new_text = [Link](pattern, replacement, text)
print(new_text) # Output: Dates: 2024-03-15 and 2024-12-25
---
**Definition:** Compile regex patterns into pattern objects for better performance when using the same pattern multiple time
**Why Use It:** Improves performance with repeated use, provides better organization, and enables pattern reuse.
**Example:**
``````````python
import re
def __init__(self):
self.email_pattern = [Link](r'^[\w.-]+@[\w.-]+\.\w+# Complete Python Documentation with Detailed Explanations
## From Basics to Advanced - Python 3.13+
---
## Table of Contents
---
### Variables
**Definition:** Variables are named containers that store data values in memory. Python is dynamically typed, meaning you d
**Why Use It:** Variables allow you to store and manipulate data throughout your program, making code reusable and maint
**Example:**
`````````python
# Simple variable assignment
name = "Alice" # String variable
age = 30 # Integer variable
height = 5.7 # Float variable
is_student = False # Boolean variable
# Multiple assignment
x, y, z = 1, 2, 3 # Assign multiple values at once
a = b = c = 10 # Assign same value to multiple variables
---
**Definition:** Data types define the kind of value a variable can hold. Python has several built-in data types.
**Why Use It:** Different data types are optimized for different operations. Using the right type improves performance and p
**Example:**
`````````python
# Integer
count = 100
print(type(count)) # <class 'int'>
# Float
price = 19.99
print(type(price)) # <class 'float'>
# String
message = "Hello, World!"
print(type(message)) # <class 'str'>
# Boolean
is_active = True
print(type(is_active)) # <class 'bool'>
# Complex numbers
complex_num = 3 + 4j
print(type(complex_num)) # <class 'complex'>
# None type
result = None
print(type(result)) # <class 'NoneType'>
`````````
---
**Definition:** Type checking verifies the data type of a variable. Type conversion transforms data from one type to another.
**Why Use It:** Ensures data integrity, prevents errors, and allows operations between different types.
**Example:**
`````````python
# Type checking
age = 25
print(isinstance(age, int)) # True - checks if age is an integer
print(isinstance(age, str)) # False
# Type conversion (casting)
str_number = "123"
number = int(str_number) # Convert string to integer
print(number + 10) # 133
---
## 2. Control Flow
**Definition:** Conditional statements that execute different code blocks based on whether conditions are true or false.
**Why Use It:** Allows your program to make decisions and execute different paths of code based on conditions, making pro
**Example:**
`````````python
# Grade calculator
score = 85
print(f"Your grade is: {grade}") # Output: Good job! Your grade is: B
`````````
---
### Ternary Operator
**Why Use It:** Makes code more readable and compact for simple conditional assignments.
**Example:**
`````````python
# Traditional if-else
age = 20
if age >= 18:
status = "Adult"
else:
status = "Minor"
---
**Definition:** A loop that iterates over a sequence (list, tuple, string, range) and executes a block of code for each item.
**Why Use It:** Automates repetitive tasks, processes collections of data, and eliminates the need for manual repetition.
**Example:**
`````````python
# Basic for loop with range
for i in range(5):
print(f"Count: {i}")
# Output: Count: 0, Count: 1, Count: 2, Count: 3, Count: 4
---
**Why Use It:** Useful when you don't know in advance how many iterations are needed, or when waiting for a specific con
**Example:**
`````````python
# Basic while loop
count = 0
while count < 5:
print(f"Count is: {count}")
count += 1
---
### Break and Continue
**Definition:**
- **break**: Exits the loop entirely
- **continue**: Skips the current iteration and moves to the next one
**Why Use It:** Provides fine control over loop execution, allowing you to skip unwanted iterations or exit early when condi
**Example:**
`````````python
# Break - exit loop when condition met
for i in range(10):
if i == 5:
break # Stop loop when i equals 5
print(i) # Output: 0, 1, 2, 3, 4
---
**Definition:** A structural pattern matching statement that compares a value against multiple patterns, similar to switch-case
**Why Use It:** Provides cleaner, more readable code than multiple if-elif statements, especially for complex pattern matchin
**Example:**
`````````python
# HTTP status code handler
def handle_response(status_code):
match status_code:
case 200:
return "Success"
case 404:
return "Not Found"
case 500 | 502 | 503: # Multiple values
return "Server Error"
case code if 400 <= code < 500: # With condition
return "Client Error"
case _: # Default case
return "Unknown Status"
---
## 3. Functions
**Definition:** A reusable block of code that performs a specific task. Functions are defined using the `def` keyword.
**Why Use It:** Promotes code reusability, organization, and maintainability. Breaks complex problems into smaller, manage
**Example:**
`````````python
# Simple function
def greet(name):
"""Greets a person by name"""
return f"Hello, {name}!"
message = greet("Alice")
print(message) # Output: Hello, Alice!
result = calculate_area(5, 3)
print(f"Area: {result}") # Output: Area: 15
---
**Definition:** Parameters that have default values assigned, making them optional when calling the function.
**Why Use It:** Makes functions more flexible and reduces the need for multiple function definitions for similar tasks.
**Example:**
`````````python
# Function with default parameter
def power(base, exponent=2):
"""Raises base to the power of exponent (default: 2)"""
return base ** exponent
# Multiple defaults
def create_profile(name, age=18, country="USA"):
return {
'name': name,
'age': age,
'country': country
}
---
**Definition:** Allows a function to accept any number of positional arguments, which are collected into a tuple.
**Why Use It:** Makes functions flexible when you don't know in advance how many arguments will be passed.
**Example:**
`````````python
# Function accepting any number of arguments
def sum_all(*args):
"""Sums all provided numbers"""
total = 0
for num in args:
total += num
return total
**Definition:** Allows a function to accept any number of keyword arguments, which are collected into a dictionary.
**Why Use It:** Provides flexibility for functions that need to handle varying named parameters, useful for configuration and
**Example:**
`````````python
# Function accepting keyword arguments
def print_info(**kwargs):
"""Prints all key-value pairs"""
for key, value in [Link]():
print(f"{key}: {value}")
---
**Definition:** Optional metadata that specifies the expected types of function parameters and return values.
**Why Use It:** Improves code documentation, enables static type checking with tools like mypy, and makes code more mai
**Example:**
`````````python
# Function with type hints
def add_numbers(x: int, y: int) -> int:
"""Adds two integers and returns an integer"""
return x + y
result = add_numbers(5, 3)
print(result) # Output: 8
---
**Definition:** A closure is a function that remembers values from its enclosing scope even after that scope has finished exec
**Why Use It:** Enables data encapsulation, creates function factories, and allows for elegant callback patterns.
**Example:**
`````````python
# Basic closure
def outer_function(x):
"""Outer function that returns an inner function"""
def inner_function(y):
"""Inner function that remembers x"""
return x + y
return inner_function
# Create a closure
add_5 = outer_function(5)
print(add_5(10)) # Output: 15 (remembers x=5)
print(add_5(20)) # Output: 25
def increment():
nonlocal count # Modify outer scope variable
count += 1
return count
return increment
counter1 = make_counter()
counter2 = make_counter()
print(counter1()) # Output: 1
print(counter1()) # Output: 2
print(counter2()) # Output: 1 (separate counter)
# Multiplier factory
def make_multiplier(n):
"""Creates a function that multiplies by n"""
def multiply(x):
return x * n
return multiply
times_3 = make_multiplier(3)
times_5 = make_multiplier(5)
print(times_3(10)) # Output: 30
print(times_5(10)) # Output: 50
`````````
---
## 4. Object-Oriented Programming
**Definition:** A class is a blueprint for creating objects. Objects are instances of classes that combine data (attributes) and b
**Why Use It:** Organizes code into reusable components, models real-world entities, and implements encapsulation, inherit
**Example:**
`````````python
# Basic class definition
class Dog:
"""Represents a dog"""
# Constructor (initializer)
def __init__(self, name, age):
"""Initialize a new dog"""
[Link] = name # Instance attribute
[Link] = age
# Instance method
def bark(self):
"""Make the dog bark"""
return f"{[Link]} says Woof!"
def get_info(self):
"""Return dog information"""
return f"{[Link]} is {[Link]} years old"
---
**Definition:** Special methods with double underscores (e.g., `__init__`, `__str__`) that define how objects behave with bui
**Why Use It:** Allows custom classes to work seamlessly with Python's built-in functions and operators, making objects be
**Example:**
`````````python
class Book:
"""Represents a book"""
def __str__(self):
"""String representation for users"""
return f"'{[Link]}' by {[Link]}"
def __repr__(self):
"""String representation for developers"""
return f"Book(title='{[Link]}', author='{[Link]}', pages={[Link]})"
def __len__(self):
"""Return number of pages"""
return [Link]
def __str__(self):
return f"Vector({self.x}, {self.y})"
v1 = Vector(2, 3)
v2 = Vector(4, 5)
v3 = v1 + v2 # Uses __add__
v4 = v1 * 3 # Uses __mul__
---
### Inheritance
**Definition:** A mechanism where a new class (child/subclass) derives properties and methods from an existing class (paren
**Why Use It:** Promotes code reuse, creates hierarchical relationships, and allows for polymorphism (same interface, differ
**Example:**
`````````python
# Parent class
class Animal:
"""Base class for all animals"""
def __init__(self, name, age):
[Link] = name
[Link] = age
def speak(self):
"""Generic speak method"""
return "Some sound"
def info(self):
return f"{[Link]} is {[Link]} years old"
# Child class
class Dog(Animal):
"""Dog class inherits from Animal"""
class Cat(Animal):
"""Cat class inherits from Animal"""
def speak(self):
return "Meow!"
def scratch(self):
return f"{[Link]} is scratching"
---
**Definition:**
- **Class methods**: Methods that receive the class as the first parameter (cls), not an instance
- **Static methods**: Methods that don't receive class or instance, just regular functions within class namespace
**Why Use It:** Class methods are useful for factory methods and alternative constructors. Static methods are utility function
**Example:**
`````````python
class Date:
"""Represents a date"""
@classmethod
def from_string(cls, date_string):
"""Factory method: Create Date from string"""
year, month, day = map(int, date_string.split('-'))
return cls(year, month, day) # Returns new instance
@classmethod
def today(cls):
"""Factory method: Create Date for today"""
import datetime
today = [Link]()
return cls([Link], [Link], [Link])
@staticmethod
def is_leap_year(year):
"""Utility function: Check if year is leap year"""
return year % 4 == 0 and (year % 100 != 0 or year % 400 == 0)
def __str__(self):
return f"{[Link]}-{[Link]:02d}-{[Link]:02d}"
@classmethod
def from_fahrenheit(cls, fahrenheit):
"""Create Temperature from Fahrenheit"""
celsius = (fahrenheit - 32) * 5/9
return cls(celsius)
@staticmethod
def celsius_to_fahrenheit(celsius):
"""Convert Celsius to Fahrenheit"""
return (celsius * 9/5) + 32
def __str__(self):
return f"{[Link]}°C"
temp1 = Temperature(25)
temp2 = Temperature.from_fahrenheit(77)
---
### Properties
**Definition:** Properties allow you to define methods that can be accessed like attributes, providing controlled access to cla
**Why Use It:** Enables encapsulation, data validation, computed attributes, and maintains a clean interface while adding log
**Example:**
`````````python
class Circle:
"""Represents a circle"""
@property
def radius(self):
"""Getter for radius"""
return self._radius
@[Link]
def radius(self, value):
"""Setter with validation"""
if value < 0:
raise ValueError("Radius cannot be negative")
self._radius = value
@property
def diameter(self):
"""Computed property"""
return self._radius * 2
@property
def area(self):
"""Computed property"""
import math
return [Link] * (self._radius ** 2)
@property
def circumference(self):
"""Computed property"""
import math
return 2 * [Link] * self._radius
# Using properties
circle = Circle(5)
# Validation works
try:
[Link] = -5
except ValueError as e:
print(f"Error: {e}") # Output: Error: Radius cannot be negative
@property
def celsius(self):
return self._celsius
@[Link]
def celsius(self, value):
if value < -273.15:
raise ValueError("Temperature below absolute zero!")
if value > 100:
print("Warning: Very high temperature!")
self._celsius = value
@property
def fahrenheit(self):
"""Convert to Fahrenheit on the fly"""
return (self._celsius * 9/5) + 32
@[Link]
def fahrenheit(self, value):
"""Set temperature in Fahrenheit"""
[Link] = (value - 32) * 5/9
thermostat = Thermostat()
print(f"Current: {[Link]}°C") # Output: Current: 20°C
print(f"In Fahrenheit: {[Link]}°F") # Output: In Fahrenheit: 68.0°F
---
**Definition:** Modules are Python files containing functions, classes, and variables. Importing allows you to use code from
**Why Use It:** Organizes code into logical units, promotes code reuse, and provides access to Python's extensive standard l
**Example:**
`````````python
# Different ways to import
current_dir = [Link]()
print(f"Current directory: {current_dir}")
# Practical example: Using multiple imports
from datetime import datetime
import json
def save_log(message):
"""Save timestamped log message"""
log_entry = {
'timestamp': [Link]().isoformat(),
'message': message
}
print([Link](log_entry, indent=2))
save_log("Application started")
`````````
---
**Definition:** Any Python file can be a module. You create one by saving Python code in a `.py` file and importing it in othe
**Why Use It:** Organizes your code into reusable components, separates concerns, and makes large projects manageable.
**Example:**
PI = 3.14159
def circle_area(radius):
"""Calculate circle area"""
return PI * radius ** 2
def circle_circumference(radius):
"""Calculate circle circumference"""
return 2 * PI * radius
def square_area(side):
"""Calculate square area"""
return side ** 2
class Calculator:
"""Simple calculator class"""
@staticmethod
def add(a, b):
return a + b
@staticmethod
def multiply(a, b):
return a * b
`````````
---
**Definition:** `__name__` is a special variable that equals `"__main__"` when the file is run directly, or the module name w
**Why Use It:** Allows you to write code that runs only when the file is executed directly, not when imported. Essential for c
**Example:**
`````````python
# [Link]
"""Utility functions"""
def process_data(data):
"""Process data"""
return [x * 2 for x in data]
def validate_input(value):
"""Validate input"""
return value > 0
test_data = [1, 2, 3, 4, 5]
result = process_data(test_data)
print(f"Test result: {result}")
---
## 6. File Handling
**Definition:** File reading operations allow you to access and read content from files stored on disk.
**Why Use It:** Essential for data processing, configuration loading, log analysis, and working with persistent data.
**Example:**
`````````python
# Method 1: Read entire file
with open('[Link]', 'r') as file:
content = [Link]()
print(content)
---
**Definition:** File writing operations allow you to create new files or modify existing ones by writing data to disk.
**Why Use It:** Saves program output, creates logs, generates reports, and persists data between program runs.
**Example:**
`````````python
# Write mode ('w') - overwrites existing file
with open('[Link]', 'w') as file:
[Link]("Hello, World!\n")
[Link]("This is line 2\n")
---
**Definition:** The `with` statement automatically handles resource setup and cleanup, ensuring files are properly closed eve
**Why Use It:** Prevents resource leaks, ensures proper cleanup, and makes code more readable and reliable.
**Example:**
`````````python
# Without context manager (not recommended)
file = open('[Link]', 'r')
try:
content = [Link]()
print(content)
finally:
[Link]() # Must remember to close
print(process_file('[Link]'))
`````````
---
**Definition:** Binary mode reads/writes files as raw bytes rather than text, used for non-text files like images, videos, and ex
**Why Use It:** Required for working with binary file formats, preserves exact byte content, and prevents text encoding issu
**Example:**
`````````python
# Reading binary file
with open('[Link]', 'rb') as file:
image_data = [Link]()
print(f"Image size: {len(image_data)} bytes")
---
## 7. Exception Handling
**Definition:** Exception handling allows you to gracefully handle errors that occur during program execution, preventing cr
**Why Use It:** Makes programs robust, provides user-friendly error messages, and allows recovery from errors.
**Example:**
`````````python
# Basic exception handling
try:
result = 10 / 0
except ZeroDivisionError:
print("Cannot divide by zero!")
result = None
---
### Try-Except-Else-Finally
**Definition:**
- **else**: Runs if no exception occurred
- **finally**: Always runs, regardless of exceptions (cleanup code)
**Why Use It:** Provides precise control over exception handling flow, ensures cleanup code runs, and separates success log
**Example:**
`````````python
# Complete exception handling structure
try:
file = open('[Link]', 'r')
data = [Link]()
number = int(data)
except FileNotFoundError:
print("File not found")
except ValueError:
print("File contains invalid data")
else:
# Runs only if no exception occurred
print(f"Successfully read number: {number}")
finally:
# Always runs (cleanup)
if 'file' in locals():
[Link]()
print("File closed")
def connect(self):
print("Connecting to database...")
def close(self):
print("Closing database connection")
def run_query(query):
"""Execute query with proper cleanup"""
db = DatabaseConnection()
try:
[Link]()
[Link](query)
except ValueError as e:
print(f"Query error: {e}")
return False
else:
print("Query executed successfully")
return True
finally:
[Link]()
---
**Why Use It:** Enforces business logic, validates inputs, and creates clear error boundaries in your code.
**Example:**
`````````python
# Raise built-in exception
def calculate_percentage(value, total):
"""Calculate percentage"""
if total == 0:
raise ZeroDivisionError("Total cannot be zero")
if value < 0 or total < 0:
raise ValueError("Values must be non-negative")
return (value / total) * 100
# Re-raising exceptions
def process_data(data):
"""Process data with logging"""
try:
result = int(data)
return result * 2
except ValueError:
print("Logging error...")
raise # Re-raise the same exception
# Using validation
try:
valid_age = set_age(25)
print(f"Age set to: {valid_age}")
invalid_age = set_age(-5)
except ValueError as e:
print(f"Validation error: {e}")
`````````
---
**Definition:** You can create your own exception classes by inheriting from the `Exception` class or its subclasses.
**Why Use It:** Creates domain-specific errors, provides better error context, and makes error handling more precise and me
**Example:**
`````````python
# Simple custom exception
class InsufficientFundsError(Exception):
"""Raised when account has insufficient funds"""
pass
class BankAccount:
"""Bank account with custom exception handling"""
[Link] -= amount
return [Link]
def lock(self):
"""Lock the account"""
[Link] = True
try:
[Link](1500)
except InsufficientFundsError as e:
print(f"Transaction failed: {e}")
try:
[Link]()
[Link](100)
except AccountLockedError as e:
print(f"Cannot process: {e}")
return True
try:
validate_user_registration("AB", "invalidemail", 16)
except ValidationError as e:
print(f"Registration failed - {e}")
`````````
---
### Iterators
**Definition:** An iterator is an object that implements the iterator protocol (`__iter__()` and `__next__()` methods), allowin
**Why Use It:** Provides a standard way to loop through data, enables lazy evaluation, and allows custom iteration behavior
**Example:**
`````````python
# Basic iterator usage
my_list = [1, 2, 3, 4, 5]
iterator = iter(my_list)
print(next(iterator)) # Output: 1
print(next(iterator)) # Output: 2
print(next(iterator)) # Output: 3
def __iter__(self):
return self
def __next__(self):
if [Link] <= 0:
raise StopIteration
[Link] -= 1
return [Link] + 1
def __iter__(self):
[Link] = open([Link], 'r')
self.line_count = 0
return self
def __next__(self):
if self.line_count >= self.max_lines:
[Link]()
raise StopIteration
line = [Link]()
if not line:
[Link]()
raise StopIteration
self.line_count += 1
return [Link]()
---
### Generators
**Definition:** Generators are functions that use `yield` to produce a sequence of values lazily, one at a time, instead of retur
**Why Use It:** Memory efficient for large datasets, creates infinite sequences, simplifies iterator creation, and enables pipel
**Example:**
`````````python
# Basic generator function
def simple_generator():
"""Yields three values"""
print("First yield")
yield 1
print("Second yield")
yield 2
print("Third yield")
yield 3
# Using generator
gen = simple_generator()
print(next(gen)) # Output: First yield, then 1
print(next(gen)) # Output: Second yield, then 2
# Infinite generator
def infinite_counter(start=0):
"""Count infinitely from start"""
count = start
while True:
yield count
count += 1
def square_numbers(numbers):
"""Square each number"""
for num in numbers:
yield num ** 2
# Chain generators
numbers = range(10)
evens = filter_even(numbers)
squared = square_numbers(evens)
print(list(squared)) # Output: [0, 4, 16, 36, 64]
`````````
---
**Definition:** A concise way to create generators using syntax similar to list comprehensions, but with parentheses instead o
**Why Use It:** More memory efficient than list comprehensions, perfect for one-time iterations, and cleaner syntax for simp
**Example:**
`````````python
# List comprehension (creates entire list in memory)
squares_list = [x**2 for x in range(1000000)] # Uses lots of memory
# Memory comparison
import sys
---
**Definition:** `yield from` delegates part of generator operations to another generator, simplifying code that chains generato
**Why Use It:** Makes generator delegation cleaner, flattens nested iterations, and improves code readability.
**Example:**
`````````python
# Without yield from (verbose)
def chain_generators_old(*iterables):
"""Chain iterables the old way"""
for iterable in iterables:
for item in iterable:
yield item
def traverse(self):
"""Traverse tree using yield from"""
yield [Link]
for child in [Link]:
yield from [Link]()
# Create tree
root = TreeNode(1, [
TreeNode(2, [TreeNode(4), TreeNode(5)]),
TreeNode(3, [TreeNode(6)])
])
# Traverse
for value in [Link]():
print(value, end=' ') # Output: 1 2 4 5 3 6
`````````
---
## 9. Decorators
**Definition:** Decorators are functions that modify or enhance other functions without changing their source code. They "w
**Why Use It:** Adds reusable functionality (logging, timing, authentication), separates concerns, and keeps code DRY (Don
**Example:**
`````````python
# Basic decorator
def my_decorator(func):
"""Simple decorator that wraps a function"""
def wrapper():
print("Something before the function")
func()
print("Something after the function")
return wrapper
@my_decorator
def say_hello():
print("Hello!")
say_hello()
# Output:
# Something before the function
# Hello!
# Something after the function
@timing_decorator
def slow_function():
import time
[Link](1)
return "Done"
result = slow_function()
# Output: slow_function took 1.0001 seconds
print(f"Calling {func.__name__}({all_args})")
result = func(*args, **kwargs)
print(f"{func.__name__} returned {result!r}")
return result
return wrapper
@log_function_call
def add(a, b):
return a + b
result = add(5, 3)
# Output:
# Calling add(5, 3)
# add returned 8
`````````
---
**Definition:** Decorators that accept arguments, requiring an extra layer of function nesting to configure behavior.
**Why Use It:** Allows customization of decorator behavior, makes decorators more flexible and reusable.
**Example:**
`````````python
# Decorator factory (decorator with parameters)
def repeat(times):
"""Repeat function execution N times"""
def decorator(func):
def wrapper(*args, **kwargs):
result = None
for _ in range(times):
result = func(*args, **kwargs)
return result
return wrapper
return decorator
@repeat(3)
def greet(name):
print(f"Hello, {name}!")
greet("Alice")
# Output:
# Hello, Alice!
# Hello, Alice!
# Hello, Alice!
@validate_range(0, 100)
def set_percentage(value):
return f"Percentage set to {value}%"
print(set_percentage(50)) # Works
# print(set_percentage(150)) # Raises ValueError
def decorator(func):
def wrapper(*args, **kwargs):
for attempt in range(1, max_attempts + 1):
try:
return func(*args, **kwargs)
except Exception as e:
if attempt == max_attempts:
print(f"Failed after {max_attempts} attempts")
raise
print(f"Attempt {attempt} failed: {e}. Retrying...")
[Link](delay)
return wrapper
return decorator
@retry(max_attempts=3, delay=0.5)
def unreliable_function():
import random
if [Link]() < 0.7:
raise ConnectionError("Network error")
return "Success!"
`````````
---
**Definition:** Using `[Link]` preserves the original function's metadata (name, docstring) when creating decorator
**Why Use It:** Maintains proper function introspection, documentation, and debugging information.
**Example:**
`````````python
from functools import wraps
def original_function():
"""This is the original function"""
pass
@bad_decorator
def bad_wrapped():
"""Original docstring"""
pass
@good_decorator
def good_wrapped():
"""Original docstring"""
pass
def my_decorator(func):
"""Decorator template with proper metadata preservation"""
@wraps(func)
def wrapper(*args, **kwargs):
# Before function
print(f"Calling {func.__name__}")
# Call function
result = func(*args, **kwargs)
# After function
print(f"Finished {func.__name__}")
return result
return wrapper
@my_decorator
def calculate(x, y):
""")
self.phone_pattern = [Link](r'^\d{3}-\d{3}-\d{4}# Complete Python Documentation with Detailed Explanations
## From Basics to Advanced - Python 3.13+
---
## Table of Contents
---
### Variables
**Definition:** Variables are named containers that store data values in memory. Python is dynamically typed, meaning you d
**Why Use It:** Variables allow you to store and manipulate data throughout your program, making code reusable and maint
**Example:**
````````python
# Simple variable assignment
name = "Alice" # String variable
age = 30 # Integer variable
height = 5.7 # Float variable
is_student = False # Boolean variable
# Multiple assignment
x, y, z = 1, 2, 3 # Assign multiple values at once
a = b = c = 10 # Assign same value to multiple variables
---
**Why Use It:** Different data types are optimized for different operations. Using the right type improves performance and p
**Example:**
````````python
# Integer
count = 100
print(type(count)) # <class 'int'>
# Float
price = 19.99
print(type(price)) # <class 'float'>
# String
message = "Hello, World!"
print(type(message)) # <class 'str'>
# Boolean
is_active = True
print(type(is_active)) # <class 'bool'>
# Complex numbers
complex_num = 3 + 4j
print(type(complex_num)) # <class 'complex'>
# None type
result = None
print(type(result)) # <class 'NoneType'>
````````
---
**Definition:** Type checking verifies the data type of a variable. Type conversion transforms data from one type to another.
**Why Use It:** Ensures data integrity, prevents errors, and allows operations between different types.
**Example:**
````````python
# Type checking
age = 25
print(isinstance(age, int)) # True - checks if age is an integer
print(isinstance(age, str)) # False
---
## 2. Control Flow
**Definition:** Conditional statements that execute different code blocks based on whether conditions are true or false.
**Why Use It:** Allows your program to make decisions and execute different paths of code based on conditions, making pro
**Example:**
````````python
# Grade calculator
score = 85
print(f"Your grade is: {grade}") # Output: Good job! Your grade is: B
````````
---
**Why Use It:** Makes code more readable and compact for simple conditional assignments.
**Example:**
````````python
# Traditional if-else
age = 20
if age >= 18:
status = "Adult"
else:
status = "Minor"
---
**Definition:** A loop that iterates over a sequence (list, tuple, string, range) and executes a block of code for each item.
**Why Use It:** Automates repetitive tasks, processes collections of data, and eliminates the need for manual repetition.
**Example:**
````````python
# Basic for loop with range
for i in range(5):
print(f"Count: {i}")
# Output: Count: 0, Count: 1, Count: 2, Count: 3, Count: 4
---
**Why Use It:** Useful when you don't know in advance how many iterations are needed, or when waiting for a specific con
**Example:**
````````python
# Basic while loop
count = 0
while count < 5:
print(f"Count is: {count}")
count += 1
---
**Definition:**
- **break**: Exits the loop entirely
- **continue**: Skips the current iteration and moves to the next one
**Why Use It:** Provides fine control over loop execution, allowing you to skip unwanted iterations or exit early when condi
**Example:**
````````python
# Break - exit loop when condition met
for i in range(10):
if i == 5:
break # Stop loop when i equals 5
print(i) # Output: 0, 1, 2, 3, 4
---
**Definition:** A structural pattern matching statement that compares a value against multiple patterns, similar to switch-case
**Why Use It:** Provides cleaner, more readable code than multiple if-elif statements, especially for complex pattern matchin
**Example:**
````````python
# HTTP status code handler
def handle_response(status_code):
match status_code:
case 200:
return "Success"
case 404:
return "Not Found"
case 500 | 502 | 503: # Multiple values
return "Server Error"
case code if 400 <= code < 500: # With condition
return "Client Error"
case _: # Default case
return "Unknown Status"
---
## 3. Functions
**Definition:** A reusable block of code that performs a specific task. Functions are defined using the `def` keyword.
**Why Use It:** Promotes code reusability, organization, and maintainability. Breaks complex problems into smaller, manage
**Example:**
````````python
# Simple function
def greet(name):
"""Greets a person by name"""
return f"Hello, {name}!"
message = greet("Alice")
print(message) # Output: Hello, Alice!
result = calculate_area(5, 3)
print(f"Area: {result}") # Output: Area: 15
---
**Definition:** Parameters that have default values assigned, making them optional when calling the function.
**Why Use It:** Makes functions more flexible and reduces the need for multiple function definitions for similar tasks.
**Example:**
````````python
# Function with default parameter
def power(base, exponent=2):
"""Raises base to the power of exponent (default: 2)"""
return base ** exponent
# Multiple defaults
def create_profile(name, age=18, country="USA"):
return {
'name': name,
'age': age,
'country': country
}
---
**Definition:** Allows a function to accept any number of positional arguments, which are collected into a tuple.
**Why Use It:** Makes functions flexible when you don't know in advance how many arguments will be passed.
**Example:**
````````python
# Function accepting any number of arguments
def sum_all(*args):
"""Sums all provided numbers"""
total = 0
for num in args:
total += num
return total
---
**Definition:** Allows a function to accept any number of keyword arguments, which are collected into a dictionary.
**Why Use It:** Provides flexibility for functions that need to handle varying named parameters, useful for configuration and
**Example:**
````````python
# Function accepting keyword arguments
def print_info(**kwargs):
"""Prints all key-value pairs"""
for key, value in [Link]():
print(f"{key}: {value}")
---
**Why Use It:** Improves code documentation, enables static type checking with tools like mypy, and makes code more mai
**Example:**
````````python
# Function with type hints
def add_numbers(x: int, y: int) -> int:
"""Adds two integers and returns an integer"""
return x + y
result = add_numbers(5, 3)
print(result) # Output: 8
---
**Definition:** A closure is a function that remembers values from its enclosing scope even after that scope has finished exec
**Why Use It:** Enables data encapsulation, creates function factories, and allows for elegant callback patterns.
**Example:**
````````python
# Basic closure
def outer_function(x):
"""Outer function that returns an inner function"""
def inner_function(y):
"""Inner function that remembers x"""
return x + y
return inner_function
# Create a closure
add_5 = outer_function(5)
print(add_5(10)) # Output: 15 (remembers x=5)
print(add_5(20)) # Output: 25
def increment():
nonlocal count # Modify outer scope variable
count += 1
return count
return increment
counter1 = make_counter()
counter2 = make_counter()
print(counter1()) # Output: 1
print(counter1()) # Output: 2
print(counter2()) # Output: 1 (separate counter)
# Multiplier factory
def make_multiplier(n):
"""Creates a function that multiplies by n"""
def multiply(x):
return x * n
return multiply
times_3 = make_multiplier(3)
times_5 = make_multiplier(5)
print(times_3(10)) # Output: 30
print(times_5(10)) # Output: 50
````````
---
## 4. Object-Oriented Programming
### Classes and Objects
**Definition:** A class is a blueprint for creating objects. Objects are instances of classes that combine data (attributes) and b
**Why Use It:** Organizes code into reusable components, models real-world entities, and implements encapsulation, inherit
**Example:**
````````python
# Basic class definition
class Dog:
"""Represents a dog"""
# Constructor (initializer)
def __init__(self, name, age):
"""Initialize a new dog"""
[Link] = name # Instance attribute
[Link] = age
# Instance method
def bark(self):
"""Make the dog bark"""
return f"{[Link]} says Woof!"
def get_info(self):
"""Return dog information"""
return f"{[Link]} is {[Link]} years old"
---
**Definition:** Special methods with double underscores (e.g., `__init__`, `__str__`) that define how objects behave with bui
**Why Use It:** Allows custom classes to work seamlessly with Python's built-in functions and operators, making objects be
**Example:**
````````python
class Book:
"""Represents a book"""
def __str__(self):
"""String representation for users"""
return f"'{[Link]}' by {[Link]}"
def __repr__(self):
"""String representation for developers"""
return f"Book(title='{[Link]}', author='{[Link]}', pages={[Link]})"
def __len__(self):
"""Return number of pages"""
return [Link]
def __eq__(self, other):
"""Check if two books are equal"""
return [Link] == [Link] and [Link] == [Link]
def __str__(self):
return f"Vector({self.x}, {self.y})"
v1 = Vector(2, 3)
v2 = Vector(4, 5)
v3 = v1 + v2 # Uses __add__
v4 = v1 * 3 # Uses __mul__
---
### Inheritance
**Definition:** A mechanism where a new class (child/subclass) derives properties and methods from an existing class (paren
**Why Use It:** Promotes code reuse, creates hierarchical relationships, and allows for polymorphism (same interface, differ
**Example:**
````````python
# Parent class
class Animal:
"""Base class for all animals"""
def speak(self):
"""Generic speak method"""
return "Some sound"
def info(self):
return f"{[Link]} is {[Link]} years old"
# Child class
class Dog(Animal):
"""Dog class inherits from Animal"""
class Cat(Animal):
"""Cat class inherits from Animal"""
def speak(self):
return "Meow!"
def scratch(self):
return f"{[Link]} is scratching"
---
**Definition:**
- **Class methods**: Methods that receive the class as the first parameter (cls), not an instance
- **Static methods**: Methods that don't receive class or instance, just regular functions within class namespace
**Why Use It:** Class methods are useful for factory methods and alternative constructors. Static methods are utility function
**Example:**
````````python
class Date:
"""Represents a date"""
@classmethod
def from_string(cls, date_string):
"""Factory method: Create Date from string"""
year, month, day = map(int, date_string.split('-'))
return cls(year, month, day) # Returns new instance
@classmethod
def today(cls):
"""Factory method: Create Date for today"""
import datetime
today = [Link]()
return cls([Link], [Link], [Link])
@staticmethod
def is_leap_year(year):
"""Utility function: Check if year is leap year"""
return year % 4 == 0 and (year % 100 != 0 or year % 400 == 0)
def __str__(self):
return f"{[Link]}-{[Link]:02d}-{[Link]:02d}"
@classmethod
def from_fahrenheit(cls, fahrenheit):
"""Create Temperature from Fahrenheit"""
celsius = (fahrenheit - 32) * 5/9
return cls(celsius)
@staticmethod
def celsius_to_fahrenheit(celsius):
"""Convert Celsius to Fahrenheit"""
return (celsius * 9/5) + 32
def __str__(self):
return f"{[Link]}°C"
temp1 = Temperature(25)
temp2 = Temperature.from_fahrenheit(77)
---
### Properties
**Definition:** Properties allow you to define methods that can be accessed like attributes, providing controlled access to cla
**Why Use It:** Enables encapsulation, data validation, computed attributes, and maintains a clean interface while adding log
**Example:**
````````python
class Circle:
"""Represents a circle"""
@property
def radius(self):
"""Getter for radius"""
return self._radius
@[Link]
def radius(self, value):
"""Setter with validation"""
if value < 0:
raise ValueError("Radius cannot be negative")
self._radius = value
@property
def diameter(self):
"""Computed property"""
return self._radius * 2
@property
def area(self):
"""Computed property"""
import math
return [Link] * (self._radius ** 2)
@property
def circumference(self):
"""Computed property"""
import math
return 2 * [Link] * self._radius
# Using properties
circle = Circle(5)
# Validation works
try:
[Link] = -5
except ValueError as e:
print(f"Error: {e}") # Output: Error: Radius cannot be negative
@property
def celsius(self):
return self._celsius
@[Link]
def celsius(self, value):
if value < -273.15:
raise ValueError("Temperature below absolute zero!")
if value > 100:
print("Warning: Very high temperature!")
self._celsius = value
@property
def fahrenheit(self):
"""Convert to Fahrenheit on the fly"""
return (self._celsius * 9/5) + 32
@[Link]
def fahrenheit(self, value):
"""Set temperature in Fahrenheit"""
[Link] = (value - 32) * 5/9
thermostat = Thermostat()
print(f"Current: {[Link]}°C") # Output: Current: 20°C
print(f"In Fahrenheit: {[Link]}°F") # Output: In Fahrenheit: 68.0°F
---
**Definition:** Modules are Python files containing functions, classes, and variables. Importing allows you to use code from
**Why Use It:** Organizes code into logical units, promotes code reuse, and provides access to Python's extensive standard l
**Example:**
````````python
# Different ways to import
current_dir = [Link]()
print(f"Current directory: {current_dir}")
def save_log(message):
"""Save timestamped log message"""
log_entry = {
'timestamp': [Link]().isoformat(),
'message': message
}
print([Link](log_entry, indent=2))
save_log("Application started")
````````
---
**Definition:** Any Python file can be a module. You create one by saving Python code in a `.py` file and importing it in othe
**Why Use It:** Organizes your code into reusable components, separates concerns, and makes large projects manageable.
**Example:**
PI = 3.14159
def circle_area(radius):
"""Calculate circle area"""
return PI * radius ** 2
def circle_circumference(radius):
"""Calculate circle circumference"""
return 2 * PI * radius
def square_area(side):
"""Calculate square area"""
return side ** 2
class Calculator:
"""Simple calculator class"""
@staticmethod
def add(a, b):
return a + b
@staticmethod
def multiply(a, b):
return a * b
````````
---
**Definition:** `__name__` is a special variable that equals `"__main__"` when the file is run directly, or the module name w
**Why Use It:** Allows you to write code that runs only when the file is executed directly, not when imported. Essential for c
**Example:**
````````python
# [Link]
"""Utility functions"""
def process_data(data):
"""Process data"""
return [x * 2 for x in data]
def validate_input(value):
"""Validate input"""
return value > 0
test_data = [1, 2, 3, 4, 5]
result = process_data(test_data)
print(f"Test result: {result}")
---
## 6. File Handling
**Definition:** File reading operations allow you to access and read content from files stored on disk.
**Why Use It:** Essential for data processing, configuration loading, log analysis, and working with persistent data.
**Example:**
````````python
# Method 1: Read entire file
with open('[Link]', 'r') as file:
content = [Link]()
print(content)
---
**Definition:** File writing operations allow you to create new files or modify existing ones by writing data to disk.
**Why Use It:** Saves program output, creates logs, generates reports, and persists data between program runs.
**Example:**
````````python
# Write mode ('w') - overwrites existing file
with open('[Link]', 'w') as file:
[Link]("Hello, World!\n")
[Link]("This is line 2\n")
---
**Definition:** The `with` statement automatically handles resource setup and cleanup, ensuring files are properly closed eve
**Why Use It:** Prevents resource leaks, ensures proper cleanup, and makes code more readable and reliable.
**Example:**
````````python
# Without context manager (not recommended)
file = open('[Link]', 'r')
try:
content = [Link]()
print(content)
finally:
[Link]() # Must remember to close
print(process_file('[Link]'))
````````
---
**Definition:** Binary mode reads/writes files as raw bytes rather than text, used for non-text files like images, videos, and ex
**Why Use It:** Required for working with binary file formats, preserves exact byte content, and prevents text encoding issu
**Example:**
````````python
# Reading binary file
with open('[Link]', 'rb') as file:
image_data = [Link]()
print(f"Image size: {len(image_data)} bytes")
---
## 7. Exception Handling
**Definition:** Exception handling allows you to gracefully handle errors that occur during program execution, preventing cr
**Why Use It:** Makes programs robust, provides user-friendly error messages, and allows recovery from errors.
**Example:**
````````python
# Basic exception handling
try:
result = 10 / 0
except ZeroDivisionError:
print("Cannot divide by zero!")
result = None
---
### Try-Except-Else-Finally
**Definition:**
- **else**: Runs if no exception occurred
- **finally**: Always runs, regardless of exceptions (cleanup code)
**Why Use It:** Provides precise control over exception handling flow, ensures cleanup code runs, and separates success log
**Example:**
````````python
# Complete exception handling structure
try:
file = open('[Link]', 'r')
data = [Link]()
number = int(data)
except FileNotFoundError:
print("File not found")
except ValueError:
print("File contains invalid data")
else:
# Runs only if no exception occurred
print(f"Successfully read number: {number}")
finally:
# Always runs (cleanup)
if 'file' in locals():
[Link]()
print("File closed")
def connect(self):
print("Connecting to database...")
def close(self):
print("Closing database connection")
def run_query(query):
"""Execute query with proper cleanup"""
db = DatabaseConnection()
try:
[Link]()
[Link](query)
except ValueError as e:
print(f"Query error: {e}")
return False
else:
print("Query executed successfully")
return True
finally:
[Link]()
---
**Definition:** You can manually trigger exceptions using the `raise` keyword to signal error conditions.
**Why Use It:** Enforces business logic, validates inputs, and creates clear error boundaries in your code.
**Example:**
````````python
# Raise built-in exception
def calculate_percentage(value, total):
"""Calculate percentage"""
if total == 0:
raise ZeroDivisionError("Total cannot be zero")
if value < 0 or total < 0:
raise ValueError("Values must be non-negative")
return (value / total) * 100
# Re-raising exceptions
def process_data(data):
"""Process data with logging"""
try:
result = int(data)
return result * 2
except ValueError:
print("Logging error...")
raise # Re-raise the same exception
# Using validation
try:
valid_age = set_age(25)
print(f"Age set to: {valid_age}")
invalid_age = set_age(-5)
except ValueError as e:
print(f"Validation error: {e}")
````````
---
**Definition:** You can create your own exception classes by inheriting from the `Exception` class or its subclasses.
**Why Use It:** Creates domain-specific errors, provides better error context, and makes error handling more precise and me
**Example:**
````````python
# Simple custom exception
class InsufficientFundsError(Exception):
"""Raised when account has insufficient funds"""
pass
class BankAccount:
"""Bank account with custom exception handling"""
if amount <= 0:
raise ValueError("Withdrawal amount must be positive")
[Link] -= amount
return [Link]
def lock(self):
"""Lock the account"""
[Link] = True
try:
[Link](1500)
except InsufficientFundsError as e:
print(f"Transaction failed: {e}")
try:
[Link]()
[Link](100)
except AccountLockedError as e:
print(f"Cannot process: {e}")
return True
try:
validate_user_registration("AB", "invalidemail", 16)
except ValidationError as e:
print(f"Registration failed - {e}")
````````
---
### Iterators
**Definition:** An iterator is an object that implements the iterator protocol (`__iter__()` and `__next__()` methods), allowin
**Why Use It:** Provides a standard way to loop through data, enables lazy evaluation, and allows custom iteration behavior
**Example:**
````````python
# Basic iterator usage
my_list = [1, 2, 3, 4, 5]
iterator = iter(my_list)
print(next(iterator)) # Output: 1
print(next(iterator)) # Output: 2
print(next(iterator)) # Output: 3
def __iter__(self):
return self
def __next__(self):
if [Link] <= 0:
raise StopIteration
[Link] -= 1
return [Link] + 1
def __iter__(self):
[Link] = open([Link], 'r')
self.line_count = 0
return self
def __next__(self):
if self.line_count >= self.max_lines:
[Link]()
raise StopIteration
line = [Link]()
if not line:
[Link]()
raise StopIteration
self.line_count += 1
return [Link]()
---
### Generators
**Definition:** Generators are functions that use `yield` to produce a sequence of values lazily, one at a time, instead of retur
**Why Use It:** Memory efficient for large datasets, creates infinite sequences, simplifies iterator creation, and enables pipel
**Example:**
````````python
# Basic generator function
def simple_generator():
"""Yields three values"""
print("First yield")
yield 1
print("Second yield")
yield 2
print("Third yield")
yield 3
# Using generator
gen = simple_generator()
print(next(gen)) # Output: First yield, then 1
print(next(gen)) # Output: Second yield, then 2
# Infinite generator
def infinite_counter(start=0):
"""Count infinitely from start"""
count = start
while True:
yield count
count += 1
def square_numbers(numbers):
"""Square each number"""
for num in numbers:
yield num ** 2
# Chain generators
numbers = range(10)
evens = filter_even(numbers)
squared = square_numbers(evens)
print(list(squared)) # Output: [0, 4, 16, 36, 64]
````````
---
**Definition:** A concise way to create generators using syntax similar to list comprehensions, but with parentheses instead o
**Why Use It:** More memory efficient than list comprehensions, perfect for one-time iterations, and cleaner syntax for simp
**Example:**
````````python
# List comprehension (creates entire list in memory)
squares_list = [x**2 for x in range(1000000)] # Uses lots of memory
# Memory comparison
import sys
---
**Definition:** `yield from` delegates part of generator operations to another generator, simplifying code that chains generato
**Why Use It:** Makes generator delegation cleaner, flattens nested iterations, and improves code readability.
**Example:**
````````python
# Without yield from (verbose)
def chain_generators_old(*iterables):
"""Chain iterables the old way"""
for iterable in iterables:
for item in iterable:
yield item
def traverse(self):
"""Traverse tree using yield from"""
yield [Link]
for child in [Link]:
yield from [Link]()
# Create tree
root = TreeNode(1, [
TreeNode(2, [TreeNode(4), TreeNode(5)]),
TreeNode(3, [TreeNode(6)])
])
# Traverse
for value in [Link]():
print(value, end=' ') # Output: 1 2 4 5 3 6
````````
---
## 9. Decorators
### Function Decorators
**Definition:** Decorators are functions that modify or enhance other functions without changing their source code. They "w
**Why Use It:** Adds reusable functionality (logging, timing, authentication), separates concerns, and keeps code DRY (Don
**Example:**
````````python
# Basic decorator
def my_decorator(func):
"""Simple decorator that wraps a function"""
def wrapper():
print("Something before the function")
func()
print("Something after the function")
return wrapper
@my_decorator
def say_hello():
print("Hello!")
say_hello()
# Output:
# Something before the function
# Hello!
# Something after the function
@timing_decorator
def slow_function():
import time
[Link](1)
return "Done"
result = slow_function()
# Output: slow_function took 1.0001 seconds
# Practical example: Logging decorator
def log_function_call(func):
"""Log function calls with arguments"""
def wrapper(*args, **kwargs):
args_str = ', '.join(repr(a) for a in args)
kwargs_str = ', '.join(f"{k}={v!r}" for k, v in [Link]())
all_args = ', '.join(filter(None, [args_str, kwargs_str]))
print(f"Calling {func.__name__}({all_args})")
result = func(*args, **kwargs)
print(f"{func.__name__} returned {result!r}")
return result
return wrapper
@log_function_call
def add(a, b):
return a + b
result = add(5, 3)
# Output:
# Calling add(5, 3)
# add returned 8
````````
---
**Definition:** Decorators that accept arguments, requiring an extra layer of function nesting to configure behavior.
**Why Use It:** Allows customization of decorator behavior, makes decorators more flexible and reusable.
**Example:**
````````python
# Decorator factory (decorator with parameters)
def repeat(times):
"""Repeat function execution N times"""
def decorator(func):
def wrapper(*args, **kwargs):
result = None
for _ in range(times):
result = func(*args, **kwargs)
return result
return wrapper
return decorator
@repeat(3)
def greet(name):
print(f"Hello, {name}!")
greet("Alice")
# Output:
# Hello, Alice!
# Hello, Alice!
# Hello, Alice!
@validate_range(0, 100)
def set_percentage(value):
return f"Percentage set to {value}%"
print(set_percentage(50)) # Works
# print(set_percentage(150)) # Raises ValueError
def decorator(func):
def wrapper(*args, **kwargs):
for attempt in range(1, max_attempts + 1):
try:
return func(*args, **kwargs)
except Exception as e:
if attempt == max_attempts:
print(f"Failed after {max_attempts} attempts")
raise
print(f"Attempt {attempt} failed: {e}. Retrying...")
[Link](delay)
return wrapper
return decorator
@retry(max_attempts=3, delay=0.5)
def unreliable_function():
import random
if [Link]() < 0.7:
raise ConnectionError("Network error")
return "Success!"
````````
---
**Definition:** Using `[Link]` preserves the original function's metadata (name, docstring) when creating decorator
**Why Use It:** Maintains proper function introspection, documentation, and debugging information.
**Example:**
````````python
from functools import wraps
def original_function():
"""This is the original function"""
pass
@bad_decorator
def bad_wrapped():
"""Original docstring"""
pass
@good_decorator
def good_wrapped():
"""Original docstring"""
pass
def my_decorator(func):
"""Decorator template with proper metadata preservation"""
@wraps(func)
def wrapper(*args, **kwargs):
# Before function
print(f"Calling {func.__name__}")
# Call function
result = func(*args, **kwargs)
# After function
print(f"Finished {func.__name__}")
return result
return wrapper
@my_decorator
def calculate(x, y):
""")
self.zip_pattern = [Link](r'^\d{5}(-\d{4})?# Complete Python Documentation with Detailed Explanations
## From Basics to Advanced - Python 3.13+
---
## Table of Contents
---
### Variables
**Definition:** Variables are named containers that store data values in memory. Python is dynamically typed, meaning you d
**Why Use It:** Variables allow you to store and manipulate data throughout your program, making code reusable and maint
**Example:**
```````python
# Simple variable assignment
name = "Alice" # String variable
age = 30 # Integer variable
height = 5.7 # Float variable
is_student = False # Boolean variable
# Multiple assignment
x, y, z = 1, 2, 3 # Assign multiple values at once
a = b = c = 10 # Assign same value to multiple variables
print(f"{name} is {age} years old") # Output: Alice is 30 years old
```````
---
**Definition:** Data types define the kind of value a variable can hold. Python has several built-in data types.
**Why Use It:** Different data types are optimized for different operations. Using the right type improves performance and p
**Example:**
```````python
# Integer
count = 100
print(type(count)) # <class 'int'>
# Float
price = 19.99
print(type(price)) # <class 'float'>
# String
message = "Hello, World!"
print(type(message)) # <class 'str'>
# Boolean
is_active = True
print(type(is_active)) # <class 'bool'>
# Complex numbers
complex_num = 3 + 4j
print(type(complex_num)) # <class 'complex'>
# None type
result = None
print(type(result)) # <class 'NoneType'>
```````
---
### Type Checking and Conversion
**Definition:** Type checking verifies the data type of a variable. Type conversion transforms data from one type to another.
**Why Use It:** Ensures data integrity, prevents errors, and allows operations between different types.
**Example:**
```````python
# Type checking
age = 25
print(isinstance(age, int)) # True - checks if age is an integer
print(isinstance(age, str)) # False
---
## 2. Control Flow
**Definition:** Conditional statements that execute different code blocks based on whether conditions are true or false.
**Why Use It:** Allows your program to make decisions and execute different paths of code based on conditions, making pro
**Example:**
```````python
# Grade calculator
score = 85
print(f"Your grade is: {grade}") # Output: Good job! Your grade is: B
```````
---
**Why Use It:** Makes code more readable and compact for simple conditional assignments.
**Example:**
```````python
# Traditional if-else
age = 20
if age >= 18:
status = "Adult"
else:
status = "Minor"
---
**Definition:** A loop that iterates over a sequence (list, tuple, string, range) and executes a block of code for each item.
**Why Use It:** Automates repetitive tasks, processes collections of data, and eliminates the need for manual repetition.
**Example:**
```````python
# Basic for loop with range
for i in range(5):
print(f"Count: {i}")
# Output: Count: 0, Count: 1, Count: 2, Count: 3, Count: 4
---
**Why Use It:** Useful when you don't know in advance how many iterations are needed, or when waiting for a specific con
**Example:**
```````python
# Basic while loop
count = 0
while count < 5:
print(f"Count is: {count}")
count += 1
---
**Definition:**
- **break**: Exits the loop entirely
- **continue**: Skips the current iteration and moves to the next one
**Why Use It:** Provides fine control over loop execution, allowing you to skip unwanted iterations or exit early when condi
**Example:**
```````python
# Break - exit loop when condition met
for i in range(10):
if i == 5:
break # Stop loop when i equals 5
print(i) # Output: 0, 1, 2, 3, 4
**Definition:** A structural pattern matching statement that compares a value against multiple patterns, similar to switch-case
**Why Use It:** Provides cleaner, more readable code than multiple if-elif statements, especially for complex pattern matchin
**Example:**
```````python
# HTTP status code handler
def handle_response(status_code):
match status_code:
case 200:
return "Success"
case 404:
return "Not Found"
case 500 | 502 | 503: # Multiple values
return "Server Error"
case code if 400 <= code < 500: # With condition
return "Client Error"
case _: # Default case
return "Unknown Status"
---
## 3. Functions
**Definition:** A reusable block of code that performs a specific task. Functions are defined using the `def` keyword.
**Why Use It:** Promotes code reusability, organization, and maintainability. Breaks complex problems into smaller, manage
**Example:**
```````python
# Simple function
def greet(name):
"""Greets a person by name"""
return f"Hello, {name}!"
message = greet("Alice")
print(message) # Output: Hello, Alice!
result = calculate_area(5, 3)
print(f"Area: {result}") # Output: Area: 15
---
**Definition:** Parameters that have default values assigned, making them optional when calling the function.
**Why Use It:** Makes functions more flexible and reduces the need for multiple function definitions for similar tasks.
**Example:**
```````python
# Function with default parameter
def power(base, exponent=2):
"""Raises base to the power of exponent (default: 2)"""
return base ** exponent
# Multiple defaults
def create_profile(name, age=18, country="USA"):
return {
'name': name,
'age': age,
'country': country
}
---
**Definition:** Allows a function to accept any number of positional arguments, which are collected into a tuple.
**Why Use It:** Makes functions flexible when you don't know in advance how many arguments will be passed.
**Example:**
```````python
# Function accepting any number of arguments
def sum_all(*args):
"""Sums all provided numbers"""
total = 0
for num in args:
total += num
return total
---
**Definition:** Allows a function to accept any number of keyword arguments, which are collected into a dictionary.
**Why Use It:** Provides flexibility for functions that need to handle varying named parameters, useful for configuration and
**Example:**
```````python
# Function accepting keyword arguments
def print_info(**kwargs):
"""Prints all key-value pairs"""
for key, value in [Link]():
print(f"{key}: {value}")
---
**Definition:** Optional metadata that specifies the expected types of function parameters and return values.
**Why Use It:** Improves code documentation, enables static type checking with tools like mypy, and makes code more mai
**Example:**
```````python
# Function with type hints
def add_numbers(x: int, y: int) -> int:
"""Adds two integers and returns an integer"""
return x + y
result = add_numbers(5, 3)
print(result) # Output: 8
---
**Definition:** A closure is a function that remembers values from its enclosing scope even after that scope has finished exec
**Why Use It:** Enables data encapsulation, creates function factories, and allows for elegant callback patterns.
**Example:**
```````python
# Basic closure
def outer_function(x):
"""Outer function that returns an inner function"""
def inner_function(y):
"""Inner function that remembers x"""
return x + y
return inner_function
# Create a closure
add_5 = outer_function(5)
print(add_5(10)) # Output: 15 (remembers x=5)
print(add_5(20)) # Output: 25
def increment():
nonlocal count # Modify outer scope variable
count += 1
return count
return increment
counter1 = make_counter()
counter2 = make_counter()
print(counter1()) # Output: 1
print(counter1()) # Output: 2
print(counter2()) # Output: 1 (separate counter)
# Multiplier factory
def make_multiplier(n):
"""Creates a function that multiplies by n"""
def multiply(x):
return x * n
return multiply
times_3 = make_multiplier(3)
times_5 = make_multiplier(5)
print(times_3(10)) # Output: 30
print(times_5(10)) # Output: 50
```````
---
## 4. Object-Oriented Programming
**Definition:** A class is a blueprint for creating objects. Objects are instances of classes that combine data (attributes) and b
**Why Use It:** Organizes code into reusable components, models real-world entities, and implements encapsulation, inherit
**Example:**
```````python
# Basic class definition
class Dog:
"""Represents a dog"""
# Constructor (initializer)
def __init__(self, name, age):
"""Initialize a new dog"""
[Link] = name # Instance attribute
[Link] = age
# Instance method
def bark(self):
"""Make the dog bark"""
return f"{[Link]} says Woof!"
def get_info(self):
"""Return dog information"""
return f"{[Link]} is {[Link]} years old"
---
**Definition:** Special methods with double underscores (e.g., `__init__`, `__str__`) that define how objects behave with bui
**Why Use It:** Allows custom classes to work seamlessly with Python's built-in functions and operators, making objects be
**Example:**
```````python
class Book:
"""Represents a book"""
def __str__(self):
"""String representation for users"""
return f"'{[Link]}' by {[Link]}"
def __repr__(self):
"""String representation for developers"""
return f"Book(title='{[Link]}', author='{[Link]}', pages={[Link]})"
def __len__(self):
"""Return number of pages"""
return [Link]
def __str__(self):
return f"Vector({self.x}, {self.y})"
v1 = Vector(2, 3)
v2 = Vector(4, 5)
v3 = v1 + v2 # Uses __add__
v4 = v1 * 3 # Uses __mul__
### Inheritance
**Definition:** A mechanism where a new class (child/subclass) derives properties and methods from an existing class (paren
**Why Use It:** Promotes code reuse, creates hierarchical relationships, and allows for polymorphism (same interface, differ
**Example:**
```````python
# Parent class
class Animal:
"""Base class for all animals"""
def speak(self):
"""Generic speak method"""
return "Some sound"
def info(self):
return f"{[Link]} is {[Link]} years old"
# Child class
class Dog(Animal):
"""Dog class inherits from Animal"""
class Cat(Animal):
"""Cat class inherits from Animal"""
def speak(self):
return "Meow!"
def scratch(self):
return f"{[Link]} is scratching"
---
**Definition:**
- **Class methods**: Methods that receive the class as the first parameter (cls), not an instance
- **Static methods**: Methods that don't receive class or instance, just regular functions within class namespace
**Why Use It:** Class methods are useful for factory methods and alternative constructors. Static methods are utility function
**Example:**
```````python
class Date:
"""Represents a date"""
@classmethod
def from_string(cls, date_string):
"""Factory method: Create Date from string"""
year, month, day = map(int, date_string.split('-'))
return cls(year, month, day) # Returns new instance
@classmethod
def today(cls):
"""Factory method: Create Date for today"""
import datetime
today = [Link]()
return cls([Link], [Link], [Link])
@staticmethod
def is_leap_year(year):
"""Utility function: Check if year is leap year"""
return year % 4 == 0 and (year % 100 != 0 or year % 400 == 0)
def __str__(self):
return f"{[Link]}-{[Link]:02d}-{[Link]:02d}"
@classmethod
def from_fahrenheit(cls, fahrenheit):
"""Create Temperature from Fahrenheit"""
celsius = (fahrenheit - 32) * 5/9
return cls(celsius)
@staticmethod
def celsius_to_fahrenheit(celsius):
"""Convert Celsius to Fahrenheit"""
return (celsius * 9/5) + 32
def __str__(self):
return f"{[Link]}°C"
temp1 = Temperature(25)
temp2 = Temperature.from_fahrenheit(77)
---
### Properties
**Definition:** Properties allow you to define methods that can be accessed like attributes, providing controlled access to cla
**Why Use It:** Enables encapsulation, data validation, computed attributes, and maintains a clean interface while adding log
**Example:**
```````python
class Circle:
"""Represents a circle"""
@property
def radius(self):
"""Getter for radius"""
return self._radius
@[Link]
def radius(self, value):
"""Setter with validation"""
if value < 0:
raise ValueError("Radius cannot be negative")
self._radius = value
@property
def diameter(self):
"""Computed property"""
return self._radius * 2
@property
def area(self):
"""Computed property"""
import math
return [Link] * (self._radius ** 2)
@property
def circumference(self):
"""Computed property"""
import math
return 2 * [Link] * self._radius
# Using properties
circle = Circle(5)
# Validation works
try:
[Link] = -5
except ValueError as e:
print(f"Error: {e}") # Output: Error: Radius cannot be negative
@property
def celsius(self):
return self._celsius
@[Link]
def celsius(self, value):
if value < -273.15:
raise ValueError("Temperature below absolute zero!")
if value > 100:
print("Warning: Very high temperature!")
self._celsius = value
@property
def fahrenheit(self):
"""Convert to Fahrenheit on the fly"""
return (self._celsius * 9/5) + 32
@[Link]
def fahrenheit(self, value):
"""Set temperature in Fahrenheit"""
[Link] = (value - 32) * 5/9
thermostat = Thermostat()
print(f"Current: {[Link]}°C") # Output: Current: 20°C
print(f"In Fahrenheit: {[Link]}°F") # Output: In Fahrenheit: 68.0°F
---
**Definition:** Modules are Python files containing functions, classes, and variables. Importing allows you to use code from
**Why Use It:** Organizes code into logical units, promotes code reuse, and provides access to Python's extensive standard l
**Example:**
```````python
# Different ways to import
current_dir = [Link]()
print(f"Current directory: {current_dir}")
def save_log(message):
"""Save timestamped log message"""
log_entry = {
'timestamp': [Link]().isoformat(),
'message': message
}
print([Link](log_entry, indent=2))
save_log("Application started")
```````
---
**Definition:** Any Python file can be a module. You create one by saving Python code in a `.py` file and importing it in othe
**Why Use It:** Organizes your code into reusable components, separates concerns, and makes large projects manageable.
**Example:**
PI = 3.14159
def circle_area(radius):
"""Calculate circle area"""
return PI * radius ** 2
def circle_circumference(radius):
"""Calculate circle circumference"""
return 2 * PI * radius
def square_area(side):
"""Calculate square area"""
return side ** 2
class Calculator:
"""Simple calculator class"""
@staticmethod
def add(a, b):
return a + b
@staticmethod
def multiply(a, b):
return a * b
```````
---
### The __name__ Variable
**Definition:** `__name__` is a special variable that equals `"__main__"` when the file is run directly, or the module name w
**Why Use It:** Allows you to write code that runs only when the file is executed directly, not when imported. Essential for c
**Example:**
```````python
# [Link]
"""Utility functions"""
def process_data(data):
"""Process data"""
return [x * 2 for x in data]
def validate_input(value):
"""Validate input"""
return value > 0
test_data = [1, 2, 3, 4, 5]
result = process_data(test_data)
print(f"Test result: {result}")
---
## 6. File Handling
**Why Use It:** Essential for data processing, configuration loading, log analysis, and working with persistent data.
**Example:**
```````python
# Method 1: Read entire file
with open('[Link]', 'r') as file:
content = [Link]()
print(content)
---
**Definition:** File writing operations allow you to create new files or modify existing ones by writing data to disk.
**Why Use It:** Saves program output, creates logs, generates reports, and persists data between program runs.
**Example:**
```````python
# Write mode ('w') - overwrites existing file
with open('[Link]', 'w') as file:
[Link]("Hello, World!\n")
[Link]("This is line 2\n")
---
**Definition:** The `with` statement automatically handles resource setup and cleanup, ensuring files are properly closed eve
**Why Use It:** Prevents resource leaks, ensures proper cleanup, and makes code more readable and reliable.
**Example:**
```````python
# Without context manager (not recommended)
file = open('[Link]', 'r')
try:
content = [Link]()
print(content)
finally:
[Link]() # Must remember to close
print(process_file('[Link]'))
```````
---
**Definition:** Binary mode reads/writes files as raw bytes rather than text, used for non-text files like images, videos, and ex
**Why Use It:** Required for working with binary file formats, preserves exact byte content, and prevents text encoding issu
**Example:**
```````python
# Reading binary file
with open('[Link]', 'rb') as file:
image_data = [Link]()
print(f"Image size: {len(image_data)} bytes")
---
## 7. Exception Handling
**Definition:** Exception handling allows you to gracefully handle errors that occur during program execution, preventing cr
**Why Use It:** Makes programs robust, provides user-friendly error messages, and allows recovery from errors.
**Example:**
```````python
# Basic exception handling
try:
result = 10 / 0
except ZeroDivisionError:
print("Cannot divide by zero!")
result = None
---
### Try-Except-Else-Finally
**Definition:**
- **else**: Runs if no exception occurred
- **finally**: Always runs, regardless of exceptions (cleanup code)
**Why Use It:** Provides precise control over exception handling flow, ensures cleanup code runs, and separates success log
**Example:**
```````python
# Complete exception handling structure
try:
file = open('[Link]', 'r')
data = [Link]()
number = int(data)
except FileNotFoundError:
print("File not found")
except ValueError:
print("File contains invalid data")
else:
# Runs only if no exception occurred
print(f"Successfully read number: {number}")
finally:
# Always runs (cleanup)
if 'file' in locals():
[Link]()
print("File closed")
def connect(self):
print("Connecting to database...")
def close(self):
print("Closing database connection")
def run_query(query):
"""Execute query with proper cleanup"""
db = DatabaseConnection()
try:
[Link]()
[Link](query)
except ValueError as e:
print(f"Query error: {e}")
return False
else:
print("Query executed successfully")
return True
finally:
[Link]()
---
**Definition:** You can manually trigger exceptions using the `raise` keyword to signal error conditions.
**Why Use It:** Enforces business logic, validates inputs, and creates clear error boundaries in your code.
**Example:**
```````python
# Raise built-in exception
def calculate_percentage(value, total):
"""Calculate percentage"""
if total == 0:
raise ZeroDivisionError("Total cannot be zero")
if value < 0 or total < 0:
raise ValueError("Values must be non-negative")
return (value / total) * 100
# Re-raising exceptions
def process_data(data):
"""Process data with logging"""
try:
result = int(data)
return result * 2
except ValueError:
print("Logging error...")
raise # Re-raise the same exception
# Using validation
try:
valid_age = set_age(25)
print(f"Age set to: {valid_age}")
invalid_age = set_age(-5)
except ValueError as e:
print(f"Validation error: {e}")
```````
---
**Definition:** You can create your own exception classes by inheriting from the `Exception` class or its subclasses.
**Why Use It:** Creates domain-specific errors, provides better error context, and makes error handling more precise and me
**Example:**
```````python
# Simple custom exception
class InsufficientFundsError(Exception):
"""Raised when account has insufficient funds"""
pass
if amount <= 0:
raise ValueError("Withdrawal amount must be positive")
[Link] -= amount
return [Link]
def lock(self):
"""Lock the account"""
[Link] = True
try:
[Link](1500)
except InsufficientFundsError as e:
print(f"Transaction failed: {e}")
try:
[Link]()
[Link](100)
except AccountLockedError as e:
print(f"Cannot process: {e}")
return True
try:
validate_user_registration("AB", "invalidemail", 16)
except ValidationError as e:
print(f"Registration failed - {e}")
```````
---
### Iterators
**Definition:** An iterator is an object that implements the iterator protocol (`__iter__()` and `__next__()` methods), allowin
**Why Use It:** Provides a standard way to loop through data, enables lazy evaluation, and allows custom iteration behavior
**Example:**
```````python
# Basic iterator usage
my_list = [1, 2, 3, 4, 5]
iterator = iter(my_list)
print(next(iterator)) # Output: 1
print(next(iterator)) # Output: 2
print(next(iterator)) # Output: 3
def __iter__(self):
return self
def __next__(self):
if [Link] <= 0:
raise StopIteration
[Link] -= 1
return [Link] + 1
def __iter__(self):
[Link] = open([Link], 'r')
self.line_count = 0
return self
def __next__(self):
if self.line_count >= self.max_lines:
[Link]()
raise StopIteration
line = [Link]()
if not line:
[Link]()
raise StopIteration
self.line_count += 1
return [Link]()
---
### Generators
**Definition:** Generators are functions that use `yield` to produce a sequence of values lazily, one at a time, instead of retur
**Why Use It:** Memory efficient for large datasets, creates infinite sequences, simplifies iterator creation, and enables pipel
**Example:**
```````python
# Basic generator function
def simple_generator():
"""Yields three values"""
print("First yield")
yield 1
print("Second yield")
yield 2
print("Third yield")
yield 3
# Using generator
gen = simple_generator()
print(next(gen)) # Output: First yield, then 1
print(next(gen)) # Output: Second yield, then 2
# Infinite generator
def infinite_counter(start=0):
"""Count infinitely from start"""
count = start
while True:
yield count
count += 1
def square_numbers(numbers):
"""Square each number"""
for num in numbers:
yield num ** 2
# Chain generators
numbers = range(10)
evens = filter_even(numbers)
squared = square_numbers(evens)
print(list(squared)) # Output: [0, 4, 16, 36, 64]
```````
---
**Definition:** A concise way to create generators using syntax similar to list comprehensions, but with parentheses instead o
**Why Use It:** More memory efficient than list comprehensions, perfect for one-time iterations, and cleaner syntax for simp
**Example:**
```````python
# List comprehension (creates entire list in memory)
squares_list = [x**2 for x in range(1000000)] # Uses lots of memory
# Generator expression (creates values on demand)
squares_gen = (x**2 for x in range(1000000)) # Uses minimal memory
# Memory comparison
import sys
---
**Definition:** `yield from` delegates part of generator operations to another generator, simplifying code that chains generato
**Why Use It:** Makes generator delegation cleaner, flattens nested iterations, and improves code readability.
**Example:**
```````python
# Without yield from (verbose)
def chain_generators_old(*iterables):
"""Chain iterables the old way"""
for iterable in iterables:
for item in iterable:
yield item
def traverse(self):
"""Traverse tree using yield from"""
yield [Link]
for child in [Link]:
yield from [Link]()
# Create tree
root = TreeNode(1, [
TreeNode(2, [TreeNode(4), TreeNode(5)]),
TreeNode(3, [TreeNode(6)])
])
# Traverse
for value in [Link]():
print(value, end=' ') # Output: 1 2 4 5 3 6
```````
---
## 9. Decorators
**Definition:** Decorators are functions that modify or enhance other functions without changing their source code. They "w
**Why Use It:** Adds reusable functionality (logging, timing, authentication), separates concerns, and keeps code DRY (Don
**Example:**
```````python
# Basic decorator
def my_decorator(func):
"""Simple decorator that wraps a function"""
def wrapper():
print("Something before the function")
func()
print("Something after the function")
return wrapper
@my_decorator
def say_hello():
print("Hello!")
say_hello()
# Output:
# Something before the function
# Hello!
# Something after the function
@timing_decorator
def slow_function():
import time
[Link](1)
return "Done"
result = slow_function()
# Output: slow_function took 1.0001 seconds
print(f"Calling {func.__name__}({all_args})")
result = func(*args, **kwargs)
print(f"{func.__name__} returned {result!r}")
return result
return wrapper
@log_function_call
def add(a, b):
return a + b
result = add(5, 3)
# Output:
# Calling add(5, 3)
# add returned 8
```````
---
**Definition:** Decorators that accept arguments, requiring an extra layer of function nesting to configure behavior.
**Why Use It:** Allows customization of decorator behavior, makes decorators more flexible and reusable.
**Example:**
```````python
# Decorator factory (decorator with parameters)
def repeat(times):
"""Repeat function execution N times"""
def decorator(func):
def wrapper(*args, **kwargs):
result = None
for _ in range(times):
result = func(*args, **kwargs)
return result
return wrapper
return decorator
@repeat(3)
def greet(name):
print(f"Hello, {name}!")
greet("Alice")
# Output:
# Hello, Alice!
# Hello, Alice!
# Hello, Alice!
@validate_range(0, 100)
def set_percentage(value):
return f"Percentage set to {value}%"
print(set_percentage(50)) # Works
# print(set_percentage(150)) # Raises ValueError
def decorator(func):
def wrapper(*args, **kwargs):
for attempt in range(1, max_attempts + 1):
try:
return func(*args, **kwargs)
except Exception as e:
if attempt == max_attempts:
print(f"Failed after {max_attempts} attempts")
raise
print(f"Attempt {attempt} failed: {e}. Retrying...")
[Link](delay)
return wrapper
return decorator
@retry(max_attempts=3, delay=0.5)
def unreliable_function():
import random
if [Link]() < 0.7:
raise ConnectionError("Network error")
return "Success!"
```````
---
**Definition:** Using `[Link]` preserves the original function's metadata (name, docstring) when creating decorator
**Why Use It:** Maintains proper function introspection, documentation, and debugging information.
**Example:**
```````python
from functools import wraps
def original_function():
"""This is the original function"""
pass
@bad_decorator
def bad_wrapped():
"""Original docstring"""
pass
@good_decorator
def good_wrapped():
"""Original docstring"""
pass
def my_decorator(func):
"""Decorator template with proper metadata preservation"""
@wraps(func)
def wrapper(*args, **kwargs):
# Before function
print(f"Calling {func.__name__}")
# Call function
result = func(*args, **kwargs)
# After function
print(f"Finished {func.__name__}")
return result
return wrapper
@my_decorator
def calculate(x, y):
""")
---
**Definition:** Advanced regex features include lookahead/lookbehind assertions, non-capturing groups, and flags for specia
**Why Use It:** Enables complex pattern matching, optimizes regex performance, and solves sophisticated text processing p
**Example:**
```````python
import re
# Flags
text = "Python is AWESOME"
# Case insensitive
result = [Link](r'python', text, [Link])
print(result) # ['Python']
# Multiline mode
multiline_text = """First line
Second line
Third line"""
matches = [Link](r'^.*line# Complete Python Documentation with Detailed Explanations
## From Basics to Advanced - Python 3.13+
---
## Table of Contents
---
### Variables
**Definition:** Variables are named containers that store data values in memory. Python is dynamically typed, meaning you d
**Why Use It:** Variables allow you to store and manipulate data throughout your program, making code reusable and maint
**Example:**
``````python
# Simple variable assignment
name = "Alice" # String variable
age = 30 # Integer variable
height = 5.7 # Float variable
is_student = False # Boolean variable
# Multiple assignment
x, y, z = 1, 2, 3 # Assign multiple values at once
a = b = c = 10 # Assign same value to multiple variables
print(f"{name} is {age} years old") # Output: Alice is 30 years old
``````
---
**Definition:** Data types define the kind of value a variable can hold. Python has several built-in data types.
**Why Use It:** Different data types are optimized for different operations. Using the right type improves performance and p
**Example:**
``````python
# Integer
count = 100
print(type(count)) # <class 'int'>
# Float
price = 19.99
print(type(price)) # <class 'float'>
# String
message = "Hello, World!"
print(type(message)) # <class 'str'>
# Boolean
is_active = True
print(type(is_active)) # <class 'bool'>
# Complex numbers
complex_num = 3 + 4j
print(type(complex_num)) # <class 'complex'>
# None type
result = None
print(type(result)) # <class 'NoneType'>
``````
---
### Type Checking and Conversion
**Definition:** Type checking verifies the data type of a variable. Type conversion transforms data from one type to another.
**Why Use It:** Ensures data integrity, prevents errors, and allows operations between different types.
**Example:**
``````python
# Type checking
age = 25
print(isinstance(age, int)) # True - checks if age is an integer
print(isinstance(age, str)) # False
---
## 2. Control Flow
**Definition:** Conditional statements that execute different code blocks based on whether conditions are true or false.
**Why Use It:** Allows your program to make decisions and execute different paths of code based on conditions, making pro
**Example:**
``````python
# Grade calculator
score = 85
print(f"Your grade is: {grade}") # Output: Good job! Your grade is: B
``````
---
**Why Use It:** Makes code more readable and compact for simple conditional assignments.
**Example:**
``````python
# Traditional if-else
age = 20
if age >= 18:
status = "Adult"
else:
status = "Minor"
---
**Definition:** A loop that iterates over a sequence (list, tuple, string, range) and executes a block of code for each item.
**Why Use It:** Automates repetitive tasks, processes collections of data, and eliminates the need for manual repetition.
**Example:**
``````python
# Basic for loop with range
for i in range(5):
print(f"Count: {i}")
# Output: Count: 0, Count: 1, Count: 2, Count: 3, Count: 4
---
**Why Use It:** Useful when you don't know in advance how many iterations are needed, or when waiting for a specific con
**Example:**
``````python
# Basic while loop
count = 0
while count < 5:
print(f"Count is: {count}")
count += 1
---
**Definition:**
- **break**: Exits the loop entirely
- **continue**: Skips the current iteration and moves to the next one
**Why Use It:** Provides fine control over loop execution, allowing you to skip unwanted iterations or exit early when condi
**Example:**
``````python
# Break - exit loop when condition met
for i in range(10):
if i == 5:
break # Stop loop when i equals 5
print(i) # Output: 0, 1, 2, 3, 4
**Definition:** A structural pattern matching statement that compares a value against multiple patterns, similar to switch-case
**Why Use It:** Provides cleaner, more readable code than multiple if-elif statements, especially for complex pattern matchin
**Example:**
``````python
# HTTP status code handler
def handle_response(status_code):
match status_code:
case 200:
return "Success"
case 404:
return "Not Found"
case 500 | 502 | 503: # Multiple values
return "Server Error"
case code if 400 <= code < 500: # With condition
return "Client Error"
case _: # Default case
return "Unknown Status"
---
## 3. Functions
**Definition:** A reusable block of code that performs a specific task. Functions are defined using the `def` keyword.
**Why Use It:** Promotes code reusability, organization, and maintainability. Breaks complex problems into smaller, manage
**Example:**
``````python
# Simple function
def greet(name):
"""Greets a person by name"""
return f"Hello, {name}!"
message = greet("Alice")
print(message) # Output: Hello, Alice!
result = calculate_area(5, 3)
print(f"Area: {result}") # Output: Area: 15
---
**Definition:** Parameters that have default values assigned, making them optional when calling the function.
**Why Use It:** Makes functions more flexible and reduces the need for multiple function definitions for similar tasks.
**Example:**
``````python
# Function with default parameter
def power(base, exponent=2):
"""Raises base to the power of exponent (default: 2)"""
return base ** exponent
# Multiple defaults
def create_profile(name, age=18, country="USA"):
return {
'name': name,
'age': age,
'country': country
}
---
**Definition:** Allows a function to accept any number of positional arguments, which are collected into a tuple.
**Why Use It:** Makes functions flexible when you don't know in advance how many arguments will be passed.
**Example:**
``````python
# Function accepting any number of arguments
def sum_all(*args):
"""Sums all provided numbers"""
total = 0
for num in args:
total += num
return total
---
**Definition:** Allows a function to accept any number of keyword arguments, which are collected into a dictionary.
**Why Use It:** Provides flexibility for functions that need to handle varying named parameters, useful for configuration and
**Example:**
``````python
# Function accepting keyword arguments
def print_info(**kwargs):
"""Prints all key-value pairs"""
for key, value in [Link]():
print(f"{key}: {value}")
---
**Definition:** Optional metadata that specifies the expected types of function parameters and return values.
**Why Use It:** Improves code documentation, enables static type checking with tools like mypy, and makes code more mai
**Example:**
``````python
# Function with type hints
def add_numbers(x: int, y: int) -> int:
"""Adds two integers and returns an integer"""
return x + y
result = add_numbers(5, 3)
print(result) # Output: 8
---
**Definition:** A closure is a function that remembers values from its enclosing scope even after that scope has finished exec
**Why Use It:** Enables data encapsulation, creates function factories, and allows for elegant callback patterns.
**Example:**
``````python
# Basic closure
def outer_function(x):
"""Outer function that returns an inner function"""
def inner_function(y):
"""Inner function that remembers x"""
return x + y
return inner_function
# Create a closure
add_5 = outer_function(5)
print(add_5(10)) # Output: 15 (remembers x=5)
print(add_5(20)) # Output: 25
def increment():
nonlocal count # Modify outer scope variable
count += 1
return count
return increment
counter1 = make_counter()
counter2 = make_counter()
print(counter1()) # Output: 1
print(counter1()) # Output: 2
print(counter2()) # Output: 1 (separate counter)
# Multiplier factory
def make_multiplier(n):
"""Creates a function that multiplies by n"""
def multiply(x):
return x * n
return multiply
times_3 = make_multiplier(3)
times_5 = make_multiplier(5)
print(times_3(10)) # Output: 30
print(times_5(10)) # Output: 50
``````
---
## 4. Object-Oriented Programming
**Definition:** A class is a blueprint for creating objects. Objects are instances of classes that combine data (attributes) and b
**Why Use It:** Organizes code into reusable components, models real-world entities, and implements encapsulation, inherit
**Example:**
``````python
# Basic class definition
class Dog:
"""Represents a dog"""
# Constructor (initializer)
def __init__(self, name, age):
"""Initialize a new dog"""
[Link] = name # Instance attribute
[Link] = age
# Instance method
def bark(self):
"""Make the dog bark"""
return f"{[Link]} says Woof!"
def get_info(self):
"""Return dog information"""
return f"{[Link]} is {[Link]} years old"
---
**Definition:** Special methods with double underscores (e.g., `__init__`, `__str__`) that define how objects behave with bui
**Why Use It:** Allows custom classes to work seamlessly with Python's built-in functions and operators, making objects be
**Example:**
``````python
class Book:
"""Represents a book"""
def __str__(self):
"""String representation for users"""
return f"'{[Link]}' by {[Link]}"
def __repr__(self):
"""String representation for developers"""
return f"Book(title='{[Link]}', author='{[Link]}', pages={[Link]})"
def __len__(self):
"""Return number of pages"""
return [Link]
def __str__(self):
return f"Vector({self.x}, {self.y})"
v1 = Vector(2, 3)
v2 = Vector(4, 5)
v3 = v1 + v2 # Uses __add__
v4 = v1 * 3 # Uses __mul__
### Inheritance
**Definition:** A mechanism where a new class (child/subclass) derives properties and methods from an existing class (paren
**Why Use It:** Promotes code reuse, creates hierarchical relationships, and allows for polymorphism (same interface, differ
**Example:**
``````python
# Parent class
class Animal:
"""Base class for all animals"""
def speak(self):
"""Generic speak method"""
return "Some sound"
def info(self):
return f"{[Link]} is {[Link]} years old"
# Child class
class Dog(Animal):
"""Dog class inherits from Animal"""
class Cat(Animal):
"""Cat class inherits from Animal"""
def speak(self):
return "Meow!"
def scratch(self):
return f"{[Link]} is scratching"
---
**Definition:**
- **Class methods**: Methods that receive the class as the first parameter (cls), not an instance
- **Static methods**: Methods that don't receive class or instance, just regular functions within class namespace
**Why Use It:** Class methods are useful for factory methods and alternative constructors. Static methods are utility function
**Example:**
``````python
class Date:
"""Represents a date"""
@classmethod
def from_string(cls, date_string):
"""Factory method: Create Date from string"""
year, month, day = map(int, date_string.split('-'))
return cls(year, month, day) # Returns new instance
@classmethod
def today(cls):
"""Factory method: Create Date for today"""
import datetime
today = [Link]()
return cls([Link], [Link], [Link])
@staticmethod
def is_leap_year(year):
"""Utility function: Check if year is leap year"""
return year % 4 == 0 and (year % 100 != 0 or year % 400 == 0)
def __str__(self):
return f"{[Link]}-{[Link]:02d}-{[Link]:02d}"
@classmethod
def from_fahrenheit(cls, fahrenheit):
"""Create Temperature from Fahrenheit"""
celsius = (fahrenheit - 32) * 5/9
return cls(celsius)
@staticmethod
def celsius_to_fahrenheit(celsius):
"""Convert Celsius to Fahrenheit"""
return (celsius * 9/5) + 32
def __str__(self):
return f"{[Link]}°C"
temp1 = Temperature(25)
temp2 = Temperature.from_fahrenheit(77)
---
### Properties
**Definition:** Properties allow you to define methods that can be accessed like attributes, providing controlled access to cla
**Why Use It:** Enables encapsulation, data validation, computed attributes, and maintains a clean interface while adding log
**Example:**
``````python
class Circle:
"""Represents a circle"""
@property
def radius(self):
"""Getter for radius"""
return self._radius
@[Link]
def radius(self, value):
"""Setter with validation"""
if value < 0:
raise ValueError("Radius cannot be negative")
self._radius = value
@property
def diameter(self):
"""Computed property"""
return self._radius * 2
@property
def area(self):
"""Computed property"""
import math
return [Link] * (self._radius ** 2)
@property
def circumference(self):
"""Computed property"""
import math
return 2 * [Link] * self._radius
# Using properties
circle = Circle(5)
# Validation works
try:
[Link] = -5
except ValueError as e:
print(f"Error: {e}") # Output: Error: Radius cannot be negative
@property
def celsius(self):
return self._celsius
@[Link]
def celsius(self, value):
if value < -273.15:
raise ValueError("Temperature below absolute zero!")
if value > 100:
print("Warning: Very high temperature!")
self._celsius = value
@property
def fahrenheit(self):
"""Convert to Fahrenheit on the fly"""
return (self._celsius * 9/5) + 32
@[Link]
def fahrenheit(self, value):
"""Set temperature in Fahrenheit"""
[Link] = (value - 32) * 5/9
thermostat = Thermostat()
print(f"Current: {[Link]}°C") # Output: Current: 20°C
print(f"In Fahrenheit: {[Link]}°F") # Output: In Fahrenheit: 68.0°F
---
**Definition:** Modules are Python files containing functions, classes, and variables. Importing allows you to use code from
**Why Use It:** Organizes code into logical units, promotes code reuse, and provides access to Python's extensive standard l
**Example:**
``````python
# Different ways to import
current_dir = [Link]()
print(f"Current directory: {current_dir}")
def save_log(message):
"""Save timestamped log message"""
log_entry = {
'timestamp': [Link]().isoformat(),
'message': message
}
print([Link](log_entry, indent=2))
save_log("Application started")
``````
---
**Definition:** Any Python file can be a module. You create one by saving Python code in a `.py` file and importing it in othe
**Why Use It:** Organizes your code into reusable components, separates concerns, and makes large projects manageable.
**Example:**
PI = 3.14159
def circle_area(radius):
"""Calculate circle area"""
return PI * radius ** 2
def circle_circumference(radius):
"""Calculate circle circumference"""
return 2 * PI * radius
def square_area(side):
"""Calculate square area"""
return side ** 2
class Calculator:
"""Simple calculator class"""
@staticmethod
def add(a, b):
return a + b
@staticmethod
def multiply(a, b):
return a * b
``````
---
### The __name__ Variable
**Definition:** `__name__` is a special variable that equals `"__main__"` when the file is run directly, or the module name w
**Why Use It:** Allows you to write code that runs only when the file is executed directly, not when imported. Essential for c
**Example:**
``````python
# [Link]
"""Utility functions"""
def process_data(data):
"""Process data"""
return [x * 2 for x in data]
def validate_input(value):
"""Validate input"""
return value > 0
test_data = [1, 2, 3, 4, 5]
result = process_data(test_data)
print(f"Test result: {result}")
---
## 6. File Handling
**Why Use It:** Essential for data processing, configuration loading, log analysis, and working with persistent data.
**Example:**
``````python
# Method 1: Read entire file
with open('[Link]', 'r') as file:
content = [Link]()
print(content)
---
**Definition:** File writing operations allow you to create new files or modify existing ones by writing data to disk.
**Why Use It:** Saves program output, creates logs, generates reports, and persists data between program runs.
**Example:**
``````python
# Write mode ('w') - overwrites existing file
with open('[Link]', 'w') as file:
[Link]("Hello, World!\n")
[Link]("This is line 2\n")
---
**Definition:** The `with` statement automatically handles resource setup and cleanup, ensuring files are properly closed eve
**Why Use It:** Prevents resource leaks, ensures proper cleanup, and makes code more readable and reliable.
**Example:**
``````python
# Without context manager (not recommended)
file = open('[Link]', 'r')
try:
content = [Link]()
print(content)
finally:
[Link]() # Must remember to close
print(process_file('[Link]'))
``````
---
**Definition:** Binary mode reads/writes files as raw bytes rather than text, used for non-text files like images, videos, and ex
**Why Use It:** Required for working with binary file formats, preserves exact byte content, and prevents text encoding issu
**Example:**
``````python
# Reading binary file
with open('[Link]', 'rb') as file:
image_data = [Link]()
print(f"Image size: {len(image_data)} bytes")
---
## 7. Exception Handling
**Definition:** Exception handling allows you to gracefully handle errors that occur during program execution, preventing cr
**Why Use It:** Makes programs robust, provides user-friendly error messages, and allows recovery from errors.
**Example:**
``````python
# Basic exception handling
try:
result = 10 / 0
except ZeroDivisionError:
print("Cannot divide by zero!")
result = None
---
### Try-Except-Else-Finally
**Definition:**
- **else**: Runs if no exception occurred
- **finally**: Always runs, regardless of exceptions (cleanup code)
**Why Use It:** Provides precise control over exception handling flow, ensures cleanup code runs, and separates success log
**Example:**
``````python
# Complete exception handling structure
try:
file = open('[Link]', 'r')
data = [Link]()
number = int(data)
except FileNotFoundError:
print("File not found")
except ValueError:
print("File contains invalid data")
else:
# Runs only if no exception occurred
print(f"Successfully read number: {number}")
finally:
# Always runs (cleanup)
if 'file' in locals():
[Link]()
print("File closed")
def connect(self):
print("Connecting to database...")
def close(self):
print("Closing database connection")
def run_query(query):
"""Execute query with proper cleanup"""
db = DatabaseConnection()
try:
[Link]()
[Link](query)
except ValueError as e:
print(f"Query error: {e}")
return False
else:
print("Query executed successfully")
return True
finally:
[Link]()
---
**Definition:** You can manually trigger exceptions using the `raise` keyword to signal error conditions.
**Why Use It:** Enforces business logic, validates inputs, and creates clear error boundaries in your code.
**Example:**
``````python
# Raise built-in exception
def calculate_percentage(value, total):
"""Calculate percentage"""
if total == 0:
raise ZeroDivisionError("Total cannot be zero")
if value < 0 or total < 0:
raise ValueError("Values must be non-negative")
return (value / total) * 100
# Re-raising exceptions
def process_data(data):
"""Process data with logging"""
try:
result = int(data)
return result * 2
except ValueError:
print("Logging error...")
raise # Re-raise the same exception
# Using validation
try:
valid_age = set_age(25)
print(f"Age set to: {valid_age}")
invalid_age = set_age(-5)
except ValueError as e:
print(f"Validation error: {e}")
``````
---
**Definition:** You can create your own exception classes by inheriting from the `Exception` class or its subclasses.
**Why Use It:** Creates domain-specific errors, provides better error context, and makes error handling more precise and me
**Example:**
``````python
# Simple custom exception
class InsufficientFundsError(Exception):
"""Raised when account has insufficient funds"""
pass
if amount <= 0:
raise ValueError("Withdrawal amount must be positive")
[Link] -= amount
return [Link]
def lock(self):
"""Lock the account"""
[Link] = True
try:
[Link](1500)
except InsufficientFundsError as e:
print(f"Transaction failed: {e}")
try:
[Link]()
[Link](100)
except AccountLockedError as e:
print(f"Cannot process: {e}")
return True
try:
validate_user_registration("AB", "invalidemail", 16)
except ValidationError as e:
print(f"Registration failed - {e}")
``````
---
### Iterators
**Definition:** An iterator is an object that implements the iterator protocol (`__iter__()` and `__next__()` methods), allowin
**Why Use It:** Provides a standard way to loop through data, enables lazy evaluation, and allows custom iteration behavior
**Example:**
``````python
# Basic iterator usage
my_list = [1, 2, 3, 4, 5]
iterator = iter(my_list)
print(next(iterator)) # Output: 1
print(next(iterator)) # Output: 2
print(next(iterator)) # Output: 3
def __iter__(self):
return self
def __next__(self):
if [Link] <= 0:
raise StopIteration
[Link] -= 1
return [Link] + 1
def __iter__(self):
[Link] = open([Link], 'r')
self.line_count = 0
return self
def __next__(self):
if self.line_count >= self.max_lines:
[Link]()
raise StopIteration
line = [Link]()
if not line:
[Link]()
raise StopIteration
self.line_count += 1
return [Link]()
---
### Generators
**Definition:** Generators are functions that use `yield` to produce a sequence of values lazily, one at a time, instead of retur
**Why Use It:** Memory efficient for large datasets, creates infinite sequences, simplifies iterator creation, and enables pipel
**Example:**
``````python
# Basic generator function
def simple_generator():
"""Yields three values"""
print("First yield")
yield 1
print("Second yield")
yield 2
print("Third yield")
yield 3
# Using generator
gen = simple_generator()
print(next(gen)) # Output: First yield, then 1
print(next(gen)) # Output: Second yield, then 2
# Infinite generator
def infinite_counter(start=0):
"""Count infinitely from start"""
count = start
while True:
yield count
count += 1
def square_numbers(numbers):
"""Square each number"""
for num in numbers:
yield num ** 2
# Chain generators
numbers = range(10)
evens = filter_even(numbers)
squared = square_numbers(evens)
print(list(squared)) # Output: [0, 4, 16, 36, 64]
``````
---
**Definition:** A concise way to create generators using syntax similar to list comprehensions, but with parentheses instead o
**Why Use It:** More memory efficient than list comprehensions, perfect for one-time iterations, and cleaner syntax for simp
**Example:**
``````python
# List comprehension (creates entire list in memory)
squares_list = [x**2 for x in range(1000000)] # Uses lots of memory
# Generator expression (creates values on demand)
squares_gen = (x**2 for x in range(1000000)) # Uses minimal memory
# Memory comparison
import sys
---
**Definition:** `yield from` delegates part of generator operations to another generator, simplifying code that chains generato
**Why Use It:** Makes generator delegation cleaner, flattens nested iterations, and improves code readability.
**Example:**
``````python
# Without yield from (verbose)
def chain_generators_old(*iterables):
"""Chain iterables the old way"""
for iterable in iterables:
for item in iterable:
yield item
def traverse(self):
"""Traverse tree using yield from"""
yield [Link]
for child in [Link]:
yield from [Link]()
# Create tree
root = TreeNode(1, [
TreeNode(2, [TreeNode(4), TreeNode(5)]),
TreeNode(3, [TreeNode(6)])
])
# Traverse
for value in [Link]():
print(value, end=' ') # Output: 1 2 4 5 3 6
``````
---
## 9. Decorators
**Definition:** Decorators are functions that modify or enhance other functions without changing their source code. They "w
**Why Use It:** Adds reusable functionality (logging, timing, authentication), separates concerns, and keeps code DRY (Don
**Example:**
``````python
# Basic decorator
def my_decorator(func):
"""Simple decorator that wraps a function"""
def wrapper():
print("Something before the function")
func()
print("Something after the function")
return wrapper
@my_decorator
def say_hello():
print("Hello!")
say_hello()
# Output:
# Something before the function
# Hello!
# Something after the function
@timing_decorator
def slow_function():
import time
[Link](1)
return "Done"
result = slow_function()
# Output: slow_function took 1.0001 seconds
print(f"Calling {func.__name__}({all_args})")
result = func(*args, **kwargs)
print(f"{func.__name__} returned {result!r}")
return result
return wrapper
@log_function_call
def add(a, b):
return a + b
result = add(5, 3)
# Output:
# Calling add(5, 3)
# add returned 8
``````
---
**Definition:** Decorators that accept arguments, requiring an extra layer of function nesting to configure behavior.
**Why Use It:** Allows customization of decorator behavior, makes decorators more flexible and reusable.
**Example:**
``````python
# Decorator factory (decorator with parameters)
def repeat(times):
"""Repeat function execution N times"""
def decorator(func):
def wrapper(*args, **kwargs):
result = None
for _ in range(times):
result = func(*args, **kwargs)
return result
return wrapper
return decorator
@repeat(3)
def greet(name):
print(f"Hello, {name}!")
greet("Alice")
# Output:
# Hello, Alice!
# Hello, Alice!
# Hello, Alice!
@validate_range(0, 100)
def set_percentage(value):
return f"Percentage set to {value}%"
print(set_percentage(50)) # Works
# print(set_percentage(150)) # Raises ValueError
def decorator(func):
def wrapper(*args, **kwargs):
for attempt in range(1, max_attempts + 1):
try:
return func(*args, **kwargs)
except Exception as e:
if attempt == max_attempts:
print(f"Failed after {max_attempts} attempts")
raise
print(f"Attempt {attempt} failed: {e}. Retrying...")
[Link](delay)
return wrapper
return decorator
@retry(max_attempts=3, delay=0.5)
def unreliable_function():
import random
if [Link]() < 0.7:
raise ConnectionError("Network error")
return "Success!"
``````
---
**Definition:** Using `[Link]` preserves the original function's metadata (name, docstring) when creating decorator
**Why Use It:** Maintains proper function introspection, documentation, and debugging information.
**Example:**
``````python
from functools import wraps
def original_function():
"""This is the original function"""
pass
@bad_decorator
def bad_wrapped():
"""Original docstring"""
pass
@good_decorator
def good_wrapped():
"""Original docstring"""
pass
def my_decorator(func):
"""Decorator template with proper metadata preservation"""
@wraps(func)
def wrapper(*args, **kwargs):
# Before function
print(f"Calling {func.__name__}")
# Call function
result = func(*args, **kwargs)
# After function
print(f"Finished {func.__name__}")
return result
return wrapper
@my_decorator
def calculate(x, y):
""", multiline_text, [Link])
print(matches) # ['First line', 'Second line', 'Third line']
---
## Table of Contents
### Variables
**Definition:** Variables are named containers that store data values in memory. Python is dynamically typed, meaning you d
**Why Use It:** Variables allow you to store and manipulate data throughout your program, making code reusable and maint
**Example:**
`````python
# Simple variable assignment
name = "Alice" # String variable
age = 30 # Integer variable
height = 5.7 # Float variable
is_student = False # Boolean variable
# Multiple assignment
x, y, z = 1, 2, 3 # Assign multiple values at once
a = b = c = 10 # Assign same value to multiple variables
---
**Definition:** Data types define the kind of value a variable can hold. Python has several built-in data types.
**Why Use It:** Different data types are optimized for different operations. Using the right type improves performance and p
**Example:**
`````python
# Integer
count = 100
print(type(count)) # <class 'int'>
# Float
price = 19.99
print(type(price)) # <class 'float'>
# String
message = "Hello, World!"
print(type(message)) # <class 'str'>
# Boolean
is_active = True
print(type(is_active)) # <class 'bool'>
# Complex numbers
complex_num = 3 + 4j
print(type(complex_num)) # <class 'complex'>
# None type
result = None
print(type(result)) # <class 'NoneType'>
`````
---
**Definition:** Type checking verifies the data type of a variable. Type conversion transforms data from one type to another.
**Why Use It:** Ensures data integrity, prevents errors, and allows operations between different types.
**Example:**
`````python
# Type checking
age = 25
print(isinstance(age, int)) # True - checks if age is an integer
print(isinstance(age, str)) # False
## 2. Control Flow
**Definition:** Conditional statements that execute different code blocks based on whether conditions are true or false.
**Why Use It:** Allows your program to make decisions and execute different paths of code based on conditions, making pro
**Example:**
`````python
# Grade calculator
score = 85
print(f"Your grade is: {grade}") # Output: Good job! Your grade is: B
`````
---
**Why Use It:** Makes code more readable and compact for simple conditional assignments.
**Example:**
`````python
# Traditional if-else
age = 20
if age >= 18:
status = "Adult"
else:
status = "Minor"
---
**Definition:** A loop that iterates over a sequence (list, tuple, string, range) and executes a block of code for each item.
**Why Use It:** Automates repetitive tasks, processes collections of data, and eliminates the need for manual repetition.
**Example:**
`````python
# Basic for loop with range
for i in range(5):
print(f"Count: {i}")
# Output: Count: 0, Count: 1, Count: 2, Count: 3, Count: 4
---
**Why Use It:** Useful when you don't know in advance how many iterations are needed, or when waiting for a specific con
**Example:**
`````python
# Basic while loop
count = 0
while count < 5:
print(f"Count is: {count}")
count += 1
---
**Definition:**
- **break**: Exits the loop entirely
- **continue**: Skips the current iteration and moves to the next one
**Why Use It:** Provides fine control over loop execution, allowing you to skip unwanted iterations or exit early when condi
**Example:**
`````python
# Break - exit loop when condition met
for i in range(10):
if i == 5:
break # Stop loop when i equals 5
print(i) # Output: 0, 1, 2, 3, 4
---
**Definition:** A structural pattern matching statement that compares a value against multiple patterns, similar to switch-case
**Why Use It:** Provides cleaner, more readable code than multiple if-elif statements, especially for complex pattern matchin
**Example:**
`````python
# HTTP status code handler
def handle_response(status_code):
match status_code:
case 200:
return "Success"
case 404:
return "Not Found"
case 500 | 502 | 503: # Multiple values
return "Server Error"
case code if 400 <= code < 500: # With condition
return "Client Error"
case _: # Default case
return "Unknown Status"
---
## 3. Functions
**Definition:** A reusable block of code that performs a specific task. Functions are defined using the `def` keyword.
**Why Use It:** Promotes code reusability, organization, and maintainability. Breaks complex problems into smaller, manage
**Example:**
`````python
# Simple function
def greet(name):
"""Greets a person by name"""
return f"Hello, {name}!"
message = greet("Alice")
print(message) # Output: Hello, Alice!
result = calculate_area(5, 3)
print(f"Area: {result}") # Output: Area: 15
# Function with no return (returns None)
def print_welcome():
print("Welcome to Python!")
# No return statement
---
**Definition:** Parameters that have default values assigned, making them optional when calling the function.
**Why Use It:** Makes functions more flexible and reduces the need for multiple function definitions for similar tasks.
**Example:**
`````python
# Function with default parameter
def power(base, exponent=2):
"""Raises base to the power of exponent (default: 2)"""
return base ** exponent
# Multiple defaults
def create_profile(name, age=18, country="USA"):
return {
'name': name,
'age': age,
'country': country
}
**Definition:** Allows a function to accept any number of positional arguments, which are collected into a tuple.
**Why Use It:** Makes functions flexible when you don't know in advance how many arguments will be passed.
**Example:**
`````python
# Function accepting any number of arguments
def sum_all(*args):
"""Sums all provided numbers"""
total = 0
for num in args:
total += num
return total
---
**Definition:** Allows a function to accept any number of keyword arguments, which are collected into a dictionary.
**Why Use It:** Provides flexibility for functions that need to handle varying named parameters, useful for configuration and
**Example:**
`````python
# Function accepting keyword arguments
def print_info(**kwargs):
"""Prints all key-value pairs"""
for key, value in [Link]():
print(f"{key}: {value}")
---
**Definition:** Optional metadata that specifies the expected types of function parameters and return values.
**Why Use It:** Improves code documentation, enables static type checking with tools like mypy, and makes code more mai
**Example:**
`````python
# Function with type hints
def add_numbers(x: int, y: int) -> int:
"""Adds two integers and returns an integer"""
return x + y
result = add_numbers(5, 3)
print(result) # Output: 8
---
**Definition:** A closure is a function that remembers values from its enclosing scope even after that scope has finished exec
**Why Use It:** Enables data encapsulation, creates function factories, and allows for elegant callback patterns.
**Example:**
`````python
# Basic closure
def outer_function(x):
"""Outer function that returns an inner function"""
def inner_function(y):
"""Inner function that remembers x"""
return x + y
return inner_function
# Create a closure
add_5 = outer_function(5)
print(add_5(10)) # Output: 15 (remembers x=5)
print(add_5(20)) # Output: 25
def increment():
nonlocal count # Modify outer scope variable
count += 1
return count
return increment
counter1 = make_counter()
counter2 = make_counter()
print(counter1()) # Output: 1
print(counter1()) # Output: 2
print(counter2()) # Output: 1 (separate counter)
# Multiplier factory
def make_multiplier(n):
"""Creates a function that multiplies by n"""
def multiply(x):
return x * n
return multiply
times_3 = make_multiplier(3)
times_5 = make_multiplier(5)
print(times_3(10)) # Output: 30
print(times_5(10)) # Output: 50
`````
---
## 4. Object-Oriented Programming
**Definition:** A class is a blueprint for creating objects. Objects are instances of classes that combine data (attributes) and b
**Why Use It:** Organizes code into reusable components, models real-world entities, and implements encapsulation, inherit
**Example:**
`````python
# Basic class definition
class Dog:
"""Represents a dog"""
# Constructor (initializer)
def __init__(self, name, age):
"""Initialize a new dog"""
[Link] = name # Instance attribute
[Link] = age
# Instance method
def bark(self):
"""Make the dog bark"""
return f"{[Link]} says Woof!"
def get_info(self):
"""Return dog information"""
return f"{[Link]} is {[Link]} years old"
---
### Magic Methods (Dunder Methods)
**Definition:** Special methods with double underscores (e.g., `__init__`, `__str__`) that define how objects behave with bui
**Why Use It:** Allows custom classes to work seamlessly with Python's built-in functions and operators, making objects be
**Example:**
`````python
class Book:
"""Represents a book"""
def __str__(self):
"""String representation for users"""
return f"'{[Link]}' by {[Link]}"
def __repr__(self):
"""String representation for developers"""
return f"Book(title='{[Link]}', author='{[Link]}', pages={[Link]})"
def __len__(self):
"""Return number of pages"""
return [Link]
def __str__(self):
return f"Vector({self.x}, {self.y})"
v1 = Vector(2, 3)
v2 = Vector(4, 5)
v3 = v1 + v2 # Uses __add__
v4 = v1 * 3 # Uses __mul__
---
### Inheritance
**Definition:** A mechanism where a new class (child/subclass) derives properties and methods from an existing class (paren
**Why Use It:** Promotes code reuse, creates hierarchical relationships, and allows for polymorphism (same interface, differ
**Example:**
`````python
# Parent class
class Animal:
"""Base class for all animals"""
def speak(self):
"""Generic speak method"""
return "Some sound"
def info(self):
return f"{[Link]} is {[Link]} years old"
# Child class
class Dog(Animal):
"""Dog class inherits from Animal"""
class Cat(Animal):
"""Cat class inherits from Animal"""
def speak(self):
return "Meow!"
def scratch(self):
return f"{[Link]} is scratching"
---
**Why Use It:** Class methods are useful for factory methods and alternative constructors. Static methods are utility function
**Example:**
`````python
class Date:
"""Represents a date"""
@classmethod
def from_string(cls, date_string):
"""Factory method: Create Date from string"""
year, month, day = map(int, date_string.split('-'))
return cls(year, month, day) # Returns new instance
@classmethod
def today(cls):
"""Factory method: Create Date for today"""
import datetime
today = [Link]()
return cls([Link], [Link], [Link])
@staticmethod
def is_leap_year(year):
"""Utility function: Check if year is leap year"""
return year % 4 == 0 and (year % 100 != 0 or year % 400 == 0)
def __str__(self):
return f"{[Link]}-{[Link]:02d}-{[Link]:02d}"
@classmethod
def from_fahrenheit(cls, fahrenheit):
"""Create Temperature from Fahrenheit"""
celsius = (fahrenheit - 32) * 5/9
return cls(celsius)
@staticmethod
def celsius_to_fahrenheit(celsius):
"""Convert Celsius to Fahrenheit"""
return (celsius * 9/5) + 32
def __str__(self):
return f"{[Link]}°C"
temp1 = Temperature(25)
temp2 = Temperature.from_fahrenheit(77)
---
### Properties
**Definition:** Properties allow you to define methods that can be accessed like attributes, providing controlled access to cla
**Why Use It:** Enables encapsulation, data validation, computed attributes, and maintains a clean interface while adding log
**Example:**
`````python
class Circle:
"""Represents a circle"""
@[Link]
def radius(self, value):
"""Setter with validation"""
if value < 0:
raise ValueError("Radius cannot be negative")
self._radius = value
@property
def diameter(self):
"""Computed property"""
return self._radius * 2
@property
def area(self):
"""Computed property"""
import math
return [Link] * (self._radius ** 2)
@property
def circumference(self):
"""Computed property"""
import math
return 2 * [Link] * self._radius
# Using properties
circle = Circle(5)
# Validation works
try:
[Link] = -5
except ValueError as e:
print(f"Error: {e}") # Output: Error: Radius cannot be negative
# Practical example: Temperature with validation
class Thermostat:
"""Temperature controller"""
@property
def celsius(self):
return self._celsius
@[Link]
def celsius(self, value):
if value < -273.15:
raise ValueError("Temperature below absolute zero!")
if value > 100:
print("Warning: Very high temperature!")
self._celsius = value
@property
def fahrenheit(self):
"""Convert to Fahrenheit on the fly"""
return (self._celsius * 9/5) + 32
@[Link]
def fahrenheit(self, value):
"""Set temperature in Fahrenheit"""
[Link] = (value - 32) * 5/9
thermostat = Thermostat()
print(f"Current: {[Link]}°C") # Output: Current: 20°C
print(f"In Fahrenheit: {[Link]}°F") # Output: In Fahrenheit: 68.0°F
---
**Definition:** Modules are Python files containing functions, classes, and variables. Importing allows you to use code from
**Why Use It:** Organizes code into logical units, promotes code reuse, and provides access to Python's extensive standard l
**Example:**
`````python
# Different ways to import
current_dir = [Link]()
print(f"Current directory: {current_dir}")
def save_log(message):
"""Save timestamped log message"""
log_entry = {
'timestamp': [Link]().isoformat(),
'message': message
}
print([Link](log_entry, indent=2))
save_log("Application started")
`````
---
**Definition:** Any Python file can be a module. You create one by saving Python code in a `.py` file and importing it in othe
**Why Use It:** Organizes your code into reusable components, separates concerns, and makes large projects manageable.
**Example:**
PI = 3.14159
def circle_area(radius):
"""Calculate circle area"""
return PI * radius ** 2
def circle_circumference(radius):
"""Calculate circle circumference"""
return 2 * PI * radius
def square_area(side):
"""Calculate square area"""
return side ** 2
class Calculator:
"""Simple calculator class"""
@staticmethod
def add(a, b):
return a + b
@staticmethod
def multiply(a, b):
return a * b
`````
---
**Definition:** `__name__` is a special variable that equals `"__main__"` when the file is run directly, or the module name w
**Why Use It:** Allows you to write code that runs only when the file is executed directly, not when imported. Essential for c
**Example:**
`````python
# [Link]
"""Utility functions"""
def process_data(data):
"""Process data"""
return [x * 2 for x in data]
def validate_input(value):
"""Validate input"""
return value > 0
test_data = [1, 2, 3, 4, 5]
result = process_data(test_data)
print(f"Test result: {result}")
---
## 6. File Handling
**Definition:** File reading operations allow you to access and read content from files stored on disk.
**Why Use It:** Essential for data processing, configuration loading, log analysis, and working with persistent data.
**Example:**
`````python
# Method 1: Read entire file
with open('[Link]', 'r') as file:
content = [Link]()
print(content)
---
**Definition:** File writing operations allow you to create new files or modify existing ones by writing data to disk.
**Why Use It:** Saves program output, creates logs, generates reports, and persists data between program runs.
**Example:**
`````python
# Write mode ('w') - overwrites existing file
with open('[Link]', 'w') as file:
[Link]("Hello, World!\n")
[Link]("This is line 2\n")
---
**Definition:** The `with` statement automatically handles resource setup and cleanup, ensuring files are properly closed eve
**Why Use It:** Prevents resource leaks, ensures proper cleanup, and makes code more readable and reliable.
**Example:**
`````python
# Without context manager (not recommended)
file = open('[Link]', 'r')
try:
content = [Link]()
print(content)
finally:
[Link]() # Must remember to close
print(process_file('[Link]'))
`````
---
**Definition:** Binary mode reads/writes files as raw bytes rather than text, used for non-text files like images, videos, and ex
**Why Use It:** Required for working with binary file formats, preserves exact byte content, and prevents text encoding issu
**Example:**
`````python
# Reading binary file
with open('[Link]', 'rb') as file:
image_data = [Link]()
print(f"Image size: {len(image_data)} bytes")
---
## 7. Exception Handling
### Try-Except Blocks
**Definition:** Exception handling allows you to gracefully handle errors that occur during program execution, preventing cr
**Why Use It:** Makes programs robust, provides user-friendly error messages, and allows recovery from errors.
**Example:**
`````python
# Basic exception handling
try:
result = 10 / 0
except ZeroDivisionError:
print("Cannot divide by zero!")
result = None
---
### Try-Except-Else-Finally
**Definition:**
- **else**: Runs if no exception occurred
- **finally**: Always runs, regardless of exceptions (cleanup code)
**Why Use It:** Provides precise control over exception handling flow, ensures cleanup code runs, and separates success log
**Example:**
`````python
# Complete exception handling structure
try:
file = open('[Link]', 'r')
data = [Link]()
number = int(data)
except FileNotFoundError:
print("File not found")
except ValueError:
print("File contains invalid data")
else:
# Runs only if no exception occurred
print(f"Successfully read number: {number}")
finally:
# Always runs (cleanup)
if 'file' in locals():
[Link]()
print("File closed")
def connect(self):
print("Connecting to database...")
def execute(self, query):
if "DROP" in query:
raise ValueError("DROP commands not allowed")
print(f"Executing: {query}")
def close(self):
print("Closing database connection")
def run_query(query):
"""Execute query with proper cleanup"""
db = DatabaseConnection()
try:
[Link]()
[Link](query)
except ValueError as e:
print(f"Query error: {e}")
return False
else:
print("Query executed successfully")
return True
finally:
[Link]()
---
**Definition:** You can manually trigger exceptions using the `raise` keyword to signal error conditions.
**Why Use It:** Enforces business logic, validates inputs, and creates clear error boundaries in your code.
**Example:**
`````python
# Raise built-in exception
def calculate_percentage(value, total):
"""Calculate percentage"""
if total == 0:
raise ZeroDivisionError("Total cannot be zero")
if value < 0 or total < 0:
raise ValueError("Values must be non-negative")
return (value / total) * 100
# Re-raising exceptions
def process_data(data):
"""Process data with logging"""
try:
result = int(data)
return result * 2
except ValueError:
print("Logging error...")
raise # Re-raise the same exception
# Using validation
try:
valid_age = set_age(25)
print(f"Age set to: {valid_age}")
invalid_age = set_age(-5)
except ValueError as e:
print(f"Validation error: {e}")
`````
---
**Definition:** You can create your own exception classes by inheriting from the `Exception` class or its subclasses.
**Why Use It:** Creates domain-specific errors, provides better error context, and makes error handling more precise and me
**Example:**
`````python
# Simple custom exception
class InsufficientFundsError(Exception):
"""Raised when account has insufficient funds"""
pass
class BankAccount:
"""Bank account with custom exception handling"""
if amount <= 0:
raise ValueError("Withdrawal amount must be positive")
[Link] -= amount
return [Link]
def lock(self):
"""Lock the account"""
[Link] = True
try:
[Link](1500)
except InsufficientFundsError as e:
print(f"Transaction failed: {e}")
try:
[Link]()
[Link](100)
except AccountLockedError as e:
print(f"Cannot process: {e}")
return True
try:
validate_user_registration("AB", "invalidemail", 16)
except ValidationError as e:
print(f"Registration failed - {e}")
`````
---
### Iterators
**Definition:** An iterator is an object that implements the iterator protocol (`__iter__()` and `__next__()` methods), allowin
**Why Use It:** Provides a standard way to loop through data, enables lazy evaluation, and allows custom iteration behavior
**Example:**
`````python
# Basic iterator usage
my_list = [1, 2, 3, 4, 5]
iterator = iter(my_list)
print(next(iterator)) # Output: 1
print(next(iterator)) # Output: 2
print(next(iterator)) # Output: 3
def __iter__(self):
return self
def __next__(self):
if [Link] <= 0:
raise StopIteration
[Link] -= 1
return [Link] + 1
def __iter__(self):
[Link] = open([Link], 'r')
self.line_count = 0
return self
def __next__(self):
if self.line_count >= self.max_lines:
[Link]()
raise StopIteration
line = [Link]()
if not line:
[Link]()
raise StopIteration
self.line_count += 1
return [Link]()
---
### Generators
**Definition:** Generators are functions that use `yield` to produce a sequence of values lazily, one at a time, instead of retur
**Why Use It:** Memory efficient for large datasets, creates infinite sequences, simplifies iterator creation, and enables pipel
**Example:**
`````python
# Basic generator function
def simple_generator():
"""Yields three values"""
print("First yield")
yield 1
print("Second yield")
yield 2
print("Third yield")
yield 3
# Using generator
gen = simple_generator()
print(next(gen)) # Output: First yield, then 1
print(next(gen)) # Output: Second yield, then 2
# Infinite generator
def infinite_counter(start=0):
"""Count infinitely from start"""
count = start
while True:
yield count
count += 1
def square_numbers(numbers):
"""Square each number"""
for num in numbers:
yield num ** 2
# Chain generators
numbers = range(10)
evens = filter_even(numbers)
squared = square_numbers(evens)
print(list(squared)) # Output: [0, 4, 16, 36, 64]
`````
---
**Definition:** A concise way to create generators using syntax similar to list comprehensions, but with parentheses instead o
**Why Use It:** More memory efficient than list comprehensions, perfect for one-time iterations, and cleaner syntax for simp
**Example:**
`````python
# List comprehension (creates entire list in memory)
squares_list = [x**2 for x in range(1000000)] # Uses lots of memory
# Memory comparison
import sys
---
**Definition:** `yield from` delegates part of generator operations to another generator, simplifying code that chains generato
**Why Use It:** Makes generator delegation cleaner, flattens nested iterations, and improves code readability.
**Example:**
`````python
# Without yield from (verbose)
def chain_generators_old(*iterables):
"""Chain iterables the old way"""
for iterable in iterables:
for item in iterable:
yield item
def traverse(self):
"""Traverse tree using yield from"""
yield [Link]
for child in [Link]:
yield from [Link]()
# Create tree
root = TreeNode(1, [
TreeNode(2, [TreeNode(4), TreeNode(5)]),
TreeNode(3, [TreeNode(6)])
])
# Traverse
for value in [Link]():
print(value, end=' ') # Output: 1 2 4 5 3 6
`````
---
## 9. Decorators
**Definition:** Decorators are functions that modify or enhance other functions without changing their source code. They "w
**Why Use It:** Adds reusable functionality (logging, timing, authentication), separates concerns, and keeps code DRY (Don
**Example:**
`````python
# Basic decorator
def my_decorator(func):
"""Simple decorator that wraps a function"""
def wrapper():
print("Something before the function")
func()
print("Something after the function")
return wrapper
@my_decorator
def say_hello():
print("Hello!")
say_hello()
# Output:
# Something before the function
# Hello!
# Something after the function
@timing_decorator
def slow_function():
import time
[Link](1)
return "Done"
result = slow_function()
# Output: slow_function took 1.0001 seconds
print(f"Calling {func.__name__}({all_args})")
result = func(*args, **kwargs)
print(f"{func.__name__} returned {result!r}")
return result
return wrapper
@log_function_call
def add(a, b):
return a + b
result = add(5, 3)
# Output:
# Calling add(5, 3)
# add returned 8
`````
---
**Definition:** Decorators that accept arguments, requiring an extra layer of function nesting to configure behavior.
**Why Use It:** Allows customization of decorator behavior, makes decorators more flexible and reusable.
**Example:**
`````python
# Decorator factory (decorator with parameters)
def repeat(times):
"""Repeat function execution N times"""
def decorator(func):
def wrapper(*args, **kwargs):
result = None
for _ in range(times):
result = func(*args, **kwargs)
return result
return wrapper
return decorator
@repeat(3)
def greet(name):
print(f"Hello, {name}!")
greet("Alice")
# Output:
# Hello, Alice!
# Hello, Alice!
# Hello, Alice!
@validate_range(0, 100)
def set_percentage(value):
return f"Percentage set to {value}%"
print(set_percentage(50)) # Works
# print(set_percentage(150)) # Raises ValueError
def decorator(func):
def wrapper(*args, **kwargs):
for attempt in range(1, max_attempts + 1):
try:
return func(*args, **kwargs)
except Exception as e:
if attempt == max_attempts:
print(f"Failed after {max_attempts} attempts")
raise
print(f"Attempt {attempt} failed: {e}. Retrying...")
[Link](delay)
return wrapper
return decorator
@retry(max_attempts=3, delay=0.5)
def unreliable_function():
import random
if [Link]() < 0.7:
raise ConnectionError("Network error")
return "Success!"
`````
---
**Definition:** Using `[Link]` preserves the original function's metadata (name, docstring) when creating decorator
**Why Use It:** Maintains proper function introspection, documentation, and debugging information.
**Example:**
`````python
from functools import wraps
def original_function():
"""This is the original function"""
pass
@bad_decorator
def bad_wrapped():
"""Original docstring"""
pass
@good_decorator
def good_wrapped():
"""Original docstring"""
pass
def my_decorator(func):
"""Decorator template with proper metadata preservation"""
@wraps(func)
def wrapper(*args, **kwargs):
# Before function
print(f"Calling {func.__name__}")
# Call function
result = func(*args, **kwargs)
# After function
print(f"Finished {func.__name__}")
return result
return wrapper
@my_decorator
def calculate(x, y):
""", text):
print("Password contains a digit")
---
## Table of Contents
1. [Basic Syntax & Data Types](#1-basic-syntax--data-types)
2. [Control Flow](#2-control-flow)
3. [Functions](#3-functions)
4. [Object-Oriented Programming](#4-object-oriented-programming)
5. [Modules & Packages](#5-modules--packages)
6. [File Handling](#6-file-handling)
7. [Exception Handling](#7-exception-handling)
8. [Iterators & Generators](#8-iterators--generators)
9. [Decorators](#9-decorators)
10. [Context Managers](#10-context-managers)
11. [Regular Expressions](#11-regular-expressions)
12. [Collections & Data Structures](#12-collections--data-structures)
13. [Comprehensions](#13-comprehensions)
14. [Lambda Functions](#14-lambda-functions)
15. [Built-in Functions](#15-built-in-functions)
16. [String Methods](#16-string-methods)
17. [List/Dict/Set Methods](#17-listdictset-methods)
18. [Type Hints & Annotations](#18-type-hints--annotations)
19. [Async/Await](#19-asyncawait-concurrency)
20. [Multithreading & Multiprocessing](#20-multithreading--multiprocessing)
21. [Memory Management](#21-memory-management)
22. [Metaclasses](#22-metaclasses)
23. [Descriptors](#23-descriptors)
24. [Property Decorators](#24-property-decorators)
25. [Abstract Base Classes](#25-abstract-base-classes)
26. [Protocol Classes](#26-protocol-classes)
27. [Dataclasses](#27-dataclasses)
28. [Enums](#28-enums)
29. [Path Operations](#29-path-operations)
30. [JSON & Serialization](#30-json--serialization)
31. [Database Operations](#31-database-operations)
32. [Testing](#32-testing-unittest-pytest)
33. [Performance Optimization](#33-performance-optimization)
34. [Design Patterns](#34-design-patterns)
35. [Advanced Topics](#35-advanced-topics)
---
### Variables
**Definition:** Variables are named containers that store data values in memory. Python is dynamically typed, meaning you d
**Why Use It:** Variables allow you to store and manipulate data throughout your program, making code reusable and maint
**Example:**
````python
# Simple variable assignment
name = "Alice" # String variable
age = 30 # Integer variable
height = 5.7 # Float variable
is_student = False # Boolean variable
# Multiple assignment
x, y, z = 1, 2, 3 # Assign multiple values at once
a = b = c = 10 # Assign same value to multiple variables
---
**Definition:** Data types define the kind of value a variable can hold. Python has several built-in data types.
**Why Use It:** Different data types are optimized for different operations. Using the right type improves performance and p
**Example:**
````python
# Integer
count = 100
print(type(count)) # <class 'int'>
# Float
price = 19.99
print(type(price)) # <class 'float'>
# String
message = "Hello, World!"
print(type(message)) # <class 'str'>
# Boolean
is_active = True
print(type(is_active)) # <class 'bool'>
# Complex numbers
complex_num = 3 + 4j
print(type(complex_num)) # <class 'complex'>
# None type
result = None
print(type(result)) # <class 'NoneType'>
````
---
**Definition:** Type checking verifies the data type of a variable. Type conversion transforms data from one type to another.
**Why Use It:** Ensures data integrity, prevents errors, and allows operations between different types.
**Example:**
````python
# Type checking
age = 25
print(isinstance(age, int)) # True - checks if age is an integer
print(isinstance(age, str)) # False
---
## 2. Control Flow
**Definition:** Conditional statements that execute different code blocks based on whether conditions are true or false.
**Why Use It:** Allows your program to make decisions and execute different paths of code based on conditions, making pro
**Example:**
````python
# Grade calculator
score = 85
print(f"Your grade is: {grade}") # Output: Good job! Your grade is: B
````
---
**Why Use It:** Makes code more readable and compact for simple conditional assignments.
**Example:**
````python
# Traditional if-else
age = 20
if age >= 18:
status = "Adult"
else:
status = "Minor"
---
**Definition:** A loop that iterates over a sequence (list, tuple, string, range) and executes a block of code for each item.
**Why Use It:** Automates repetitive tasks, processes collections of data, and eliminates the need for manual repetition.
**Example:**
````python
# Basic for loop with range
for i in range(5):
print(f"Count: {i}")
# Output: Count: 0, Count: 1, Count: 2, Count: 3, Count: 4
---
**Why Use It:** Useful when you don't know in advance how many iterations are needed, or when waiting for a specific con
**Example:**
````python
# Basic while loop
count = 0
while count < 5:
print(f"Count is: {count}")
count += 1
---
**Definition:**
- **break**: Exits the loop entirely
- **continue**: Skips the current iteration and moves to the next one
**Why Use It:** Provides fine control over loop execution, allowing you to skip unwanted iterations or exit early when condi
**Example:**
````python
# Break - exit loop when condition met
for i in range(10):
if i == 5:
break # Stop loop when i equals 5
print(i) # Output: 0, 1, 2, 3, 4
---
**Definition:** A structural pattern matching statement that compares a value against multiple patterns, similar to switch-case
**Why Use It:** Provides cleaner, more readable code than multiple if-elif statements, especially for complex pattern matchin
**Example:**
````python
# HTTP status code handler
def handle_response(status_code):
match status_code:
case 200:
return "Success"
case 404:
return "Not Found"
case 500 | 502 | 503: # Multiple values
return "Server Error"
case code if 400 <= code < 500: # With condition
return "Client Error"
case _: # Default case
return "Unknown Status"
---
## 3. Functions
**Definition:** A reusable block of code that performs a specific task. Functions are defined using the `def` keyword.
**Why Use It:** Promotes code reusability, organization, and maintainability. Breaks complex problems into smaller, manage
**Example:**
````python
# Simple function
def greet(name):
"""Greets a person by name"""
return f"Hello, {name}!"
message = greet("Alice")
print(message) # Output: Hello, Alice!
result = calculate_area(5, 3)
print(f"Area: {result}") # Output: Area: 15
---
### Default Arguments
**Definition:** Parameters that have default values assigned, making them optional when calling the function.
**Why Use It:** Makes functions more flexible and reduces the need for multiple function definitions for similar tasks.
**Example:**
````python
# Function with default parameter
def power(base, exponent=2):
"""Raises base to the power of exponent (default: 2)"""
return base ** exponent
# Multiple defaults
def create_profile(name, age=18, country="USA"):
return {
'name': name,
'age': age,
'country': country
}
---
**Definition:** Allows a function to accept any number of positional arguments, which are collected into a tuple.
**Why Use It:** Makes functions flexible when you don't know in advance how many arguments will be passed.
**Example:**
````python
# Function accepting any number of arguments
def sum_all(*args):
"""Sums all provided numbers"""
total = 0
for num in args:
total += num
return total
---
**Definition:** Allows a function to accept any number of keyword arguments, which are collected into a dictionary.
**Why Use It:** Provides flexibility for functions that need to handle varying named parameters, useful for configuration and
**Example:**
````python
# Function accepting keyword arguments
def print_info(**kwargs):
"""Prints all key-value pairs"""
for key, value in [Link]():
print(f"{key}: {value}")
---
**Definition:** Optional metadata that specifies the expected types of function parameters and return values.
**Why Use It:** Improves code documentation, enables static type checking with tools like mypy, and makes code more mai
**Example:**
````python
# Function with type hints
def add_numbers(x: int, y: int) -> int:
"""Adds two integers and returns an integer"""
return x + y
result = add_numbers(5, 3)
print(result) # Output: 8
---
**Definition:** A closure is a function that remembers values from its enclosing scope even after that scope has finished exec
**Why Use It:** Enables data encapsulation, creates function factories, and allows for elegant callback patterns.
**Example:**
````python
# Basic closure
def outer_function(x):
"""Outer function that returns an inner function"""
def inner_function(y):
"""Inner function that remembers x"""
return x + y
return inner_function
# Create a closure
add_5 = outer_function(5)
print(add_5(10)) # Output: 15 (remembers x=5)
print(add_5(20)) # Output: 25
def increment():
nonlocal count # Modify outer scope variable
count += 1
return count
return increment
counter1 = make_counter()
counter2 = make_counter()
print(counter1()) # Output: 1
print(counter1()) # Output: 2
print(counter2()) # Output: 1 (separate counter)
# Multiplier factory
def make_multiplier(n):
"""Creates a function that multiplies by n"""
def multiply(x):
return x * n
return multiply
times_3 = make_multiplier(3)
times_5 = make_multiplier(5)
print(times_3(10)) # Output: 30
print(times_5(10)) # Output: 50
````
---
## 4. Object-Oriented Programming
**Definition:** A class is a blueprint for creating objects. Objects are instances of classes that combine data (attributes) and b
**Why Use It:** Organizes code into reusable components, models real-world entities, and implements encapsulation, inherit
**Example:**
````python
# Basic class definition
class Dog:
"""Represents a dog"""
# Constructor (initializer)
def __init__(self, name, age):
"""Initialize a new dog"""
[Link] = name # Instance attribute
[Link] = age
# Instance method
def bark(self):
"""Make the dog bark"""
return f"{[Link]} says Woof!"
def get_info(self):
"""Return dog information"""
return f"{[Link]} is {[Link]} years old"
# Creating objects (instances)
buddy = Dog("Buddy", 3)
max_dog = Dog("Max", 5)
---
**Definition:** Special methods with double underscores (e.g., `__init__`, `__str__`) that define how objects behave with bui
**Why Use It:** Allows custom classes to work seamlessly with Python's built-in functions and operators, making objects be
**Example:**
````python
class Book:
"""Represents a book"""
def __str__(self):
"""String representation for users"""
return f"'{[Link]}' by {[Link]}"
def __repr__(self):
"""String representation for developers"""
return f"Book(title='{[Link]}', author='{[Link]}', pages={[Link]})"
def __len__(self):
"""Return number of pages"""
return [Link]
v1 = Vector(2, 3)
v2 = Vector(4, 5)
v3 = v1 + v2 # Uses __add__
v4 = v1 * 3 # Uses __mul__
---
### Inheritance
**Definition:** A mechanism where a new class (child/subclass) derives properties and methods from an existing class (paren
**Why Use It:** Promotes code reuse, creates hierarchical relationships, and allows for polymorphism (same interface, differ
**Example:**
````python
# Parent class
class Animal:
"""Base class for all animals"""
def speak(self):
"""Generic speak method"""
return "Some sound"
def info(self):
return f"{[Link]} is {[Link]} years old"
# Child class
class Dog(Animal):
"""Dog class inherits from Animal"""
class Cat(Animal):
"""Cat class inherits from Animal"""
def speak(self):
return "Meow!"
def scratch(self):
return f"{[Link]} is scratching"
---
**Definition:**
- **Class methods**: Methods that receive the class as the first parameter (cls), not an instance
- **Static methods**: Methods that don't receive class or instance, just regular functions within class namespace
**Why Use It:** Class methods are useful for factory methods and alternative constructors. Static methods are utility function
**Example:**
````python
class Date:
"""Represents a date"""
def __init__(self, year, month, day):
[Link] = year
[Link] = month
[Link] = day
@classmethod
def from_string(cls, date_string):
"""Factory method: Create Date from string"""
year, month, day = map(int, date_string.split('-'))
return cls(year, month, day) # Returns new instance
@classmethod
def today(cls):
"""Factory method: Create Date for today"""
import datetime
today = [Link]()
return cls([Link], [Link], [Link])
@staticmethod
def is_leap_year(year):
"""Utility function: Check if year is leap year"""
return year % 4 == 0 and (year % 100 != 0 or year % 400 == 0)
def __str__(self):
return f"{[Link]}-{[Link]:02d}-{[Link]:02d}"
@classmethod
def from_fahrenheit(cls, fahrenheit):
"""Create Temperature from Fahrenheit"""
celsius = (fahrenheit - 32) * 5/9
return cls(celsius)
@staticmethod
def celsius_to_fahrenheit(celsius):
"""Convert Celsius to Fahrenheit"""
return (celsius * 9/5) + 32
def __str__(self):
return f"{[Link]}°C"
temp1 = Temperature(25)
temp2 = Temperature.from_fahrenheit(77)
---
### Properties
**Definition:** Properties allow you to define methods that can be accessed like attributes, providing controlled access to cla
**Why Use It:** Enables encapsulation, data validation, computed attributes, and maintains a clean interface while adding log
**Example:**
````python
class Circle:
"""Represents a circle"""
@property
def radius(self):
"""Getter for radius"""
return self._radius
@[Link]
def radius(self, value):
"""Setter with validation"""
if value < 0:
raise ValueError("Radius cannot be negative")
self._radius = value
@property
def diameter(self):
"""Computed property"""
return self._radius * 2
@property
def area(self):
"""Computed property"""
import math
return [Link] * (self._radius ** 2)
@property
def circumference(self):
"""Computed property"""
import math
return 2 * [Link] * self._radius
# Using properties
circle = Circle(5)
# Validation works
try:
[Link] = -5
except ValueError as e:
print(f"Error: {e}") # Output: Error: Radius cannot be negative
@property
def celsius(self):
return self._celsius
@[Link]
def celsius(self, value):
if value < -273.15:
raise ValueError("Temperature below absolute zero!")
if value > 100:
print("Warning: Very high temperature!")
self._celsius = value
@property
def fahrenheit(self):
"""Convert to Fahrenheit on the fly"""
return (self._celsius * 9/5) + 32
@[Link]
def fahrenheit(self, value):
"""Set temperature in Fahrenheit"""
[Link] = (value - 32) * 5/9
thermostat = Thermostat()
print(f"Current: {[Link]}°C") # Output: Current: 20°C
print(f"In Fahrenheit: {[Link]}°F") # Output: In Fahrenheit: 68.0°F
---
**Definition:** Modules are Python files containing functions, classes, and variables. Importing allows you to use code from
**Why Use It:** Organizes code into logical units, promotes code reuse, and provides access to Python's extensive standard l
**Example:**
````python
# Different ways to import
current_dir = [Link]()
print(f"Current directory: {current_dir}")
def save_log(message):
"""Save timestamped log message"""
log_entry = {
'timestamp': [Link]().isoformat(),
'message': message
}
print([Link](log_entry, indent=2))
save_log("Application started")
````
---
**Definition:** Any Python file can be a module. You create one by saving Python code in a `.py` file and importing it in othe
**Why Use It:** Organizes your code into reusable components, separates concerns, and makes large projects manageable.
**Example:**
PI = 3.14159
def circle_area(radius):
"""Calculate circle area"""
return PI * radius ** 2
def circle_circumference(radius):
"""Calculate circle circumference"""
return 2 * PI * radius
def square_area(side):
"""Calculate square area"""
return side ** 2
class Calculator:
"""Simple calculator class"""
@staticmethod
def add(a, b):
return a + b
@staticmethod
def multiply(a, b):
return a * b
````
---
**Definition:** `__name__` is a special variable that equals `"__main__"` when the file is run directly, or the module name w
**Why Use It:** Allows you to write code that runs only when the file is executed directly, not when imported. Essential for c
**Example:**
````python
# [Link]
"""Utility functions"""
def process_data(data):
"""Process data"""
return [x * 2 for x in data]
def validate_input(value):
"""Validate input"""
return value > 0
test_data = [1, 2, 3, 4, 5]
result = process_data(test_data)
print(f"Test result: {result}")
---
## 6. File Handling
**Definition:** File reading operations allow you to access and read content from files stored on disk.
**Why Use It:** Essential for data processing, configuration loading, log analysis, and working with persistent data.
**Example:**
````python
# Method 1: Read entire file
with open('[Link]', 'r') as file:
content = [Link]()
print(content)
---
### Writing Files
**Definition:** File writing operations allow you to create new files or modify existing ones by writing data to disk.
**Why Use It:** Saves program output, creates logs, generates reports, and persists data between program runs.
**Example:**
````python
# Write mode ('w') - overwrites existing file
with open('[Link]', 'w') as file:
[Link]("Hello, World!\n")
[Link]("This is line 2\n")
---
**Why Use It:** Prevents resource leaks, ensures proper cleanup, and makes code more readable and reliable.
**Example:**
````python
# Without context manager (not recommended)
file = open('[Link]', 'r')
try:
content = [Link]()
print(content)
finally:
[Link]() # Must remember to close
print(process_file('[Link]'))
````
---
**Definition:** Binary mode reads/writes files as raw bytes rather than text, used for non-text files like images, videos, and ex
**Why Use It:** Required for working with binary file formats, preserves exact byte content, and prevents text encoding issu
**Example:**
````python
# Reading binary file
with open('[Link]', 'rb') as file:
image_data = [Link]()
print(f"Image size: {len(image_data)} bytes")
---
## 7. Exception Handling
**Definition:** Exception handling allows you to gracefully handle errors that occur during program execution, preventing cr
**Why Use It:** Makes programs robust, provides user-friendly error messages, and allows recovery from errors.
**Example:**
````python
# Basic exception handling
try:
result = 10 / 0
except ZeroDivisionError:
print("Cannot divide by zero!")
result = None
### Try-Except-Else-Finally
**Definition:**
- **else**: Runs if no exception occurred
- **finally**: Always runs, regardless of exceptions (cleanup code)
**Why Use It:** Provides precise control over exception handling flow, ensures cleanup code runs, and separates success log
**Example:**
````python
# Complete exception handling structure
try:
file = open('[Link]', 'r')
data = [Link]()
number = int(data)
except FileNotFoundError:
print("File not found")
except ValueError:
print("File contains invalid data")
else:
# Runs only if no exception occurred
print(f"Successfully read number: {number}")
finally:
# Always runs (cleanup)
if 'file' in locals():
[Link]()
print("File closed")
def connect(self):
print("Connecting to database...")
def close(self):
print("Closing database connection")
def run_query(query):
"""Execute query with proper cleanup"""
db = DatabaseConnection()
try:
[Link]()
[Link](query)
except ValueError as e:
print(f"Query error: {e}")
return False
else:
print("Query executed successfully")
return True
finally:
[Link]()
---
**Definition:** You can manually trigger exceptions using the `raise` keyword to signal error conditions.
**Why Use It:** Enforces business logic, validates inputs, and creates clear error boundaries in your code.
**Example:**
````python
# Raise built-in exception
def calculate_percentage(value, total):
"""Calculate percentage"""
if total == 0:
raise ZeroDivisionError("Total cannot be zero")
if value < 0 or total < 0:
raise ValueError("Values must be non-negative")
return (value / total) * 100
# Re-raising exceptions
def process_data(data):
"""Process data with logging"""
try:
result = int(data)
return result * 2
except ValueError:
print("Logging error...")
raise # Re-raise the same exception
# Using validation
try:
valid_age = set_age(25)
print(f"Age set to: {valid_age}")
invalid_age = set_age(-5)
except ValueError as e:
print(f"Validation error: {e}")
````
---
**Definition:** You can create your own exception classes by inheriting from the `Exception` class or its subclasses.
**Why Use It:** Creates domain-specific errors, provides better error context, and makes error handling more precise and me
**Example:**
````python
# Simple custom exception
class InsufficientFundsError(Exception):
"""Raised when account has insufficient funds"""
pass
class BankAccount:
"""Bank account with custom exception handling"""
if amount <= 0:
raise ValueError("Withdrawal amount must be positive")
[Link] -= amount
return [Link]
def lock(self):
"""Lock the account"""
[Link] = True
try:
[Link](1500)
except InsufficientFundsError as e:
print(f"Transaction failed: {e}")
try:
[Link]()
[Link](100)
except AccountLockedError as e:
print(f"Cannot process: {e}")
return True
try:
validate_user_registration("AB", "invalidemail", 16)
except ValidationError as e:
print(f"Registration failed - {e}")
````
---
### Iterators
**Definition:** An iterator is an object that implements the iterator protocol (`__iter__()` and `__next__()` methods), allowin
**Why Use It:** Provides a standard way to loop through data, enables lazy evaluation, and allows custom iteration behavior
**Example:**
````python
# Basic iterator usage
my_list = [1, 2, 3, 4, 5]
iterator = iter(my_list)
print(next(iterator)) # Output: 1
print(next(iterator)) # Output: 2
print(next(iterator)) # Output: 3
# Custom iterator class
class Countdown:
"""Iterator that counts down from a number"""
def __iter__(self):
return self
def __next__(self):
if [Link] <= 0:
raise StopIteration
[Link] -= 1
return [Link] + 1
def __iter__(self):
[Link] = open([Link], 'r')
self.line_count = 0
return self
def __next__(self):
if self.line_count >= self.max_lines:
[Link]()
raise StopIteration
line = [Link]()
if not line:
[Link]()
raise StopIteration
self.line_count += 1
return [Link]()
---
### Generators
**Definition:** Generators are functions that use `yield` to produce a sequence of values lazily, one at a time, instead of retur
**Why Use It:** Memory efficient for large datasets, creates infinite sequences, simplifies iterator creation, and enables pipel
**Example:**
````python
# Basic generator function
def simple_generator():
"""Yields three values"""
print("First yield")
yield 1
print("Second yield")
yield 2
print("Third yield")
yield 3
# Using generator
gen = simple_generator()
print(next(gen)) # Output: First yield, then 1
print(next(gen)) # Output: Second yield, then 2
# Infinite generator
def infinite_counter(start=0):
"""Count infinitely from start"""
count = start
while True:
yield count
count += 1
def square_numbers(numbers):
"""Square each number"""
for num in numbers:
yield num ** 2
# Chain generators
numbers = range(10)
evens = filter_even(numbers)
squared = square_numbers(evens)
print(list(squared)) # Output: [0, 4, 16, 36, 64]
````
---
### Generator Expressions
**Definition:** A concise way to create generators using syntax similar to list comprehensions, but with parentheses instead o
**Why Use It:** More memory efficient than list comprehensions, perfect for one-time iterations, and cleaner syntax for simp
**Example:**
````python
# List comprehension (creates entire list in memory)
squares_list = [x**2 for x in range(1000000)] # Uses lots of memory
# Memory comparison
import sys
---
**Why Use It:** Makes generator delegation cleaner, flattens nested iterations, and improves code readability.
**Example:**
````python
# Without yield from (verbose)
def chain_generators_old(*iterables):
"""Chain iterables the old way"""
for iterable in iterables:
for item in iterable:
yield item
def traverse(self):
"""Traverse tree using yield from"""
yield [Link]
for child in [Link]:
yield from [Link]()
# Create tree
root = TreeNode(1, [
TreeNode(2, [TreeNode(4), TreeNode(5)]),
TreeNode(3, [TreeNode(6)])
])
# Traverse
for value in [Link]():
print(value, end=' ') # Output: 1 2 4 5 3 6
````
---
## 9. Decorators
**Definition:** Decorators are functions that modify or enhance other functions without changing their source code. They "w
**Why Use It:** Adds reusable functionality (logging, timing, authentication), separates concerns, and keeps code DRY (Don
**Example:**
````python
# Basic decorator
def my_decorator(func):
"""Simple decorator that wraps a function"""
def wrapper():
print("Something before the function")
func()
print("Something after the function")
return wrapper
@my_decorator
def say_hello():
print("Hello!")
say_hello()
# Output:
# Something before the function
# Hello!
# Something after the function
@timing_decorator
def slow_function():
import time
[Link](1)
return "Done"
result = slow_function()
# Output: slow_function took 1.0001 seconds
print(f"Calling {func.__name__}({all_args})")
result = func(*args, **kwargs)
print(f"{func.__name__} returned {result!r}")
return result
return wrapper
@log_function_call
def add(a, b):
return a + b
result = add(5, 3)
# Output:
# Calling add(5, 3)
# add returned 8
````
---
**Why Use It:** Allows customization of decorator behavior, makes decorators more flexible and reusable.
**Example:**
````python
# Decorator factory (decorator with parameters)
def repeat(times):
"""Repeat function execution N times"""
def decorator(func):
def wrapper(*args, **kwargs):
result = None
for _ in range(times):
result = func(*args, **kwargs)
return result
return wrapper
return decorator
@repeat(3)
def greet(name):
print(f"Hello, {name}!")
greet("Alice")
# Output:
# Hello, Alice!
# Hello, Alice!
# Hello, Alice!
@validate_range(0, 100)
def set_percentage(value):
return f"Percentage set to {value}%"
print(set_percentage(50)) # Works
# print(set_percentage(150)) # Raises ValueError
# Practical example: Retry decorator
def retry(max_attempts=3, delay=1):
"""Retry function on failure"""
import time
def decorator(func):
def wrapper(*args, **kwargs):
for attempt in range(1, max_attempts + 1):
try:
return func(*args, **kwargs)
except Exception as e:
if attempt == max_attempts:
print(f"Failed after {max_attempts} attempts")
raise
print(f"Attempt {attempt} failed: {e}. Retrying...")
[Link](delay)
return wrapper
return decorator
@retry(max_attempts=3, delay=0.5)
def unreliable_function():
import random
if [Link]() < 0.7:
raise ConnectionError("Network error")
return "Success!"
````
---
**Definition:** Using `[Link]` preserves the original function's metadata (name, docstring) when creating decorator
**Why Use It:** Maintains proper function introspection, documentation, and debugging information.
**Example:**
````python
from functools import wraps
def original_function():
"""This is the original function"""
pass
@bad_decorator
def bad_wrapped():
"""Original docstring"""
pass
@good_decorator
def good_wrapped():
"""Original docstring"""
pass
def my_decorator(func):
"""Decorator template with proper metadata preservation"""
@wraps(func)
def wrapper(*args, **kwargs):
# Before function
print(f"Calling {func.__name__}")
# Call function
result = func(*args, **kwargs)
# After function
print(f"Finished {func.__name__}")
return result
return wrapper
@my_decorator
def calculate(x, y):
"""
return bool([Link](pattern, password))
print(validate_strong_password("Weak")) # False
print(validate_strong_password("StrongPass1!")) # True
````
---
### Lists
**Definition:** Lists are ordered, mutable sequences that can contain elements of any type. Created using square brackets `[]
**Why Use It:** Most versatile Python data structure, supports dynamic sizing, allows duplicates, and provides extensive bui
**Example:**
````python
# Creating lists
numbers = [1, 2, 3, 4, 5]
mixed = [1, "hello", 3.14, True]
nested = [[1, 2], [3, 4], [5, 6]]
empty = []
# Adding elements
[Link]('date') # Add to end
[Link](1, 'apricot') # Insert at index
[Link](['fig', 'grape']) # Add multiple
# Removing elements
[Link]('banana') # Remove by value
popped = [Link]() # Remove last (or by index)
del fruits[0] # Delete by index
# Accessing elements
first = fruits[0]
last = fruits[-1]
subset = fruits[1:3] # Slicing
# List methods
[Link]() # Sort in place
[Link]() # Reverse in place
count = [Link]('apple') # Count occurrences
index = [Link]('cherry') # Find index
def show_tasks(self):
if not [Link]:
print("No tasks")
for i, task in enumerate([Link], 1):
print(f"{i}. {task}")
todo = TaskList()
todo.add_task("Buy groceries")
todo.add_task("Write code")
todo.show_tasks()
````
---
### Tuples
**Definition:** Tuples are ordered, immutable sequences similar to lists but cannot be modified after creation. Created using
**Why Use It:** Immutability ensures data integrity, faster than lists, can be used as dictionary keys, and perfect for fixed col
**Example:**
````python
# Creating tuples
coordinates = (10, 20)
single = (1,) # Note the comma for single element
empty = ()
mixed = (1, "hello", 3.14)
# Unpacking tuples
x, y = coordinates
print(f"x={x}, y={y}") # Output: x=10, y=20
---
### Dictionaries
**Definition:** Dictionaries are unordered collections of key-value pairs, providing fast lookups by key. Created using curly
**Why Use It:** Fast O(1) average-case lookup, models real-world relationships, perfect for mappings and configurations.
**Example:**
````python
# Creating dictionaries
person = {
'name': 'Alice',
'age': 30,
'city': 'NYC'
}
# Accessing values
name = person['name'] # KeyError if not exists
age = [Link]('age', 0) # Returns default if not exists
# Adding/modifying
person['email'] = 'alice@[Link]' # Add new key
person['age'] = 31 # Modify existing
# Removing
del person['city'] # Remove key
popped = [Link]('email', None) # Remove and return value
# Dictionary methods
keys = [Link]() # Get all keys
values = [Link]() # Get all values
items = [Link]() # Get key-value pairs
# Checking existence
if 'name' in person:
print("Name exists")
print(authenticate('alice', 'secret123'))
````
---
### Sets
**Definition:** Sets are unordered collections of unique elements, supporting mathematical set operations. Created using cur
**Why Use It:** Automatic duplicate removal, fast membership testing O(1), supports set mathematics (union, intersection, e
**Example:**
````python
# Creating sets
numbers = {1, 2, 3, 4, 5}
empty_set = set() # Note: {} creates empty dict, not set
from_list = set([1, 2, 2, 3, 3, 3]) # Duplicates removed
# Adding/removing elements
[Link](6) # Add single element
[Link]([7, 8, 9]) # Add multiple
[Link](1) # Remove (raises error if not exists)
[Link](10) # Remove (no error if not exists)
popped = [Link]() # Remove arbitrary element
# Set operations
a = {1, 2, 3, 4, 5}
b = {4, 5, 6, 7, 8}
union = a | b # or [Link](b)
# {1, 2, 3, 4, 5, 6, 7, 8}
difference = a - b # or [Link](b)
# {# Complete Python Documentation with Detailed Explanations
## From Basics to Advanced - Python 3.13+
---
## Table of Contents
---
### Variables
**Definition:** Variables are named containers that store data values in memory. Python is dynamically typed, meaning you d
**Why Use It:** Variables allow you to store and manipulate data throughout your program, making code reusable and maint
**Example:**
```python
# Simple variable assignment
name = "Alice" # String variable
age = 30 # Integer variable
height = 5.7 # Float variable
is_student = False # Boolean variable
# Multiple assignment
x, y, z = 1, 2, 3 # Assign multiple values at once
a = b = c = 10 # Assign same value to multiple variables
---
**Definition:** Data types define the kind of value a variable can hold. Python has several built-in data types.
**Why Use It:** Different data types are optimized for different operations. Using the right type improves performance and p
**Example:**
```python
# Integer
count = 100
print(type(count)) # <class 'int'>
# Float
price = 19.99
print(type(price)) # <class 'float'>
# String
message = "Hello, World!"
print(type(message)) # <class 'str'>
# Boolean
is_active = True
print(type(is_active)) # <class 'bool'>
# Complex numbers
complex_num = 3 + 4j
print(type(complex_num)) # <class 'complex'>
# None type
result = None
print(type(result)) # <class 'NoneType'>
```
---
**Definition:** Type checking verifies the data type of a variable. Type conversion transforms data from one type to another.
**Why Use It:** Ensures data integrity, prevents errors, and allows operations between different types.
**Example:**
```python
# Type checking
age = 25
print(isinstance(age, int)) # True - checks if age is an integer
print(isinstance(age, str)) # False
# Type conversion (casting)
str_number = "123"
number = int(str_number) # Convert string to integer
print(number + 10) # 133
---
## 2. Control Flow
**Definition:** Conditional statements that execute different code blocks based on whether conditions are true or false.
**Why Use It:** Allows your program to make decisions and execute different paths of code based on conditions, making pro
**Example:**
```python
# Grade calculator
score = 85
print(f"Your grade is: {grade}") # Output: Good job! Your grade is: B
```
---
### Ternary Operator
**Why Use It:** Makes code more readable and compact for simple conditional assignments.
**Example:**
```python
# Traditional if-else
age = 20
if age >= 18:
status = "Adult"
else:
status = "Minor"
---
**Definition:** A loop that iterates over a sequence (list, tuple, string, range) and executes a block of code for each item.
**Why Use It:** Automates repetitive tasks, processes collections of data, and eliminates the need for manual repetition.
**Example:**
```python
# Basic for loop with range
for i in range(5):
print(f"Count: {i}")
# Output: Count: 0, Count: 1, Count: 2, Count: 3, Count: 4
---
**Why Use It:** Useful when you don't know in advance how many iterations are needed, or when waiting for a specific con
**Example:**
```python
# Basic while loop
count = 0
while count < 5:
print(f"Count is: {count}")
count += 1
---
### Break and Continue
**Definition:**
- **break**: Exits the loop entirely
- **continue**: Skips the current iteration and moves to the next one
**Why Use It:** Provides fine control over loop execution, allowing you to skip unwanted iterations or exit early when condi
**Example:**
```python
# Break - exit loop when condition met
for i in range(10):
if i == 5:
break # Stop loop when i equals 5
print(i) # Output: 0, 1, 2, 3, 4
---
**Definition:** A structural pattern matching statement that compares a value against multiple patterns, similar to switch-case
**Why Use It:** Provides cleaner, more readable code than multiple if-elif statements, especially for complex pattern matchin
**Example:**
```python
# HTTP status code handler
def handle_response(status_code):
match status_code:
case 200:
return "Success"
case 404:
return "Not Found"
case 500 | 502 | 503: # Multiple values
return "Server Error"
case code if 400 <= code < 500: # With condition
return "Client Error"
case _: # Default case
return "Unknown Status"
---
## 3. Functions
**Definition:** A reusable block of code that performs a specific task. Functions are defined using the `def` keyword.
**Why Use It:** Promotes code reusability, organization, and maintainability. Breaks complex problems into smaller, manage
**Example:**
```python
# Simple function
def greet(name):
"""Greets a person by name"""
return f"Hello, {name}!"
message = greet("Alice")
print(message) # Output: Hello, Alice!
result = calculate_area(5, 3)
print(f"Area: {result}") # Output: Area: 15
---
**Definition:** Parameters that have default values assigned, making them optional when calling the function.
**Why Use It:** Makes functions more flexible and reduces the need for multiple function definitions for similar tasks.
**Example:**
```python
# Function with default parameter
def power(base, exponent=2):
"""Raises base to the power of exponent (default: 2)"""
return base ** exponent
# Multiple defaults
def create_profile(name, age=18, country="USA"):
return {
'name': name,
'age': age,
'country': country
}
---
**Definition:** Allows a function to accept any number of positional arguments, which are collected into a tuple.
**Why Use It:** Makes functions flexible when you don't know in advance how many arguments will be passed.
**Example:**
```python
# Function accepting any number of arguments
def sum_all(*args):
"""Sums all provided numbers"""
total = 0
for num in args:
total += num
return total
**Definition:** Allows a function to accept any number of keyword arguments, which are collected into a dictionary.
**Why Use It:** Provides flexibility for functions that need to handle varying named parameters, useful for configuration and
**Example:**
```python
# Function accepting keyword arguments
def print_info(**kwargs):
"""Prints all key-value pairs"""
for key, value in [Link]():
print(f"{key}: {value}")
---
**Definition:** Optional metadata that specifies the expected types of function parameters and return values.
**Why Use It:** Improves code documentation, enables static type checking with tools like mypy, and makes code more mai
**Example:**
```python
# Function with type hints
def add_numbers(x: int, y: int) -> int:
"""Adds two integers and returns an integer"""
return x + y
result = add_numbers(5, 3)
print(result) # Output: 8
---
**Definition:** A closure is a function that remembers values from its enclosing scope even after that scope has finished exec
**Why Use It:** Enables data encapsulation, creates function factories, and allows for elegant callback patterns.
**Example:**
```python
# Basic closure
def outer_function(x):
"""Outer function that returns an inner function"""
def inner_function(y):
"""Inner function that remembers x"""
return x + y
return inner_function
# Create a closure
add_5 = outer_function(5)
print(add_5(10)) # Output: 15 (remembers x=5)
print(add_5(20)) # Output: 25
def increment():
nonlocal count # Modify outer scope variable
count += 1
return count
return increment
counter1 = make_counter()
counter2 = make_counter()
print(counter1()) # Output: 1
print(counter1()) # Output: 2
print(counter2()) # Output: 1 (separate counter)
# Multiplier factory
def make_multiplier(n):
"""Creates a function that multiplies by n"""
def multiply(x):
return x * n
return multiply
times_3 = make_multiplier(3)
times_5 = make_multiplier(5)
print(times_3(10)) # Output: 30
print(times_5(10)) # Output: 50
```
---
## 4. Object-Oriented Programming
**Definition:** A class is a blueprint for creating objects. Objects are instances of classes that combine data (attributes) and b
**Why Use It:** Organizes code into reusable components, models real-world entities, and implements encapsulation, inherit
**Example:**
```python
# Basic class definition
class Dog:
"""Represents a dog"""
# Constructor (initializer)
def __init__(self, name, age):
"""Initialize a new dog"""
[Link] = name # Instance attribute
[Link] = age
# Instance method
def bark(self):
"""Make the dog bark"""
return f"{[Link]} says Woof!"
def get_info(self):
"""Return dog information"""
return f"{[Link]} is {[Link]} years old"
---
**Definition:** Special methods with double underscores (e.g., `__init__`, `__str__`) that define how objects behave with bui
**Why Use It:** Allows custom classes to work seamlessly with Python's built-in functions and operators, making objects be
**Example:**
```python
class Book:
"""Represents a book"""
def __str__(self):
"""String representation for users"""
return f"'{[Link]}' by {[Link]}"
def __repr__(self):
"""String representation for developers"""
return f"Book(title='{[Link]}', author='{[Link]}', pages={[Link]})"
def __len__(self):
"""Return number of pages"""
return [Link]
def __str__(self):
return f"Vector({self.x}, {self.y})"
v1 = Vector(2, 3)
v2 = Vector(4, 5)
v3 = v1 + v2 # Uses __add__
v4 = v1 * 3 # Uses __mul__
---
### Inheritance
**Definition:** A mechanism where a new class (child/subclass) derives properties and methods from an existing class (paren
**Why Use It:** Promotes code reuse, creates hierarchical relationships, and allows for polymorphism (same interface, differ
**Example:**
```python
# Parent class
class Animal:
"""Base class for all animals"""
def __init__(self, name, age):
[Link] = name
[Link] = age
def speak(self):
"""Generic speak method"""
return "Some sound"
def info(self):
return f"{[Link]} is {[Link]} years old"
# Child class
class Dog(Animal):
"""Dog class inherits from Animal"""
class Cat(Animal):
"""Cat class inherits from Animal"""
def speak(self):
return "Meow!"
def scratch(self):
return f"{[Link]} is scratching"
---
**Definition:**
- **Class methods**: Methods that receive the class as the first parameter (cls), not an instance
- **Static methods**: Methods that don't receive class or instance, just regular functions within class namespace
**Why Use It:** Class methods are useful for factory methods and alternative constructors. Static methods are utility function
**Example:**
```python
class Date:
"""Represents a date"""
@classmethod
def from_string(cls, date_string):
"""Factory method: Create Date from string"""
year, month, day = map(int, date_string.split('-'))
return cls(year, month, day) # Returns new instance
@classmethod
def today(cls):
"""Factory method: Create Date for today"""
import datetime
today = [Link]()
return cls([Link], [Link], [Link])
@staticmethod
def is_leap_year(year):
"""Utility function: Check if year is leap year"""
return year % 4 == 0 and (year % 100 != 0 or year % 400 == 0)
def __str__(self):
return f"{[Link]}-{[Link]:02d}-{[Link]:02d}"
@classmethod
def from_fahrenheit(cls, fahrenheit):
"""Create Temperature from Fahrenheit"""
celsius = (fahrenheit - 32) * 5/9
return cls(celsius)
@staticmethod
def celsius_to_fahrenheit(celsius):
"""Convert Celsius to Fahrenheit"""
return (celsius * 9/5) + 32
def __str__(self):
return f"{[Link]}°C"
temp1 = Temperature(25)
temp2 = Temperature.from_fahrenheit(77)
---
### Properties
**Definition:** Properties allow you to define methods that can be accessed like attributes, providing controlled access to cla
**Why Use It:** Enables encapsulation, data validation, computed attributes, and maintains a clean interface while adding log
**Example:**
```python
class Circle:
"""Represents a circle"""
@property
def radius(self):
"""Getter for radius"""
return self._radius
@[Link]
def radius(self, value):
"""Setter with validation"""
if value < 0:
raise ValueError("Radius cannot be negative")
self._radius = value
@property
def diameter(self):
"""Computed property"""
return self._radius * 2
@property
def area(self):
"""Computed property"""
import math
return [Link] * (self._radius ** 2)
@property
def circumference(self):
"""Computed property"""
import math
return 2 * [Link] * self._radius
# Using properties
circle = Circle(5)
# Validation works
try:
[Link] = -5
except ValueError as e:
print(f"Error: {e}") # Output: Error: Radius cannot be negative
@property
def celsius(self):
return self._celsius
@[Link]
def celsius(self, value):
if value < -273.15:
raise ValueError("Temperature below absolute zero!")
if value > 100:
print("Warning: Very high temperature!")
self._celsius = value
@property
def fahrenheit(self):
"""Convert to Fahrenheit on the fly"""
return (self._celsius * 9/5) + 32
@[Link]
def fahrenheit(self, value):
"""Set temperature in Fahrenheit"""
[Link] = (value - 32) * 5/9
thermostat = Thermostat()
print(f"Current: {[Link]}°C") # Output: Current: 20°C
print(f"In Fahrenheit: {[Link]}°F") # Output: In Fahrenheit: 68.0°F
---
**Definition:** Modules are Python files containing functions, classes, and variables. Importing allows you to use code from
**Why Use It:** Organizes code into logical units, promotes code reuse, and provides access to Python's extensive standard l
**Example:**
```python
# Different ways to import
current_dir = [Link]()
print(f"Current directory: {current_dir}")
# Practical example: Using multiple imports
from datetime import datetime
import json
def save_log(message):
"""Save timestamped log message"""
log_entry = {
'timestamp': [Link]().isoformat(),
'message': message
}
print([Link](log_entry, indent=2))
save_log("Application started")
```
---
**Definition:** Any Python file can be a module. You create one by saving Python code in a `.py` file and importing it in othe
**Why Use It:** Organizes your code into reusable components, separates concerns, and makes large projects manageable.
**Example:**
PI = 3.14159
def circle_area(radius):
"""Calculate circle area"""
return PI * radius ** 2
def circle_circumference(radius):
"""Calculate circle circumference"""
return 2 * PI * radius
def square_area(side):
"""Calculate square area"""
return side ** 2
class Calculator:
"""Simple calculator class"""
@staticmethod
def add(a, b):
return a + b
@staticmethod
def multiply(a, b):
return a * b
```
---
**Definition:** `__name__` is a special variable that equals `"__main__"` when the file is run directly, or the module name w
**Why Use It:** Allows you to write code that runs only when the file is executed directly, not when imported. Essential for c
**Example:**
```python
# [Link]
"""Utility functions"""
def process_data(data):
"""Process data"""
return [x * 2 for x in data]
def validate_input(value):
"""Validate input"""
return value > 0
test_data = [1, 2, 3, 4, 5]
result = process_data(test_data)
print(f"Test result: {result}")
---
## 6. File Handling
**Definition:** File reading operations allow you to access and read content from files stored on disk.
**Why Use It:** Essential for data processing, configuration loading, log analysis, and working with persistent data.
**Example:**
```python
# Method 1: Read entire file
with open('[Link]', 'r') as file:
content = [Link]()
print(content)
---
**Definition:** File writing operations allow you to create new files or modify existing ones by writing data to disk.
**Why Use It:** Saves program output, creates logs, generates reports, and persists data between program runs.
**Example:**
```python
# Write mode ('w') - overwrites existing file
with open('[Link]', 'w') as file:
[Link]("Hello, World!\n")
[Link]("This is line 2\n")
---
**Definition:** The `with` statement automatically handles resource setup and cleanup, ensuring files are properly closed eve
**Why Use It:** Prevents resource leaks, ensures proper cleanup, and makes code more readable and reliable.
**Example:**
```python
# Without context manager (not recommended)
file = open('[Link]', 'r')
try:
content = [Link]()
print(content)
finally:
[Link]() # Must remember to close
print(process_file('[Link]'))
```
---
**Definition:** Binary mode reads/writes files as raw bytes rather than text, used for non-text files like images, videos, and ex
**Why Use It:** Required for working with binary file formats, preserves exact byte content, and prevents text encoding issu
**Example:**
```python
# Reading binary file
with open('[Link]', 'rb') as file:
image_data = [Link]()
print(f"Image size: {len(image_data)} bytes")
---
## 7. Exception Handling
**Definition:** Exception handling allows you to gracefully handle errors that occur during program execution, preventing cr
**Why Use It:** Makes programs robust, provides user-friendly error messages, and allows recovery from errors.
**Example:**
```python
# Basic exception handling
try:
result = 10 / 0
except ZeroDivisionError:
print("Cannot divide by zero!")
result = None
---
### Try-Except-Else-Finally
**Definition:**
- **else**: Runs if no exception occurred
- **finally**: Always runs, regardless of exceptions (cleanup code)
**Why Use It:** Provides precise control over exception handling flow, ensures cleanup code runs, and separates success log
**Example:**
```python
# Complete exception handling structure
try:
file = open('[Link]', 'r')
data = [Link]()
number = int(data)
except FileNotFoundError:
print("File not found")
except ValueError:
print("File contains invalid data")
else:
# Runs only if no exception occurred
print(f"Successfully read number: {number}")
finally:
# Always runs (cleanup)
if 'file' in locals():
[Link]()
print("File closed")
def connect(self):
print("Connecting to database...")
def close(self):
print("Closing database connection")
def run_query(query):
"""Execute query with proper cleanup"""
db = DatabaseConnection()
try:
[Link]()
[Link](query)
except ValueError as e:
print(f"Query error: {e}")
return False
else:
print("Query executed successfully")
return True
finally:
[Link]()
---
**Why Use It:** Enforces business logic, validates inputs, and creates clear error boundaries in your code.
**Example:**
```python
# Raise built-in exception
def calculate_percentage(value, total):
"""Calculate percentage"""
if total == 0:
raise ZeroDivisionError("Total cannot be zero")
if value < 0 or total < 0:
raise ValueError("Values must be non-negative")
return (value / total) * 100
# Re-raising exceptions
def process_data(data):
"""Process data with logging"""
try:
result = int(data)
return result * 2
except ValueError:
print("Logging error...")
raise # Re-raise the same exception
# Using validation
try:
valid_age = set_age(25)
print(f"Age set to: {valid_age}")
invalid_age = set_age(-5)
except ValueError as e:
print(f"Validation error: {e}")
```
---
**Definition:** You can create your own exception classes by inheriting from the `Exception` class or its subclasses.
**Why Use It:** Creates domain-specific errors, provides better error context, and makes error handling more precise and me
**Example:**
```python
# Simple custom exception
class InsufficientFundsError(Exception):
"""Raised when account has insufficient funds"""
pass
class BankAccount:
"""Bank account with custom exception handling"""
[Link] -= amount
return [Link]
def lock(self):
"""Lock the account"""
[Link] = True
try:
[Link](1500)
except InsufficientFundsError as e:
print(f"Transaction failed: {e}")
try:
[Link]()
[Link](100)
except AccountLockedError as e:
print(f"Cannot process: {e}")
return True
try:
validate_user_registration("AB", "invalidemail", 16)
except ValidationError as e:
print(f"Registration failed - {e}")
```
---
### Iterators
**Definition:** An iterator is an object that implements the iterator protocol (`__iter__()` and `__next__()` methods), allowin
**Why Use It:** Provides a standard way to loop through data, enables lazy evaluation, and allows custom iteration behavior
**Example:**
```python
# Basic iterator usage
my_list = [1, 2, 3, 4, 5]
iterator = iter(my_list)
print(next(iterator)) # Output: 1
print(next(iterator)) # Output: 2
print(next(iterator)) # Output: 3
def __iter__(self):
return self
def __next__(self):
if [Link] <= 0:
raise StopIteration
[Link] -= 1
return [Link] + 1
def __iter__(self):
[Link] = open([Link], 'r')
self.line_count = 0
return self
def __next__(self):
if self.line_count >= self.max_lines:
[Link]()
raise StopIteration
line = [Link]()
if not line:
[Link]()
raise StopIteration
self.line_count += 1
return [Link]()
---
### Generators
**Definition:** Generators are functions that use `yield` to produce a sequence of values lazily, one at a time, instead of retur
**Why Use It:** Memory efficient for large datasets, creates infinite sequences, simplifies iterator creation, and enables pipel
**Example:**
```python
# Basic generator function
def simple_generator():
"""Yields three values"""
print("First yield")
yield 1
print("Second yield")
yield 2
print("Third yield")
yield 3
# Using generator
gen = simple_generator()
print(next(gen)) # Output: First yield, then 1
print(next(gen)) # Output: Second yield, then 2
# Infinite generator
def infinite_counter(start=0):
"""Count infinitely from start"""
count = start
while True:
yield count
count += 1
def square_numbers(numbers):
"""Square each number"""
for num in numbers:
yield num ** 2
# Chain generators
numbers = range(10)
evens = filter_even(numbers)
squared = square_numbers(evens)
print(list(squared)) # Output: [0, 4, 16, 36, 64]
```
---
**Definition:** A concise way to create generators using syntax similar to list comprehensions, but with parentheses instead o
**Why Use It:** More memory efficient than list comprehensions, perfect for one-time iterations, and cleaner syntax for simp
**Example:**
```python
# List comprehension (creates entire list in memory)
squares_list = [x**2 for x in range(1000000)] # Uses lots of memory
# Memory comparison
import sys
---
**Definition:** `yield from` delegates part of generator operations to another generator, simplifying code that chains generato
**Why Use It:** Makes generator delegation cleaner, flattens nested iterations, and improves code readability.
**Example:**
```python
# Without yield from (verbose)
def chain_generators_old(*iterables):
"""Chain iterables the old way"""
for iterable in iterables:
for item in iterable:
yield item
def traverse(self):
"""Traverse tree using yield from"""
yield [Link]
for child in [Link]:
yield from [Link]()
# Create tree
root = TreeNode(1, [
TreeNode(2, [TreeNode(4), TreeNode(5)]),
TreeNode(3, [TreeNode(6)])
])
# Traverse
for value in [Link]():
print(value, end=' ') # Output: 1 2 4 5 3 6
```
---
## 9. Decorators
**Definition:** Decorators are functions that modify or enhance other functions without changing their source code. They "w
**Why Use It:** Adds reusable functionality (logging, timing, authentication), separates concerns, and keeps code DRY (Don
**Example:**
```python
# Basic decorator
def my_decorator(func):
"""Simple decorator that wraps a function"""
def wrapper():
print("Something before the function")
func()
print("Something after the function")
return wrapper
@my_decorator
def say_hello():
print("Hello!")
say_hello()
# Output:
# Something before the function
# Hello!
# Something after the function
@timing_decorator
def slow_function():
import time
[Link](1)
return "Done"
result = slow_function()
# Output: slow_function took 1.0001 seconds
print(f"Calling {func.__name__}({all_args})")
result = func(*args, **kwargs)
print(f"{func.__name__} returned {result!r}")
return result
return wrapper
@log_function_call
def add(a, b):
return a + b
result = add(5, 3)
# Output:
# Calling add(5, 3)
# add returned 8
```
---
**Definition:** Decorators that accept arguments, requiring an extra layer of function nesting to configure behavior.
**Why Use It:** Allows customization of decorator behavior, makes decorators more flexible and reusable.
**Example:**
```python
# Decorator factory (decorator with parameters)
def repeat(times):
"""Repeat function execution N times"""
def decorator(func):
def wrapper(*args, **kwargs):
result = None
for _ in range(times):
result = func(*args, **kwargs)
return result
return wrapper
return decorator
@repeat(3)
def greet(name):
print(f"Hello, {name}!")
greet("Alice")
# Output:
# Hello, Alice!
# Hello, Alice!
# Hello, Alice!
@validate_range(0, 100)
def set_percentage(value):
return f"Percentage set to {value}%"
print(set_percentage(50)) # Works
# print(set_percentage(150)) # Raises ValueError
def decorator(func):
def wrapper(*args, **kwargs):
for attempt in range(1, max_attempts + 1):
try:
return func(*args, **kwargs)
except Exception as e:
if attempt == max_attempts:
print(f"Failed after {max_attempts} attempts")
raise
print(f"Attempt {attempt} failed: {e}. Retrying...")
[Link](delay)
return wrapper
return decorator
@retry(max_attempts=3, delay=0.5)
def unreliable_function():
import random
if [Link]() < 0.7:
raise ConnectionError("Network error")
return "Success!"
```
---
**Definition:** Using `[Link]` preserves the original function's metadata (name, docstring) when creating decorator
**Why Use It:** Maintains proper function introspection, documentation, and debugging information.
**Example:**
```python
from functools import wraps
def original_function():
"""This is the original function"""
pass
@bad_decorator
def bad_wrapped():
"""Original docstring"""
pass
@good_decorator
def good_wrapped():
"""Original docstring"""
pass
def my_decorator(func):
"""Decorator template with proper metadata preservation"""
@wraps(func)
def wrapper(*args, **kwargs):
# Before function
print(f"Calling {func.__name__}")
# Call function
result = func(*args, **kwargs)
# After function
print(f"Finished {func.__name__}")
return result
return wrapper
@my_decorator
def calculate(x, y):
"""