📚 Python Basics
🎯 What is Python?
Python is a high-level, interpreted programming language known for its simplicity and readability. Created by Guido van Rossum in 1991, Python has become one of the most popular programming languages in the world.
Key Features:
- Easy to Learn: Simple syntax similar to English
- Versatile: Used for web development, data science, AI, automation, and more
- Large Community: Extensive libraries and frameworks
- Open Source: Free to use and distribute
- Cross-platform: Works on Windows, Mac, and Linux
📌 Variables & Data Types
Variables are containers for storing data values. Python has several built-in data types:
| Data Type |
Description |
Example |
| int |
Integer (whole number) |
x = 10 |
| float |
Floating-point (decimal number) |
x = 3.14 |
| str |
String (text) |
x = "Hello" |
| bool |
Boolean (True or False) |
x = True |
| list |
List (ordered collection) |
x = [1, 2, 3] |
Example: Variables and Data Types
# Integer
age = 25
print(type(age)) # <class 'int'>
# String
name = "John Doe"
print(name)
# Float
height = 5.9
print(height)
# Boolean
is_student = True
print(is_student)
# Multiple assignment
a, b, c = 10, 20, 30
print(a, b, c)
💡 Tip:
Variable names should be descriptive. Use lowercase with underscores for multiple words (snake_case): student_name instead of studentName.
🧮 Arithmetic Operations
Python supports all basic mathematical operations:
| Operator |
Name |
Example |
Result |
| + |
Addition |
10 + 3 |
13 |
| - |
Subtraction |
10 - 3 |
7 |
| * |
Multiplication |
10 * 3 |
30 |
| / |
Division |
10 / 3 |
3.333... |
| // |
Floor Division |
10 // 3 |
3 |
| % |
Modulus |
10 % 3 |
1 |
| ** |
Exponent |
2 ** 3 |
8 |
Example: Arithmetic Operations
a = 10
b = 3
print("Addition:", a + b) # 13
print("Subtraction:", a - b) # 7
print("Multiplication:", a * b) # 30
print("Division:", a / b) # 3.333...
print("Floor Division:", a // b) # 3
print("Modulus:", a % b) # 1
print("Exponent:", a ** b) # 1000
# Order of operations (PEMDAS/BODMAS)
result = 2 + 3 * 4 # Multiplication first
print(result) # 14
❓ Comparison & Logical Operators
Used to compare values and make logical decisions:
| Operator |
Meaning |
Example |
| == |
Equal to |
a == b |
| != |
Not equal to |
a != b |
| < |
Less than |
a < b |
| > |
Greater than |
a > b |
| <= |
Less than or equal to |
a <= b |
| >= |
Greater than or equal to |
a >= b |
Example: Comparison Operators
a = 10
b = 5
print(a == b) # False
print(a != b) # True
print(a > b) # True
print(a < b) # False
print(a >= b) # True
print(a <= b) # False
🔀 Conditional Statements (if, elif, else)
Use if, elif, and else to make decisions in your code:
Example: Basic if-else
age = 20
if age >= 18:
print("You are an adult")
else:
print("You are a minor")
Example: 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")
Example: Nested if statements
age = 25
has_license = True
if age >= 18:
if has_license:
print("You can drive")
else:
print("You need a license")
else:
print("You are too young to drive")
💡 Tip:
Always use proper indentation (4 spaces) in Python. Indentation is part of the syntax, not just for readability!
✏️ Exercise: Temperature Converter
Write a program that converts Celsius to Fahrenheit and prints a message:
- If temperature < 0: "Freezing"
- If temperature 0-15: "Cold"
- If temperature 16-25: "Comfortable"
- If temperature > 25: "Hot"
Formula: F = (C × 9/5) + 32
🔤 Working with Strings
📝 String Basics
Strings are sequences of characters enclosed in quotes (single or double):
Example: Creating Strings
# Single quotes
str1 = 'Hello'
# Double quotes
str2 = "World"
# Multi-line strings
str3 = """This is a
multi-line
string"""
print(str1)
print(str2)
print(str3)
✂️ String Methods
Python provides many built-in methods for string manipulation:
| Method |
Description |
Example |
| upper() |
Convert to uppercase |
"hello".upper() → "HELLO" |
| lower() |
Convert to lowercase |
"HELLO".lower() → "hello" |
| capitalize() |
Capitalize first letter |
"hello".capitalize() → "Hello" |
| replace() |
Replace substring |
"hello".replace("l", "x") → "hexxo" |
| split() |
Split into list |
"hello world".split() → ["hello", "world"] |
| join() |
Join list into string |
" ".join(["hello", "world"]) → "hello world" |
| strip() |
Remove whitespace |
" hello ".strip() → "hello" |
| startswith() |
Check start of string |
"hello".startswith("he") → True |
Example: String Methods
text = "Python Programming"
# Convert case
print(text.upper()) # PYTHON PROGRAMMING
print(text.lower()) # python programming
print(text.capitalize()) # Python programming
# Find and replace
print(text.replace("Python", "Java")) # Java Programming
# Check if contains
print("Python" in text) # True
# Get length
print(len(text)) # 19
# String slicing
print(text[0]) # P (first character)
print(text[0:6]) # Python (first 6 characters)
print(text[-11:]) # Programming (last 11 characters)
🎨 String Formatting
Different ways to format strings in Python:
Method 1: f-strings (Python 3.6+) - Recommended
name = "Alice"
age = 25
height = 5.7
print(f"Name: {name}")
print(f"Age: {age}")
print(f"Height: {height:.1f} feet")
print(f"Next year I'll be {age + 1} years old")
Method 2: format() method
name = "Bob"
age = 30
print("Name: {}".format(name))
print("Age: {}".format(age))
print("{} is {} years old".format(name, age))
Method 3: % operator (older style)
name = "Charlie"
age = 35
print("Name: %s" % name)
print("Age: %d" % age)
print("%s is %d years old" % (name, age))
💡 Tip:
f-strings are the modern and recommended way to format strings. They are faster and more readable.
📍 String Indexing & Slicing
Access individual characters or portions of a string:
text = "Python"
# 012345 (forward indexing)
# -654321 (backward indexing)
# Indexing (single character)
print(text[0]) # P
print(text[5]) # n
print(text[-1]) # n (last character)
print(text[-2]) # o (second to last)
# Slicing (substring)
print(text[0:3]) # Pyt
print(text[2:5]) # tho
print(text[:3]) # Pyt (from start)
print(text[3:]) # hon (to end)
print(text[::2]) # Pto (every 2nd character)
print(text[::-1]) # nohtyP (reversed)
✏️ Exercise: Email Validator
Create a program that:
- Takes an email as input
- Checks if it contains exactly one "@" symbol
- Checks if it has a domain (e.g., .com, .org)
- Prints whether the email is valid or invalid
🔄 Loops
📍 for Loop
Iterate over a sequence (list, string, range, etc.):
Example: Loop through range
# Print numbers 0 to 4
for i in range(5):
print(i)
# Print numbers 1 to 5
for i in range(1, 6):
print(i)
# Print even numbers 0 to 10
for i in range(0, 11, 2):
print(i)
Example: Loop through list
fruits = ["apple", "banana", "cherry"]
for fruit in fruits:
print(fruit)
# With index
for index, fruit in enumerate(fruits):
print(f"{index}: {fruit}")
Example: Loop through string
text = "Hello"
for char in text:
print(char)
⏰ while Loop
Repeat code while a condition is true:
Example: Simple while loop
count = 0
while count < 5:
print(f"Count: {count}")
count += 1
print("Done!")
Example: while with break
count = 0
while True:
print(count)
count += 1
if count >= 5:
break # Exit the loop
Example: while with continue
for i in range(10):
if i % 2 == 0:
continue # Skip even numbers
print(i) # Print only odd numbers
🎯 Loop Control Statements
Control the flow of loops:
| Statement |
Description |
Example |
| break |
Exit the loop |
if x > 5: break |
| continue |
Skip to next iteration |
if x < 0: continue |
| pass |
Do nothing (placeholder) |
if x: pass |
Example: Practical use
# Find first number divisible by 3
for i in range(1, 20):
if i % 3 == 0:
print(f"Found: {i}")
break
# Print numbers except multiples of 2
for i in range(10):
if i % 2 == 0:
continue
print(i)
🏗️ Nested Loops
Loops inside loops:
Example: Times table
# Print 3x3 times table
for i in range(1, 4):
for j in range(1, 4):
print(f"{i} × {j} = {i*j}", end=" ")
print() # New line
Example: Pattern
# Print a triangle pattern
for i in range(1, 6):
for j in range(i):
print("*", end=" ")
print()
✏️ Exercise: Prime Number Checker
Write a program that checks if a number is prime:
- Get a number from the user
- Check if it's divisible by any number from 2 to n-1
- Print if the number is prime or not
Hint: Use a for loop with break statement
⚙️ Functions
🎯 Function Basics
Functions are reusable blocks of code that perform specific tasks:
Example: Simple function
def greet():
print("Hello, World!")
# Call the function
greet()
greet()
Example: Function with parameters
def greet(name):
print(f"Hello, {name}!")
greet("Alice")
greet("Bob")
Example: Function with return value
def add(a, b):
result = a + b
return result
sum1 = add(5, 3)
sum2 = add(10, 20)
print(f"Sum 1: {sum1}")
print(f"Sum 2: {sum2}")
⚙️ Default Parameters & Keyword Arguments
Make functions more flexible with default values:
Example: Default parameters
def greet(name, greeting="Hello"):
print(f"{greeting}, {name}!")
greet("Alice") # Uses default greeting
greet("Bob", "Hi") # Custom greeting
greet("Charlie", greeting="Hey") # Keyword argument
Example: Multiple parameters
def calculate(a, b, operation="+"):
if operation == "+":
return a + b
elif operation == "-":
return a - b
elif operation == "*":
return a * b
elif operation == "/":
return a / b if b != 0 else "Cannot divide by zero"
print(calculate(10, 5)) # 15
print(calculate(10, 5, "-")) # 5
print(calculate(10, 5, "*")) # 50
📦 *args and **kwargs
Handle variable number of arguments:
Example: *args (multiple arguments)
def sum_all(*numbers):
total = 0
for num in numbers:
total += num
return total
print(sum_all(1, 2, 3)) # 6
print(sum_all(1, 2, 3, 4, 5)) # 15
Example: **kwargs (keyword arguments)
def print_info(**info):
for key, value in info.items():
print(f"{key}: {value}")
print_info(name="John", age=25, city="NYC")
Example: Combined *args and **kwargs
def function(arg1, arg2, *args, **kwargs):
print(f"arg1: {arg1}")
print(f"arg2: {arg2}")
print(f"args: {args}")
print(f"kwargs: {kwargs}")
function(1, 2, 3, 4, 5, name="John", age=25)
🎁 Lambda Functions
Small anonymous functions for simple operations:
Example: Basic lambda
# Traditional function
def square(x):
return x ** 2
# Lambda function
square_lambda = lambda x: x ** 2
print(square(5)) # 25
print(square_lambda(5)) # 25
Example: Lambda with map()
numbers = [1, 2, 3, 4, 5]
# Square each number
squared = list(map(lambda x: x ** 2, numbers))
print(squared) # [1, 4, 9, 16, 25]
# Filter even numbers
evens = list(filter(lambda x: x % 2 == 0, numbers))
print(evens) # [2, 4]
📚 Scope (Local vs Global)
Variables can have local or global scope:
Example: Local vs Global variables
global_var = 10 # Global variable
def my_function():
local_var = 5 # Local variable (only accessible inside function)
print(global_var) # Can access global
print(local_var) # Can access local
my_function()
print(global_var) # Can access global
print(local_var) # Error! local_var not defined outside function
Example: Modifying global variables
count = 0
def increment():
global count # Declare we're using the global variable
count += 1
return count
print(increment()) # 1
print(increment()) # 2
print(count) # 2
✏️ Exercise: Calculator Function
Create a calculator function that:
- Takes two numbers and an operation as parameters
- Supports: add, subtract, multiply, divide
- Returns the result
- Handles division by zero
📚 Data Structures
📋 Lists
Ordered, mutable collections of items (can be modified):
Example: Creating and accessing lists
# Create a list
fruits = ["apple", "banana", "cherry", "date"]
# Access elements
print(fruits[0]) # apple (first element)
print(fruits[-1]) # date (last element)
print(fruits[1:3]) # ['banana', 'cherry'] (slicing)
# Length
print(len(fruits)) # 4
Example: Modifying lists
fruits = ["apple", "banana", "cherry"]
# Add elements
fruits.append("date") # Add at end
fruits.insert(1, "blueberry") # Insert at index
# Remove elements
fruits.remove("banana") # Remove by value
fruits.pop() # Remove last element
fruits.pop(0) # Remove first element
# Modify element
fruits[0] = "apricot"
print(fruits)
Example: List methods
numbers = [3, 1, 4, 1, 5, 9]
# Sorting
numbers.sort() # [1, 1, 3, 4, 5, 9]
# Reverse
numbers.reverse() # [9, 5, 4, 3, 1, 1]
# Count occurrences
count = numbers.count(1) # 2
# Find index
index = numbers.index(3) # 3
# Copy list
copy = numbers.copy()
🔐 Tuples
Ordered, immutable collections (cannot be modified after creation):
Example: Creating and accessing tuples
# Create a tuple
coordinates = (10, 20, 30)
# Access elements
print(coordinates[0]) # 10
print(coordinates[1:]) # (20, 30)
# Unpacking
x, y, z = coordinates
print(x, y, z)
# Length
print(len(coordinates)) # 3
Example: Tuple operations
# Tuples are immutable
coordinates = (10, 20)
# coordinates[0] = 15 # Error! Cannot modify
# But you can create new tuples
coordinates = coordinates + (30,)
print(coordinates) # (10, 20, 30)
# Concatenation
tuple1 = (1, 2)
tuple2 = (3, 4)
tuple3 = tuple1 + tuple2
print(tuple3) # (1, 2, 3, 4)
💡 Why Tuples?
Tuples are useful when you want to ensure data cannot be accidentally modified. They're also faster and use less memory than lists.
🗝️ Dictionaries
Unordered collections of key-value pairs:
Example: Creating and accessing dictionaries
# Create a dictionary
student = {
"name": "John",
"age": 20,
"grade": "A",
"subjects": ["Math", "Physics", "Chemistry"]
}
# Access values
print(student["name"]) # John
print(student["age"]) # 20
print(student.get("city", "Unknown")) # Unknown (default if not found)
Example: Modifying dictionaries
student = {"name": "Alice", "age": 22}
# Add or update key-value pairs
student["age"] = 23 # Update
student["city"] = "NYC" # Add new
# Remove
del student["city"]
student.pop("age") # Remove and return value
print(student)
Example: Dictionary methods
student = {"name": "Bob", "age": 21, "grade": "B"}
# Get all keys
print(student.keys()) # dict_keys(['name', 'age', 'grade'])
# Get all values
print(student.values()) # dict_values(['Bob', 21, 'B'])
# Get key-value pairs
print(student.items()) # dict_items([...])
# Check if key exists
if "name" in student:
print("Name exists")
# Loop through dictionary
for key, value in student.items():
print(f"{key}: {value}")
❌ Sets
Unordered collections of unique elements:
Example: Creating and using sets
# Create a set
colors = {"red", "green", "blue", "red"} # Duplicate removed
print(colors) # {'red', 'green', 'blue'}
# Add and remove
colors.add("yellow")
colors.remove("red")
# Check membership
if "blue" in colors:
print("Blue is in the set")
# Length
print(len(colors))
Example: Set operations
set1 = {1, 2, 3, 4}
set2 = {3, 4, 5, 6}
# Union (all elements)
print(set1 | set2) # {1, 2, 3, 4, 5, 6}
# Intersection (common elements)
print(set1 & set2) # {3, 4}
# Difference (in set1 but not set2)
print(set1 - set2) # {1, 2}
# Symmetric difference (in either but not both)
print(set1 ^ set2) # {1, 2, 5, 6}
✏️ Exercise: Student Grade System
Create a program using a dictionary to:
- Store student names and their grades
- Add new students
- Update grades
- Calculate average grade
- Find the highest and lowest grades
🏛️ Object-Oriented Programming (OOP)
📦 Classes and Objects
Classes are templates for creating objects. Objects are instances of classes.
Example: Basic class
class Dog:
def __init__(self, name, age):
self.name = name
self.age = age
def bark(self):
print(f"{self.name} says: Woof!")
def get_info(self):
return f"{self.name} is {self.age} years old"
# Create objects
dog1 = Dog("Buddy", 3)
dog2 = Dog("Max", 5)
# Use methods
dog1.bark()
print(dog1.get_info())
🔗 Inheritance
Inheritance allows a class to inherit properties and methods from another class:
Example: Inheritance
class Animal:
def __init__(self, name):
self.name = name
def speak(self):
print(f"{self.name} makes a sound")
class Dog(Animal): # Dog inherits from Animal
def speak(self): # Override parent method
print(f"{self.name} says: Woof!")
class Cat(Animal):
def speak(self):
print(f"{self.name} says: Meow!")
# Create objects
dog = Dog("Buddy")
cat = Cat("Whiskers")
dog.speak() # Buddy says: Woof!
cat.speak() # Whiskers says: Meow!
🎭 Polymorphism
Same method name can have different implementations in different classes:
Example: Polymorphism
class Shape:
def area(self):
pass
class Square(Shape):
def __init__(self, side):
self.side = side
def area(self):
return self.side ** 2
class Circle(Shape):
def __init__(self, radius):
self.radius = radius
def area(self):
return 3.14 * self.radius ** 2
# Create objects
square = Square(5)
circle = Circle(3)
print(f"Square area: {square.area()}") # 25
print(f"Circle area: {circle.area()}") # 28.26
🔒 Encapsulation
Hide internal details and provide a controlled interface:
Example: Private attributes
class BankAccount:
def __init__(self, owner, balance):
self.owner = owner
self.__balance = balance # Private attribute (__ prefix)
def deposit(self, amount):
if amount > 0:
self.__balance += amount
def withdraw(self, amount):
if amount > 0 and amount <= self.__balance:
self.__balance -= amount
def get_balance(self):
return self.__balance
# Create account
account = BankAccount("John", 1000)
account.deposit(500)
account.withdraw(200)
print(account.get_balance()) # 1300
# print(account.__balance) # Error! Cannot access private attribute
✨ Special Methods (Magic Methods)
Methods with double underscores that have special meaning:
| Method |
Called When |
Example |
| __init__ |
Object is created |
Dog("Buddy") |
| __str__ |
print() is called |
print(dog) |
| __len__ |
len() is called |
len(dog) |
| __add__ |
+ operator is used |
dog1 + dog2 |
| __eq__ |
== operator is used |
dog1 == dog2 |
Example: Magic methods
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def __str__(self):
return f"{self.name}, age {self.age}"
def __eq__(self, other):
return self.age == other.age
def __lt__(self, other):
return self.age < other.age
person1 = Person("Alice", 25)
person2 = Person("Bob", 30)
print(person1) # Alice, age 25
print(person1 == person2) # False
print(person1 < person2) # True
✏️ Exercise: Library System
Create a Book class and Library class:
- Book: title, author, isbn, available
- Methods: get_info(), mark_borrowed(), mark_returned()
- Library: store multiple books
- Methods: add_book(), remove_book(), find_book(), borrow_book(), return_book()
🚀 Advanced Topics
📂 List Comprehensions
Concise way to create lists by applying an operation to each element:
Example: Basic list comprehensions
# Create a list of squares
numbers = [1, 2, 3, 4, 5]
squares = [x**2 for x in numbers]
print(squares) # [1, 4, 9, 16, 25]
# Traditional way
squares_traditional = []
for x in numbers:
squares_traditional.append(x**2)
print(squares_traditional) # Same result
Example: List comprehension with conditions
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
# Filter even numbers
evens = [x for x in numbers if x % 2 == 0]
print(evens) # [2, 4, 6, 8, 10]
# Filter and transform
even_squares = [x**2 for x in numbers if x % 2 == 0]
print(even_squares) # [4, 16, 36, 64, 100]
# Nested comprehension
matrix = [[x*y for x in range(1, 4)] for y in range(1, 4)]
print(matrix)
Example: Dictionary and set comprehensions
# Dictionary comprehension
numbers = [1, 2, 3, 4, 5]
squares_dict = {x: x**2 for x in numbers}
print(squares_dict) # {1: 1, 2: 4, 3: 9, 4: 16, 5: 25}
# Set comprehension
unique_squares = {x**2 for x in [1, 2, 2, 3, 3, 4]}
print(unique_squares) # {1, 4, 9, 16}
⚡ Generators
Functions that generate values one at a time (memory-efficient):
Example: Simple generator
def countdown(n):
while n > 0:
yield n # Yield instead of return
n -= 1
# Use the generator
for num in countdown(5):
print(num)
# Or manually
gen = countdown(3)
print(next(gen)) # 3
print(next(gen)) # 2
print(next(gen)) # 1
Example: Generator expression
# Similar to list comprehension but uses ()
numbers = [1, 2, 3, 4, 5]
# List comprehension (loads all into memory)
squares_list = [x**2 for x in numbers]
# Generator expression (generates on demand)
squares_gen = (x**2 for x in numbers)
print(list(squares_gen)) # [1, 4, 9, 16, 25]
🛡️ Exception Handling
Handle errors gracefully so your program doesn't crash:
Example: try-except
try:
age = int(input("Enter your age: "))
print(f"You are {age} years old")
except ValueError:
print("Please enter a valid number")
Example: Multiple except blocks
try:
numbers = [1, 2, 3]
print(numbers[10]) # IndexError
except ValueError:
print("Invalid value")
except IndexError:
print("Index out of range")
except Exception as e:
print(f"An error occurred: {e}")
Example: try-except-finally
try:
file = open("data.txt", "r")
data = file.read()
except FileNotFoundError:
print("File not found")
finally:
# This always runs, even if an error occurred
if 'file' in locals():
file.close()
print("Cleanup complete")
Example: Raising exceptions
def check_age(age):
if age < 0:
raise ValueError("Age cannot be negative")
if age < 18:
raise ValueError("Must be 18 or older")
return "Age is valid"
try:
print(check_age(-5))
except ValueError as e:
print(f"Error: {e}")
🔄 Decorators
Functions that modify the behavior of other functions:
Example: Simple decorator
def my_decorator(func):
def wrapper():
print("Before function")
func()
print("After function")
return wrapper
@my_decorator
def say_hello():
print("Hello!")
say_hello()
# Output:
# Before function
# Hello!
# After function
Example: Decorator with parameters
def my_decorator(func):
def wrapper(*args, **kwargs):
print(f"Calling {func.__name__}")
result = func(*args, **kwargs)
print(f"{func.__name__} returned {result}")
return result
return wrapper
@my_decorator
def add(a, b):
return a + b
add(5, 3)
Example: Timing decorator
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} seconds")
return result
return wrapper
@timer
def slow_function():
time.sleep(2)
print("Done!")
slow_function()
📦 Modules and Packages
Organize code into reusable modules:
Example: Importing modules
import math
# Access module contents with dot notation
print(math.pi) # 3.14159...
print(math.sqrt(16)) # 4.0
from datetime import datetime
print(datetime.now())
from random import randint
print(randint(1, 10))
Example: Popular modules
# Math operations
import math
print(math.ceil(4.3)) # 5
print(math.floor(4.7)) # 4
print(math.factorial(5)) # 120
# Random numbers
import random
print(random.random()) # Random float 0-1
print(random.choice([1, 2, 3])) # Random choice
# Date and time
from datetime import datetime, timedelta
today = datetime.now()
tomorrow = today + timedelta(days=1)
# Operating system
import os
print(os.getcwd()) # Current directory
✏️ Exercise: File Processing Program
Create a program that:
- Creates a simple text file with sample data
- Reads the file content
- Counts words and lines
- Finds the longest word
- Implements error handling for file operations
Note: This requires the actual Python interpreter, not the browser version
⚠️ Browser Limitations
The browser-based code editor has limitations with some advanced features:
- ❌ File operations (open, read, write)
- ❌ External libraries (numpy, pandas, requests)
- ❌ Some modules (os, sys, etc.)
- ✅ Core Python features work
- ✅ Classes, functions, loops work
- ✅ List comprehensions work
For full Python development, use: