← Introduction to Programming

Part 1: Selection Control Structures (Making Decisions)

Programs often need to execute different code based on whether a certain condition is true or false. This is called selection or conditional execution.

Key Terminology:

  • Condition: An expression that evaluates to a Boolean value (True or False). Usually involves relational (>, ==, etc.) and logical (and, or, not) operators.
  • Code Block: A group of one or more statements that are executed together. In Python, code blocks are defined by indentation (usually 4 spaces).

The if Statement

Theory

The simplest control structure. It executes a block of code only if a condition is True. If the condition is False, the indented block is skipped entirely.

Syntax

if condition:
    # Code to execute if condition is True
    # This block is indented

Example: Special Welcome Program

  • Problem: Write a program that asks for a user’s name. If the name is exactly “admin”, greet them with a special welcome message before saying goodbye. Otherwise, just say goodbye.

  • Solution:
    # --- Example 1: The 'if' Statement ---
    print("--- Special Welcome Program ---")
    
    name = input("Please enter your name: ")
    
    # Check if the name is 'admin'
    if name == "admin":
        # This block is indented, so it only runs if the 'if' condition is True
        print("Welcome, Administrator!")
        print("You have special privileges.")
    
    print(f"\nGoodbye, {name}. End of program.")
    
  • Example Output (if name is “admin”):
    --- Special Welcome Program ---
    Please enter your name: admin
    Welcome, Administrator!
    You have special privileges.
    
    Goodbye, admin. End of program.
    
  • Example Output (if name is “Bob”):
    --- Special Welcome Program ---
    Please enter your name: Bob
    
    Goodbye, Bob. End of program.
    

The if-else Statement

Theory

Executes one block of code if the condition is True and a different block if it is False. This guarantees that exactly one of the two blocks will run.

Syntax

if condition:
    # Code to execute if condition is True
else:
    # Code to execute if condition is False

Example: The Age Checker

  • Problem: Create a program that asks a user for their age. If they are 18 or older, inform them that they are old enough to vote. Otherwise, tell them they are not old enough and show how many years are left until they turn 18.

  • Solution:
    # --- Example 2: The 'if-else' Statement ---
    print("\n--- Age Checker ---")
    
    # Get user input for age and convert it to an integer
    age_str = input("Please enter your age: ")
    age = int(age_str)
    
    # Check if the user is 18 or older
    if age >= 18:
        print("You are old enough to vote.")
        print("Please make sure you are registered.")
    else:
        print("You are not old enough to vote yet.")
        years_left = 18 - age
        print(f"You can vote in {years_left} years.")
    
    print("--- End of Program ---")
    
  • Example Output (if age is 25):
    --- Age Checker ---
    Please enter your age: 25
    You are old enough to vote.
    Please make sure you are registered.
    --- End of Program ---
    

The if-elif-else Statement

Theory

Used to check multiple, mutually exclusive conditions in sequence. As soon as one condition is True, its block is executed, and the rest of the chain is skipped. The else block at the end is optional and runs if none of the preceding conditions were met.

Syntax

if condition_1:
    # Executes if condition_1 is True
elif condition_2:
    # Executes if condition_1 is False AND condition_2 is True
else:
    # Executes if ALL preceding conditions are False

Example: Grade Converter

  • Problem: Write a program that converts a numerical score (0-100) into a letter grade (A, B, C, D, F) based on the following scale:
    • 90-100: A
    • 80-89: B
    • 70-79: C
    • 60-69: D
    • Below 60: F
  • Solution:
    # --- Example 3: The if-elif-else Ladder ---
    print("\n--- Grade Converter ---")
    score_str = input("Enter your numerical score (0-100): ")
    score = int(score_str)
    
    # Determine the letter grade
    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"Your score of {score} is a grade of '{grade}'.")
    
  • Example Output (if score is 85):
    --- Grade Converter ---
    Enter your numerical score (0-100): 85
    Your score of 85 is a grade of 'B'.
    

Nested Conditionals

Theory

You can place if, elif, or else statements inside other conditional blocks. This is useful for checking for more complex scenarios where a second check only makes sense if the first one has already passed.

Syntax

The syntax is simply an if statement indented inside another if or else block.

if outer_condition:
    # Code for outer condition
    if inner_condition:
        # Code for inner condition
    else:
        # Code for inner condition else
else:
    # Code for outer condition else

Example: Simple Login System

  • Problem: Create a simple login system. The program should first check if the username is correct. Only if the username is correct should it then check the password. Provide specific feedback to the user (“Unknown user”, “Incorrect password”, or “Welcome!”).

  • Solution:
    # --- Example 4: Nested if Statements ---
    print("\n--- Simple Login System ---")
    
    correct_username = "admin"
    correct_password = "password123"
    
    username = input("Enter your username: ")
    password = input("Enter your password: ")
    
    if username == correct_username:
        # This inner block only runs if the username was correct
        print("Username accepted.")
        if password == correct_password:
            print("Password accepted. Welcome!")
        else:
            print("Incorrect password. Access denied.")
    else:
        print("Unknown user. Access denied.")
    
  • Example Output (for a correct login):
    --- Simple Login System ---
    Enter your username: admin
    Enter your password: password123
    Username accepted.
    Password accepted. Welcome!
    

Part 2: Repetition Structures (Loops)

Loops allow you to execute a block of code multiple times without rewriting it. This process is also called iteration.


The while Loop

Theory

A while loop is a condition-controlled loop. It repeats a block of code as long as a specified condition remains True. It is crucial that something inside the loop eventually makes the condition False, otherwise you will create an infinite loop, a common bug where the program runs forever.

Syntax

while condition:
    # Code to execute repeatedly
    # IMPORTANT: Something inside this block must eventually
    # make the condition False!

Example: T-Minus Countdown

  • Problem: Write a program that counts down from 5 to 1 and then prints “Blast off!”.

  • Solution:
    # --- Example 5: The while Loop ---
    print("\n--- T-Minus Countdown ---")
    
    counter = 5
    
    while counter > 0:
        print(f"{counter}...")
        # IMPORTANT: Update the loop variable to avoid an infinite loop.
        counter = counter - 1  # or counter -= 1
    
    print("Blast off!")
    
  • Example Output:
    --- T-Minus Countdown ---
    5...
    4...
    3...
    2...
    1...
    Blast off!
    

The for Loop

Theory

A for loop is a count-controlled loop. It is used to iterate over a sequence (like a list, a string, or a range of numbers) a specific number of times. In Python, it is often used with the range() function to generate a sequence of numbers.

The range() function:

  • range(stop): Generates numbers from 0 up to (but not including) stop.
  • range(start, stop): Generates numbers from start up to stop.
  • range(start, stop, step): Generates numbers from start up to stop, incrementing by step.

Syntax

for variable_name in sequence:
    # Code to execute for each item in the sequence

Example: Exploring range()

  • Problem: Demonstrate the three main ways to use the range() function in a for loop:
    1. Print numbers from 0 to 4.
    2. Print numbers from 1 to 5.
    3. Print all even numbers from 2 to 10.
  • Solution:
    # --- Example 6: The for Loop ---
    print("\n--- Exploring the range() function ---")
    
    # Case 1: range(stop)
    print("Printing numbers from 0 to 4:")
    for i in range(5):
        print(f"Current number is {i}")
    
    # Case 2: range(start, stop)
    print("\nPrinting numbers from 1 to 5:")
    for number in range(1, 6):
        print(f"The number is {number}")
    
    # Case 3: range(start, stop, step)
    print("\nPrinting even numbers from 2 to 10:")
    for num in range(2, 11, 2):
        print(f"Even number: {num}")
    
  • Example Output:
    --- Exploring the range() function ---
    Printing numbers from 0 to 4:
    Current number is 0
    Current number is 1
    Current number is 2
    Current number is 3
    Current number is 4
    
    Printing numbers from 1 to 5:
    The number is 1
    The number is 2
    The number is 3
    The number is 4
    The number is 5
    
    Printing even numbers from 2 to 10:
    Even number: 2
    Even number: 4
    Even number: 6
    Even number: 8
    Even number: 10
    

Loop Control Statements

Theory

Loop control statements change the normal flow of execution inside a loop.

  • break: Immediately terminates the current loop entirely. Execution continues at the first statement after the loop block.
  • continue: Skips the rest of the code in the current iteration and proceeds directly to the next iteration of the loop.

Syntax

These keywords are used inside a loop, typically within an if statement.

# break syntax
if condition:
    break

# continue syntax
if condition:
    continue

Example: Using break and continue

  • Problem 1 (break): Search for the first number between 1 and 20 that is divisible by 7. Once it’s found, print it and stop searching.
  • Problem 2 (continue): Print all the odd numbers between 1 and 10.

  • Solution:
    # --- Example 7: Loop Control Statements ---
    print("\n--- Finding the first number divisible by 7 (using break) ---")
    for number in range(1, 21):
        print(f"Checking {number}...")
        if number % 7 == 0:
            print(f"Found it! The first number divisible by 7 is {number}.")
            break # Exit the loop immediately
    
    print("\n--- Printing only ODD numbers (using continue) ---")
    for number in range(1, 11):
        if number % 2 == 0: # If the number is even...
            continue      # ...skip the print() and go to the next iteration.
        print(f"Odd number: {number}")
    
  • Example Output:
    --- Finding the first number divisible by 7 (using break) ---
    Checking 1...
    Checking 2...
    Checking 3...
    Checking 4...
    Checking 5...
    Checking 6...
    Checking 7...
    Found it! The first number divisible by 7 is 7.
    
    --- Printing only ODD numbers (using continue) ---
    Odd number: 1
    Odd number: 3
    Odd number: 5
    Odd number: 7
    Odd number: 9
    

Nested Loops

Theory

A nested loop is a loop placed inside another loop. For each single iteration of the outer loop, the inner loop completes all of its iterations. This is useful for working with two-dimensional data, like grids or tables.

Syntax

for outer_variable in outer_sequence:
    # Code in the outer loop
    for inner_variable in inner_sequence:
        # Code in the inner loop
        # This block runs completely for each outer loop iteration

Example: Drawing a Rectangle

  • Problem: Write a program that uses nested loops to draw a 4x5 rectangle of asterisks (*) on the screen.

  • Solution:
    # --- Example 8: Nested Loops ---
    print("\n--- Drawing a 4x5 Rectangle ---")
    height = 4
    width = 5
    
    # The outer loop controls the rows
    for row_num in range(height):
        # The inner loop controls the columns for the CURRENT row
        for col_num in range(width):
            # The 'end' parameter prevents print() from adding a newline
            print("* ", end="")
            
        # After the inner loop finishes, print a newline to move to the next row
        print()
    
  • Example Output:

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

Part 3: Problem-Based Learning Activities

Problem 1: The Simple Calculator

  • Problem Statement: Build a simple calculator that asks the user for two numbers and an operator (+, -, *, /). The program should perform the calculation and print the result. Crucially, if the user tries to divide by zero, the program must not crash; instead, it should print a friendly error message.

  • Solution:
    # --- Problem 1: Simple Calculator ---
    
    print("--- Simple Calculator ---")
    num1 = float(input("Enter the first number: "))
    operator = input("Enter an operator (+, -, *, /): ")
    num2 = float(input("Enter the second number: "))
    
    # Use an if-elif-else chain to check the operator
    if operator == '+':
        result = num1 + num2
        print(f"Result: {num1} + {num2} = {result}")
    elif operator == '-':
        result = num1 - num2
        print(f"Result: {num1} - {num2} = {result}")
    elif operator == '*':
        result = num1 * num2
        print(f"Result: {num1} * {num2} = {result}")
    elif operator == '/':
        # Use a nested if to handle the edge case of division by zero
        if num2 == 0:
            print("Error: Cannot divide by zero.")
        else:
            result = num1 / num2
            print(f"Result: {num1} / {num2} = {result}")
    else:
        # Handle invalid operator input
        print("Error: Invalid operator entered.")
    
  • Example Output (Division by Zero):
    --- Simple Calculator ---
    Enter the first number: 10
    Enter an operator (+, -, *, /): /
    Enter the second number: 0
    Error: Cannot divide by zero.
    

Problem 2: Guess the Number Game

  • Problem Statement: Create a ‘Guess the Number’ game. The computer will have a secret number (e.g., 42). The user gets a fixed number of attempts (e.g., 5) to guess it. After each guess, the program should tell the user if their guess was too high, too low, or correct. The game ends if the user guesses correctly or runs out of attempts.

  • Solution:
    # --- Problem 2: Guess the Number Game ---
    secret_number = 42
    max_attempts = 5
    print(f"I'm thinking of a number. You have {max_attempts} attempts to guess it.")
    
    # A 'for' loop is great here because we know the maximum number of attempts
    for attempt_num in range(1, max_attempts + 1):
        print(f"\n--- Attempt {attempt_num} ---")
        guess = int(input("Enter your guess: "))
    
        if guess == secret_number:
            print(f"Congratulations! You guessed it! The number was {secret_number}.")
            break # Exit the loop because the game is over
        elif guess < secret_number:
            print("Too low! Try a higher number.")
        else: # guess > secret_number
            print("Too high! Try a lower number.")
            
        # Check if this was the last attempt and they still haven't won
        if attempt_num == max_attempts:
            print(f"\nSorry, you've run out of attempts. The secret number was {secret_number}.")
    
  • Example Output (User wins):
    I'm thinking of a number. You have 5 attempts to guess it.
    
    --- Attempt 1 ---
    Enter your guess: 20
    Too low! Try a higher number.
    
    --- Attempt 2 ---
    Enter your guess: 50
    Too high! Try a lower number.
    
    --- Attempt 3 ---
    Enter your guess: 42
    Congratulations! You guessed it! The number was 42.
    

Problem 3: Prime Number Checker

  • Problem Statement: Write a program that asks for a positive integer and determines if it is a prime number. A prime number is a number greater than 1 that has no positive divisors other than 1 and itself.

  • Solution:
    # --- Problem 3: Prime Number Checker ---
    print("--- Prime Number Checker ---")
    number = int(input("Enter a positive integer to check: "))
    
    # A "flag" variable to keep track of the result. Assume it's prime.
    is_prime = True
    
    # Prime numbers must be greater than 1
    if number <= 1:
        is_prime = False
    else:
        # Check for divisors from 2 up to number-1
        for i in range(2, number):
            # If the number is perfectly divisible by any 'i', it's not prime
            if (number % i) == 0:
                is_prime = False # Change the flag
                print(f"{number} is divisible by {i}, so it is not a prime number.")
                break # Found a divisor, no need to check further.
    
    # After the loop, check the flag to print the final result
    if is_prime:
        print(f"{number} is a prime number!")
    # This condition prevents printing the message twice for numbers <= 1
    elif number > 1:
        print(f"{number} is not a prime number.")
    else: # Handles the specific case of numbers <= 1
        print(f"{number} is not considered a prime number.")
    
  • Example Output (for a non-prime number):
    --- Prime Number Checker ---
    Enter a positive integer to check: 9
    9 is divisible by 3, so it is not a prime number.
    9 is not a prime number.