🔹 Variables in Python
A variable stores a value. Python is dynamically typed, so you don't need to declare a type.
# Basic variable assignment
age = 25
name = "Alice"
price = 99.99
is_python_fun = True
Naming Rules
- Must start with letter or underscore
- Can contain letters, numbers, and underscores
- Case-sensitive (Age ≠ AGE ≠ age)
- Use snake_case convention (my_variable)
Dynamic Typing
# Reassign different types value = 100 # Integer value = "Python" # Now string value = [1, 2, 3] # Now list
Type Conversion
num_str = str(42) # "42" str_num = int("123") # 123 num_float = float(7) # 7.0
Common Methods
# String methods name = "python" upper_name = name.upper() # "PYTHON" # List methods numbers = [1, 2, 3] numbers.append(4) # [1, 2, 3, 4] # Dictionary methods user = {"name": "Alice", "age": 30} keys = user.keys() # dict_keys(['name', 'age'])
Multiple Assignment
# Assign multiple variables x, y, z = 1, 2, 3 # Swap values a, b = 10, 20 a, b = b, a # a=20, b=10
Formatted Strings (f-strings)
# Common formatting with f-strings name = "Bob" age = 25 print(f"{name} is {age} years old") # Bob is 25 years old # Centering a string name = "Bob" print(f"{name:{'-'}^20}") # --------Bob--------- # Padding string to the right name = "Bob" print(f"{name:{'-'}<10}") # Bob------- # Padding string to the left name = "Bob" print(f"{name:{'-'}>10}") # -------Bob
🔹 Data Types in Python
Python uses dynamic typing and has several built-in data types:
Type | Description | Example |
---|---|---|
int | Integer numbers | 42 |
float | Floating-point numbers | 3.1415 |
str | Text sequences | "Hello" |
bool | Boolean values | True/False |
list | Mutable sequence | [1, 2, 3] |
tuple | Immutable sequence | (1, 2, 3) |
dict | Key-value pairs | {"key": "value"} |
set | Unique elements | {1, 2, 3} |
Type Conversion
int("25") # 25 → Convert to integer float(7) # 7.0 → Convert to float str(100) # "100" → Convert to string list("hello") # ['h', 'e', 'l', 'l', 'o'] tuple([1,2,3]) # (1, 2, 3) set([1,2,2,3]) # {1, 2, 3}
Type Checking
type(42) # → <class 'int'> isinstance(3.14, float) # → True
Special Values
None # Represents absence of value True/False # Boolean constants ...
🔹 Type Checking & Conversion
Type Checking
num = 42 print(type(num)) # <class 'int'> name = "Alice" print(isinstance(name, str)) # True mixed_list = [1, "two", 3.0] print(type(mixed_list)) # <class 'list'>
Conversion Functions
# String to numeric int_num = int("100") # 100 float_num = float("3.14") # 3.14 # Numeric to string str_num = str(255) # "255" # List conversions num_tuple = tuple([1, 2, 3]) # (1, 2, 3) char_list = list("Hello") # ['H', 'e', 'l', 'l', 'o'] # Boolean conversion bool_val = bool(1) # True int_from_bool = int(True) # 1
Special Conversions
# Base conversion hex_num = int("ff", 16) # 255 bin_num = bin(42) # '0b101010' # ASCII conversion char = chr(65) # 'A' code = ord('A') # 65 # String formatting formatted = f"{255:x}" # "ff" (hexadecimal)
Error Handling
try:
num = int("123a")
except ValueError as e:
print(f"Conversion error: {e}")
# Check before conversion
value = "3.14"
if value.replace('.', '', 1).isdigit():
print(float(value))
🔹 Operators & Expressions
Operators in Python allow you to perform calculations and logical comparisons.
🔸 Arithmetic Operators
print(10 + 3) # Addition → 13 print(10 - 3) # Subtraction → 7 print(10 * 3) # Multiplication → 30 print(10 ** 3) # Exponentiation → 1000 print(10 / 3) # Division → 3.333... print(10 // 3) # Floor Division → 3 print(10 % 3) # Modulus → 1
🔸 Assignment Operators
x = 5 x += 3 # x = x + 3 → 8 x -= 2 # x = x - 2 → 6 x *= 4 # x = x * 4 → 24 x /= 3 # x = x / 3 → 8.0 x **= 2 # x = x ** 2 → 64.0 x %= 5 # x = x % 5 → 4.0
🔸 Comparison Operators
print(5 == 5) # Equal → True print(5 != 3) # Not Equal → True print(5 > 3) # Greater Than → True print(5 <= 3) # Less or Equal → False print("a" == "A")# Case-sensitive → False print(1.0 == 1) # Value comparison → True
🔸 Logical Operators
age = 25 has_license = True # And/Or combinations can_drive = age >= 18 and has_license discount = age <= 12 or age >= 65 # Truthy/Falsy evaluation name = "" if not name: print("Name is required")
🔸 Identity Operators
a = [1,2,3] b = [1,2,3] print(a is b) # False (different objects) print(a == b) # True (same values) x = None print(x is None) # True
🔸 Membership Operators
colors = ["red", "green", "blue"] print("green" in colors) # True print("yellow" not in colors) # True text = "Hello World" print("World" in text) # True
🔸 Bitwise Operators
a = 60 # 0011 1100 b = 13 # 0000 1101 print(a & b) # AND → 12 (0000 1100) print(a | b) # OR → 61 (0011 1101) print(a ^ b) # XOR → 49 (0011 0001) print(~a) # NOT → -61 print(a << 2) # Shift left → 240 print(a >> 2) # Shift right → 15
🔸 Walrus Operator
# Assignment expression (Python 3.8+) if (n := len(items)) > 10: print(f"List is long ({n} items)") # In list comprehension [x for x in range(100) if (square := x**2) < 100] # In while loop while (chunk := file.read(8192)):
🔸 Order of Operations
From highest to lowest precedence:
- () - Parentheses
- ** - Exponentiation
- ~ + - - Unary operators
- * / % // - Multiplication/Division
- + - - Addition/Subtraction
- << >> - Bitwise shifts
- & - Bitwise AND
- ^ | - Bitwise XOR/OR
- := - Assignment expression (Walrus)
- <= < > >= == != - Comparisons
- is, is not, in, not in - Identity/Membership
- not - Logical NOT
- and - Logical AND
- or - Logical OR
🔹 Conditional Statements
Python supports if
, elif
, and else
statements for decision-making.
🔸 Basic Syntax
x = 20 if x > 10: print("Greater than 10") elif x == 10: print("Exactly 10") else: print("Less than 10")
🔸 Multiple Conditions
age = 25 has_license = True if age >= 18 and has_license: print("Can drive") elif age >= 16 or has_license: print("Learner's permit") else: print("Cannot drive")
🔸 Nested Conditionals
num = 15 if num > 0: if num % 2 == 0: print("Positive even number") else: print("Positive odd number") else: print("Non-positive number")
🔸 Ternary Operator
# Short-hand if-else age = 20 status = "Adult" if age >= 18 else "Minor" print(status) # Adult
🔹 Loops in Python
Loops help automate repetitive tasks.
🔸 For Loop
# Iterate through list fruits = ["apple", "banana", "cherry"] for fruit in fruits: print(fruit.upper()) # With index using enumerate for index, fruit in enumerate(fruits): print(f"{index}: {fruit}") # Range with step for num in range(0, 10, 2): print(num) # 0, 2, 4, 6, 8
🔸 While Loop
# Basic while loop count = 0 while count < 5: print(count) count += 1 # With break/continue while True: user_input = input("Enter 'q' to quit: ") if user_input == 'q': break elif user_input.isdigit(): continue print(f"You entered: {user_input}")
🔸 Loop Control
# Else clause in loops for n in range(2, 10): for x in range(2, n): if n % x == 0: break else: print(f"{n} is prime") # Zip multiple iterables names = ["Alice", "Bob"] ages = [25, 30] for name, age in zip(names, ages): print(f"{name} is {age} years old")
🔸 Comprehensions
# List comprehension squares = [x**2 for x in range(10)] # Dictionary comprehension square_dict = {x: x**2 for x in range(5)} # Set comprehension unique_lengths = {len(word) for word in ["hello", "world", "python"]}
🔹 Functions in Python
Functions help organize code into reusable blocks.
🔸 Basic Function
def greet(name):
return "Hello " + name
print(greet("Alice")) # Outputs: Hello Alice
🔸 Parameters & Return Values
# Multiple parameters and return values def calculate(x, y): sum = x + y product = x * y return sum, product s, p = calculate(3, 4) print(f"Sum: {s}, Product: {p}") # Sum: 7, Product: 12
🔸 Advanced Parameters
# *args for variable arguments def average(*numbers): return sum(numbers) / len(numbers) print(average(5, 10, 15)) # 10.0 # **kwargs for keyword arguments def user_profile(**details): for key, value in details.items(): print(f"{key}: {value}") user_profile(name="Alice", age=25, city="NY")
🔸 Special Function Types
# Lambda (anonymous) functions square = lambda x: x ** 2 print(square(5)) # 25 # Decorator functions def logger(func): def wrapper(*args, **kwargs): print(f"Calling {func.__name__}") return func(*args, **kwargs) return wrapper @logger def example(): print("Hello from example") example()
🔸 Recursion
def factorial(n):
return 1 if n <= 1 else n * factorial(n-1)
print(factorial(5)) # 120
🔸 Function Best Practices
# Type hints and docstrings def power(base: float, exponent: int) -> float: """Calculate base raised to the power of exponent. Args: base: The base number exponent: The exponent (must be positive integer) Returns: The result of base^exponent """ return base ** exponent print(power(2, 3)) # 8.0
🔸 Scope & Closures
def outer(): message = "Hello" def inner(): print(message) # Accessing outer scope return inner closure = outer() closure() # Hello
🔸 Global & Local Variables
count = 0 # Global variable def increment(): global count # Declare global variable local_num = 5 # Local variable count += local_num increment() print(count) # 5 # Accessing global without modification def show_global(): print("Global count:", count) show_global() # Global count: 5
Note: Avoid using global variables when possible. Use function parameters and return values instead.
🔹 Lists & Tuples in Python
🔸 Lists
Ordered, mutable collection. Created with square brackets []
# Basic operations nums = [1, 2, 3, 4, 5] print(nums[1]) # 2 (indexing) print(nums[-1]) # 5 (negative indexing) print(nums[1:4]) # [2, 3, 4] (slicing) print(len(nums)) # 5 (length) print(3 in nums) # True (membership check)
# Common methods fruits = ["apple", "banana"] fruits.append("orange") # Add item fruits.insert(1, "mango") # Insert at position fruits.remove("banana") # Remove item popped = fruits.pop(0) # Remove and return item fruits.sort() # Sort in-place fruits.reverse() # Reverse in-place print(fruits) # ['orange', 'mango']
# List operations a = [1, 2] + [3, 4] # Concatenation → [1,2,3,4] b = [0] * 3 # Repetition → [0,0,0] c = [x**2 for x in a] # List comprehension → [1,4,9,16] d = a.copy() # Shallow copy
🔸 Tuples
Ordered, immutable collection. Created with parentheses ()
# Basic operations colors = ('red', 'green', 'blue') print(colors[1]) # green print(colors[::2]) # ('red', 'blue') (slicing) print(len(colors)) # 3 print('red' in colors) # True
# Tuple methods numbers = (1, 2, 2, 3) print(numbers.count(2)) # 2 (occurrences) print(numbers.index(3)) # 3 (first occurrence index)
# Tuple unpacking point = (10, 20) x, y = point # x=10, y=20 # Returning multiple values def min_max(nums): return min(nums), max(nums) result = min_max([5,2,8,1]) # (1,8)
# Immutability note # colors[0] = 'yellow' # TypeError # Can contain mutable elements mixed = (1, [2, 3], "hello") mixed[1].append(4) # Valid → (1, [2,3,4], "hello")
🔸 List vs Tuple Comparison
Feature | List | Tuple |
---|---|---|
Mutability | Mutable | Immutable |
Memory | More memory | Less memory |
Use Case | Changing data | Fixed data |
Methods | append(), sort(), etc | count(), index() |
🔹 Dictionaries & Sets
🔸 Dictionaries
Mutable mapping type storing key-value pairs. Created with {}
or dict()
# Dictionary creation empty_dict = {} grades = dict(Alice=95, Bob=88) person = {"name": "Alice", "age": 25, "scores": [95, 88]} # Access methods print(person.get("name")) # Alice print(person.get("height", 160)) # 160 (default if key missing) print(person.keys()) # dict_keys(['name', 'age', 'scores']) print(person.values()) # dict_values(['Alice', 25, [95, 88]]) print(person.items()) # dict_items([('name', 'Alice'), ...])
# Dictionary operations person["city"] = "New York" # Add/update del person["age"] # Delete key popped = person.pop("scores") # Remove and return value person.update({"age": 30, "job": "Engineer"}) # Merge dictionaries # Dictionary comprehension square_dict = {x: x**2 for x in range(5)} # {0:0, 1:1, 2:4, 3:9, 4:16}
🔸 Sets
Unordered collection of unique elements. Created with {}
or set()
# Set operations a = {1, 2, 3} b = {2, 3, 4} print(a | b) # Union → {1,2,3,4} print(a & b) # Intersection → {2,3} print(a - b) # Difference → {1} print(a ^ b) # Symmetric Difference → {1,4}
# Set methods s = {1, 2, 3} s.add(4) # {1,2,3,4} s.discard(2) # {1,3,4} (no error if missing) s.remove(3) # {1,4} (raises KeyError if missing) s.update([5,6]) # {1,4,5,6} popped = s.pop() # Remove and return arbitrary element # Set comprehension even_squares = {x**2 for x in range(10) if x%2 == 0}
🔸 Dictionary vs Set Comparison
Feature | Dictionary | Set |
---|---|---|
Elements | Key-value pairs | Unique values |
Ordering | Insertion ordered (Python 3.7+) | Unordered |
Mutability | Mutable | Mutable |
Use Case | Data records, lookups | Membership testing, duplicates removal |
🔹 Object-Oriented Programming (OOP)
🔸 Encapsulation & Properties
class Temperature: def __init__(self, celsius): self._celsius = celsius # Protected attribute @property def fahrenheit(self): return (self._celsius * 9/5) + 32 @fahrenheit.setter def fahrenheit(self, value): self._celsius = (value - 32) * 5/9 temp = Temperature(25) print(temp.fahrenheit) # 77.0 temp.fahrenheit = 32 print(temp._celsius) # 0.0
🔸 Multiple Inheritance
class Flyer: def fly(self): return "Flying" class Swimmer: def swim(self): return "Swimming" class Duck(Flyer, Swimmer): pass duck = Duck() print(duck.fly()) # Flying print(duck.swim()) # Swimming
🔸 Abstract Base Classes
from abc import ABC, abstractmethod class Shape(ABC): @abstractmethod def area(self): pass class Circle(Shape): def __init__(self, radius): self.radius = radius def area(self): return 3.14 * self.radius ** 2 # shape = Shape() # Error circle = Circle(5) print(circle.area()) # 78.5
🔸 Operator Overloading
class Book:
def __init__(self, title, pages):
self.title = title
self.pages = pages
def __add__(self, other):
return Book(f"{self.title} & {other.title}", self.pages + other.pages)
def __str__(self):
return f"'{self.title}' ({self.pages} pages)"
b1 = Book("Python 101", 300)
b2 = Book("OOP Guide", 200)
combined = b1 + b2
print(combined) # 'Python 101 & OOP Guide' (500 pages)
🔸 Decorators (Logging/Caching)
import functools import time # Logging decorator def logger(func): @functools.wraps(func) def wrapper(*args, **kwargs): print(f"Calling {func.__name__}") result = func(*args, **kwargs) print(f"Finished {func.__name__}") return result return wrapper # Caching decorator def cache(max_size=128): def decorator(func): cache = {} @functools.wraps(func) def wrapper(*args): if args in cache: return cache[args] result = func(*args) cache[args] = result return result return wrapper return decorator class Calculator: @logger def add(self, a, b): return a + b @cache() def factorial(self, n): return 1 if n <= 1 else n * self.factorial(n-1) calc = Calculator() print(calc.add(2, 3)) # Logs calls print(calc.factorial(5)) # Caches results
Common decorator uses: logging, caching, timing, access control, validation
🔹 File Handling in Python
🔸 Basic File Operations
# Modes: r (read), w (write), a (append), r+ (read/write) # b (binary mode), t (text mode, default) # Writing to a file with open("diary.txt", "w") as f: f.write("First line\n") f.writelines(["Second line\n", "Third line\n"]) # Reading entire content with open("diary.txt", "r") as f: print(f.read()) # Full content # Reading line by line with open("diary.txt", "r") as f: for line in f: print(line.strip())
🔸 File Positioning
with open("data.bin", "wb+") as f: # Write binary data f.write(b"\x00\x01\x02\x03") # Move to start (position 0) f.seek(0) # Read first 2 bytes print(f.read(2)) # b'\x00\x01' # Current position print(f.tell()) # 2
🔸 CSV Files
import csv # Writing CSV with open("data.csv", "w", newline="") as f: writer = csv.writer(f) writer.writerow(["Name", "Age"]) writer.writerows([ ["Alice", 25], ["Bob", 30] ]) # Reading CSV with open("data.csv", "r") as f: reader = csv.DictReader(f) for row in reader: print(f"{row['Name']}: {row['Age']}")
🔸 JSON Files
import json # Writing to a JSON file data = {"name": "Alice", "scores": [88, 95]} with open("data.json", "w") as f: json.dump(data, f, indent=2) # Reading from a JSON file with open("data.json", "r") as f: loaded = json.load(f) print(loaded["name"]) # Alice
🔸 File Management
import os import shutil # File operations os.rename("old.txt", "new.txt") # Rename os.remove("file.txt") # Delete shutil.copy("src.txt", "dst.txt") # Copy shutil.move("src.txt", "dest/") # Move # Directory operations os.mkdir("new_dir") # Create directory os.listdir(".") # List files os.path.exists("file.txt") # Check existence
🔹 Exception Handling
Python uses try
/except
blocks to handle runtime errors. Built-in exceptions include:
ValueError
- Invalid value
TypeError
- Invalid operation type
IndexError
- Invalid sequence index
KeyError
- Missing dictionary key
FileNotFoundError
- Missing file
KeyboardInterrupt
- User interrupt
🔸 Basic Error Handling
try: age = int(input("Enter age: ")) except ValueError: print("Please enter a valid number!")
🔸 Advanced Handling
# Catching multiple exceptions
try:
file = open("data.txt")
data = file.read()
value = int(data)
except (FileNotFoundError, ValueError) as e:
print(f"Error: {str(e)}")
else:
print("Successfully read value:", value)
finally:
file.close() if 'file' in locals() else None
🔸 Custom Exceptions
class InvalidEmailError(Exception): """Raised when email format is invalid""" def __init__(self, email): self.email = email super().__init__(f"Invalid email: {email}") def validate_email(email): if "@" not in email: raise InvalidEmailError(email) return True try: validate_email("user.example.com") except InvalidEmailError as e: print(e)
🔸 Exception Chaining
try: open("missing.txt") except FileNotFoundError as e: raise RuntimeError("Failed to process file") from e
🔸 Best Practices
✓ Use specific exceptions instead of bare except:
✓ Include cleanup code in finally
blocks
✓ Use else
for code that should run only if no exceptions
✓ Log exceptions with logging.exception()
🔹 Modules & Imports
Modules allow you to organize code into reusable files. Python's module system includes:
🔸 Import Types
# 1. Standard import import math print(math.pi) # 2. Import with alias import numpy as np print(np.array([1,2])) # 3. From-import from datetime import datetime print(datetime.now()) # 4. Wildcard import (not recommended) from random import * print(randint(1,10))
🔸 Module Attributes
# mymodule.py
__version__ = "1.0"
def helper():
return "Help!"
def main():
print("Running module")
if __name__ == "__main__":
main()
# main.py import mymodule print(mymodule.__version__) # 1.0 print(mymodule.__name__) # mymodule
🔸 Packages
# Package structure my_package/ ├── __init__.py ├── utils.py └── subpackage/ ├── __init__.py └── helpers.py # Import from package from my_package.utils import format_data from my_package.subpackage.helpers import validate
🔸 Common Built-in Modules
sys
- System parameters
os
- OS operations
math
- Math functions
datetime
- Date/time handling
json
- JSON processing
re
- Regular expressions
argparse
- CLI parsing
logging
- Logging system
🔸 Module Search Path
import sys print(sys.path) # List of directories Python searches for modules # Add custom path sys.path.append("/path/to/my/modules")
🔸 Reloading Modules
import importlib
import mymodule
# After modifying mymodule.py
importlib.reload(mymodule)
🔹 Lambda Functions
Anonymous functions defined with lambda
keyword. Syntax: lambda arguments: expression
🔸 Basic Syntax
# Simple addition add = lambda a, b: a + b print(add(3, 5)) # 8 # No arguments greet = lambda: "Hello World" print(greet()) # Hello World
🔸 Common Use Cases
# Sorting with key people = [{"name": "Alice", "age": 25}, {"name": "Bob", "age": 30}] sorted_ages = sorted(people, key=lambda x: x['age']) print(sorted_ages) # [{'name': 'Alice', 'age': 25}, ...]
# Filtering with condition numbers = [1, 2, 3, 4, 5, 6] even = list(filter(lambda x: x % 2 == 0, numbers)) print(even) # [2, 4, 6]
# Reduce with lambda from functools import reduce product = reduce(lambda x, y: x * y, [1, 2, 3, 4]) print(product) # 24
🔸 Advanced Patterns
# Conditional logic grade = lambda score: 'Pass' if score >= 50 else 'Fail' print(grade(65)) # Pass # Multiple arguments full_name = lambda first, last: f"{first.strip().title()} {last.strip().title()}" print(full_name(" john ", "doe ")) # John Doe
🔸 Limitations & Best Practices
✓ Use for simple operations only
✓ Avoid complex logic (use regular functions instead)
✓ Can't contain statements (only expressions)
✓ No annotations or docstrings
✓ Preserve readability - don't chain multiple lambdas
🔹 Decorators
Decorators modify or enhance functions without changing their core functionality.
🔸 Basic Decorator
# Basic decorator example
def decorator(func):
def wrapper():
print("Before function call")
func()
print("After function call")
return wrapper
@decorator
def hello():
print("Hello, world!")
hello()
# Decorator with arguments def repeat(n_times): def decorator(func): def wrapper(*args, **kwargs): for _ in range(n_times): result = func(*args, **kwargs) return result return wrapper return decorator @repeat(n_times=3) def greet(name): print(f"Hello {name}") greet("Alice") # Prints 3 times
# Class-based decorator class Timer: def __init__(self, func): self.func = func def __call__(self, *args, **kwargs): import time start = time.time() result = self.func(*args, **kwargs) end = time.time() print(f"Execution time: {end - start:.2f}s") return result @Timer def long_operation(): time.sleep(1) long_operation() # Prints execution time
# Using functools.wraps to preserve metadata
import functools
def decorator(func):
@functools.wraps(func)
def wrapper(*args, **kwargs):
return func(*args, **kwargs)
return wrapper
# Stacking multiple decorators
@decorator1
@decorator2
def my_function():
pass
# Error handling in decorators
def handle_errors(func):
@functools.wraps(func)
def wrapper(*args, **kwargs):
try:
return func(*args, **kwargs)
except Exception as e:
print(f"Error: {str(e)}")
return wrapper
🔹 Generators in Python
Generators produce values on-the-fly using yield
, preserving memory for large datasets.
🔸 Generator Basics
# Generator function example def fibonacci(limit): a, b = 0, 1 while a < limit: yield a a, b = b, a + b # Using generator for num in fibonacci(100): print(num) # 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89
🔸 Generator Expressions
# Similar to list comprehension but with () squares = (x**2 for x in range(10)) print(next(squares)) # 0 print(next(squares)) # 1 # Memory efficient sum sum_of_squares = sum(x**2 for x in range(1000000))
🔸 Sending Values
def accumulator(): total = 0 while True: value = yield total += value yield total gen = accumulator() next(gen) # Prime the generator print(gen.send(10)) # 10 print(gen.send(20)) # 30
🔸 Yield From
def countdown(n):
while n > 0:
yield n
n -= 1
def countup(n):
yield from countdown(n)
yield from range(1, n+1)
for num in countup(3):
print(num) # 3, 2, 1, 1, 2, 3
🔸 Generator Methods
def generator_func(): try: while True: item = yield print(item) except GeneratorExit: print("Generator closed") gen = generator_func() next(gen) # Start generator gen.send("Hello") # Prints Hello gen.close() # Prints Generator closed
🔸 Best Practices
✓ Use for memory-efficient iteration
✓ Prefer generator expressions for simple cases
✓ Handle GeneratorExit
for cleanup
✓ Use yield from
for nested generators
✓ Remember generators are single-use
🔹 Working with CSV & JSON
🔸 Advanced CSV Handling
import csv # Reading with DictReader with open("data.csv", "r") as f: reader = csv.DictReader(f) for row in reader: print(f"{row['Name']} is {row['Age']} years old") # Writing with DictWriter with open("output.csv", "w", newline="") as f: fieldnames = ["Name", "Email"] writer = csv.DictWriter(f, fieldnames=fieldnames, delimiter=';') writer.writeheader() writer.writerow({"Name": "Alice", "Email": "alice@example.com"}) # Handling TSV files with open("data.tsv", "w", newline="") as f: writer = csv.writer(f, delimiter='\t') writer.writerow(["ID", "Value"])
🔸 Advanced JSON Handling
import json from datetime import datetime # Custom JSON encoder class CustomEncoder(json.JSONEncoder): def default(self, obj): if isinstance(obj, datetime): return obj.isoformat() return super().default(obj) data = {"time": datetime.now(), "name": "Alice"} json_str = json.dumps(data, cls=CustomEncoder) # Custom JSON decoder def datetime_decoder(dct): for key, value in dct.items(): try: dct[key] = datetime.fromisoformat(value) except: pass return dct loaded = json.loads(json_str, object_hook=datetime_decoder)
🔸 Using Pandas
import pandas as pd # Read CSV df = pd.read_csv("data.csv", parse_dates=['timestamp']) # Write JSON df.to_json("data.json", orient='records') # Handle large files chunk_iter = pd.read_csv("large.csv", chunksize=10000) for chunk in chunk_iter: process(chunk)
🔹 Multithreading in Python
🔸 Thread Pools
from concurrent.futures import ThreadPoolExecutor
import time
def task(n):
time.sleep(n)
return n * n
with ThreadPoolExecutor(max_workers=3) as executor:
futures = [executor.submit(task, i) for i in range(1,4)]
results = [f.result() for f in futures]
print(results) # [1, 4, 9]
🔸 Thread Synchronization
from threading import Lock
counter = 0
lock = Lock()
def increment():
global counter
with lock:
temp = counter
temp += 1
counter = temp
threads = [threading.Thread(target=increment) for _ in range(1000)]
for t in threads:
t.start()
for t in threads:
t.join()
print(counter) # 1000
🔸 Daemon Threads
def background_task():
while True:
print("Running...")
time.sleep(1)
daemon = threading.Thread(target=background_task, daemon=True)
daemon.start()
# Will terminate when main program exits
🔸 Best Practices
✓ Use thread pools instead of manual thread management
✓ Always use locks for shared resources
✓ Prefer ThreadPoolExecutor for most cases
✓ Use daemon threads for background tasks
✓ Avoid the Global Interpreter Lock (GIL) limitations
🔹 Regular Expressions (Regex)
Pattern matching using Python's re
module. Common metacharacters:
.
Any character
\d
Digit (0-9)
\w
Word character
\s
Whitespace
^
Start of string
$
End of string
[abc]
Any of a/b/c
a|b
a or b
🔸 Common Methods
import re # Match object methods text = "Date: 2023-08-15" match = re.search(r"(\d{4})-(\d{2})-(\d{2})", text) if match: print(match.group()) # 2023-08-15 print(match.groups()) # ('2023', '08', '15') print(match.start()) # 6 print(match.end()) # 16
🔸 Substitution
# Replace dates text = "Copyright 2022. Updated 2023." new_text = re.sub(r"\d{4}", "YEAR", text) print(new_text) # Copyright YEAR. Updated YEAR.
🔸 Compiled Patterns
# Precompile for reuse phone_re = re.compile(r"\(\d{3}\) \d{3}-\d{4}") text = "Call (415) 555-1234" match = phone_re.search(text) print(match.group()) # (415) 555-1234
🔸 Regex Flags
# Case-insensitive matching text = "Color or colour?" matches = re.findall(r"colou?r", text, flags=re.IGNORECASE) print(matches) # ['Color', 'colour']
🔸 Advanced Patterns
# Lookaheads and lookbehinds text = "100kg 200lb" weights = re.findall(r"\d+(?=kg)", text) # Positive lookahead print(weights) # ['100'] # Named groups date_re = r"(?P\d{4})-(?P \d{2})" match = re.search(date_re, "2023-08") print(match.groupdict()) # {'year': '2023', 'month': '08'}
🔸 Best Practices
✓ Use raw strings (r"pattern")
✓ Precompile patterns for repeated use
✓ Use verbose mode for complex patterns
pattern = re.compile(r""" \b # Word boundary [A-Z0-9._%+-]+ # Username @ [A-Z0-9.-]+ # Domain \. [A-Z]{2,} # TLD \b""", re.VERBOSE | re.IGNORECASE)
✓ Test patterns with online regex testers
🔹 Working with APIs (Requests Module)
Handle HTTP requests with Python's requests
library. Common methods:
GET
- Retrieve data
POST
- Create resource
PUT
- Update resource
DELETE
- Remove resource
PATCH
- Partial update
HEAD
- Get headers
🔸 HTTP Methods
# PUT request response = requests.put("https://api.example.com/items/1", json={"name": "new item"}) # DELETE request response = requests.delete("https://api.example.com/items/1") # PATCH request response = requests.patch("https://api.example.com/items/1", json={"price": 19.99})
🔸 Headers & Authentication
# Custom headers headers = { "User-Agent": "MyApp/1.0", "Authorization": "Bearer abc123" } response = requests.get("https://api.example.com", headers=headers) # Basic auth from requests.auth import HTTPBasicAuth response = requests.get( "https://api.example.com", auth=HTTPBasicAuth("user", "pass") )
🔸 Response Handling
response = requests.get("https://api.example.com") print(response.status_code) # 200 print(response.headers) # Response headers print(response.text[:100]) # First 100 characters print(response.json().keys()) # JSON keys print(response.raise_for_status()) # Raise exception for 4xx/5xx
🔸 Error Handling
try: response = requests.get("https://api.example.com", timeout=5) response.raise_for_status() except requests.exceptions.HTTPError as err: print(f"HTTP error: {err}") except requests.exceptions.Timeout: print("Request timed out") except requests.exceptions.RequestException as err: print(f"Request error: {err}")
🔸 Using Sessions
with requests.Session() as session:
session.headers.update({"X-API-Key": "secret"})
# Persistent settings
response1 = session.get("https://api.example.com/list")
response2 = session.post("https://api.example.com/create", json={"data": "value"})
🔸 File Uploads
files = {"file": open("report.pdf", "rb")} response = requests.post("https://api.example.com/upload", files=files)
🔸 Best Practices
✓ Always set timeouts
✓ Use sessions for multiple requests
✓ Handle exceptions properly
✓ Validate SSL certificates
✓ Rate limit your requests
# Safe request with timeout and verification
requests.get("https://api.example.com", timeout=5, verify=True)
🔹 Working with Databases (SQLite3)
🔸 Core Operations
import sqlite3 from contextlib import closing # Using context manager for connection with closing(sqlite3.connect("app.db")) as conn: with closing(conn.cursor()) as cursor: # Parameterized query cursor.execute("INSERT INTO users (name, age) VALUES (?, ?)", ("Bob", 30)) # Batch insert users = [("Charlie", 25), ("Diana", 28)] cursor.executemany("INSERT INTO users (name, age) VALUES (?, ?)", users) conn.commit()
🔸 Advanced Queries
# Foreign key support conn.execute("PRAGMA foreign_keys = ON") # Create table with relations conn.execute("""CREATE TABLE orders ( id INTEGER PRIMARY KEY, user_id INTEGER, amount REAL, FOREIGN KEY(user_id) REFERENCES users(id) )""")
🔸 Transactions
try: conn = sqlite3.connect("bank.db") conn.execute("UPDATE accounts SET balance = balance - 100 WHERE id = 1") conn.execute("UPDATE accounts SET balance = balance + 100 WHERE id = 2") conn.commit() except sqlite3.Error: conn.rollback() finally: conn.close()
🔸 Row Factories
# Access columns by name
conn.row_factory = sqlite3.Row
cursor = conn.cursor()
cursor.execute("SELECT * FROM users LIMIT 1")
row = cursor.fetchone()
print(row["name"], row["age"])
🔸 Date/Time Handling
import datetime
# Register adapters and converters
sqlite3.register_adapter(datetime.datetime, lambda dt: dt.isoformat())
sqlite3.register_converter("timestamp", lambda dt: datetime.datetime.fromisoformat(dt.decode()))
conn = sqlite3.connect(":memory:", detect_types=sqlite3.PARSE_DECLTYPES)
conn.execute("CREATE TABLE events (id INTEGER, created_at timestamp)")
🔸 Best Practices
✓ Always use parameterized queries
✓ Use context managers for connections
✓ Enable foreign key support
✓ Handle transactions explicitly
✓ Close connections properly
✓ Use row factories for named access
🔹 Web Scraping with Python
🔸 Advanced BeautifulSoup
from bs4 import BeautifulSoup import requests # Configure session session = requests.Session() session.headers.update({"User-Agent": "Mozilla/5.0"}) # Handle pagination for page in range(1, 4): url = f"https://example.com/page/{page}" response = session.get(url) soup = BeautifulSoup(response.text, "lxml") # Using lxml parser # CSS Selectors articles = soup.select("div.article > h2.title") for article in articles: print(article.get_text(strip=True)) # Extract attributes and handle missing elements prices = soup.find_all("span", class_="price") for price in prices: print(price["data-value"] if price else "N/A")
🔸 Advanced Selenium
from selenium.webdriver import Chrome from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC driver = Chrome() driver.get("https://example.com/login") # Form interaction driver.find_element(By.ID, "username").send_keys("user123") driver.find_element(By.ID, "password").send_keys("pass123") driver.find_element(By.XPATH, "//button[@type='submit']").click() # Wait for elements try: element = WebDriverWait(driver, 10).until( EC.presence_of_element_located((By.CLASS_NAME, "dashboard")) ) print("Login successful") except TimeoutError: print("Login failed") # Execute JavaScript driver.execute_script("window.scrollTo(0, document.body.scrollHeight);") driver.save_screenshot("page.png") driver.quit()
🔸 Scrapy Framework
import scrapy class QuoteSpider(scrapy.Spider): name = "quotes" start_urls = ["http://quotes.toscrape.com"] def parse(self, response): for quote in response.css("div.quote"): yield { "text": quote.css("span.text::text").get(), "author": quote.css("small.author::text").get(), } next_page = response.css("li.next a::attr(href)").get() if next_page: yield response.follow(next_page, self.parse)
🔸 Best Practices
✓ Respect robots.txt and website terms
✓ Use delays between requests (time.sleep(2))
✓ Rotate user agents and IP addresses
✓ Handle CAPTCHAs and JavaScript challenges
✓ Cache responses for development
# Proxies and headers
proxies = {"http": "http://10.10.1.10:3128"}
headers = {"User-Agent": "Mozilla/5.0 (X11; Linux x86_64)"}
response = requests.get(url, headers=headers, proxies=proxies)
🔸 Advanced Techniques
# Headless browsing from selenium.webdriver.chrome.options import Options options = Options() options.add_argument("--headless=new") driver = Chrome(options=options) # Handling JavaScript-rendered content driver.get("https://example.com") WebDriverWait(driver, 10).until( EC.presence_of_element_located((By.CLASS_NAME, "dynamic-content")) ) # Scraping tables table = driver.find_element(By.TAG_NAME, "table") rows = table.find_elements(By.TAG_NAME, "tr") for row in rows: print([cell.text for cell in row.find_elements(By.TAG_NAME, "td")])
🔹 Data Science with Python
🔸 NumPy (Numerical Computing)
import numpy as np # Array creation arr = np.array([[1, 2], [3, 4]]) # 2D array zeros = np.zeros((3, 3)) # 3x3 zero matrix range_arr = np.arange(0, 10, 2) # [0 2 4 6 8] # Array operations print(arr.shape) # (2, 2) print(arr.reshape(4)) # [1 2 3 4] print(arr.T) # Transpose print(np.dot(arr, arr)) # Matrix multiplication # Universal functions print(np.sqrt(arr)) # Element-wise square root print(np.sum(arr)) # 10 print(arr.mean(axis=0)) # Column means [2. 3.]
🔸 Pandas (Data Manipulation)
import pandas as pd # DataFrame operations df = pd.read_csv("data.csv") print(df.head(2)) # First 2 rows print(df.describe()) # Statistics print(df[df['Age'] > 25]) # Filtering print(df.groupby('City')['Salary'].mean()) # Aggregation # Handling missing data df['Age'] = df['Age'].fillna(df['Age'].mean()) df = df.dropna() # Merging DataFrames df1 = pd.DataFrame({'key': ['A', 'B'], 'val': [1, 2]}) df2 = pd.DataFrame({'key': ['A', 'B'], 'val': [3, 4]}) merged = pd.merge(df1, df2, on='key')
🔸 Matplotlib (Data Visualization)
import matplotlib.pyplot as plt # Subplots and styling fig, ax = plt.subplots(2, 1, figsize=(8, 6)) ax[0].plot([1, 2, 3], [2, 4, 3], 'ro-', label='Line 1') ax[0].set_title('Sales Data') ax[0].legend() # Histogram ax[1].hist(np.random.randn(1000), bins=30, alpha=0.5) ax[1].set_xlabel('Values') plt.tight_layout() plt.savefig('plot.png')
🔸 Scikit-learn (Machine Learning)
from sklearn.linear_model import LinearRegression
from sklearn.model_selection import train_test_split
# Model training
X = [[1], [2], [3], [4]]
y = [2, 4, 6, 8]
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2)
model = LinearRegression()
model.fit(X_train, y_train)
print(f"R² Score: {model.score(X_test, y_test):.2f}")
🔸 Seaborn (Advanced Visualization)
import seaborn as sns
# Advanced plots
tips = sns.load_dataset("tips")
sns.jointplot(x="total_bill", y="tip", data=tips, kind="reg")
sns.pairplot(tips, hue="time")
plt.show()
🔸 Best Practices
✓ Use vectorized operations in NumPy
✓ Optimize pandas with proper dtypes
✓ Handle missing data early
✓ Normalize features for ML models
✓ Use virtual environments
# Install packages # pip install numpy pandas matplotlib scikit-learn seaborn
🔹 GUI Programming with Python
🔸 Tkinter Advanced
import tkinter as tk from tkinter import ttk, messagebox class App(tk.Tk): def __init__(self): super().__init__() self.title("Advanced Tkinter") self.geometry("400x300") # Widgets self.label = ttk.Label(self, text="Enter text:") self.entry = ttk.Entry(self) self.button = ttk.Button(self, text="Submit", command=self.on_submit) self.listbox = tk.Listbox(self) # Layout self.label.pack(pady=5) self.entry.pack(pady=5) self.button.pack(pady=5) self.listbox.pack(pady=5, fill=tk.BOTH, expand=True) # Menu menubar = tk.Menu(self) file_menu = tk.Menu(menubar, tearoff=0) file_menu.add_command(label="Exit", command=self.destroy) menubar.add_cascade(label="File", menu=file_menu) self.config(menu=menubar) def on_submit(self): text = self.entry.get() if text: self.listbox.insert(tk.END, text) self.entry.delete(0, tk.END) else: messagebox.showwarning("Input Error", "Please enter text") if __name__ == "__main__": app = App() app.mainloop()
🔸 PyQt Advanced
from PyQt5.QtWidgets import (QApplication, QMainWindow, QWidget, QVBoxLayout, QLabel, QPushButton, QLineEdit, QListWidget) from PyQt5.QtCore import Qt class MainWindow(QMainWindow): def __init__(self): super().__init__() self.setWindowTitle("Advanced PyQt") self.setGeometry(100, 100, 400, 300) # Central widget central_widget = QWidget() self.setCentralWidget(central_widget) layout = QVBoxLayout() # Widgets self.label = QLabel("Enter text:") self.entry = QLineEdit() self.button = QPushButton("Submit") self.list_widget = QListWidget() # Layout layout.addWidget(self.label) layout.addWidget(self.entry) layout.addWidget(self.button) layout.addWidget(self.list_widget) central_widget.setLayout(layout) # Signals self.button.clicked.connect(self.on_submit) self.entry.returnPressed.connect(self.on_submit) # Menu menu = self.menuBar() file_menu = menu.addMenu("File") exit_action = file_menu.addAction("Exit") exit_action.triggered.connect(self.close) def on_submit(self): text = self.entry.text() if text: self.list_widget.addItem(text) self.entry.clear() else: self.statusBar().showMessage("Please enter text", 3000) if __name__ == "__main__": app = QApplication([]) window = MainWindow() window.show() app.exec_()
🔸 Best Practices
✓ Separate UI and business logic
✓ Use threading for long-running tasks
✓ Follow platform-specific design guidelines
✓ Implement error handling
✓ Use layout managers (grid/pack in Tkinter, QLayout in PyQt)
# Threading example for PyQt from PyQt5.QtCore import QThread class Worker(QThread): def run(self): # Long-running task self.sleep(5) # Usage worker = Worker() worker.start()
🔸 Other GUI Libraries
Kivy: Cross-platform, mobile-friendly
from kivy.app import App from kivy.uix.button import Button class MyApp(App): def build(self): return Button(text='Hello Kivy') MyApp().run()
PySimpleGUI: Simplified wrapper
import PySimpleGUI as sg layout = [[sg.Text("Hello")], [sg.Button("OK")]] window = sg.Window("Demo", layout) event, values = window.read()
🔹 Machine Learning with Python
🔸 Scikit-learn Pipeline
from sklearn.pipeline import make_pipeline from sklearn.preprocessing import StandardScaler from sklearn.svm import SVC # Create pipeline pipe = make_pipeline( StandardScaler(), SVC(kernel='rbf') ) # Train and evaluate pipe.fit(X_train, y_train) score = pipe.score(X_test, y_test)
🔸 TensorFlow Training
# Model training model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['accuracy']) history = model.fit(X_train, y_train, epochs=10, validation_split=0.2) # Evaluation test_loss, test_acc = model.evaluate(X_test, y_test) print(f"Test accuracy: {test_acc:.2f}") # Save model model.save("model.h5")
🔸 PyTorch Training Loop
import torch.optim as optim criterion = nn.MSELoss() optimizer = optim.Adam(model.parameters(), lr=0.001) for epoch in range(100): # Forward pass outputs = model(inputs) loss = criterion(outputs, labels) # Backward pass optimizer.zero_grad() loss.backward() optimizer.step() if (epoch+1) % 10 == 0: print(f'Epoch {epoch+1}, Loss: {loss.item():.4f}')
🔸 Model Evaluation
from sklearn.metrics import classification_report # Classification report y_pred = model.predict(X_test) print(classification_report(y_test, y_pred)) # Confusion matrix from sklearn.metrics import confusion_matrix print(confusion_matrix(y_test, y_pred))
🔸 Best Practices
✓ Split data into train/validation/test sets
✓ Normalize/standardize features
✓ Use cross-validation
✓ Monitor training with TensorBoard
✓ Version control your models
# Data splitting
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.2, random_state=42)
🔸 Hyperparameter Tuning
from sklearn.model_selection import GridSearchCV params = {'C': [0.1, 1, 10], 'gamma': [1, 0.1, 0.01]} grid = GridSearchCV(SVC(), params, cv=5) grid.fit(X_train, y_train) print(f"Best params: {grid.best_params_}")
🔹 Cybersecurity with Python
🔸 Secure Password Hashing
import bcrypt import secrets # Generate secure password hash password = "user_password".encode() salt = bcrypt.gensalt(rounds=12) hashed = bcrypt.hashpw(password, salt) # Verify password if bcrypt.checkpw(password, hashed): print("Access granted")
🔸 RSA Encryption
from cryptography.hazmat.primitives.asymmetric import rsa, padding from cryptography.hazmat.primitives import hashes # Generate key pair private_key = rsa.generate_private_key(public_exponent=65537, key_size=2048) public_key = private_key.public_key() # Encrypt with public key message = b"Secret Message" ciphertext = public_key.encrypt( message, padding.OAEP( mgf=padding.MGF1(algorithm=hashes.SHA256()), algorithm=hashes.SHA256(), label=None ) ) # Decrypt with private key plaintext = private_key.decrypt( ciphertext, padding.OAEP( mgf=padding.MGF1(algorithm=hashes.SHA256()), algorithm=hashes.SHA256(), label=None ) )
🔸 Digital Signatures
from cryptography.hazmat.primitives.asymmetric import padding from cryptography.hazmat.primitives import hashes # Sign message signature = private_key.sign( message, padding.PSS( mgf=padding.MGF1(hashes.SHA256()), salt_length=padding.PSS.MAX_LENGTH ), hashes.SHA256() ) # Verify signature try: public_key.verify( signature, message, padding.PSS( mgf=padding.MGF1(hashes.SHA256()), salt_length=padding.PSS.MAX_LENGTH ), hashes.SHA256() ) print("Signature valid") except InvalidSignature: print("Signature invalid")
🔸 SSL/TLS Verification
import requests import ssl # Secure requests response = requests.get("https://api.example.com", verify=True) # Create SSL context context = ssl.create_default_context() context.check_hostname = True context.verify_mode = ssl.CERT_REQUIRED
🔸 Security Utilities
# Secure random generation import secrets token = secrets.token_urlsafe(32) # 256-bit secure URL-safe token # Input validation import re def sanitize_input(input_str): return re.sub(r'[^a-zA-Z0-9]', '', input_str) # Secret management from getpass import getpass
🔸 Best Practices
✓ Use bcrypt/argon2 for password storage
✓ Never store secrets in code
✓ Validate all user inputs
✓ Use HTTPS for network communication
✓ Rotate encryption keys regularly
# Dependency security check # pip install safety # safety check