Introduction & Setup
What is Python?
Python is a high-level, interpreted, dynamically-typed programming language known for its readability and simplicity. It was created by Guido van Rossum and officially released in 1991. Python was designed with one major goal in mind: making programming easier to read, write, and understand.
Unlike many older programming languages that require complex syntax, Python uses clean and straightforward code that closely resembles the English language. This makes it one of the best programming languages for beginners while remaining powerful enough for professionals working on enterprise applications.
Today, Python is one of the most popular programming languages in the world. It is used by students, software engineers, scientists, researchers, cybersecurity experts, game developers, automation engineers, and companies such as Google, Netflix, NASA, Microsoft, Dropbox, Spotify, and Instagram.
- Readable Syntax: Python code is clean and resembles normal English, making programs easier to understand.
- Interpreted: Python executes code line by line instead of compiling the entire program first, making testing and debugging much faster.
- Dynamically Typed: You don't need to declare variable data types manually. Python automatically determines the appropriate type during execution.
- Multi-paradigm: Supports Procedural Programming, Object-Oriented Programming (OOP), and Functional Programming.
- Cross Platform: Python programs can run on Windows, Linux, and macOS with little or no modification.
- Massive Ecosystem: Python has thousands of free libraries that help developers build websites, AI applications, desktop software, games, automation scripts, APIs, and scientific software.
- Large Community: Millions of developers contribute tutorials, libraries, and solutions, making it easy to find help whenever you encounter a problem.
Why Learn Python?
Python is often recommended as the first programming language because it allows beginners to focus on learning programming concepts rather than complicated syntax. Once you understand Python, learning other programming languages becomes much easier.
Another reason Python is so popular is its versatility. Instead of learning different languages for different tasks, Python can be used across many fields of software development.
- Web Development
- Artificial Intelligence (AI)
- Machine Learning
- Data Science and Data Analysis
- Automation and Scripting
- Cybersecurity Tools
- Desktop Applications
- Game Development
- Internet of Things (IoT)
- Cloud Computing
How Python Works
Python is called an interpreted language because it uses an interpreter to execute your code. When you run a Python program, the interpreter reads your program one line at a time, converts it into instructions the computer understands, and executes those instructions immediately.
This process makes development much faster because you don't have to compile the entire project every time you make a small change.
- You write Python code inside a .py file.
- The Python Interpreter reads your code.
- Python checks for syntax errors.
- If no errors are found, the program executes from top to bottom.
- The results are displayed in the terminal or command prompt.
Setting Up the Environment
Before writing Python programs, you need to install Python on your computer. The official installer can be downloaded from python.org.
During installation, make sure to enable the option that says "Add Python to PATH". This allows you to run Python from any terminal or command prompt without needing to specify its installation location manually.
Once installation is complete, open your Command Prompt (Windows) or Terminal (Linux/macOS) and type:
python --version
If Python is installed correctly, you'll see the installed version displayed, for example:
Python 3.13.0
If the python command doesn't work, try:
python3 --version
Choosing a Code Editor
You can write Python programs using any text editor, but using a proper code editor makes development much easier. Modern editors provide syntax highlighting, error detection, auto-completion, and debugging tools.
- Visual Studio Code (VS Code)
- PyCharm
- Sublime Text
- Notepad++
- IDLE (Included with Python)
Writing Your First Program
Traditionally, the first program every programmer writes is called Hello, World!. Although it is very simple, it teaches you how to create a Python file and execute your first program.
Create a new file named hello.py and type the following code:
print("Hello, World!")
Save the file and open your terminal. Navigate to the folder where the file is saved, then run:
python hello.py
The output should be:
Hello, World!
Understanding the print() Function
The print() function is one of the most frequently used functions in Python. It displays information on the screen so users can see messages, numbers, variables, or the results of calculations.
Everything placed inside the parentheses of the print() function is displayed in the console.
print("Welcome to Python!")
print(100)
print(25 + 15)
The output will be:
Welcome to Python! 100 40
- Save every Python program with the .py extension.
- Python is case-sensitive. For example,
Print()is different fromprint(). - Read error messages carefullyβthey often tell you exactly what went wrong.
- Practice writing small programs regularly to improve your programming skills.
- Experiment with the code by changing values and observing the output.
Complete the following tasks:
- Install Python on your computer.
- Verify the installation using
python --version. - Create a file named hello.py.
- Write the "Hello, World!" program.
- Run the program from your terminal or command prompt.
- Modify the program to display your own name.
- Finally, run the following command to verify your installation:
python -c "print('Python is set up successfully!')"
Variables & Data Types
Variables and Dynamic Typing
A variable is a named location in memory used to store data that can be accessed and modified throughout a program. Variables allow programmers to save information such as numbers, text, or logical values so they can be reused whenever needed.
Unlike some programming languages, Python does not require you to declare the data type of a variable before using it. Instead, Python automatically creates the variable when you assign a value using the assignment operator (=).
This feature is known as dynamic typing. Python determines the variable's data type automatically based on the value assigned to it. If the value changes, the variable's data type can also change.
- A variable stores information in memory.
- The variable name acts as a label for accessing that information.
- Variables can be updated as many times as needed.
- Python automatically determines the appropriate data type.
- No special keywords are required to create variables.
For example:
message = "Hello" print(message) message = "Welcome to Python" print(message)
Notice that the variable message is reused with a different value. This is completely normal in Python.
Dynamic Typing Example
Because Python is dynamically typed, a variable can even change from one data type to another during program execution.
value = 100 print(type(value)) value = "One Hundred" print(type(value)) value = True print(type(value))
Although Python allows this flexibility, constantly changing a variable's data type can make programs difficult to understand. It is considered good practice to keep variables representing the same kind of information.
Variable Naming Rules
Python has several rules that every variable name must follow.
- Variable names can contain letters, numbers, and underscores (
_). - A variable name cannot begin with a number.
- Variable names are case-sensitive.
- Spaces are not allowed inside variable names.
- Avoid using Python keywords such as
if,for, orwhileas variable names.
Examples of valid variable names:
student_name = "Alice" age = 18 total_marks = 450 price2 = 199.99 _is_logged_in = True
Examples of invalid variable names:
2price = 50 # Starts with a number student name = "Bob" # Contains a space for = 10 # Python keyword
Variable Naming Conventions
Although Python allows many naming styles, professional Python developers generally follow the snake_case naming convention.
student_nameβοΈtotal_marksβοΈaccount_balanceβοΈStudentNameβ (Usually reserved for classes)studentNameβ (Less common in Python)
Standard Data Types
Every value stored in Python belongs to a particular data type. The data type determines what kind of information the value represents and what operations can be performed on it.
The four most common built-in data types are:
- Integers (int): Whole numbers without decimal places, such as
5,100, and-25. - Floating Point Numbers (float): Numbers containing decimal points, such as
3.14,99.95, and-0.5. - Strings (str): Text enclosed inside single or double quotation marks.
- Booleans (bool): Logical values that can only be
TrueorFalse.
- int: 1, 20, -100
- float: 5.5, 100.01, -8.2
- str: "Python", "Hello World"
- bool: True, False
Creating Variables
Creating variables in Python is simple. Assign a value using the assignment operator (=).
age = 25 # Integer price = 19.99 # Float name = "CodeTutor" # String is_active = True # Boolean print(type(age)) # Output: <class 'int'> print(type(price)) # Output: <class 'float'> print(type(name)) # Output: <class 'str'> print(type(is_active))# Output: <class 'bool'>
The type() Function
The type() function is used to determine the data type of any value or variable. This function is especially useful while learning Python because it allows you to verify exactly what type of data Python has assigned.
x = 50 y = 3.14 z = "Python" print(type(x)) print(type(y)) print(type(z))
Multiple Variable Assignment
Python also allows multiple variables to be assigned in a single line.
x, y, z = 10, 20, 30 print(x) print(y) print(z)
You can also assign the same value to multiple variables.
a = b = c = 100 print(a) print(b) print(c)
Best Practices
- Use meaningful variable names.
- Avoid very short names unless used for simple loops.
- Use
snake_casefor multi-word variable names. - Keep variables related to one purpose.
- Choose names that describe the data they store.
Common Beginner Mistakes
- Using spaces in variable names.
- Starting variable names with numbers.
- Confusing
=(assignment) with==(comparison). - Misspelling variable names.
- Using reserved Python keywords as variable names.
Create a Python program that performs the following tasks:
- Create a variable for a book title.
- Create a variable for the author's name.
- Create a variable for the book price.
- Create a variable for the book rating out of 5.
- Create a variable that stores whether the book is currently in stock.
- Print each variable.
- Use the
type()function to display the data type of every variable. - Change one variable to a different data type and observe how Python automatically updates its type.
Operators & Expressions
What are Operators?
Operators are special symbols that tell Python to perform a particular operation on one or more values. These values are called operands. Operators allow programmers to perform calculations, compare values, combine conditions, assign data to variables, and much more.
For example, in the expression 5 + 3, the + symbol is an operator, while 5 and 3 are operands. Python evaluates the expression and returns the result 8.
Operators are one of the most important building blocks of programming because nearly every program performs some type of calculation or decision using operators.
- Arithmetic Operators
- Assignment Operators
- Comparison Operators
- Logical Operators
- Identity Operators
- Membership Operators
- Bitwise Operators (Advanced)
What are Expressions?
An expression is a combination of values, variables, operators, and function calls that Python evaluates to produce a single result.
For example:
x = 10 y = 5 result = x + y print(result)
The expression x + y is evaluated first, and the result is then stored in the variable result.
Arithmetic Operators
Arithmetic operators are used with numeric values to perform common mathematical calculations. They work with integers and floating-point numbers.
+Addition-Subtraction*Multiplication/Division (Always returns a float)//Floor Division (Returns the whole-number quotient)%Modulus (Returns the remainder)**Exponentiation (Raises one number to the power of another)
a = 15 b = 4 print(a + b) print(a - b) print(a * b) print(a / b) print(a // b) print(a % b) print(a ** b)
Output:
19 11 60 3.75 3 3 50625
Understanding Each Arithmetic Operator
Addition (+) adds two numbers together.
print(10 + 5)
Subtraction (-) subtracts one value from another.
print(20 - 7)
Multiplication (*) multiplies two numbers.
print(6 * 8)
Division (/) divides one number by another. The result is always a floating-point number.
print(20 / 4) print(5 / 2)
Floor Division (//) removes the decimal portion and returns only the whole number.
print(20 // 4) print(5 // 2)
Modulus (%) returns the remainder after division.
print(10 % 3) print(18 % 5)
Exponentiation (**) raises one number to the power of another.
print(2 ** 3) print(5 ** 2)
Assignment Operators
Assignment operators are used to store values inside variables. Python also provides shorthand assignment operators that combine arithmetic with assignment.
=Assign value+=Add and assign-=Subtract and assign*=Multiply and assign/=Divide and assign//=Floor divide and assign%=Modulus and assign**=Exponentiate and assign
score = 50 score += 10 score *= 2 print(score)
Comparison Operators
Comparison operators compare two values and always return either True or False. They are commonly used when making decisions in a program.
==Equal to!=Not equal to>Greater than<Less than>=Greater than or equal to<=Less than or equal to
age = 18 print(age == 18) print(age != 20) print(age > 15) print(age < 30)
Logical Operators
Logical operators combine multiple conditions together. They are mainly used with comparison operators to build more complex decision-making statements.
andReturns True if both conditions are True.orReturns True if at least one condition is True.notReverses the Boolean value.
has_discount = True is_member = False print(has_discount and is_member) print(has_discount or is_member) print(not is_member)
Identity Operators
Identity operators compare whether two variables refer to the same object in memory.
isReturns True if both variables reference the same object.is notReturns True if they reference different objects.
x = [1, 2] y = x print(x is y) print(x is not y)
Membership Operators
Membership operators check whether a value exists inside a sequence such as a string, list, or tuple.
inReturns True if the value exists.not inReturns True if the value does not exist.
language = "Python"
print("P" in language)
print("Java" not in language)
Operator Precedence
When an expression contains multiple operators, Python follows a specific order of operations known as operator precedence.
- () Parentheses
- ** Exponentiation
- * / // % Multiplication, Division, Floor Division, Modulus
- + - Addition and Subtraction
- Comparison Operators
- not
- and
- or
result = 10 + 5 * 2 print(result) result = (10 + 5) * 2 print(result)
Common Beginner Mistakes
- Using
=instead of==for comparisons. - Forgetting that
/always returns a float. - Confusing
//with/. - Ignoring operator precedence.
- Using logical operators with incorrect conditions.
# Arithmetic result = 10 // 3 remainder = 10 % 3 power = 2 ** 3 # Comparison & Logical has_discount = True is_member = False can_buy = has_discount and not is_member print(result) print(remainder) print(power) print(can_buy)
Complete the following tasks:
- Create variables for the radius and the value of
pi. - Calculate the area of a circle using the formula
pi * radius ** 2. - Print the calculated area.
- Determine whether the area is greater than 100 using a comparison operator.
- Create two Boolean variables and combine them using the
and,or, andnotoperators. - Experiment with parentheses to observe how operator precedence changes the result.
Control Flow
Conditional Statements
Conditional structures allow a program to make decisions and execute different blocks of code based on conditions. Python uses the keywords if, elif (else if), and else.
Every program needs a way to make decisions. Imagine a login system checking whether a password is correct, or a game deciding whether the player has won or lost. These are examples of decision-making, also known as control flow. Instead of executing every line of code from top to bottom, Python can choose which code to execute depending on whether a condition is True or False.
A condition is simply an expression that evaluates to either True or False. Python evaluates the condition first, and then executes the appropriate block of code.
Unlike languages like C++ or Java that use curly braces {} to define code blocks, Python relies entirely on indentation (typically 4 spaces). Incorrect indentation will cause an IndentationError.
Comparison Operators
Conditional statements usually work together with comparison operators. These operators compare two values and return either True or False.
age = 20 print(age == 20) # True print(age != 18) # True print(age > 18) # True print(age < 18) # False print(age >= 20) # True print(age <= 21) # True
The most common comparison operators are:
==Equal to!=Not equal to>Greater than<Less than>=Greater than or equal to<=Less than or equal to
The if Statement
The if statement executes a block of code only if its condition is True. If the condition is False, Python skips that block and continues with the next statement.
temperature = 35
if temperature > 30:
print("It is a hot day.")
Since the condition temperature > 30 is true, the message will be displayed.
The if...else Statement
The else block runs when the condition inside the if statement is false. It provides an alternative path for the program.
age = 16
if age >= 18:
print("You are an adult.")
else:
print("You are a minor.")
The if...elif...else Statement
Sometimes there are more than two possible outcomes. The elif keyword allows Python to check additional conditions after the first one.
score = 85
if score >= 90:
print("Grade: A")
elif score >= 80:
print("Grade: B") # This block runs
else:
print("Grade: C")
Python checks each condition from top to bottom. As soon as one condition becomes True, its block executes and the remaining conditions are ignored.
Flow of Execution
The order in which Python evaluates an if-elif-else statement is:
- Evaluate the
ifcondition. - If it is true, execute that block and skip the rest.
- If it is false, evaluate the first
elif. - Continue checking each
elifuntil one is true. - If none of the conditions are true, execute the
elseblock.
Logical Operators
Sometimes you need to combine multiple conditions. Python provides logical operators for this purpose.
andβ Both conditions must be true.orβ At least one condition must be true.notβ Reverses a condition.
age = 25
has_id = True
if age >= 18 and has_id:
print("Access granted.")
is_weekend = False
is_holiday = True
if is_weekend or is_holiday:
print("You can relax today!")
logged_in = False
if not logged_in:
print("Please log in.")
Nested Conditional Statements
You can place one conditional statement inside another. This is called nesting.
age = 22
citizen = True
if age >= 18:
if citizen:
print("Eligible to vote.")
else:
print("Citizenship required.")
else:
print("Too young to vote.")
Common Mistakes
Beginners often make these mistakes:
- Using
=instead of==when comparing values. - Forgetting to add a colon
:afterif,elif, orelse. - Incorrect indentation.
- Writing multiple
elseblocks for the sameifstatement. - Checking conditions in the wrong order, causing some conditions to never execute.
Real-World Applications
Conditional statements are used in almost every Python application, including:
- Login and authentication systems.
- ATM and banking software.
- Games that respond to player actions.
- Weather applications.
- Student grading systems.
- E-commerce websites that calculate discounts.
- Security systems that verify permissions.
Summary
In this lesson you learned how Python controls the flow of a program using conditional statements. You learned how to use if, elif, and else, how comparison and logical operators work, how nested conditions are written, and some common mistakes to avoid. These concepts are essential because they allow programs to make intelligent decisions based on different situations.
Write a program that takes a number and prints whether it is "Positive", "Negative", or "Zero". Add checking to see if it is even or odd if it is positive.
Bonus Challenges:
- Ask the user to enter their age and determine whether they are a child, teenager, adult, or senior.
- Create a simple grading system that prints A, B, C, D, or F based on a student's score.
- Write a program that asks for a username and password and displays whether login is successful.
- Ask the user to enter three numbers and print the largest number.
- Create a calculator that asks the user to choose an operation (+, -, *, /) and performs the selected calculation.
Loops & Iteration
Introduction to Loops
Loops are one of the most important programming concepts in Python. They allow you to execute the same block of code multiple times without writing it repeatedly. Instead of copying and pasting the same code over and over, you can place it inside a loop and let Python repeat it automatically.
Loops are useful whenever you need to process collections of data, repeat calculations, validate user input, search through information, or automate repetitive tasks. Nearly every real-world Python program uses loops in some form.
- Reduce duplicate code.
- Process large amounts of data efficiently.
- Repeat actions automatically.
- Iterate through lists, strings, tuples, dictionaries, and other collections.
- Create cleaner, shorter, and easier-to-maintain programs.
What is Iteration?
Iteration means repeating a process multiple times. Each time a loop executes its body, it completes one iteration. The loop continues running until its stopping condition is met or until it reaches the end of the sequence it is iterating over.
For example, if a loop prints numbers from 1 to 5, it performs five separate iterations.
While Loops
A while loop repeatedly executes a block of code as long as a specified condition evaluates to True. Before each iteration, Python checks the condition. If it remains true, the loop continues. Once the condition becomes false, the loop stops.
A while loop is useful when you do not know exactly how many times a task should repeat.
- Python checks the condition.
- If the condition is
True, the loop body executes. - After execution, Python checks the condition again.
- The process repeats until the condition becomes
False.
count = 1
while count <= 5:
print(count)
count += 1
Output:
1 2 3 4 5
Notice that the variable count increases during each iteration. Eventually the condition count <= 5 becomes false, causing the loop to terminate.
Infinite Loops
An infinite loop occurs when the loop condition never becomes false. This causes the loop to run forever until the program is manually stopped.
while True:
print("This loop never ends!")
Infinite loops are sometimes useful in applications such as games, servers, or continuously running programs, but they should usually contain a break statement to provide a way to exit.
For Loops
A for loop is used to iterate over a sequence such as a string, list, tuple, dictionary, set, or the values produced by the range() function.
Unlike a while loop, a for loop automatically moves to the next item in the sequence until every element has been processed.
fruits = ["Apple", "Banana", "Orange"]
for fruit in fruits:
print(fruit)
The range() Function
The range() function generates a sequence of numbers and is commonly used with for loops when you want to repeat a task a specific number of times.
range(stop)range(start, stop)range(start, stop, step)
for i in range(5):
print(i)
print()
for i in range(1, 6):
print(i)
print()
for i in range(2, 11, 2):
print(i)
Output:
0 1 2 3 4 1 2 3 4 5 2 4 6 8 10
Looping Through Strings
Strings are sequences of characters, so they can also be iterated one character at a time.
word = "Python"
for letter in word:
print(letter)
Nested Loops
A nested loop is simply a loop inside another loop. Nested loops are useful when working with tables, grids, matrices, or when comparing multiple values.
for i in range(1, 4):
for j in range(1, 4):
print(i, j)
Loop Control Statements
Python provides several statements that change the normal behavior of loops.
breakβ Immediately terminates the loop.continueβ Skips the current iteration and continues with the next one.passβ Does nothing and acts as a placeholder.
The break Statement
The break statement exits the loop immediately, even if there are more iterations remaining.
for number in range(1, 10):
if number == 6:
break
print(number)
The continue Statement
The continue statement skips the current iteration and moves directly to the next one.
for number in range(1, 6):
if number == 3:
continue
print(number)
The pass Statement
The pass statement is used when Python expects a block of code but you do not want to write any functionality yet. It is commonly used while developing programs.
for i in range(5):
pass
Complete Example
# For loop with range
for i in range(1, 6):
if i == 3:
continue
print(i)
print()
# While loop with break
count = 0
while True:
print("Count:", count)
count += 1
if count >= 3:
break
Real-World Uses of Loops
- Reading files line by line.
- Processing lists of students or products.
- Searching for specific information.
- Generating reports.
- Creating games and animations.
- Automating repetitive computer tasks.
- Validating user input.
- Machine learning and data analysis.
Common Beginner Mistakes
- Forgetting to update the loop variable in a
whileloop. - Creating accidental infinite loops.
- Incorrect indentation inside loops.
- Using
breakwhencontinueis intended. - Using the wrong range values.
Complete the following programming exercises:
- Print the numbers from 1 to 20 using a
forloop. - Print only the even numbers between 1 and 20.
- Use a
whileloop to count backwards from 10 to 1. - Create a multiplication table for the number 7.
- Print every character of your name using a
forloop. - Write a program that prints all prime numbers between 2 and 30 using nested loops and the
breakstatement. - Modify the prime number program so it counts how many prime numbers were found.
Functions & Scope
Defining and Calling Functions
Functions are blocks of organized, reusable code used to perform a single related action. In Python, functions are defined using the def keyword, followed by the function name and parentheses containing parameters.
Functions help programmers avoid writing the same code repeatedly. Instead of copying and pasting code multiple times, you can place it inside a function and call it whenever it is needed. This makes programs shorter, easier to read, easier to debug, and much easier to maintain.
Think of a function as a small machine. You provide it with some input (arguments), it performs a task, and it may produce an output (a return value). Every function should ideally perform one specific job.
def greet():
print("Hello, World!")
greet()
When Python reaches greet(), it jumps to the function, executes its code, and then returns to the next line after the function call.
Function Naming
Function names should clearly describe what the function does. According to Python's naming convention (PEP 8), function names should be written in lowercase with words separated by underscores.
def calculate_area():
pass
def print_report():
pass
def send_email():
pass
Arguments and Parameters
A parameter is a variable listed in a function definition, while an argument is the actual value passed to the function when it is called.
def greet(name):
print("Hello", name)
greet("Alice")
greet("John")
In this example, name is the parameter, while "Alice" and "John" are arguments.
Arguments and Return Values
Functions can accept arguments and return values using the return statement. If no return value is specified, the function returns None. Python supports default arguments, keyword arguments, and arbitrary arguments (*args and **kwargs).
The return statement sends a value back to the part of the program that called the function. Once a return statement executes, the function immediately stops running.
def square(number):
return number * number
result = square(6)
print(result)
Default Arguments
Default arguments allow a function to use a predefined value if no argument is supplied by the caller.
def greet(name, message="Welcome"):
print(f"{message}, {name}")
greet("Alice")
greet("Bob", "Good Morning")
If no second argument is provided, Python automatically uses the default value.
Keyword Arguments
Python allows arguments to be passed using their parameter names. These are called keyword arguments.
def introduce(name, age):
print(name, age)
introduce(age=20, name="Alice")
Keyword arguments improve readability and allow arguments to be supplied in any order.
Arbitrary Arguments
Sometimes you do not know how many arguments will be passed. Python provides *args and **kwargs for these situations.
def total(*numbers):
print(sum(numbers))
total(10, 20)
total(10, 20, 30, 40)
def display(**person):
print(person["name"])
print(person["age"])
display(name="Alice", age=25)
Variable Scope
Variables defined inside a function are in the local scope and cannot be accessed outside. Variables defined outside are in the global scope. Use the global keyword to modify a global variable inside a function.
Scope determines where a variable can be accessed in your program. Understanding scope helps prevent unexpected errors and makes programs easier to understand.
Local Variables
Variables created inside a function exist only while that function is running.
def example():
message = "Inside function"
print(message)
example()
The variable message cannot be accessed outside the function because it belongs to the local scope.
Global Variables
Variables created outside every function belong to the global scope. They can usually be accessed from anywhere in the program.
language = "Python"
def show_language():
print(language)
show_language()
The global Keyword
Normally, assigning a value to a variable inside a function creates a new local variable. To modify a global variable, you must use the global keyword.
def greet(name, message="Welcome"):
return f"Hello {name}, {message}!"
# Call function
greeting = greet("Alice")
print(greeting) # Output: Hello Alice, Welcome!
# Variable Scope
total = 0 # Global variable
def add_to_total(amount):
global total
total += amount
add_to_total(25)
print(total)
Why Functions Are Important
Functions provide several advantages when writing software:
- Reduce duplicated code.
- Make programs easier to read.
- Allow code to be reused throughout a project.
- Make debugging easier because each function performs one task.
- Help organize large programs into smaller, manageable sections.
- Allow multiple programmers to work on different parts of the same project.
Common Mistakes
- Forgetting the parentheses when calling a function.
- Using the wrong number of arguments.
- Confusing parameters with arguments.
- Trying to use local variables outside their function.
- Forgetting to use
returnwhen a value should be sent back. - Modifying global variables without the
globalkeyword.
Real-World Applications
Functions are used everywhere in software development, including:
- User authentication systems.
- Mathematical calculations.
- Database operations.
- Processing user input.
- File handling.
- Web applications.
- Game development.
- Machine learning projects.
Summary
Functions are one of the most powerful features in Python. They allow programmers to organize code into reusable blocks that perform specific tasks. In this lesson you learned how to define functions, pass arguments, return values, use default and keyword arguments, work with *args and **kwargs, understand local and global scope, and avoid common mistakes. Mastering functions is an essential step toward writing clean, efficient, and professional Python programs.
Create a function called calculate_tax that accepts a subtotal price and an optional tax rate (defaulting to 0.08). The function should return the total price including tax.
Bonus Challenges:
- Create a function that converts Celsius to Fahrenheit.
- Write a function that returns the largest of three numbers.
- Create a function that counts the number of vowels in a string.
- Write a function using
*argsthat calculates the average of any number of values. - Create a simple calculator using separate functions for addition, subtraction, multiplication, and division.
Lists & Tuples
Lists (Mutable Sequences)
A list is a ordered, mutable collection of items. Lists can contain items of different data types, and allow duplicate values. Items are indexable starting from 0, and support negative indexing (counting from the end).
Tuples (Immutable Sequences)
A tuple is similar to a list, but it is **immutable** (cannot be modified after creation). Tuples are defined using parentheses () and are useful for read-only data structures or returning multiple values from a function.
# List operations
fruits = ["apple", "banana", "cherry"]
fruits.append("orange")
fruits[0] = "blueberry" # Allowed (mutable)
print(fruits[1:3]) # Slicing: ['banana', 'cherry']
# Tuple operations
coordinates = (10.0, 20.0)
# coordinates[0] = 15.0 # TypeError (immutable)
Given the list numbers = [12, 45, 2, 41, 31, 10, 8, 6, 4], write a script to find the maximum value, reverse the list, append the number 99, and print the resulting slice of the first three items.
Dictionaries & Sets
Dictionaries (Key-Value Pairs)
A dictionary is an unordered, mutable collection of key-value pairs. Keys must be unique and immutable (such as strings, numbers, or tuples), while values can be of any data type. Dictionaries are optimized for retrieving values when you know the key.
Dictionaries are one of the most useful data structures in Python. Instead of storing values by position like a list, dictionaries store values using keys. Each key acts like a label that points to its corresponding value, making data easy to organize and retrieve.
Think of a dictionary as a real-world dictionary. You search for a word (the key), and the dictionary gives you its definition (the value). Python dictionaries work in the same way.
Creating Dictionaries
Dictionaries are created using curly braces {}, where each key is separated from its value using a colon (:).
student = {
"name": "Alice",
"age": 20,
"course": "Computer Science"
}
print(student)
Accessing Dictionary Values
You can access values by using their keys inside square brackets or by using the safer get() method.
student = {
"name": "Alice",
"age": 20
}
print(student["name"])
print(student.get("age"))
If a key does not exist, get() returns None (or a default value if provided) instead of raising an error.
student = {
"name": "Alice"
}
print(student.get("grade", "Not Available"))
Adding and Updating Items
Dictionaries are mutable, meaning you can easily add new key-value pairs or update existing values.
student = {
"name": "Alice",
"age": 20
}
student["age"] = 21
student["grade"] = "A"
print(student)
Removing Items
Dictionary items can be removed using pop(), del, or clear().
student = {
"name": "Alice",
"age": 20,
"grade": "A"
}
student.pop("grade")
print(student)
Looping Through Dictionaries
You can loop through dictionary keys, values, or both using a for loop.
student = {
"name": "Alice",
"age": 20,
"grade": "A"
}
for key, value in student.items():
print(key, value)
Common Dictionary Methods
get()β Returns the value for a key.keys()β Returns all dictionary keys.values()β Returns all values.items()β Returns key-value pairs.pop()β Removes a specified item.update()β Updates multiple items.clear()β Removes all items.
Sets (Unique Collections)
A set is an unordered collection of unique elements. Sets are written with curly braces {} and are useful for removing duplicate values from sequences and performing mathematical set operations (union, intersection, difference).
Unlike lists, sets do not allow duplicate values. If duplicate elements are added, Python automatically keeps only one copy of each value.
numbers = {1, 2, 2, 3, 4, 4, 5}
print(numbers)
Adding and Removing Set Elements
Sets are mutable, allowing elements to be added or removed after creation.
colors = {"red", "blue"}
colors.add("green")
colors.remove("red")
print(colors)
Set Operations
Sets support several mathematical operations that are useful when comparing collections.
- Union combines all unique elements.
- Intersection returns common elements.
- Difference returns elements that exist in one set but not the other.
- Symmetric Difference returns elements that are unique to each set.
a = {1, 2, 3}
b = {3, 4, 5}
print(a.union(b))
print(a.intersection(b))
print(a.difference(b))
print(a.symmetric_difference(b))
Checking Membership
You can quickly check whether an item exists in a dictionary or set using the in keyword.
student = {
"name": "Alice",
"grade": "A"
}
if "grade" in student:
print("Grade found.")
colors = {"red", "green", "blue"}
if "green" in colors:
print("Green exists.")
Dictionary vs Set
| Dictionary | Set |
|---|---|
| Stores key-value pairs. | Stores unique values only. |
| Uses keys to access values. | Has no keys or indexes. |
| Mutable. | Mutable. |
| Duplicate keys are not allowed. | Duplicate values are automatically removed. |
# Dictionary operations
student = {"name": "Bob", "grade": "A", "age": 20}
student["age"] = 21
student["major"] = "CS"
print(student.get("grade"))
# Set operations
a = {1, 2, 3, 3}
b = {3, 4, 5}
print(a.union(b))
print(a.intersection(b))
print(a.difference(b))
print(a.symmetric_difference(b))
Real-World Applications
Dictionaries and sets are used in many software applications:
- Student management systems.
- User account information.
- Online shopping carts.
- Phone contact applications.
- Word frequency counters.
- Removing duplicate records from datasets.
- Database caching and fast lookups.
- Permission and role management systems.
Common Mistakes
- Trying to access a dictionary key that does not exist.
- Assuming dictionaries are accessed using numeric indexes like lists.
- Expecting sets to keep duplicate values.
- Trying to access set elements using indexes.
- Using mutable objects such as lists as dictionary keys.
- Forgetting that dictionaries require unique keys.
Summary
Dictionaries and sets are powerful built-in Python data structures. Dictionaries organize information using key-value pairs, making data retrieval fast and efficient. Sets store only unique elements and provide useful mathematical operations such as union, intersection, and difference. Mastering these data structures will help you write cleaner, faster, and more efficient Python programs.
Create a dictionary representing a simple store inventory with product names as keys and prices as values. Write code to check if "milk" is in the inventory. If it is, update its price; if not, add it with a price of 2.50.
Bonus Challenges:
- Create a phone book using a dictionary.
- Count how many times each word appears in a sentence using a dictionary.
- Remove duplicate numbers from a list using a set.
- Find the common elements between two lists by converting them into sets.
- Create a student record system where each student has a name, age, and grade stored in a dictionary.
String Processing
String Slicing and Formatting
Strings are one of the most commonly used data types in Python. A string is a sequence of
characters enclosed in either single quotes (' ') or double quotes
(" "). Strings are used to store and manipulate text such as names,
sentences, passwords, file names, and user input.
Python strings are immutable, which means that once a string has been created, its characters cannot be changed directly. If you perform an operation that appears to modify a string, Python actually creates a new string instead of changing the original one.
Since strings are sequences, each character has an index. The first character starts at
index 0, the second at 1, and so on. Python also supports
negative indexing, where -1 represents the last character, -2
represents the second last character, and so forth.
One of Python's most powerful features is string slicing. Slicing allows
you to extract a portion of a string using the syntax
string[start:end:step].
- start β The index where slicing begins (inclusive).
- end β The index where slicing stops (exclusive).
- step β Determines how many characters to skip between each selection.
Examples of slicing:
text[0:5]β Returns characters from index 0 to 4.text[:5]β Starts from the beginning and stops before index 5.text[3:]β Returns everything from index 3 to the end.text[-4:]β Returns the last four characters.text[::-1]β Returns the string in reverse order.
Python also provides several ways to insert variables into strings. The recommended and
most modern method is using f-strings, introduced in Python 3.6.
An f-string begins with the letter f before the quotation marks and allows
variables or expressions to be embedded directly inside curly braces
({ }).
F-strings are easier to read, faster than older formatting methods, and are widely used in professional Python applications for displaying messages, reports, and formatted output.
Common String Methods
Python provides many built-in methods that make working with strings simple and efficient. These methods return new strings rather than modifying the original string because strings are immutable.
-
strip(): Removes whitespace from both the beginning and end of a string. It is commonly used to clean user input. -
lower(): Converts every letter in a string to lowercase. Useful for case-insensitive comparisons. -
upper(): Converts every character to uppercase. -
split(separator): Splits a string into a list using the specified separator. If no separator is given, spaces are used automatically. -
join(iterable): Joins all items from a list or other iterable into one string using the specified separator. -
replace(old, new): Replaces every occurrence of one substring with another. -
startswith(): Checks whether a string begins with a specified sequence of characters. -
endswith(): Checks whether a string ends with a specified sequence. -
find(): Returns the index of the first occurrence of a substring. If it is not found, it returns-1. -
count(): Counts how many times a substring appears inside a string. -
isalpha(): ReturnsTrueif all characters are alphabetic. -
isdigit(): ReturnsTrueif all characters are numeric digits. -
isalnum(): ReturnsTrueif all characters are either letters or numbers.
These methods are extremely useful when validating user input, processing files, formatting text, searching for keywords, and cleaning data before analysis.
# Original string
msg = " Python Coding "
# Remove extra spaces
clean_msg = msg.strip()
# Convert to uppercase
clean_msg = clean_msg.upper()
print(clean_msg)
# Output: PYTHON CODING
# String slicing
text = "Programming"
print(text[0:7]) # Program
print(text[3:]) # gramming
print(text[-4:]) # ming
print(text[::-1]) # gnimmargorP
# f-strings
name = "Alice"
version = 3.12
sentence = f"Hello {name}, you are using Python {version}."
print(sentence)
# Split a sentence into words
words = clean_msg.split()
print(words)
# ['PYTHON', 'CODING']
# Join words using a separator
rejoined = "-".join(words)
print(rejoined)
# PYTHON-CODING
# Replace text
message = "I like Java."
updated = message.replace("Java", "Python")
print(updated)
# Find text
position = updated.find("Python")
print(position)
# Count characters
print(updated.count("o"))
# Check the beginning and end
print(updated.startswith("I"))
print(updated.endswith("."))
Write a program that asks the user to enter a sentence.
Your program should perform the following tasks:
- Count and display the total number of spaces.
- Count the total number of words in the sentence.
- Convert the sentence to uppercase.
- Replace every vowel (
a, e, i, o, u) with an asterisk (*). - Display the reversed version of the sentence using string slicing.
- Print the final processed sentence.
Challenge: Modify your program so that it also counts how many vowels were replaced and displays that number to the user.
File Handling
Reading and Writing Files
Python makes it easy to read from and write to external files. The basic built-in function to open a file is open(filename, mode). Common modes include "r" for reading, "w" for writing (overwriting), and "a" for appending.
File handling allows programs to store information permanently. Unlike variables, whose values disappear when a program ends, data saved in a file remains available the next time the program is run. File handling is essential for creating applications that save user information, settings, reports, logs, and databases.
Python provides powerful built-in tools for working with files, making it simple to create, read, update, and delete data stored on your computer.
Always open files using the with statement (Context Manager). This ensures that the file is automatically closed when execution leaves the block, preventing resource leaks even if exceptions occur.
Understanding File Modes
The second argument passed to open() specifies how the file should be used. Choosing the correct mode is important because each mode behaves differently.
| Mode | Description |
|---|---|
r |
Read a file. The file must already exist. |
w |
Write to a file. Creates a new file or overwrites an existing one. |
a |
Append data to the end of a file without deleting existing content. |
x |
Create a new file. Generates an error if the file already exists. |
rb |
Read a binary file such as an image or video. |
wb |
Write binary data to a file. |
Writing to a File
The write() method writes text into a file. If the file is opened in "w" mode, any existing content will be replaced.
with open("message.txt", "w") as file:
file.write("Welcome to Python!")
file.write("\nLearning file handling.")
Reading an Entire File
The read() method reads all the contents of a file and returns it as a string.
with open("message.txt", "r") as file:
content = file.read()
print(content)
Reading One Line at a Time
Sometimes files are very large. Instead of reading everything at once, you can read one line at a time using readline().
with open("message.txt", "r") as file:
print(file.readline())
print(file.readline())
Reading Files with a Loop
A for loop provides an efficient way to process files line by line.
with open("message.txt", "r") as file:
for line in file:
print(line.strip())
The strip() method removes unnecessary whitespace and newline characters from each line.
Appending to a File
Using append mode ("a") adds new data to the end of the file without removing the existing content.
with open("message.txt", "a") as file:
file.write("\nThis line was appended.")
Working with File Paths
A file path tells Python where a file is located. If only the filename is provided, Python looks for the file in the current working directory.
with open("documents/report.txt", "r") as file:
print(file.read())
Checking if a File Exists
Before opening a file, it is often useful to check whether it exists to avoid runtime errors.
import os
if os.path.exists("message.txt"):
print("File exists.")
else:
print("File not found.")
Handling File Errors
If Python cannot find a file, it raises a FileNotFoundError. You can handle this error using a try...except block.
try:
with open("missing.txt", "r") as file:
print(file.read())
except FileNotFoundError:
print("The file could not be found.")
Working with Binary Files
Not all files contain text. Images, videos, PDFs, and audio files are stored as binary data. Binary files should be opened using binary modes such as "rb" or "wb".
with open("photo.jpg", "rb") as file:
data = file.read()
print(len(data))
Example Program
# Writing to a file
with open("test.txt", "w") as file:
file.write("Hello, this is file I/O in Python.\n")
file.write("Using context managers is recommended.")
# Reading from a file
with open("test.txt", "r") as file:
content = file.read()
print(content)
Common File Methods
read()β Reads the entire file.readline()β Reads one line.readlines()β Returns all lines as a list.write()β Writes text to a file.writelines()β Writes multiple lines.close()β Closes the file (usually unnecessary when usingwith).
Common Mistakes
- Opening a file in
"w"mode when you intended to append data. - Trying to read a file that does not exist.
- Forgetting to use the
withstatement. - Using incorrect file paths.
- Opening binary files in text mode.
- Forgetting that
read()returns a string.
Real-World Applications
File handling is used in almost every software application, including:
- Saving game progress.
- Creating log files.
- Reading configuration settings.
- Processing CSV and text files.
- Generating reports.
- Reading and writing documents.
- Working with images and multimedia files.
- Storing user preferences.
Summary
File handling allows Python programs to store and retrieve information from external files. In this lesson you learned how to open files, use different file modes, read and write text, append data, process files line by line, work with file paths, check for file existence, handle errors, and read binary files. These skills are essential for building practical applications that save and manage data outside the program.
Write a program that creates a text file named notes.txt and writes 5 lines of diary notes into it. Then, reopen the file in read mode and print each line prefixed with its line number.
Bonus Challenges:
- Create a program that copies the contents of one file into another.
- Count the number of words, lines, and characters in a text file.
- Append today's date and time to a log file every time the program runs.
- Create a simple contact manager that stores names and phone numbers in a text file.
- Read a file containing student marks and calculate the average score.
Exception Handling
Handling Errors Gracefully
Exceptions are errors detected during execution. If they are not handled, the program will terminate immediately. Python uses the try, except, else, and finally blocks to intercept and manage exceptions.
Exception Keywords
try: Contains the block of code that might raise an error.except: Contains the code block that handles the specified exception.else: Runs code that should execute only if no exceptions were raised.finally: Executes cleanup code under all circumstances (with or without errors).
try:
num1 = int(input("Enter number: "))
result = 100 / num1
except ZeroDivisionError:
print("Error: You cannot divide by zero.")
except ValueError:
print("Error: Invalid inputs. Please enter numbers.")
else:
print(f"Result: {result}")
finally:
print("Execution complete.")
Write a function safe_divide(a, b) that returns a / b. Wrap the operation in a try-except block to handle division by zero errors, returning None if a division by zero occurs.
OOP: Classes & Objects
Object-Oriented Programming (OOP)
Object-Oriented Programming is a paradigm that uses **Classes** (blueprints) and **Objects** (instances of classes) to organize code. Python is fully object-oriented, allowing custom classes to bundle data attributes and functions together.
Class Attributes and Constructors
The constructor method __init__ initializes an object's state when it is created. The self parameter represents the instance of the object being created, allowing access to its attributes and methods.
class Car:
# Constructor
def __init__(self, brand, year):
self.brand = brand # Instance attribute
self.year = year # Instance attribute
self.speed = 0
# Instance method
def accelerate(self, amount):
self.speed += amount
print(f"The {self.brand} speed is now {self.speed} km/h.")
# Creating objects
my_car = Car("Toyota", 2022)
my_car.accelerate(50) # Output: The Toyota speed is now 50 km/h.
Create a class BankAccount with attributes owner and balance (starting at 0). Implement methods deposit(amount) and withdraw(amount). Withdrawals should verify sufficient funds before updating the balance.
OOP: Inheritance & Polymorphism
Inheritance
Inheritance allows a new class (child/subclass) to inherit attributes and methods from an existing class (parent/superclass). This promotes code reuse and hierarchical class design. The super() function is used to call parent methods inside child classes.
Polymorphism
Polymorphism allows child classes to define unique behaviors for methods that share the same name as methods in parent classes (method overriding).
class Animal:
def __init__(self, name):
self.name = name
def make_sound(self):
return "Generic Sound"
class Dog(Animal):
# Method overriding (Polymorphism)
def make_sound(self):
return "Woof!"
class Cat(Animal):
# Method overriding (Polymorphism)
def make_sound(self):
return "Meow!"
pets = [Dog("Buddy"), Cat("Luna")]
for pet in pets:
print(f"{pet.name} says {pet.make_sound()}")
Create a base class Shape with a method area() that returns 0. Define subclasses Rectangle (with width and height attributes) and Circle (with a radius attribute) that override the area() method to return their respective mathematical areas.
Modules & Packages
Importing Standard Libraries
Python code is organized into modules (single .py files) and packages (folders of modules). You can use any external or built-in script by importing it via the import statement.
Popular Built-in Modules
math: Provides access to mathematical functions likesqrt(),sin(), and constants likepi.random: Offers tools to generate random numbers and select random list elements.datetime: Used for manipulating dates and times.
import math from random import randint, choice # Use math print(math.sqrt(16)) # 4.0 # Use random num = randint(1, 100) # Random int between 1 and 100 colors = ["red", "green", "blue"] chosen = choice(colors) # Select random element
Third-party libraries are hosted on PyPI (Python Package Index). You can install them via terminal command: pip install package_name (e.g., pip install requests).
Write a script that uses the random module to generate a list of 6 random numbers between 1 and 49 (representing lottery numbers), sorts them in ascending order, and prints the result.
Functional Programming
List Comprehensions
List comprehensions provide a concise way to create lists. They consist of brackets containing an expression followed by a for clause, then zero or more for or if clauses. They run faster and are cleaner than traditional loops.
Lambda Functions (Anonymous Functions)
A lambda function is a small anonymous function defined using the lambda keyword. It can take any number of arguments but can only have a single expression.
Map & Filter
map(func, iterable): Applies a function to all items in an input list.filter(func, iterable): Filters list elements based on a function that returns a boolean.
# List Comprehension squares = [x**2 for x in range(1, 6)] # [1, 4, 9, 16, 25] # Lambda function double = lambda x: x * 2 print(double(5)) # 10 # Map & Filter numbers = [1, 2, 3, 4, 5, 6] evens = list(filter(lambda x: x % 2 == 0, numbers)) # [2, 4, 6] doubled = list(map(lambda x: x * 2, numbers)) # [2, 4, 6, 8, 10, 12]
Write a list comprehension that takes the list names = ["john", "sarah", "mary", "alex"] and returns a new list containing only names that start with "m", capitalized (e.g. ["Mary"]).
Final Capstone Project
Project: Command-Line Contact Book
For your capstone project, you will build a command-line Contact Management application. This project consolidates everything you have learned: variables, conditionals, loops, functions, lists, dictionaries, files, exceptions, and OOP.
Project Requirements:
- Contact Class: Create a
Contactclass containing name, phone, and email attributes. - ContactBook Class: Create a
ContactBookclass that manages a list of Contact objects. - Persistent Storage: Load contacts from a text file on startup and save contacts back to the file upon exiting.
- User Menu: Provide a loop interface allowing users to:
- View all contacts
- Add a new contact
- Search for a contact by name
- Delete a contact
- Save and Exit
- Exception Handling: Safely catch and handle potential errors (like inputting text when integers are expected, or opening a non-existent file).
class Contact:
def __init__(self, name, phone, email):
self.name = name
self.phone = phone
self.email = email
def __str__(self):
return f"{self.name} | Phone: {self.phone} | Email: {self.email}"
class ContactBook:
def __init__(self):
self.contacts = []
def add_contact(self, contact):
self.contacts.append(contact)
print("Contact added successfully.")
# Implement the rest of the ContactBook logic and main menu loop
Write the complete script in a file named contacts.py. Run and test it by adding a few contacts, saving, exiting, and confirming the text file stores your entries correctly.