1. Introduction to Python

Python is a high-level, interpreted programming language created by Guido van Rossum in 1991. Known for its simple, readable syntax, Python is one of the most popular languages worldwide.

Why Learn Python?

Python vs Other Languages

Feature Python C Java
Learning Curve Easy Moderate Moderate
Speed Slower Fastest Fast
Typing Dynamic Static Static
Use Cases AI, Web, Data OS, Embedded Enterprise, Android

Python 2 vs Python 3

📌 Important: Python 2 is outdated (EOL since 2020). Always use Python 3! This tutorial covers Python 3.

2. Environment Setup

Installation

Windows:

Download from python.org and check "Add Python to PATH"

macOS:

brew install python3

Linux:

sudo apt-get install python3

First Program

# Save as hello.py
print("Hello, World!")

Run in terminal:

python3 hello.py

Python Interpreter

# Start interactive Python
python3

# Try commands:
>>> 2 + 3
5
>>> print("Hi")
Hi
>>> exit()
💡 Recommended IDEs: VS Code, PyCharm, Jupyter Notebook, Thonny (beginners)

3. Basic Syntax

Python Indentation

Python uses indentation (spaces) instead of curly braces to define code blocks.

# Correct indentation (4 spaces)
if 5 > 3:
    print("Five is greater than three")
    print("This is also inside the if")
print("This is outside")

Comments

# This is a single-line comment

"""
This is a
multi-line comment (docstring)
"""

'Single quotes work too'

Multiple Statements per Line

# Using semicolons (not recommended)
x = 5; y = 10; print(x + y)
📌 PEP 8 Style Guide: Use 4 spaces for indentation, 79 characters per line, blank lines between functions.

4. Variables and Data Types

Variables in Python are created when you assign a value. No declaration needed!

Variable Assignment

# Simple assignment
name = "Alice"
age = 25
height = 5.6
is_student = True

# Multiple assignment
x, y, z = 1, 2, 3

# Same value to multiple variables
a = b = c = 0

# Type checking
print(type(name))   # <class 'str'>
print(type(age))    # <class 'int'>
print(type(height)) # <class 'float'>

Data Types

Type Example Mutable?
int x = 42 No
float x = 3.14 No
str x = "hello" No
bool x = True No
list x = [1, 2, 3] Yes
tuple x = (1, 2, 3) No
dict x = {"a": 1} Yes
set x = {1, 2, 3} Yes

Type Conversion

# String to int
age = int("25")

# Int to string
score = str(100)

# Int to float
pi = float(3)

# Float to int (truncates)
n = int(3.7)  # 3
⚠️ Naming Rules:
  • Must start with letter or underscore
  • Can contain letters, numbers, underscores
  • Case-sensitive (name ≠ Name)
  • Cannot use Python keywords (if, for, while, etc.)

5. Input/Output

Output with print()

# Basic print
print("Hello World")

# Multiple values
print("Name:", "Alice", "Age:", 25)

# Using f-strings (Python 3.6+)
name = "Alice"
age = 25
print(f"Name: {name}, Age: {age}")

# Using format()
print("Name: {}, Age: {}".format(name, age))

# End parameter
print("Hello", end=" ")
print("World")  # Output: Hello World

Input with input()

# Always returns a string
name = input("Enter your name: ")
print(f"Hello, {name}!")

# Convert to int
age = int(input("Enter your age: "))

# Convert to float
height = float(input("Enter height: "))
📌 Tip: input() always returns a string. Use int() or float() to convert.

6. Operators

Arithmetic Operators

x = 10
y = 3

print(x + y)   # 13  (addition)
print(x - y)   # 7   (subtraction)
print(x * y)   # 30  (multiplication)
print(x / y)   # 3.333 (division)
print(x // y)  # 3   (floor division)
print(x % y)   # 1   (modulus)
print(x ** y)  # 1000 (power)

Comparison Operators

print(5 == 5)   # True
print(5 != 3)   # True
print(5 > 3)    # True
print(5 < 3)    # False
print(5 >= 5)   # True
print(5 <= 3)   # False

Logical Operators

print(True and False)  # False
print(True or False)   # True
print(not True)        # False

Membership Operators

fruits = ["apple", "banana", "cherry"]

print("apple" in fruits)   # True
print("grape" not in fruits) # True

Identity Operators

a = [1, 2, 3]
b = [1, 2, 3]
c = a

print(a is b)      # False (different objects)
print(a is c)      # True (same object)
print(a is not b)  # True

7. Conditional Statements

if Statement

age = 18

if age >= 18:
    print("You are an adult")

if-else

score = 75

if score >= 50:
    print("Passed!")
else:
    print("Failed.")

if-elif-else

score = 85

if score >= 90:
    print("Grade: A")
elif score >= 80:
    print("Grade: B")
elif score >= 70:
    print("Grade: C")
elif score >= 60:
    print("Grade: D")
else:
    print("Grade: F")

Nested if

num = 15

if num > 0:
    if num % 2 == 0:
        print("Positive even")
    else:
        print("Positive odd")
else:
    print("Not positive")

Ternary Operator

age = 20
status = "adult" if age >= 18 else "minor"
print(status)  # adult

8. Loops

for Loop

# Iterate over range
for i in range(5):
    print(i)  # 0, 1, 2, 3, 4

# Range with start, stop, step
for i in range(1, 10, 2):
    print(i)  # 1, 3, 5, 7, 9

# Iterate over list
fruits = ["apple", "banana", "cherry"]
for fruit in fruits:
    print(fruit)

# Iterate with index
for i, fruit in enumerate(fruits):
    print(f"{i}: {fruit}")

while Loop

count = 0
while count < 5:
    print(count)
    count += 1

Loop Control

# break - exit loop
for i in range(10):
    if i == 5:
        break
    print(i)  # 0, 1, 2, 3, 4

# continue - skip iteration
for i in range(10):
    if i % 2 == 0:
        continue
    print(i)  # 1, 3, 5, 7, 9

# pass - do nothing
for i in range(5):
    if i == 3:
        pass  # Placeholder
    print(i)

else in Loops

for i in range(5):
    if i == 10:
        break
else:
    print("Loop completed without break")

9. Functions

Basic Function

def greet(name):
    print(f"Hello, {name}!")

greet("Alice")

Return Value

def add(a, b):
    return a + b

result = add(5, 3)
print(result)  # 8

Default Parameters

def greet(name, greeting="Hello"):
    print(f"{greeting}, {name}!")

greet("Alice")           # Hello, Alice!
greet("Bob", "Hi")      # Hi, Bob!

*args and **kwargs

def sum_all(*args):
    return sum(args)

print(sum_all(1, 2, 3, 4))  # 10

def print_info(**kwargs):
    for key, value in kwargs.items():
        print(f"{key}: {value}")

print_info(name="Alice", age=25)

Lambda Functions

# Anonymous one-line functions
add = lambda a, b: a + b
print(add(5, 3))  # 8

# Used with map, filter
nums = [1, 2, 3, 4, 5]
squares = list(map(lambda x: x**2, nums))
evens = list(filter(lambda x: x % 2 == 0, nums))

Scope

x = 10  # Global

def my_func():
    x = 20  # Local
    print(x)  # 20

my_func()
print(x)  # 10 (global unchanged)

10. Lists

Lists are ordered, mutable collections that can hold any data type.

List Operations

# Create list
fruits = ["apple", "banana", "cherry"]

# Access
print(fruits[0])    # apple
print(fruits[-1])   # cherry

# Slicing
print(fruits[0:2])  # ['apple', 'banana']

# Modify
fruits[0] = "avocado"

# Add
fruits.append("date")
fruits.insert(1, "apricot")
fruits.extend(["elderberry", "fig"])

# Remove
fruits.remove("banana")
fruits.pop()       # Removes last
fruits.pop(0)     # Removes first
del fruits[0]

# Other methods
fruits.sort()
fruits.reverse()
fruits.copy()
fruits.clear()
len(fruits)
min(fruits)
max(fruits)

List Comprehension

# Basic
squares = [x**2 for x in range(10)]

# With condition
evens = [x for x in range(20) if x % 2 == 0]

# Nested
matrix = [[i*3+j for j in range(3)] for i in range(3)]

11. Tuples

Tuples are ordered, immutable collections. Use when data shouldn't change.

# Create tuple
colors = ("red", "green", "blue")

# Access
print(colors[0])    # red

# Unpacking
r, g, b = colors
print(r)  # red

# Single element tuple needs comma
single = (42,)

# Tuple methods
colors.count("red")
colors.index("green")

# Can't modify!
# colors[0] = "yellow"  # Error!
📌 Tuples vs Lists: Tuples are faster and use less memory. Use them for fixed data like coordinates, RGB colors, database records.

12. Dictionaries

Dictionaries store key-value pairs. Similar to hash maps in other languages.

# Create dictionary
person = {
    "name": "Alice",
    "age": 25,
    "city": "New York"
}

# Access
print(person["name"])        # Alice
print(person.get("phone", "N/A"))  # N/A

# Modify
person["age"] = 26
person["email"] = "alice@email.com"

# Remove
del person["city"]
person.pop("email")

# Methods
person.keys()
person.values()
person.items()
person.update({"phone": "123-456"})
person.copy()
person.clear()

Dictionary Comprehension

squares = {x: x**2 for x in range(5)}
# {0: 0, 1: 1, 2: 4, 3: 9, 4: 16}

13. Sets

Sets are unordered collections of unique elements.

# Create set
nums = {1, 2, 3, 4, 5}

# Remove duplicates
unique = list(set([1, 1, 2, 2, 3]))

# Add/Remove
nums.add(6)
nums.remove(1)
nums.discard(10)  # No error if not found

# Set operations
a = {1, 2, 3}
b = {3, 4, 5}

print(a | b)   # Union: {1,2,3,4,5}
print(a & b)   # Intersection: {3}
print(a - b)   # Difference: {1,2}
print(a ^ b)   # Symmetric diff: {1,2,4,5}

14. Strings

# String creation
s1 = "Hello"
s2 = 'World'
s3 = """Multi-line
string"""

# Slicing
s = "Hello, World!"
print(s[0:5])    # Hello
print(s[::-1])   # !dlroW ,olleH

# Methods
s.upper()        # HELLO, WORLD!
s.lower()        # hello, world!
s.strip()        # Remove whitespace
s.split(", ")   # ['Hello', 'World!']
s.replace("World", "Python")
s.find("World")  # 7
s.count("l")    # 3
s.startswith("Hello")  # True
s.endswith("!")         # True

# Check
"Hello" in s   # True
s.isdigit()     # False
s.isalpha()     # False

# Formatting
name = "Alice"
print(f"Hello, {name}!")        # f-string
print("Hello, {}!".format(name))  # format
print("Hello, %s!" % name)      # % formatting

15. File I/O

# Write to file
with open("file.txt", "w") as f:
    f.write("Hello, World!\n")
    f.write("Second line\n")

# Read from file
with open("file.txt", "r") as f:
    content = f.read()
    print(content)

# Read line by line
with open("file.txt", "r") as f:
    for line in f:
        print(line.strip())

# Append
with open("file.txt", "a") as f:
    f.write("New line\n")

File Modes

Mode Description
"r" Read only (default)
"w" Write (creates/truncates)
"a" Append
"x" Create (error if exists)
"r+" Read and write

16. Error Handling

try:
    num = int(input("Enter number: "))
    result = 10 / num
except ValueError:
    print("Invalid input!")
except ZeroDivisionError:
    print("Cannot divide by zero!")
except Exception as e:
    print(f"Error: {e}")
else:
    print(f"Result: {result}")
finally:
    print("This always runs")

Raising Exceptions

def set_age(age):
    if age < 0:
        raise ValueError("Age cannot be negative")
    return age

17. Object-Oriented Programming

class Dog:
    # Class attribute
    species = "Canis familiaris"
    
    # Constructor
    def __init__(self, name, age):
        self.name = name
        self.age = age
    
    # Instance method
    def bark(self):
        return f"{self.name} says Woof!"
    
    # String representation
    def __str__(self):
        return f"{self.name} is {self.age} years old"

# Create object
dog = Dog("Rex", 5)
print(dog.bark())    # Rex says Woof!
print(dog)           # Rex is 5 years old
print(dog.species)   # Canis familiaris

Inheritance

class Animal:
    def __init__(self, name):
        self.name = name
    
    def speak(self):
        raise NotImplementedError

class Cat(Animal):
    def speak(self):
        return "Meow!"

class Dog(Animal):
    def speak(self):
        return "Woof!"

Properties

class Circle:
    def __init__(self, radius):
        self._radius = radius
    
    @property
    def radius(self):
        return self._radius
    
    @radius.setter
    def radius(self, value):
        if value < 0:
            raise ValueError("Radius cannot be negative")
        self._radius = value
    
    @property
    def area(self):
        return 3.14159 * self._radius ** 2

18. Modules and Packages

# Import entire module
import math
print(math.sqrt(16))

# Import specific function
from math import pi, sqrt
print(pi)

# Import with alias
import numpy as np

# Create your own module
# mymodule.py
def hello():
    return "Hello from mymodule!"

Popular Standard Library Modules

Module Purpose
math Mathematical functions
random Random number generation
os Operating system interface
sys System-specific parameters
datetime Date and time
json JSON parsing
re Regular expressions

19. Practice Problems

Beginner

1. FizzBuzz Easy

Print 1-100. Multiples of 3: "Fizz", 5: "Buzz", both: "FizzBuzz"

View Solution
for i in range(1, 101):
    if i % 15 == 0:
        print("FizzBuzz")
    elif i % 3 == 0:
        print("Fizz")
    elif i % 5 == 0:
        print("Buzz")
    else:
        print(i)

2. Factorial Easy

Calculate factorial of a number using recursion.

View Solution
def factorial(n):
    if n <= 1:
        return 1
    return n * factorial(n - 1)

print(factorial(5))  # 120

3. Palindrome Check Easy

Check if a string reads the same forwards and backwards.

View Solution
def is_palindrome(s):
    s = s.lower().replace(" ", "")
    return s == s[::-1]

print(is_palindrome("racecar"))  # True
print(is_palindrome("hello"))    # False

Intermediate

4. Fibonacci Generator Medium

Generate first N Fibonacci numbers.

View Solution
def fibonacci(n):
    a, b = 0, 1
    result = []
    for _ in range(n):
        result.append(a)
        a, b = b, a + b
    return result

print(fibonacci(10))
# [0, 1, 1, 2, 3, 5, 8, 13, 21, 34]

5. Anagram Checker Medium

Check if two strings are anagrams of each other.

View Solution
def is_anagram(s1, s2):
    return sorted(s1.lower()) == sorted(s2.lower())

print(is_anagram("listen", "silent"))  # True

6. Matrix Transpose Medium

Transpose a matrix (swap rows and columns).

View Solution
def transpose(matrix):
    return [list(row) for row in zip(*matrix)]

matrix = [[1, 2, 3], [4, 5, 6]]
print(transpose(matrix))
# [[1, 4], [2, 5], [3, 6]]

Advanced

7. Binary Search Hard

Implement binary search on a sorted list.

View Solution
def binary_search(arr, target):
    low, high = 0, len(arr) - 1
    while low <= high:
        mid = (low + high) // 2
        if arr[mid] == target:
            return mid
        elif arr[mid] < target:
            low = mid + 1
        else:
            high = mid - 1
    return -1

nums = [1, 3, 5, 7, 9, 11]
print(binary_search(nums, 7))  # 3

8. Decorator Hard

Create a timing decorator for functions.

View Solution
import time

def timer(func):
    def wrapper(*args, **kwargs):
        start = time.time()
        result = func(*args, **kwargs)
        end = time.time()
        print(f"{func.__name__} took {end-start:.4f}s")
        return result
    return wrapper

@timer
def slow_function():
    time.sleep(1)

slow_function()  # slow_function took 1.0012s
💡 Next Steps:
  • Practice on LeetCode, HackerRank, or Codewars
  • Build projects: web scraper, API, game
  • Learn frameworks: Django, Flask, FastAPI
  • Explore data science: NumPy, Pandas, Matplotlib