Back To Home
Code Newb

Learn Python!

Lesson 1: Python Basics

1.1 Introduction to Python

Python is a powerful, easy-to-learn programming language widely used in web development, data science, automation, and more. It is known for its simple syntax, making it a great first language for beginners.

1.2 Why Learn Python?

  • Easy to Read and Write: Python’s syntax is intuitive and close to human language.
  • Versatile: Used in web development, AI, data science, automation, and more.
  • Large Community: Extensive support and libraries available.
  • Beginner-Friendly: Ideal for new programmers due to its readability.

Writing Your First Python Program

On VS Code or Replit create a new file called HelloWorld.py and type:

print("Hello, World!")

This prints Hello, World! to the screen, a traditional first program.

1.4 Understanding Variables and Data Types

Variables: A variable stores a value that can change.

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

Data Types:

  • Integers (int): Whole numbers (e.g., 10, -5).
  • Floats (float): Decimal numbers (e.g., 3.14, -0.5).
  • Strings (str): Text (e.g., 'Hello', "Python").
  • Booleans (bool): True or False.

1.5 Basic Operations

Python supports basic mathematical operations:

x = 10
y = 5
print(x + y)  # Addition
print(x - y)  # Subtraction
print(x * y)  # Multiplication
print(x / y)  # Division

1.6 Coding Challenge: Simple Math Calculator

Task: Write a Python program that asks the user for two numbers and prints their sum, difference, product, and quotient.

Example Output:

Enter first number: 8
Enter second number: 2
Sum: 10
Difference: 6
Product: 16
Quotient: 4.0

Use input() to get user input and convert it to a number:

num1 = float(input("Enter first number: "))
num2 = float(input("Enter second number: "))

print("Sum:", num1 + num2)
print("Difference:", num1 - num2)
print("Product:", num1 * num2)
print("Quotient:", num1 / num2)

Lesson 2: Control Flow – Making Decisions in Python

2.1 Conditional Statements (if, elif, else)

Python’s if-elif-else structure allows your program to make decisions based on conditions.

if condition:
    # Code executes if condition is True
elif another_condition:
    # Code executes if previous conditions were False and this condition is True
else:
    # Code executes if none of the conditions are True

Example: Simple Age Check

age = int(input("Enter your age: "))

if age < 18:
    print("You are a minor.")
elif age == 18:
    print("You just became an adult!")
else:
    print("You are an adult.")

2.2 Logical Operators

You can combine multiple conditions using and, or, not.

OperatorDescriptionExample
andBoth conditions must be Trueif x > 0 and x < 10:
orAt least one condition must be Trueif x < 0 or x > 10:
notReverses the conditionif not x == 5:

Example: Login System

username = input("Enter username: ")
password = input("Enter password: ")

if username == "admin" and password == "1234":
    print("Access granted!")
else:
    print("Invalid credentials.")

2.3 Loops – Repeating Actions

The for Loop

for i in range(1, 6):  # Loops 5 times (1 to 5)
    print("Iteration:", i)

Looping through a list:

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

The while Loop

x = 0
while x < 5:
    print("Value of x:", x)
    x += 1  # Increments x to avoid infinite loop

2.4 Loop Control Statements

break: Stops the loop completely.

continue: Skips the current iteration but continues looping.

Example: Skipping Even Numbers

for num in range(1, 10):
    if num % 2 == 0:
        continue  # Skip even numbers
    print(num)

2.5 Coding Challenge 2: FizzBuzz

Write a program that prints numbers from 1 to 20 but:

Expected Output

1
2
Fizz
4
Buzz
Fizz
7
8
Fizz
Buzz
11
Fizz
13
14
FizzBuzz
...

Mini-Project: Simple Number Guessing Game

Concepts used: if-else, while, break

Steps:

  1. Generate a random number.
  2. Prompt the user to guess the number.
  3. Give hints (e.g., "Too high" or "Too low").
  4. Keep looping until they guess correctly.

Lesson 3: Functions & Modular Code

3.1 Defining Functions

Functions help break down a large program into smaller, manageable parts.

Syntax:

def function_name(parameters):
    # Code block
    return value  # (Optional)

Example: Simple Greeting Function

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

greet("Anthony")  # Output: Hello, Anthony!

Key Takeaways:

  • Use def to define a function.
  • Function names should be descriptive.
  • Parameters allow passing values into functions.
  • return gives a result back (optional).

3.2 Parameters & Return Values

Example: Add Two Numbers

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

result = add_numbers(5, 10)
print(result)  # Output: 15

Key Takeaways:

  • Functions can take multiple arguments.
  • The return statement outputs a value.

3.3 Function Scope & Variables

Example: Scope Difference

x = 10  # Global variable

def change_x():
    x = 5  # Local variable
    print("Inside function:", x)

change_x()
print("Outside function:", x)  # Output: 10 (global x is unchanged)

Key Takeaways:

  • Variables inside a function don’t affect global variables.
  • Use global inside a function to modify a global variable.

3.4 Recursion

Example: Factorial Calculation

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

print(factorial(5))  # Output: 120

Key Takeaways:

  • Every recursion needs a base case to stop.
  • Useful for problems like factorial, Fibonacci, and tree traversal.

3.5 Lambda Functions (Anonymous Functions)

Example: Multiply by 2

double = lambda x: x * 2
print(double(5))  # Output: 10

Example: Sorting a List by Length

words = ["apple", "kiwi", "banana"]
words.sort(key=lambda word: len(word))
print(words)  # Output: ['kiwi', 'apple', 'banana']

Key Takeaways:

  • Use lambda for short, simple functions.
  • Great for sorting, filtering, and quick calculations.

Coding Challenge 3: Even or Odd Checker

Write a function that:

Expected Output

print(check_number(7))  # Output: Odd
print(check_number(10)) # Output: Even

Mini-Project: Simple Calculator

Concepts used: Functions, loops, user input.

Objective: Create a program where the user can input two numbers and choose an operation (+, -, *, /).

Steps

Lesson 4: Data Structures (Lists, Tuples, Sets, Dictionaries)

4.1 Lists (Ordered, Mutable Collection)

A list is an ordered collection of items that can be changed (mutable).

Creating a List

fruits = ["apple", "banana", "cherry"]
print(fruits)  # Output: ['apple', 'banana', 'cherry']

Common List Operations

fruits.append("orange")   # Adds "orange" to the end
fruits.remove("banana")   # Removes "banana"
fruits.insert(1, "grape") # Inserts "grape" at index 1
print(fruits)  # Output: ['apple', 'grape', 'cherry', 'orange']

Accessing Elements

print(fruits[0])   # Output: apple (first element)
print(fruits[-1])  # Output: orange (last element)

Key Takeaways:

  • Lists are ordered and mutable (can be modified).
  • Supports indexing and slicing.
  • Methods like .append(), .remove(), .insert() modify lists.

4.2 Tuples (Ordered, Immutable Collection)

A tuple is similar to a list but cannot be modified after creation.

Creating a Tuple

coordinates = (4, 5)
print(coordinates)  # Output: (4, 5)

Accessing Elements

print(coordinates[0])  # Output: 4

Key Takeaways:

  • Tuples are faster than lists.
  • Use when data should not be changed.
  • Supports indexing like lists.

4.3 Sets (Unordered, Unique Collection)

A set is an unordered collection where each element is unique.

Creating a Set

unique_numbers = {1, 2, 3, 3, 2, 1}
print(unique_numbers)  # Output: {1, 2, 3} (removes duplicates)

Set Operations

unique_numbers.add(4)  # Adds 4 to the set
unique_numbers.remove(2)  # Removes 2
print(unique_numbers)  # Output: {1, 3, 4}

Key Takeaways:

  • Sets are unordered and only store unique values.
  • Great for removing duplicates.
  • Supports union, intersection, and difference.

4.4 Dictionaries (Key-Value Pairs)

A dictionary stores data as key-value pairs, making lookups efficient.

Creating a Dictionary

student = {
    "name": "Anthony",
    "age": 22,
    "major": "Computer Science"
}
print(student["name"])  # Output: Anthony

Modifying a Dictionary

student["age"] = 23  # Updates age
student["city"] = "Kansas City"  # Adds new key-value pair
del student["major"]  # Deletes "major" key

Key Takeaways:

  • Dictionaries are mutable.
  • Keys must be unique and immutable (e.g., strings, numbers).
  • Useful for quick lookups.

4.5 Coding Challenge: Find Unique Words in a Sentence

Write a function that:

print(unique_words("Hello world hello"))  # Output: {'hello', 'world'}

Mini-Project: Student Database (Using Dictionaries)

Concepts used: Lists, dictionaries, user input.

Objective: Create a program to store and retrieve student information.

Steps

  1. Use a dictionary where each student's name is the key and their grades are the values.
  2. Allow users to:
    • Add new students.
    • Update student grades.
    • Retrieve student information.
  3. Display all student data in a formatted way.

Lesson 5: Object-Oriented Programming (OOP)

5.1 Introduction to Classes and Objects

In Python, everything is an object. A class is a blueprint for creating objects, and an object is an instance of a class.

class Car:
    def __init__(self, brand, model, year):
        self.brand = brand
        self.model = model
        self.year = year

    def display_info(self):
        print(f"{self.year} {self.brand} {self.model}")

# Creating an object (instance)
my_car = Car("Toyota", "Camry", 2022)
my_car.display_info()  # Output: 2022 Toyota Camry

Key Takeaways:

  • The __init__ method is a constructor that initializes object attributes.
  • self refers to the instance of the class.
  • Methods are functions inside a class that operate on object attributes.

5.2 Encapsulation (Data Hiding & Protection)

Encapsulation restricts direct access to data, ensuring better security.

class BankAccount:
    def __init__(self, balance):
        self.__balance = balance  # Private variable

    def deposit(self, amount):
        self.__balance += amount

    def withdraw(self, amount):
        if amount <= self.__balance:
            self.__balance -= amount
        else:
            print("Insufficient funds")

    def get_balance(self):
        return self.__balance

# Creating an account
account = BankAccount(1000)
account.deposit(500)
print(account.get_balance())  # Output: 1500

Key Takeaways:

  • Private attributes use __ (double underscore) to restrict direct access.
  • Use getter/setter methods to control access.

5.3 Inheritance (Reusability & Hierarchies)

Inheritance allows a child class to inherit properties and methods from a parent class.

class Vehicle:
    def __init__(self, brand):
        self.brand = brand

    def start(self):
        print(f"{self.brand} is starting...")

class Car(Vehicle):  # Car inherits from Vehicle
    def honk(self):
        print("Beep beep!")

my_car = Car("Toyota")
my_car.start()  # Output: Toyota is starting...
my_car.honk()   # Output: Beep beep!

Key Takeaways:

  • A child class inherits attributes and methods from the parent.
  • The child class can extend functionality with additional methods.

5.4 Polymorphism (Same Interface, Different Behavior)

Polymorphism allows different classes to have methods with the same name but different implementations.

class Animal:
    def speak(self):
        print("Animal makes a sound")

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

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

animals = [Dog(), Cat()]
for animal in animals:
    animal.speak()

# Output:
# Woof!
# Meow!

Key Takeaways:

  • Polymorphism allows objects of different types to be treated uniformly.
  • Method overriding lets subclasses change inherited methods.

5.6 Coding Challenge: Employee Management System

Write a class-based program that:

Expected Output:

employee = Employee("Anthony", 22, 50000)
employee.display_info()
# Output: Name: Anthony, Age: 22, Salary: $50000

Mini-Project: Library Management System (Using OOP)

Objective: Create a simple Library System that allows users to borrow and return books.

Steps:

  1. Define a Book class with attributes like title and author.
  2. Create a Library class with methods to:
    • Add books to the collection.
    • Display available books.
    • Allow users to borrow and return books.

Lesson 6: File Handling in Python

6.1 Opening and Closing Files

Python provides the built-in open() function to interact with files. Always close the file after performing operations to free up system resources.

Opening and Closing a File

file = open("example.txt", "r")  # Open file in read mode
content = file.read()  
print(content)
file.close()  # Always close the file

Key Takeaways:

  • "r" mode = read
  • "w" mode = write (overwrites existing content)
  • "a" mode = append (adds to existing content)
  • Always close the file to prevent memory leaks.

6.2 Reading a File

Python allows reading files in different ways.

Reading the Entire File

with open("example.txt", "r") as file:
    content = file.read()
    print(content)  # Prints entire file content

Using with open(), the file closes automatically.

Reading Line by Line

with open("example.txt", "r") as file:
    for line in file:
        print(line.strip())  # Removes extra newlines

Reading Specific Number of Characters

with open("example.txt", "r") as file:
    print(file.read(10))  # Reads the first 10 characters

Key Takeaways:

  • .read() loads the whole file.
  • .readline() reads a single line.
  • .readlines() returns a list of lines.

6.3 Writing to a File

Writing replaces existing content in a file.

Writing New Content

with open("example.txt", "w") as file:
    file.write("Hello, this is a new file!")

Key Takeaway:

  • "w" mode overwrites existing content.

Appending to a File

with open("example.txt", "a") as file:
    file.write("\nAdding a new line!")

Key Takeaway:

  • "a" mode adds content to the end.

6.4 Working with CSV Files

CSV (Comma-Separated Values) files store structured data.

Writing a CSV File

import csv

with open("data.csv", "w", newline="") as file:
    writer = csv.writer(file)
    writer.writerow(["Name", "Age", "City"])
    writer.writerow(["Anthony", "22", "Kansas City"])
    writer.writerow(["Sarah", "25", "New York"])

Reading a CSV File

with open("data.csv", "r") as file:
    reader = csv.reader(file)
    for row in reader:
        print(row)

Key Takeaways:

  • The csv.writer() and csv.reader() methods help work with structured data.
  • Always use newline="" to prevent extra newlines.

6.5 Coding Challenge: Word Counter

Write a program that:

Expected Output

Enter filename: example.txt
Total words: 42

Mini-Project: To-Do List (File-Based Storage)

Objective: Build a simple to-do list that allows users to add tasks, view tasks, and remove tasks, storing them in a file.

Steps

  1. Create a text file (tasks.txt) to store tasks.
  2. Implement functions to:
    • Add a new task.
    • View all tasks.
    • Remove a completed task.
  3. Save changes to the file after every action.

Lesson 7: Exception Handling in Python

7.1 Understanding Errors in Python

Python encounters two main types of errors:

  • Syntax Errors – Mistakes in the code structure.
  • print("Hello)  # SyntaxError: Missing closing quote
  • Runtime Errors (Exceptions) – Errors that occur while the program runs.
  • x = 10 / 0  # ZeroDivisionError

Key Takeaways:

  • Syntax Errors prevent the code from running.
  • Exceptions happen during execution and can be handled.

7.2 Handling Exceptions with `try-except`

The `try-except` block prevents the program from crashing.

try:
    num = int(input("Enter a number: "))  # User might enter a non-numeric value
    print(f"You entered: {num}")
except ValueError:
    print("Invalid input! Please enter a number.")

Key Takeaway:

  • Code inside `try:` runs normally.
  • If an error occurs, `except:` executes instead.

7.3 Handling Multiple Exceptions

We can catch multiple exceptions to handle different errors.

try:
    num = int(input("Enter a number: "))
    result = 10 / num  # Might cause ZeroDivisionError
    print(f"Result: {result}")
except ValueError:
    print("Invalid input! Please enter a number.")
except ZeroDivisionError:
    print("You can't divide by zero!")

Key Takeaway:

  • Use multiple `except` blocks for different error types.

7.4 Using `finally` to Run Cleanup Code

The `finally` block always executes, whether an exception occurs or not.

try:
    file = open("data.txt", "r")
    content = file.read()
    print(content)
except FileNotFoundError:
    print("File not found!")
finally:
    file.close()  # Ensures file is always closed
    print("File closed.")

Key Takeaway:

  • The `finally` block is useful for cleaning up resources.

7.5 Raising Custom Exceptions

We can manually trigger exceptions using `raise`.

def check_age(age):
    if age < 18:
        raise ValueError("You must be 18 or older!")
    return "Access granted."

try:
    print(check_age(16))
except ValueError as e:
    print(f"Error: {e}")

Key Takeaway:

  • `raise` is used to intentionally trigger an exception.

7.6 Coding Challenge : Safe Division

Write a function `safe_divide(a, b)` that:

Expected Output:

safe_divide(10, 2)  # Output: 5.0
safe_divide(5, 0)   # Output: Cannot divide by zero

Mini-Project: Password Validator

Concepts used: Exception handling, string manipulation, user input.

Objective: Build a password validator that:

Lesson 8: Advanced Python Topics

8.1 Generators

Generators are a special type of function that yield values one at a time, making them memory-efficient for large datasets.

Example: Simple Generator

def simple_generator():
    yield 1
    yield 2
    yield 3

for value in simple_generator():
    print(value)  # Output: 1, 2, 3

Key Takeaways:

  • Generators use yield instead of return.
  • They are memory-efficient for large datasets.

8.2 Decorators

Decorators are functions that modify the behavior of other functions without changing their code.

Example: Simple Decorator

def my_decorator(func):
    def wrapper():
        print("Something is happening before the function is called.")
        func()
        print("Something is happening after the function is called.")
    return wrapper

@my_decorator
def say_hello():
    print("Hello!")

say_hello()

Key Takeaways:

  • Decorators are used to extend or modify the behavior of functions.
  • They are often used for logging, timing, or access control.

8.3 Context Managers

Context managers allow you to manage resources (like files) efficiently using the with statement.

Example: File Handling with Context Manager

with open("example.txt", "r") as file:
    content = file.read()
    print(content)

Key Takeaways:

  • Context managers ensure resources are properly managed and released.
  • They are commonly used with file handling, database connections, and threading.

8.4 Regular Expressions

Regular expressions (regex) are used for pattern matching in strings.

Example: Simple Regex

import re

pattern = r"\d+"  # Matches one or more digits
text = "There are 3 apples and 5 oranges."
matches = re.findall(pattern, text)
print(matches)  # Output: ['3', '5']

Key Takeaways:

  • Regex is powerful for searching, extracting, and validating text patterns.
  • Commonly used in data validation, parsing, and text processing.

8.5 Coding Challenge: Email Validator

Write a function that:

Expected Output:

print(validate_email("[email protected]"))  # Output: True
print(validate_email("invalid-email"))    # Output: False

Mini-Project: Web Scraper

Concepts used: Regular expressions, file handling, web requests.

Objective: Build a simple web scraper that:

Lesson 9: Working with APIs

9.1 Introduction to APIs

APIs (Application Programming Interfaces) allow programs to communicate with external services and retrieve data.

Example: Fetching Data from an API

import requests

response = requests.get("https://api.github.com")
print(response.status_code)  # Output: 200 (success)
print(response.json())  # Output: JSON data from the API

Key Takeaways:

  • APIs allow you to interact with external services like GitHub, Twitter, or weather services.
  • Common HTTP methods include GET, POST, PUT, and DELETE.

9.2 Making API Requests

Python’s requests library is commonly used to make HTTP requests.

Example: Fetching Weather Data

import requests

url = "https://api.openweathermap.org/data/2.5/weather"
params = {
    "q": "London",
    "appid": "your_api_key"
}

response = requests.get(url, params=params)
print(response.json())  # Output: Weather data for London

Key Takeaways:

  • Use requests.get() to fetch data from an API.
  • Pass parameters using the params argument.

9.3 Handling API Responses

API responses are often in JSON format, which can be easily parsed in Python.

Example: Parsing JSON Data

import requests

response = requests.get("https://api.github.com")
data = response.json()

print(data["current_user_url"])  # Output: https://api.github.com/user

Key Takeaways:

  • Use .json() to parse API responses into Python dictionaries.
  • Access data using dictionary keys.

9.4 Error Handling in API Requests

API requests can fail due to network issues, invalid URLs, or rate limits. Use try-except to handle errors gracefully.

Example: Handling API Errors

import requests

try:
    response = requests.get("https://api.github.com/invalid-url")
    response.raise_for_status()  # Raises an HTTPError for bad responses
except requests.exceptions.HTTPError as err:
    print(f"HTTP Error: {err}")
except requests.exceptions.RequestException as err:
    print(f"Request Error: {err}")

Key Takeaways:

  • Use try-except to handle errors in API requests.
  • raise_for_status() raises an error for bad responses (e.g., 404, 500).

9.5 Coding Challenge: Weather App

Write a program that:

Expected Output:

Enter city: London
Temperature: 15°C
Condition: Cloudy
Humidity: 75%

Mini-Project: Currency Converter

Concepts used: API requests, JSON parsing, error handling.

Objective: Build a currency converter that:

Lesson 10: Final Project

10.1 Project Overview

In this final project, you will build a complete Python application that incorporates everything you’ve learned so far.

Project Options:

  • Option 1: Personal Finance Tracker
  • Option 2: Blog Management System
  • Option 3: E-commerce Inventory System

10.2 Project Requirements

Your project should include:

  • File Handling: Save and load data from files.
  • OOP: Use classes and objects to structure your code.
  • Error Handling: Handle exceptions gracefully.
  • User Interaction: Allow users to interact with the program via a command-line interface.
  • Advanced Features: Incorporate at least one advanced topic (e.g., APIs, decorators, or regex).

10.3 Project Submission

Submit your project as a GitHub repository with:

  • A README file explaining your project.
  • Well-documented code with comments.
  • A requirements.txt file listing dependencies.

10.4 Example Project: Personal Finance Tracker

Here’s an example of what your project might look like:

class Transaction:
    def __init__(self, date, description, amount):
        self.date = date
        self.description = description
        self.amount = amount

class FinanceTracker:
    def __init__(self):
        self.transactions = []

    def add_transaction(self, transaction):
        self.transactions.append(transaction)

    def save_transactions(self, filename):
        with open(filename, "w") as file:
            for transaction in self.transactions:
                file.write(f"{transaction.date},{transaction.description},{transaction.amount}\n")

    def load_transactions(self, filename):
        with open(filename, "r") as file:
            for line in file:
                date, description, amount = line.strip().split(",")
                self.transactions.append(Transaction(date, description, float(amount)))

# Example usage
tracker = FinanceTracker()
tracker.add_transaction(Transaction("2023-10-01", "Groceries", -50.0))
tracker.save_transactions("transactions.txt")

This final project is your opportunity to apply everything you’ve learned in Python. Choose a project that interests you and showcases your skills!