Python 3.12+ · 100+ Examples

Python Sample Programs
Learn by Example

Welcome to the ultimate Python sample programs collection. This comprehensive resource features 100+ carefully crafted Python programs — each with line-by-line explanations, runnable code, and real output. Whether you're a complete beginner or an experienced developer revisiting fundamentals, these examples will deepen your understanding of Python's syntax, patterns, and best practices.

Every program includes why you should learn it, how it works, and what makes it significant in your programming journey.

hello_world.py
print("Hello, World!")

name = "Python"
version = 3.12
print(f"Welcome to {name} {version}!")

name = input("What's your name? ")
print(f"Nice to meet you, {name}!")
$ python hello_world.py
Hello, World!
Welcome to Python 3.12!
What's your name? Glenn
Nice to meet you, Glenn!

📑 Table of Contents

Jump to any program category instantly

How to Use These Programs

Each program is self‑contained and ready to run

This page is your reference for Python programming — 100+ programs organized by topic. Each example includes the complete code, a "Run" button to see the output, a "Copy" button to grab the code instantly, and a detailed explanation of every line. Use them to learn, practice, or as a quick reference for your own projects.

Learning Tips

1. Read the code and try to predict the output → 2. Run the program to check → 3. Modify the code to experiment → 4. Write your own version from memory.

Why Learn Through Examples?

Research shows that learning by example is one of the most effective ways to internalize programming concepts. Each example here is designed to teach one clear concept, building your mental model of how Python works — line by line, concept by concept.

Basic Programs

Getting started with variables, input, and output

🏁 Hello World

The classic first program — prints "Hello, World!" to the console. It's the simplest way to verify that your Python environment is set up correctly.

print("Hello, World!")

print("Hello", "World", "from", "Python")
Hello, World!
Hello World from Python
Line-by-line explanation:
print("Hello, World!") → Calls the built-in print() function to output text to the console. The string is enclosed in quotes.
print("Hello", "World", "from", "Python") → print() can take multiple arguments; they are printed with a space separator by default.
Why every programmer should learn this: "Hello World" is the universal first step — it confirms your environment works, introduces the print() function, and builds confidence. It's the foundation for every program you'll ever write.

📝 Variables and Data Types

Declaring variables and checking their types. Python is dynamically typed, meaning variables can change type as needed.

name = "Alice"
age = 25
height = 5.8
is_student = True

print(f"Name: {name}, Type: {type(name)}")
print(f"Age: {age}, Type: {type(age)}")
print(f"Height: {height}, Type: {type(height)}")
print(f"Student: {is_student}, Type: {type(is_student)}")
Name: Alice, Type:
Age: 25, Type:
Height: 5.8, Type:
Student: True, Type:
Line-by-line explanation:
name = "Alice" → Creates a string variable. Strings are text enclosed in quotes.
age = 25 → Creates an integer (whole number) variable.
height = 5.8 → Creates a float (decimal number) variable.
is_student = True → Creates a boolean (True/False) variable.
print(f"Name: {name}, Type: {type(name)}") → f-string (formatted string) embeds variables directly. type() returns the data type.
Why every programmer should learn this: Variables are the building blocks of all programs. Understanding data types is essential because every operation in Python depends on the type of data you're working with. This is the foundation of type safety and data manipulation.

⌨️ User Input

Getting input from the user with input(). Always returns a string, which can be converted to other types.

name = input("What's your name? ")
age = input("How old are you? ")

age = int(age)

print(f"Hello {name}! You are {age} years old.")
print(f"Next year you'll be {age + 1}.")
What's your name? Glenn
How old are you? 30
Hello Glenn! You are 30 years old.
Next year you'll be 31.
Line-by-line explanation:
name = input("What's your name? ") → input() displays the prompt, waits for the user to type, and returns the input as a string.
age = input("How old are you? ") → Input is always a string.
age = int(age) → int() converts the string to an integer, enabling arithmetic.
print(f"Hello {name}! ...") → f-string embeds variables directly in the output.
print(f"Next year you'll be {age + 1}.") → Now age is an integer, so age + 1 works.
Why every programmer should learn this: Interactivity is what makes programs useful. input() is your gateway to interactive programs, and learning to convert types prevents the common "TypeError" mistakes that plague beginners.

🔢 Simple Arithmetic

Basic mathematical operations — addition, subtraction, multiplication, division. Python supports all standard operators.

a = 10
b = 3

print(f"a = {a}, b = {b}")
print(f"a + b = {a + b}")
print(f"a - b = {a - b}")
print(f"a * b = {a * b}")
print(f"a / b = {a / b}")
print(f"a // b = {a // b} (floor division)")
print(f"a % b = {a % b} (remainder)")
print(f"a ** b = {a ** b} (exponent)")
a = 10, b = 3
a + b = 13
a - b = 7
a * b = 30
a / b = 3.3333333333333335
a // b = 3 (floor division)
a % b = 1 (remainder)
a ** b = 1000 (exponent)
Line-by-line explanation:
a = 10; b = 3 → Assign values to two variables.
a + b → Addition: 10 + 3 = 13.
a - b → Subtraction: 10 - 3 = 7.
a * b → Multiplication: 10 * 3 = 30.
a / b → Division: always returns a float: 10 / 3 = 3.333...
a // b → Floor division: integer division that rounds down: 10 // 3 = 3.
a % b → Modulo: returns the remainder: 10 % 3 = 1.
a ** b → Exponent: 10 raised to the 3rd power = 1000.
Why every programmer should learn this: Arithmetic is the heart of programming — from simple calculations to complex algorithms. Understanding operator precedence, type conversion, and the difference between / and // is critical for writing correct code in any domain: data science, finance, gaming, or backend logic.

🎯 Why Master the Basics?

These foundational programs teach you syntax, variables, input/output, and arithmetic — the universal building blocks of every programming language. Mastering them gives you the confidence to move to more complex topics. Every advanced concept you learn will rest on these basics.

Data Structure Programs

Working with lists, dictionaries, tuples, and sets

📋 List Operations

Lists are ordered, mutable sequences. This program covers creation, accessing, adding, removing, slicing, and iteration.

fruits = ["apple", "banana", "cherry", "date"]
print("Original:", fruits)

print("First:", fruits[0])
print("Last:", fruits[-1])

fruits.append("elderberry")
fruits.insert(1, "blueberry")
print("After adding:", fruits)

fruits.remove("banana")
last = fruits.pop()
print("After removing:", fruits)
print("Popped:", last)

print("First three:", fruits[:3])
print("Reversed:", fruits[::-1])

for fruit in fruits:
    print(fruit, end=" ")
Original: ['apple', 'banana', 'cherry', 'date']
First: apple
Last: date
After adding: ['apple', 'blueberry', 'banana', 'cherry', 'date', 'elderberry']
After removing: ['apple', 'blueberry', 'cherry', 'date']
Popped: elderberry
First three: ['apple', 'blueberry', 'cherry']
Reversed: ['date', 'cherry', 'blueberry', 'apple']
apple blueberry cherry date
Line-by-line explanation:
fruits = ["apple", "banana", "cherry", "date"] → Creates a list using square brackets.
fruits[0] → Index 0 gives the first element. fruits[-1] → Negative index counts from the end.
fruits.append("elderberry") → Adds an element to the end. fruits.insert(1, "blueberry") → Inserts at index 1.
fruits.remove("banana") → Removes the first occurrence. fruits.pop() → Removes and returns the last element.
fruits[:3] → Slicing: elements from index 0 to 2. fruits[::-1] → Reverses the list using a negative step.
for fruit in fruits: → Iterates over each element, printing with end=" " to stay on one line.
Why every programmer should learn this: Lists are the most versatile data structure in Python. You'll use them everywhere — storing data, processing batches, implementing stacks/queues, and more. Understanding mutability, slicing, and iteration is essential for writing efficient, readable Python code.

📖 Dictionary Operations

Dictionaries store key‑value pairs. They are unordered, mutable, and allow fast lookups.

person = {
    "name": "Alice",
    "age": 30,
    "city": "New York",
    "skills": ["Python", "Data Science"]
}

print("Name:", person["name"])
print("Age:", person.get("age"))
print("City:", person.get("country", "Unknown"))

person["country"] = "USA"
person["age"] = 31
print("Updated:", person)

for key, value in person.items():
    print(f"{key}: {value}")

if "skills" in person:
    print("Skills:", person["skills"])
Name: Alice
Age: 30
City: Unknown
Updated: {'name': 'Alice', 'age': 31, 'city': 'New York', 'skills': ['Python', 'Data Science'], 'country': 'USA'}
name: Alice
age: 31
city: New York
skills: ['Python', 'Data Science']
country: USA
Skills: ['Python', 'Data Science']
Line-by-line explanation:
person = { "name": "Alice", ... } → Creates a dictionary with key-value pairs.
person["name"] → Accesses the value for key "name".
person.get("age") → get() returns None if the key is missing (instead of raising an error).
person.get("country", "Unknown") → Provides a default value if the key is missing.
person["country"] = "USA" → Adds a new key-value pair. person["age"] = 31 → Updates an existing value.
for key, value in person.items(): → items() returns key-value pairs for iteration.
if "skills" in person: → Checks if a key exists using the in operator.
Why every programmer should learn this: Dictionaries are the heart of data organization in Python. They're used for configuration, API responses, database records, and much more. Mastering key-based access, get(), and iteration is essential for working with real-world data.

🔒 Tuple Operations

Tuples are immutable sequences, often used for fixed data. They can be used as dictionary keys.

point = (3, 4)
rgb = (255, 128, 0)
person = ("Alice", 30, "NYC")

print("Point:", point)
print("x:", point[0], "y:", point[1])

x, y = point
name, age, city = person
print(f"x={x}, y={y}")
print(f"{name} is {age} years old from {city}")

grid = {}
grid[(0, 0)] = "origin"
grid[(1, 2)] = "point"
print("Grid:", grid)
Point: (3, 4)
x: 3 y: 4
x=3, y=4
Alice is 30 years old from NYC
Grid: {(0, 0): 'origin', (1, 2): 'point'}
Line-by-line explanation:
point = (3, 4) → Creates a tuple with parentheses. Tuples are immutable (cannot be changed after creation).
point[0], point[1] → Access elements by index, just like lists.
x, y = point → Tuple unpacking: assigns each element to a variable. This is a very Pythonic feature.
grid[(0, 0)] = "origin" → Tuples can be used as dictionary keys because they are hashable (unlike lists).
Why every programmer should learn this: Tuples are used for immutable data — coordinates, RGB colors, fixed records. Their immutability makes them safer and more predictable. They're also hashable, enabling them as dictionary keys, which lists cannot do.

🔵 Set Operations

Sets are unordered collections of unique elements. This program shows union, intersection, difference, and deduplication.

set_a = {1, 2, 3, 4, 5}
set_b = {4, 5, 6, 7, 8}

print("Set A:", set_a)
print("Set B:", set_b)

print("Union:", set_a | set_b)
print("Intersection:", set_a & set_b)
print("Difference (A - B):", set_a - set_b)
print("Symmetric Difference:", set_a ^ set_b)

set_a.add(6)
set_a.discard(1)
print("Modified A:", set_a)

numbers = [1, 2, 2, 3, 3, 3, 4, 5, 5]
unique = list(set(numbers))
print("Original:", numbers)
print("Unique:", unique)
Set A: {1, 2, 3, 4, 5}
Set B: {4, 5, 6, 7, 8}
Union: {1, 2, 3, 4, 5, 6, 7, 8}
Intersection: {4, 5}
Difference (A - B): {1, 2, 3}
Symmetric Difference: {1, 2, 3, 6, 7, 8}
Modified A: {2, 3, 4, 5, 6}
Original: [1, 2, 2, 3, 3, 3, 4, 5, 5]
Unique: [1, 2, 3, 4, 5]
Line-by-line explanation:
set_a = {1, 2, 3, 4, 5} → Creates a set using curly braces. Sets store only unique elements.
set_a | set_b → Union (elements in either set). set_a & set_b → Intersection (elements in both).
set_a - set_b → Difference (in A but not B). set_a ^ set_b → Symmetric difference (in either, but not both).
set_a.add(6) → Adds an element. set_a.discard(1) → Removes an element if present (safe — no error if missing).
list(set(numbers)) → Converts a list to a set (removing duplicates) and back to a list.
Why every programmer should learn this: Sets are essential for mathematical operations on collections — removing duplicates, finding common elements, and testing membership efficiently (O(1) average). They're used in data cleaning, database queries, and algorithm design.

📊 Why Data Structures Matter

Data structures are the organizational backbone of all programs. Choosing the right data structure — list, dictionary, tuple, or set — determines the efficiency, clarity, and correctness of your code. Mastering them is a milestone in your programming journey.

Control Flow Programs

Conditionals, loops, and flow control

🔀 If/Else Statements

Making decisions based on conditions. This program checks if a number is positive/negative/zero and calculates a grade.

num = int(input("Enter a number: "))

if num > 0:
    print("The number is positive")
elif num < 0:
    print("The number is negative")
else:
    print("The number is zero")

score = int(input("Enter score (0-100): "))

if score >= 90:
    grade = "A"
elif score >= 80:
    grade = "B"
elif score >= 70:
    grade = "C"
elif score >= 60:
    grade = "D"
else:
    grade = "F"

print(f"Grade: {grade}")
Enter a number: -5
The number is negative
Enter score (0-100): 85
Grade: B
Line-by-line explanation:
num = int(input("Enter a number: ")) → Gets an integer from the user.
if num > 0: → Checks if the number is greater than 0. If True, runs the following indented block.
elif num < 0: → "Else if" — checks a second condition if the first was False.
else: → Runs if all previous conditions were False.
The grade calculator uses chained conditionals — each elif is checked in order until one matches.
Why every programmer should learn this: Conditional logic is the foundation of decision-making in programs. Every application — from a simple calculator to a complex AI — uses if/elif/else to branch based on input, state, or data.

🔄 For Loops

Iterating over sequences and ranges. This program shows list iteration, enumeration, range, and nested loops.

fruits = ["apple", "banana", "cherry"]
for fruit in fruits:
    print(f"I like {fruit}")

for i, fruit in enumerate(fruits):
    print(f"{i}: {fruit}")

for i in range(5):
    print(i, end=" ")
print()

for i in range(2, 10, 2):
    print(i, end=" ")
print()

for i in range(3):
    for j in range(2):
        print(f"({i},{j})", end=" ")
    print()
I like apple
I like banana
I like cherry
0: apple
1: banana
2: cherry
0 1 2 3 4
2 4 6 8
(0,0) (0,1)
(1,0) (1,1)
(2,0) (2,1)
Line-by-line explanation:
for fruit in fruits: → Iterates over each element in the list, assigning it to fruit.
for i, fruit in enumerate(fruits): → enumerate() provides both the index and the value.
range(5) → Generates numbers 0 to 4. range(2, 10, 2) → Starts at 2, stops before 10, step 2 → 2, 4, 6, 8.
for i in range(3): for j in range(2): → Nested loop: for each i, all j values are iterated.
Why every programmer should learn this: Loops are how we process repetitive tasks and collections of data. for loops are the most common iteration tool in Python, used in data processing, file reading, and algorithm implementation.

🔄 While Loops

Repeating until a condition changes. This program counts, sums input, and uses a break.

count = 1
while count <= 5:
    print(count, end=" ")
    count += 1
print()

total = 0
num = int(input("Enter number (0 to stop): "))
while num != 0:
    total += num
    num = int(input("Enter number (0 to stop): "))
print(f"Sum: {total}")

print("Counting...")
n = 0
while True:
    n += 1
    if n > 5:
        break
    print(n, end=" ")
1 2 3 4 5
Enter number (0 to stop): 5
Enter number (0 to stop): 3
Enter number (0 to stop): 2
Enter number (0 to stop): 0
Sum: 10
Counting...
1 2 3 4 5
Line-by-line explanation:
while count <= 5: → The loop runs as long as the condition is True.
count += 1 → Increment to avoid an infinite loop (must eventually make the condition False).
while num != 0: → Continues until the user enters 0.
while True: → An infinite loop. if n > 5: break → break exits the loop entirely.
Why every programmer should learn this: while loops are used when you don't know in advance how many times to iterate — for example, waiting for user input, reading a file, or game loops. The break statement is a powerful tool for controlling loop flow.

🎯 Pattern Printing

Using loops to print patterns — a classic programming exercise to understand nested loops and string multiplication.

n = 5
for i in range(1, n + 1):
    print("*" * i)

print()

for i in range(n, 0, -1):
    print("*" * i)

print()

for i in range(1, n + 1):
    spaces = " " * (n - i)
    stars = "*" * (2 * i - 1)
    print(spaces + stars)

for i in range(1, 6):
    for j in range(1, i + 1):
        print(j, end=" ")
    print()
*
**
***
****
*****

*****
****
***
**
*

*
***
*****
*******
*********

1
1 2
1 2 3
1 2 3 4
1 2 3 4 5
Line-by-line explanation:
print("*" * i) → String multiplication: repeats the string i times.
for i in range(n, 0, -1): → Counts from n down to 1 (negative step).
spaces = " " * (n - i) → Calculates the number of leading spaces for the pyramid.
stars = "*" * (2 * i - 1) → Stars count: 1, 3, 5, 7, 9... (odd numbers).
for j in range(1, i + 1): → Inner loop prints numbers from 1 to i.
Why every programmer should learn this: Pattern printing trains nested loop logic, string manipulation, and algorithmic thinking. It's a classic exercise that builds mental models for more complex nested structures like matrices, trees, and grids.

🔁 The Power of Control Flow

Control flow (if, for, while) is what makes programs dynamic and interactive. Without it, programs would be a linear list of instructions. Mastering control flow is the transition from scripting to algorithmic thinking.

Function Programs

Defining and using functions — reusability and modularity

🔧 Function Basics

Functions are reusable blocks of code. This program shows parameters, return values, default arguments, and multiple returns.

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

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

def is_even(n):
    return n % 2 == 0

print(greet("Alice"))
print("5 + 3 =", add(5, 3))
print("Is 10 even?", is_even(10))
print("Is 7 even?", is_even(7))

def power(base, exponent=2):
    return base ** exponent

print("3^2 =", power(3))
print("2^5 =", power(2, 5))

def min_max(numbers):
    return min(numbers), max(numbers)

min_val, max_val = min_max([3, 1, 4, 1, 5, 9])
print("Min:", min_val, "Max:", max_val)
Hello, Alice!
5 + 3 = 8
Is 10 even? True
Is 7 even? False
3^2 = 9
2^5 = 32
Min: 1 Max: 9
Line-by-line explanation:
def greet(name): → Defines a function named greet that takes one parameter name.
return f"Hello, {name}!" → Returns a value to the caller.
def power(base, exponent=2): → exponent has a default value of 2. It can be omitted when calling.
return min(numbers), max(numbers) → Returns a tuple of two values (unpacked on the caller side).
Why every programmer should learn this: Functions are the building blocks of reusable code. They help you organize, test, and document your logic. Mastering parameters, return values, and default arguments is essential for writing clean, maintainable code.

🔄 Recursion

Functions that call themselves — solving problems by breaking them down. This program shows factorial, Fibonacci, and list sum.

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

print("5! =", factorial(5))
print("10! =", factorial(10))

def fibonacci(n):
    if n <= 1:
        return n
    return fibonacci(n - 1) + fibonacci(n - 2)

for i in range(10):
    print(fibonacci(i), end=" ")

print()

def sum_list(lst):
    if not lst:
        return 0
    return lst[0] + sum_list(lst[1:])

print("Sum [1,2,3,4] =", sum_list([1, 2, 3, 4]))
5! = 120
10! = 3628800
0 1 1 2 3 5 8 13 21 34
Sum [1,2,3,4] = 10
Line-by-line explanation:
def factorial(n): → Base case: if n <= 1: return 1 stops the recursion.
return n * factorial(n - 1) → Recursive step: calls itself with a smaller argument.
def fibonacci(n): → Each number is the sum of the previous two. Two recursive calls.
def sum_list(lst): → Recursion on a list: first element + sum of the rest (lst[1:] creates a new list — not efficient, but demonstrates the pattern).
Why every programmer should learn this: Recursion is a paradigm shift from iterative thinking. It's essential for tree traversal, divide-and-conquer algorithms, and functional programming. Understanding recursion unlocks new ways to solve complex problems.

🎯 Lambda Functions

Anonymous, one‑line functions — useful for simple operations. This program shows lambda with map, filter, sorted, and reduce.

square = lambda x: x ** 2
print("Square of 5:", square(5))

numbers = [1, 2, 3, 4, 5]
squared = list(map(lambda x: x ** 2, numbers))
print("Squared:", squared)

evens = list(filter(lambda x: x % 2 == 0, numbers))
print("Evens:", evens)

words = ["apple", "banana", "cherry", "date"]
sorted_words = sorted(words, key=lambda w: len(w))
print("Sorted by length:", sorted_words)

from functools import reduce
product = reduce(lambda a, b: a * b, numbers)
print("Product:", product)
Square of 5: 25
Squared: [1, 4, 9, 16, 25]
Evens: [2, 4]
Sorted by length: ['date', 'apple', 'banana', 'cherry']
Product: 120
Line-by-line explanation:
square = lambda x: x ** 2 → Creates an anonymous function that squares a number. Equivalent to def square(x): return x ** 2.
map(lambda x: x ** 2, numbers) → map() applies the lambda to every element in numbers.
filter(lambda x: x % 2 == 0, numbers) → filter() keeps only elements where the lambda returns True.
sorted(words, key=lambda w: len(w)) → Sorts by the length of each word.
reduce(lambda a, b: a * b, numbers) → reduce() accumulates values from left to right: (((1*2)*3)*4)*5 = 120.
Why every programmer should learn this: Lambdas enable functional programming in Python. They're used with map, filter, sorted, and reduce to write concise, readable code that processes collections elegantly.

🧩 Functions: The Art of Reusability

Functions transform you from a script writer to a program architect. They enable modularity, testability, and code reuse. Learning to design good functions is one of the most valuable skills in programming.

Object‑Oriented Programming

Classes, objects, inheritance, and polymorphism

🏗️ Class and Object

Defining a class with an initializer and methods, then creating instances.

class Car:
    def __init__(self, make, model, year):
        self.make = make
        self.model = model
        self.year = year
        self.mileage = 0

    def drive(self, miles):
        self.mileage += miles
        return f"Driven {miles} miles. Total: {self.mileage}"

    def display(self):
        return f"{self.year} {self.make} {self.model}, Mileage: {self.mileage}"

car1 = Car("Toyota", "Camry", 2020)
car2 = Car("Honda", "Civic", 2022)

print(car1.display())
print(car2.display())
print(car1.drive(150))
print(car1.display())
2020 Toyota Camry, Mileage: 0
2022 Honda Civic, Mileage: 0
Driven 150 miles. Total: 150
2020 Toyota Camry, Mileage: 150
Line-by-line explanation:
class Car: → Defines a new class. Classes are blueprints for objects.
def __init__(self, make, model, year): → The constructor. self refers to the instance being created.
self.make = make → Assigns the parameter to an instance attribute (state).
def drive(self, miles): → A method that modifies the object's state.
car1 = Car("Toyota", "Camry", 2020) → Creates an instance of the Car class.
Why every programmer should learn this: OOP is the dominant paradigm in Python and many other languages. It models real-world entities as objects with state and behavior. Understanding classes and objects is the foundation of system design and framework development.

🌿 Inheritance

Extending classes — reusing and customizing behavior. This program uses super() and demonstrates method overriding.

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

    def speak(self):
        return "Some sound"

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

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

class Bird(Animal):
    def __init__(self, name, can_fly):
        super().__init__(name)
        self.can_fly = can_fly

    def speak(self):
        return "Chirp!"

animals = [Dog("Buddy"), Cat("Whiskers"), Bird("Tweety", True)]

for animal in animals:
    print(f"{animal.name} says: {animal.speak()}")
    if isinstance(animal, Bird):
        print(f"Can fly: {animal.can_fly}")
Buddy says: Woof!
Whiskers says: Meow!
Tweety says: Chirp!
Can fly: True
Line-by-line explanation:
class Dog(Animal): → Dog inherits from Animal.
def speak(self): return "Woof!" → Overrides the parent's speak method (polymorphism).
class Bird(Animal): → Adds a new attribute can_fly.
super().__init__(name) → Calls the parent class constructor, so self.name is set correctly.
isinstance(animal, Bird) → Checks if the object is an instance of Bird (or a subclass).
Why every programmer should learn this: Inheritance enables code reuse and extensibility. It's the foundation of polymorphism — treating different objects through a common interface. This is essential for building frameworks, libraries, and large-scale systems.

🔒 Encapsulation with @property

Controlling access to attributes with getters and setters. This ensures data integrity.

class BankAccount:
    def __init__(self, owner, balance=0):
        self.owner = owner
        self._balance = balance

    @property
    def balance(self):
        return self._balance

    @balance.setter
    def balance(self, value):
        if value < 0:
            raise ValueError("Balance cannot be negative")
        self._balance = value

    def deposit(self, amount):
        if amount <= 0:
            raise ValueError("Amount must be positive")
        self._balance += amount

    def withdraw(self, amount):
        if amount > self._balance:
            raise ValueError("Insufficient funds")
        self._balance -= amount

account = BankAccount("Alice", 1000)
print(f"Balance: ${account.balance}")
account.deposit(500)
print(f"After deposit: ${account.balance}")
account.withdraw(200)
print(f"After withdrawal: ${account.balance}")
Balance: $1000
After deposit: $1500
After withdrawal: $1300
Line-by-line explanation:
self._balance = balance → The leading underscore indicates "protected" — it's not meant to be accessed directly.
@property → Decorator that makes a method accessible like an attribute: account.balance.
@balance.setter → Defines a setter method that runs when account.balance = value is called.
if value < 0: raise ValueError(...) → Validation: prevents negative balances.
Why every programmer should learn this: Encapsulation is a core OOP principle — it hides internal state and controls access through methods. @property is the Pythonic way to implement getters/setters, enabling validation, computed attributes, and maintainable APIs.

🏛️ OOP: The Language of Systems

OOP is how we model complex systems — from GUI applications to game engines. Learning classes, inheritance, and encapsulation prepares you for professional software development and framework design.

String Programs

Working with text — manipulation, formatting, and analysis

📝 String Manipulation

Common string operations — strip, case conversion, split, join, replace, find, count, and startswith/endswith.

text = "  Hello, World!  "

print("Strip:", text.strip())

print("Lower:", text.lower())
print("Upper:", text.upper())
print("Title:", text.title())

words = text.strip().split(", ")
print("Split:", words)
joined = "|".join(words)
print("Join:", joined)

replaced = text.replace("World", "Python")
print("Replace:", replaced)

print("Find 'World':", text.find("World"))
print("Count 'l':", text.count("l"))

print("Starts with 'Hello':", text.strip().startswith("Hello"))
print("Ends with '!':", text.strip().endswith("!"))
Strip: Hello, World!
Lower: hello, world!
Upper: HELLO, WORLD!
Title: Hello, World!
Split: ['Hello', 'World!']
Join: Hello|World!
Replace: Hello, Python!
Find 'World': 9
Count 'l': 3
Starts with 'Hello': True
Ends with '!': True
Line-by-line explanation:
text.strip() → Removes leading and trailing whitespace.
text.lower() → Converts all characters to lowercase. upper() → Uppercase. title() → Capitalizes each word.
text.strip().split(", ") → Splits the string into a list at each ", " delimiter.
"|".join(words) → Joins the list into a single string with "|" between elements.
text.replace("World", "Python") → Replaces all occurrences of "World" with "Python".
text.find("World") → Returns the index where "World" starts (or -1 if not found). text.count("l") → Counts occurrences.
text.strip().startswith("Hello") → Checks if the string starts with "Hello". endswith("!") → Checks the ending.
Why every programmer should learn this: String manipulation is essential for data cleaning, text processing, and user input validation. These methods are used in virtually every program that handles text — from web scraping to natural language processing.

🔍 Palindrome Checker

Check if a string reads the same forward and backward. This program normalizes by lowering case and removing spaces.

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

words = ["racecar", "A man a plan a canal Panama", "hello", "never odd or even"]

for word in words:
    result = is_palindrome(word)
    print(f"'{word}' → {result}")
'racecar' → True
'A man a plan a canal Panama' → True
'hello' → False
'never odd or even' → True
Line-by-line explanation:
text = text.lower() → Converts to lowercase to make case-insensitive checks.
text = text.lower().replace(" ", "") → Removes all spaces. This makes phrases like "never odd or even" work.
text == text[::-1] → text[::-1] reverses the string using slicing with a negative step. Returns True if the reversed string equals the original.
Why every programmer should learn this: The palindrome checker teaches string reversal, normalization, and comparison. It's a common coding interview question that demonstrates attention to edge cases (spaces, case sensitivity).

📊 Word Frequency Counter

Count how many times each word appears in a text. This program uses Counter and a manual dictionary.

from collections import Counter

text = "Python is amazing. Python is fun. Python is the best language."

words = text.lower().split()
word_counts = Counter(words)

for word, count in word_counts.most_common():
    print(f"{word}: {count}")

counts = {}
for word in words:
    counts[word] = counts.get(word, 0) + 1

print("Manual count:", counts)
python: 3
is: 3
the: 1
amazing.: 1
fun.: 1
best: 1
language.: 1
Manual count: {'python': 3, 'is': 3, 'amazing.': 1, 'fun.': 1, 'the': 1, 'best': 1, 'language.': 1}
Line-by-line explanation:
words = text.lower().split() → Converts to lowercase and splits into a list of words.
word_counts = Counter(words) → Counter from the collections module counts occurrences automatically.
word_counts.most_common() → Returns items sorted by count (descending).
counts.get(word, 0) + 1 → Manual counting: get() returns 0 if the key doesn't exist, then adds 1.
Why every programmer should learn this: Word frequency is a fundamental text analysis task used in search engines, sentiment analysis, and data mining. It introduces dictionaries, Counter, and data aggregation — skills essential for data processing.

📝 Strings: The Universal Data Format

Strings are how we handle text — the most common data type in the world. From user input to API responses, mastering string operations is crucial for data processing, web development, and natural language processing.

Math Programs

Number theory, statistics, and mathematical algorithms

🔢 Prime Number Checker

Determine if a number is prime. This program uses trial division up to the square root.

import math

def is_prime(n):
    if n < 2:
        return False
    for i in range(2, int(math.sqrt(n)) + 1):
        if n % i == 0:
            return False
    return True

test_numbers = [1, 2, 3, 4, 17, 18, 97, 100]
for n in test_numbers:
    print(f"{n}: {is_prime(n)}")

primes = [n for n in range(50) if is_prime(n)]
print("Primes up to 50:", primes)
1: False
2: True
3: True
4: False
17: True
18: False
97: True
100: False
Primes up to 50: [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47]
Line-by-line explanation:
if n < 2: return False → Numbers less than 2 are not prime.
for i in range(2, int(math.sqrt(n)) + 1): → Only need to check up to the square root (optimization).
if n % i == 0: return False → If i divides n, it's not prime.
return True → If no divisors found, it's prime.
[n for n in range(50) if is_prime(n)] → List comprehension to collect all primes up to 50.
Why every programmer should learn this: Prime checking introduces optimization (checking up to sqrt), modulo operations, and algorithm efficiency. Primes are fundamental in cryptography, hashing, and number theory.

📊 Fibonacci Sequence

Generate the Fibonacci sequence up to n terms. This program shows both iterative and generator approaches.

def fibonacci_iter(n):
    if n <= 0:
        return []
    elif n == 1:
        return [0]
    elif n == 2:
        return [0, 1]
    
    seq = [0, 1]
    for i in range(2, n):
        seq.append(seq[-1] + seq[-2])
    return seq

def fibonacci_gen(n):
    a, b = 0, 1
    for _ in range(n):
        yield a
        a, b = b, a + b

print("Fibonacci (iterative):", fibonacci_iter(10))
print("Fibonacci (generator):", list(fibonacci_gen(10)))

fibo = fibonacci_iter(50)
print("50th Fibonacci:", fibo[-1])
Fibonacci (iterative): [0, 1, 1, 2, 3, 5, 8, 13, 21, 34]
Fibonacci (generator): [0, 1, 1, 2, 3, 5, 8, 13, 21, 34]
50th Fibonacci: 7778742049
Line-by-line explanation:
def fibonacci_iter(n): → Iterative approach: builds the sequence from the bottom up.
seq = [0, 1] → Starting values. for i in range(2, n): seq.append(seq[-1] + seq[-2]) → Each new term is the sum of the previous two.
def fibonacci_gen(n): → Generator approach: uses yield to produce values lazily (memory efficient).
a, b = 0, 1 → Multiple assignment. a, b = b, a + b → Simultaneous update.
Why every programmer should learn this: Fibonacci is the classic recursive and iterative example. It teaches sequence generation, optimization, and memory efficiency (generators). Fibonacci numbers appear in nature, algorithms, and financial modeling.

📊 Statistics — Mean, Median, Mode

Calculate basic statistical measures using the statistics module.

from statistics import mean, median, mode, stdev

data = [10, 12, 14, 16, 18, 18, 20, 22, 24, 26, 28, 30, 30, 30]

print("Data:", data)
print("Count:", len(data))
print("Mean:", mean(data))
print("Median:", median(data))
print("Mode:", mode(data))
print("Standard Deviation:", stdev(data))
print("Min:", min(data))
print("Max:", max(data))
print("Sum:", sum(data))

print("Manual mean:", sum(data) / len(data))
Data: [10, 12, 14, 16, 18, 18, 20, 22, 24, 26, 28, 30, 30, 30]
Count: 14
Mean: 21.285714285714285
Median: 21.0
Mode: 30
Standard Deviation: 6.947394884291915
Min: 10
Max: 30
Sum: 298
Manual mean: 21.285714285714285
Line-by-line explanation:
from statistics import mean, median, mode, stdev → Imports specific statistical functions.
mean(data) → Average of the data set. median(data) → Middle value when sorted.
mode(data) → Most frequent value. stdev(data) → Standard deviation (measure of spread).
sum(data) / len(data) → Manual calculation of the mean.
Why every programmer should learn this: Statistics are fundamental to data analysis, machine learning, and scientific computing. The statistics module provides a quick, reliable way to compute common measures — essential for data-driven decision making.

🔄 GCD and LCM

Greatest Common Divisor and Least Common Multiple using the Euclidean algorithm.

import math

a, b = 48, 18

print("GCD (math):", math.gcd(a, b))
print("LCM (math):", abs(a * b) // math.gcd(a, b))

def gcd_euclidean(a, b):
    while b:
        a, b = b, a % b
    return a

def lcm(a, b):
    return abs(a * b) // gcd_euclidean(a, b)

print("GCD (Euclidean):", gcd_euclidean(a, b))
print("LCM:", lcm(a, b))

numbers = [24, 36, 48, 60]
result = numbers[0]
for n in numbers[1:]:
    result = math.gcd(result, n)
print("GCD of", numbers, "=", result)
GCD (math): 6
LCM (math): 144
GCD (Euclidean): 6
LCM: 144
GCD of [24, 36, 48, 60] = 12
Line-by-line explanation:
math.gcd(a, b) → Built-in GCD function.
abs(a * b) // math.gcd(a, b) → LCM formula: product divided by GCD.
def gcd_euclidean(a, b): → Manual implementation of the Euclidean algorithm.
while b: a, b = b, a % b → Repeats until b becomes 0. The GCD is a.
for n in numbers[1:]: result = math.gcd(result, n) → Computes GCD of multiple numbers sequentially.
Why every programmer should learn this: GCD and LCM are foundational in number theory, fraction arithmetic, and algorithm design. The Euclidean algorithm is one of the oldest and most efficient algorithms in mathematics — a perfect example of algorithmic thinking.

🔢 Mathematics: The Language of Algorithms

Math is the foundation of algorithmic thinking. These programs teach you optimization (prime checking), sequence generation (Fibonacci), data analysis (statistics), and number theory (GCD/LCM) — skills essential for computer science and data science.

File Handling Programs

Reading from and writing to files

📂 File Read and Write

Basic file operations — read, write, and append. The with statement ensures proper resource cleanup.

with open("sample.txt", "w", encoding="utf-8") as f:
    f.write("Hello, file!\n")
    f.write("This is line two.\n")
    f.write("Python makes file handling easy.\n")

with open("sample.txt", "r", encoding="utf-8") as f:
    content = f.read()
    print("File content:")
    print(content)

with open("sample.txt", "r", encoding="utf-8") as f:
    print("Lines:")
    for line in f:
        print(f"  {line.strip()}")

with open("sample.txt", "a", encoding="utf-8") as f:
    f.write("This line is appended.\n")
File content:
Hello, file!
This is line two.
Python makes file handling easy.

Lines:
Hello, file!
This is line two.
Python makes file handling easy.
This line is appended.
Line-by-line explanation:
with open("sample.txt", "w", encoding="utf-8") as f: → Opens the file in write mode ("w"). The with statement ensures the file is properly closed after the block.
f.write("Hello, file!\n") → Writes a string to the file. \n adds a newline.
content = f.read() → Reads the entire file content into a string.
for line in f: → Iterates over the file line by line (memory efficient for large files).
open("sample.txt", "a") → Open in append mode: adds content to the end of the file.
Why every programmer should learn this: File handling is essential for data persistence, logging, and configuration management. The with statement is the Pythonic way to manage resources — preventing memory leaks and corrupted files.

📊 CSV File Processing

Reading and writing CSV files using the csv module. This program uses csv.writer and csv.DictReader.

import csv

data = [
    ["Name", "Age", "City"],
    ["Alice", 25, "NYC"],
    ["Bob", 30, "LA"],
    ["Charlie", 35, "Chicago"]
]

with open("people.csv", "w", newline="", encoding="utf-8") as f:
    writer = csv.writer(f)
    writer.writerows(data)

with open("people.csv", "r", encoding="utf-8") as f:
    reader = csv.reader(f)
    for row in reader:
        print(row)

with open("people.csv", "r", encoding="utf-8") as f:
    reader = csv.DictReader(f)
    for row in reader:
        print(f"{row['Name']} is {row['Age']} years old from {row['City']}")
['Name', 'Age', 'City']
['Alice', '25', 'NYC']
['Bob', '30', 'LA']
['Charlie', '35', 'Chicago']
Alice is 25 years old from NYC
Bob is 30 years old from LA
Charlie is 35 years old from Chicago
Line-by-line explanation:
import csv → Imports the CSV module for handling comma-separated values.
with open("people.csv", "w", newline="") as f: → newline="" prevents extra blank lines on Windows.
writer = csv.writer(f) → Creates a CSV writer. writer.writerows(data) → Writes all rows at once.
reader = csv.reader(f) → Creates a CSV reader. Iterating gives each row as a list.
reader = csv.DictReader(f) → Reads CSV as dictionaries using the header row as keys.
Why every programmer should learn this: CSV is the universal data exchange format for spreadsheets and databases. The csv module is essential for data import/export, data cleaning, and report generation.

💾 File Handling: The Bridge Between Programs and Data

File handling is how programs persist data and communicate with other systems. Mastering file operations — text, CSV, JSON — is essential for data pipelines, application configuration, and system integration.

Advanced Programs

Decorators, generators, comprehensions, and more

🎨 Decorator Example

Functions that wrap other functions — timing, logging, and more. This program shows a timer and logging decorator.

import functools, time

def timer(func):
    @functools.wraps(func)
    def wrapper(*args, **kwargs):
        start = time.perf_counter()
        result = func(*args, **kwargs)
        elapsed = time.perf_counter() - start
        print(f"{func.__name__} took {elapsed:.4f} seconds")
        return result
    return wrapper

def log(func):
    @functools.wraps(func)
    def wrapper(*args, **kwargs):
        print(f"Calling {func.__name__} with args={args}, kwargs={kwargs}")
        result = func(*args, **kwargs)
        print(f"{func.__name__} returned {result}")
        return result
    return wrapper

@timer
def slow_function():
    time.sleep(0.5)
    return "Done"

@log
@timer
def add(a, b):
    return a + b

print(slow_function())
print(add(3, 4))
slow_function took 0.5012 seconds
Done
Calling add with args=(3, 4), kwargs={}
add took 0.0000 seconds
add returned 7
7
Line-by-line explanation:
def timer(func): → Decorator function that takes a function as an argument.
@functools.wraps(func) → Preserves the original function's metadata (name, docstring).
def wrapper(*args, **kwargs): → Inner function that wraps the original. *args and **kwargs handle any arguments.
start = time.perf_counter() → High-precision timer. elapsed = time.perf_counter() - start → Calculates elapsed time.
@timer → Applies the timer decorator. @log → Applies the log decorator. Decorators can be stacked.
time.sleep(0.5) → Pauses the program for 0.5 seconds (to demonstrate timing).
Why every programmer should learn this: Decorators are a powerful Python feature used extensively in frameworks like Flask (routes), Django (permissions), and pytest (fixtures). They enable separation of concerns and code reuse.

📦 Generator Example

Memory‑efficient iteration with yield. This program shows a generator for squares, generator expressions, and reading large files.

def squares(n):
    for i in range(n):
        yield i ** 2

for sq in squares(5):
    print(sq, end=" ")
print()

list_comp = [x**2 for x in range(5)]
gen_exp = (x**2 for x in range(5))

print("List comprehension:", list_comp)
print("Generator expression:", list(gen_exp))

def read_large_file(filename):
    with open(filename, "r", encoding="utf-8") as f:
        for line in f:
            yield line.strip()

for line in read_large_file("sample.txt"):
    print("Line:", line)
0 1 4 9 16
List comprehension: [0, 1, 4, 9, 16]
Generator expression: [0, 1, 4, 9, 16]
Line: Hello, file!
Line: This is line two.
Line: Python makes file handling easy.
Line: This line is appended.
Line-by-line explanation:
def squares(n): for i in range(n): yield i ** 2 → A generator function. yield produces values lazily — one at a time.
list_comp = [x**2 for x in range(5)] → List comprehension: creates the entire list in memory.
gen_exp = (x**2 for x in range(5)) → Generator expression: parentheses instead of brackets. Produces values on demand.
def read_large_file(filename): ... yield line.strip() → Reads a file line by line without loading the whole file into memory — essential for large files.
Why every programmer should learn this: Generators enable memory-efficient programming — processing data streams without loading everything into memory. They're essential for big data, streaming, and infinite sequences.

🔧 List Comprehensions

Clean, concise way to create lists. This program shows basic comprehension, conditions, nested, flattening, dictionary and set comprehensions.

squares = [x**2 for x in range(10)]
print("Squares:", squares)

evens = [x for x in range(20) if x % 2 == 0]
print("Evens:", evens)

matrix = [[i * j for j in range(1, 4)] for i in range(1, 4)]
for row in matrix:
    print(row)

nested = [[1, 2], [3, 4, 5], [6, 7]]
flattened = [item for sublist in nested for item in sublist]
print("Flattened:", flattened)

pairs = [(1, "one"), (2, "two"), (3, "three")]
dict_comp = {k: v for k, v in pairs}
print("Dictionary:", dict_comp)

set_comp = {x**2 for x in [1, 2, 2, 3, 3, 3]}
print("Set:", set_comp)
Squares: [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
Evens: [0, 2, 4, 6, 8, 10, 12, 14, 16, 18]
[1, 2, 3]
[2, 4, 6]
[3, 6, 9]
Flattened: [1, 2, 3, 4, 5, 6, 7]
Dictionary: {1: 'one', 2: 'two', 3: 'three'}
Set: {1, 4, 9}
Line-by-line explanation:
[x**2 for x in range(10)] → Basic list comprehension: square each number.
[x for x in range(20) if x % 2 == 0] → With condition: keep only even numbers.
[[i * j for j in range(1, 4)] for i in range(1, 4)] → Nested comprehension: creates a 3x3 multiplication table.
[item for sublist in nested for item in sublist] → Flattening: two for clauses in the comprehension (order is outer to inner).
{k: v for k, v in pairs} → Dictionary comprehension: creates a dictionary from key-value pairs.
{x**2 for x in [1, 2, 2, 3, 3, 3]} → Set comprehension: deduplicates automatically.
Why every programmer should learn this: Comprehensions are Pythonic — they make code shorter, faster, and more readable. They're used extensively in data processing, transformation pipelines, and functional programming.

🧵 Exception Handling

Graceful error handling with try/except/finally. This program also shows custom exceptions.

def safe_divide(a, b):
    try:
        result = a / b
    except ZeroDivisionError:
        return "Cannot divide by zero"
    except TypeError:
        return "Invalid types provided"
    except Exception as e:
        return f"Unexpected error: {e}"
    else:
        return result
    finally:
        print("Division attempted")

print(safe_divide(10, 2))
print(safe_divide(10, 0))
print(safe_divide(10, "2"))

class ValidationError(Exception):
    pass

def validate_age(age):
    if age < 0:
        raise ValidationError("Age cannot be negative")
    if age > 150:
        raise ValidationError("Age seems unrealistic")
    return "Valid age"

try:
    print(validate_age(25))
    print(validate_age(-5))
except ValidationError as e:
    print("Error:", e)
Division attempted
5.0
Division attempted
Cannot divide by zero
Division attempted
Invalid types provided
Valid age
Error: Age cannot be negative
Line-by-line explanation:
try: result = a / b → The code that might raise an exception.
except ZeroDivisionError: → Catches a specific exception type (division by zero).
except Exception as e: → Catches any other exception (catch-all).
else: → Runs only if no exception was raised.
finally: → Always runs, regardless of whether an exception occurred (good for cleanup).
raise ValidationError("...") → Manually raises a custom exception.
Why every programmer should learn this: Exception handling is what makes programs robust and user-friendly. It prevents crashes, provides meaningful error messages, and ensures graceful degradation — essential for production software.

🚀 Advanced Python: The Professional Toolkit

Decorators, generators, comprehensions, and exception handling are the tools of professional Python developers. They enable clean, efficient, and maintainable code — the hallmark of experienced programmers.

Sample Programs FAQ

Quick answers about these examples

How do I run these programs?

+

Click the "Run" button below each code snippet to see the output. Or click "Copy" to copy the code and run it on your own machine with python filename.py.

Can I modify the code?

+

Absolutely! Copy the code and modify it to experiment. The "Run" button shows the original output, but you can paste the code into a file or an online Python editor to try your own variations.

What Python version do these programs use?

+

All programs are written for Python 3.10+ and use features like f‑strings, the statistics module, and modern type hints where appropriate.

How can I practice more?

+

After understanding each program, try modifying it — change the input, add new features, or combine concepts. The best way to learn is to write code yourself.

Where can I find more Python examples?

+

Check the other lesson pages on Poetic Bytes — we have dedicated pages for data science, web development, backend, machine learning, and automation with even more examples.

🎓 Congratulations — You've Completed the Python Sample Programs!

From "Hello World" to decorators and generators, you've explored 100+ Python programs with line-by-line explanations. Each program taught you a specific concept — building your mental model of Python, one example at a time.

Remember: programming is a skill that grows with practice. Revisit these examples, modify them, and write your own versions. The journey from beginner to master is paved with code — keep writing, keep learning.

⬆️ Back to Basics 🏠 Back to Home