← Tutorials ☕ Java 🧩 DSA 🌿 Spring Boot 🚀 DevOps 🗂 MySQL 🏗 System Design ❓ FAQ 🌐 HTML 🔇 JavaScript ⚛ ReactJS 🌻 NodeJS 🐍 Python 🍏 MongoDB 📋 Cheatsheet
Tutorials › Python

Introduction to Python

Beginner · 5 min read

Python is a high-level, dynamically typed, general-purpose language known for its clean, readable syntax. It is used in web development (Django/Flask/FastAPI), data science, machine learning, automation, scripting, and more.

Why Python?

  • Clean, readable syntax — feels like English
  • Huge standard library + 400,000+ packages on PyPI
  • Dominant in data science, ML (NumPy, Pandas, TensorFlow)
  • Excellent for scripting and automation
  • CPython (reference), PyPy (fast JIT), Jython (JVM)
  • Current version: Python 3.12+

Running Python

# Check version python3 --version # Run a script python3 hello.py # Interactive REPL python3 >>> print("Hello, World!") Hello, World! # hello.py print("Hello, World!")
💡 Python uses indentation (4 spaces) to define code blocks — there are no curly braces. Consistent indentation is mandatory, not optional.

Variables & Data Types

Beginner · 8 min read

# No type declaration needed — Python infers types name = "Aftab" # str age = 28 # int salary = 75000.50 # float is_active = True # bool (capital T/F) nothing = None # NoneType (like null) big = 10 ** 100 # int — Python has arbitrary precision! # Multiple assignment x = y = z = 0 a, b, c = 1, 2, 3 a, *rest = [1, 2, 3, 4] # a=1, rest=[2,3,4] # type() and isinstance() type(name) # <class 'str'> isinstance(age, int) # True # Type conversion int("42") # 42 float("3.14") # 3.14 str(100) # '100' bool(0) # False (0, "", [], {}, None are falsy) # Strings — immutable s = "Hello, World!" s[0] # 'H' s[-1] # '!' s[0:5] # 'Hello' (slicing) s.lower() # 'hello, world!' s.upper() # 'HELLO, WORLD!' s.split(', ') # ['Hello', 'World!'] ' hello '.strip() # 'hello' s.replace('World', 'Python') # f-strings (Python 3.6+) — preferred msg = f"Name: {name}, Age: {age:.2f}" expr = f"2 + 2 = {2 + 2}" # expressions inside {}

Operators

Beginner · 6 min read

# Arithmetic 10 + 3 # 13 10 - 3 # 7 10 * 3 # 30 10 / 3 # 3.333... (always float) 10 // 3 # 3 (floor division) 10 % 3 # 1 (modulus) 2 ** 10 # 1024 (exponentiation) # Comparison 5 == 5 # True 5 != 6 # True 5 > 3 # True 5 <= 5 # True # Chained comparison (Pythonic!) 1 < x < 10 # True if x in (1,10) # Logical True and False # False True or False # True not True # False # Identity & Membership x is None # True if x is None (identity check) x is not None 'hello' in 'hello world' # True 3 in [1, 2, 3] # True 'key' not in my_dict # True # Walrus operator := (Python 3.8+) — assign in expression while chunk := f.read(1024): process(chunk)

Control Flow

Beginner · 8 min read

# if / elif / else score = 85 if score >= 90: grade = 'A' elif score >= 75: grade = 'B' else: grade = 'C' # Inline ternary label = 'Pass' if score >= 50 else 'Fail' # for loop (iterates over any iterable) for i in range(5): # 0,1,2,3,4 print(i) for i in range(2, 10, 2): # 2,4,6,8 print(i) # for + enumerate for idx, val in enumerate(['a', 'b', 'c'], start=1): print(f"{idx}: {val}") # for + zip (iterate parallel iterables) for name, score in zip(names, scores): print(f"{name}: {score}") # while n = 0 while n < 5: n += 1 # break, continue, else (for/while with else — Pythonic) for i in range(10): if i == 5: break else: print("Loop completed without break") # match statement (Python 3.10+ — structural pattern matching) match command: case "quit": quit_game() case "start": start_game() case _: print("Unknown command")

Functions

Beginner · 10 min read

def greet(name, greeting="Hello"): """Docstring: greet a user.""" return f"{greeting}, {name}!" greet("Aftab") # Hello, Aftab! greet("Aftab", "Hi") # Hi, Aftab! greet(greeting="Hey", name="Aftab") # keyword args # *args — variable positional arguments def total(*nums): return sum(nums) total(1, 2, 3) # 6 # **kwargs — variable keyword arguments def create_user(**fields): return fields create_user(name="Aftab", role="admin") # Lambda — anonymous one-liner function square = lambda x: x ** 2 add = lambda a, b: a + b numbers = [3, 1, 4, 1, 5] numbers.sort(key=lambda x: -x) # sort descending # Higher-order functions list(map(lambda x: x*2, [1,2,3])) # [2,4,6] list(filter(lambda x: x%2==0, [1,2,3,4])) # [2,4] sorted(users, key=lambda u: u['name']) # Unpacking into function calls args = (1, 2) kwargs = {'greeting': 'Hey'} greet(*args) # positional unpack greet(**kwargs) # keyword unpack

Lists & Tuples

Beginner · 10 min read

# List — mutable, ordered, allows duplicates fruits = ['apple', 'banana', 'cherry'] fruits[0] # 'apple' fruits[-1] # 'cherry' fruits[1:3] # ['banana','cherry'] fruits[::-1] # reversed fruits.append('date') fruits.insert(1, 'avocado') fruits.extend(['elderberry', 'fig']) fruits.remove('banana') # remove by value fruits.pop() # remove & return last fruits.pop(0) # remove & return at index fruits.index('cherry') # find index fruits.count('apple') # frequency fruits.sort() # in-place sort sorted(fruits) # returns new sorted list fruits.reverse() len(fruits) # length # Tuple — immutable, ordered point = (3, 4) single = (42,) # trailing comma makes it a tuple x, y = point # unpacking print(point[0]) # 3 # Named tuple from collections import namedtuple Point = namedtuple('Point', ['x', 'y']) p = Point(3, 4) p.x, p.y # 3, 4

Sets & Dictionaries

Beginner · 10 min read

# Set — unordered, unique values, mutable s = {1, 2, 3, 3} # {1, 2, 3} s.add(4) s.discard(2) # no error if not found s.remove(3) # raises KeyError if not found len(s) a = {1, 2, 3} b = {2, 3, 4} a | b # union: {1,2,3,4} a & b # intersection: {2,3} a - b # difference: {1} a ^ b # symmetric diff: {1,4} # Dict — key-value, ordered (Python 3.7+), mutable user = { 'name': 'Aftab', 'age': 28, 'city': 'Noida' } user['name'] # 'Aftab' user.get('email', 'N/A') # 'N/A' (no KeyError) user['email'] = 'a@b.com' del user['city'] user.pop('age') # removes & returns value user.keys() # dict_keys(['name','email']) user.values() user.items() # dict_items([('name','Aftab'),...]) user.update({'role': 'admin'}) # Dict comprehension squares = {x: x**2 for x in range(5)} # {0:0, 1:1, 2:4...} # defaultdict from collections import defaultdict word_count = defaultdict(int) for w in words: word_count[w] += 1 # no KeyError

Comprehensions

Intermediate · 7 min read

# List comprehension — [expression for item in iterable if condition] squares = [x**2 for x in range(10)] evens = [x for x in range(20) if x % 2 == 0] flat = [n for row in matrix for n in row] # flatten 2D upper = [s.upper() for s in names if s.startswith('A')] # Dict comprehension inverted = {v: k for k, v in my_dict.items()} filtered = {k: v for k, v in d.items() if v > 0} # Set comprehension unique_len = {len(word) for word in words} # Generator expression — lazy, memory-efficient gen = (x**2 for x in range(1_000_000)) # no list in memory! next(gen) # 0 (compute one at a time) sum(x**2 for x in range(100)) # pass generator to built-ins
💡 Use generator expressions inside sum(), any(), all(), max(), min() instead of list comprehensions to avoid building an intermediate list.

Classes & Objects

Intermediate · 10 min read

class BankAccount: # Class variable (shared by all instances) bank_name = "SDS Bank" _accounts = 0 def __init__(self, owner, balance=0): # Instance variables self.owner = owner self._balance = balance # _prefix: convention for private BankAccount._accounts += 1 def deposit(self, amount): if amount <= 0: raise ValueError("Amount must be positive") self._balance += amount return self # method chaining def withdraw(self, amount): if amount > self._balance: raise ValueError("Insufficient funds") self._balance -= amount return self # Property — controlled attribute access @property def balance(self): return self._balance # Class method @classmethod def total_accounts(cls): return cls._accounts # Static method (no self or cls) @staticmethod def validate_amount(amount): return amount > 0 acc = BankAccount("Aftab", 1000) acc.deposit(500).withdraw(200) # chaining acc.balance # 1300

Inheritance & Polymorphism

Intermediate · 10 min read

class Shape: def __init__(self, color="white"): self.color = color def area(self): raise NotImplementedError("Subclasses must implement area()") def describe(self): return f"A {self.color} shape with area {self.area():.2f}" class Circle(Shape): def __init__(self, radius, **kwargs): super().__init__(**kwargs) self.radius = radius def area(self): return 3.14159 * self.radius ** 2 class Rectangle(Shape): def __init__(self, w, h, **kwargs): super().__init__(**kwargs) self.w, self.h = w, h def area(self): return self.w * self.h # Polymorphism — same interface, different behavior shapes = [Circle(5, color='red'), Rectangle(4, 6)] for s in shapes: print(s.describe()) # works for all Shape subclasses # isinstance / issubclass isinstance(Circle(1), Shape) # True issubclass(Circle, Shape) # True # Abstract Base Class (enforces interface) from abc import ABC, abstractmethod class Vehicle(ABC): @abstractmethod def start(self): ...

Dunder / Magic Methods

Intermediate · 10 min read

Dunder (double underscore) methods let you define how your objects behave with built-in Python operations like +, len(), print(), comparisons, and more.

class Vector: def __init__(self, x, y): self.x, self.y = x, y def __repr__(self): # for developers: repr(obj) return f"Vector({self.x}, {self.y})" def __str__(self): # for users: str(obj) / print() return f"({self.x}, {self.y})" def __add__(self, other): # v1 + v2 return Vector(self.x + other.x, self.y + other.y) def __mul__(self, scalar): # v * 3 return Vector(self.x * scalar, self.y * scalar) def __len__(self): # len(v) return int((self.x**2 + self.y**2) ** 0.5) def __eq__(self, other): # v1 == v2 return self.x == other.x and self.y == other.y def __bool__(self): # bool(v) / if v: return bool(self.x or self.y) def __contains__(self, val): # val in v return val in (self.x, self.y) v1 = Vector(2, 3) v2 = Vector(1, 4) v1 + v2 # Vector(3, 7) print(v1) # (2, 3) len(v1) # 3

Decorators

Advanced · 10 min read

A decorator is a function that wraps another function to add behavior without modifying it.

# Basic decorator def timer(func): import time def wrapper(*args, **kwargs): start = time.time() result = func(*args, **kwargs) print(f"{func.__name__} took {time.time()-start:.3f}s") return result return wrapper @timer # equivalent to: my_func = timer(my_func) def slow_function(): ... # Decorator with arguments def retry(times=3, delay=1): def decorator(func): import time, functools @functools.wraps(func) # preserve metadata def wrapper(*args, **kwargs): for i in range(times): try: return func(*args, **kwargs) except Exception as e: if i == times - 1: raise time.sleep(delay) return wrapper return decorator @retry(times=5, delay=2) def call_external_api(): ... # Class decorator def singleton(cls): instances = {} def get_instance(*args, **kwargs): if cls not in instances: instances[cls] = cls(*args, **kwargs) return instances[cls] return get_instance @singleton class DatabaseConnection: ...

Generators & Iterators

Advanced · 8 min read

# Generator function — uses yield def fibonacci(): a, b = 0, 1 while True: yield a a, b = b, a + b gen = fibonacci() [next(gen) for _ in range(8)] # [0,1,1,2,3,5,8,13] # Finite generator with return def chunked(lst, size): for i in range(0, len(lst), size): yield lst[i:i+size] list(chunked(range(10), 3)) # [[0,1,2],[3,4,5],[6,7,8],[9]] # Custom iterator protocol class Countdown: def __init__(self, n): self.n = n def __iter__(self): return self def __next__(self): if self.n <= 0: raise StopIteration self.n -= 1 return self.n + 1 for n in Countdown(3): print(n) # 3, 2, 1 # itertools — powerful iterator tools from itertools import chain, islice, groupby, product, combinations list(chain([1,2], [3,4])) # [1,2,3,4] list(islice(fibonacci(), 10)) # first 10 Fibonacci numbers list(combinations('ABC', 2)) # [('A','B'),('A','C'),('B','C')]

Context Managers

Advanced · 8 min read

Context managers handle setup and teardown automatically — used with the with statement. Most common use: file handling, database connections, locks.

# Using a context manager with open('file.txt', 'r') as f: content = f.read() # file is auto-closed even if exception occurs # Custom context manager via class class Timer: import time def __enter__(self): self.start = time.time() return self def __exit__(self, exc_type, exc_val, exc_tb): print(f"Elapsed: {time.time() - self.start:.3f}s") return False # False = don't suppress exceptions with Timer() as t: run_heavy_task() # contextlib — easier custom managers from contextlib import contextmanager @contextmanager def db_transaction(connection): try: yield connection connection.commit() except: connection.rollback() raise with db_transaction(conn) as db: db.execute("INSERT INTO ...")

File Handling

Intermediate · 8 min read

# Reading files with open('data.txt', 'r', encoding='utf-8') as f: content = f.read() # entire file as string lines = f.readlines() # list of lines line = f.readline() # one line for line in f: # memory-efficient iteration print(line.strip()) # Writing files with open('output.txt', 'w') as f: f.write("Hello\n") f.writelines(["line1\n", "line2\n"]) # Append with open('log.txt', 'a') as f: f.write("New log entry\n") # JSON import json with open('config.json') as f: config = json.load(f) with open('out.json', 'w') as f: json.dump(data, f, indent=2) # CSV import csv with open('data.csv') as f: reader = csv.DictReader(f) rows = [row for row in reader] # pathlib — modern file paths (Python 3.4+) from pathlib import Path p = Path('data/users.json') p.exists() p.read_text() # one-liner read p.write_text("hello") # one-liner write p.parent # Path('data') p.glob('*.json') # pattern matching

Error Handling

Intermediate · 8 min read

# Basic try/except try: result = 10 / 0 except ZeroDivisionError: print("Cannot divide by zero") except (TypeError, ValueError) as e: print(f"Error: {e}") except Exception as e: print(f"Unexpected: {e}") raise # re-raise else: print("No exception occurred") # runs if no except triggered finally: print("Always runs — cleanup here") # Custom exceptions class ValidationError(ValueError): def __init__(self, field, message): super().__init__(f"[{field}] {message}") self.field = field raise ValidationError("email", "Invalid format") # Exception chaining try: connect_db() except ConnectionError as e: raise RuntimeError("App startup failed") from e # Common built-in exceptions # ValueError, TypeError, KeyError, IndexError # AttributeError, FileNotFoundError, ImportError # OSError, PermissionError, TimeoutError # StopIteration, RecursionError, MemoryError

Modules & Packages

Intermediate · 8 min read

# Importing import math import os, sys from pathlib import Path from datetime import datetime, timedelta import numpy as np # alias # Creating a module (utils.py) def add(a, b): return a + b PI = 3.14159 # Package structure myapp/ __init__.py # makes it a package models.py utils.py api/ __init__.py routes.py # pip — package manager pip install requests pip install "fastapi==0.100.0" pip freeze > requirements.txt pip install -r requirements.txt # Virtual environment (venv) python3 -m venv venv source venv/bin/activate # Mac/Linux venv\Scripts\activate.bat # Windows pip install flask deactivate # Useful standard library modules import os # OS operations import sys # Python runtime import re # regex import json # JSON import datetime # dates import random # random numbers import hashlib # hashing import logging # logging import threading # threads import subprocess # shell commands

Regular Expressions

Advanced · 8 min read

import re # Compile for reuse pattern = re.compile(r'\d{4}-\d{2}-\d{2}') # ISO date # Functions re.match(r'\d+', '123abc') # match at START re.search(r'\d+', 'abc123') # search ANYWHERE re.findall(r'\d+', 'a1b2c3') # ['1','2','3'] re.sub(r'\s+', ' ', text) # replace multiple spaces re.split(r'[,;]', 'a,b;c') # ['a','b','c'] # Groups m = re.search(r'(\d{4})-(\d{2})-(\d{2})', '2024-06-15') m.group(0) # '2024-06-15' (full match) m.group(1) # '2024' # Named groups m = re.match(r'(?P<year>\d{4})-(?P<month>\d{2})', '2024-06') m.group('year') # '2024' # Flags re.search(r'hello', text, re.IGNORECASE | re.MULTILINE) # Common patterns EMAIL = r'^[\w.+-]+@[\w-]+\.\w{2,}$' PHONE = r'^\+?[\d\s\-]{10,13}$' URL = r'https?://[^\s]+' IP = r'\b\d{1,3}(\.\d{1,3}){3}\b'

JSON & HTTP APIs

Intermediate · 8 min read

import json, requests # JSON — serialisation data = {'name': 'Aftab', 'scores': [95, 87]} json_str = json.dumps(data, indent=2) # dict → JSON string back = json.loads(json_str) # JSON string → dict # HTTP with requests library # pip install requests # GET r = requests.get( 'https://api.github.com/users/torvalds', headers={'Accept': 'application/json'}, timeout=10 ) r.raise_for_status() # raise HTTPError if 4xx/5xx user = r.json() # parse JSON response # POST r = requests.post( 'https://api.example.com/users', json={'name': 'Aftab', 'email': 'a@b.com'}, headers={'Authorization': 'Bearer TOKEN'} ) # Session (reuse TCP connection) with requests.Session() as s: s.headers.update({'Authorization': 'Bearer TOKEN'}) r1 = s.get('/api/profile') r2 = s.get('/api/orders')

Async Python (asyncio)

Advanced · 10 min read

Python's asyncio enables concurrent I/O without threads. Ideal for API calls, database queries, and web servers (FastAPI, aiohttp).

import asyncio # async def creates a coroutine async def fetch_user(user_id): await asyncio.sleep(1) # simulate I/O return {'id': user_id, 'name': 'Aftab'} # Run a single coroutine user = asyncio.run(fetch_user(1)) # gather — run concurrently async def main(): users = await asyncio.gather( fetch_user(1), fetch_user(2), fetch_user(3) ) print(users) # all 3 complete in ~1s, not 3s asyncio.run(main()) # aiohttp for async HTTP import aiohttp async def get_data(url): async with aiohttp.ClientSession() as session: async with session.get(url) as resp: return await resp.json() # asyncio Task — schedule without waiting async def background(): task = asyncio.create_task(slow_operation()) await fast_operation() # runs while slow_op is pending await task # wait for it here

Type Hints

Advanced · 8 min read

Python 3.5+ supports type hints — annotations that document expected types. They are checked by tools like mypy and Pyright, not at runtime.

from typing import Optional, Union, List, Dict, Tuple, Callable, Any from __future__ import annotations # deferred evaluation (older Python) # Function signatures def greet(name: str, times: int = 1) -> str: return (name + ' ') * times # Modern generics (Python 3.9+) def first(items: list[int]) -> int | None: # | for Union return items[0] if items else None # Type aliases UserId = int UserDict = dict[str, str | int] # Callable types def apply(func: Callable[[int], int], val: int) -> int: return func(val) # TypedDict — typed dictionaries from typing import TypedDict class User(TypedDict): name: str age: int email: str # dataclass — typed, auto-generates __init__, __repr__ from dataclasses import dataclass, field @dataclass class Product: name: str price: float tags: list[str] = field(default_factory=list) p = Product("Widget", 9.99) print(p) # Product(name='Widget', price=9.99, tags=[])