Previous | Tutorial index | Next

Tutorial 6: Practical Coding Exercises (Challenges)

Learning Objective

Solidify understanding of for loops, while loops, break, continue, and nested loops through hands-on, progressively challenging coding problems. Develop problem-solving skills by translating real-world requirements into working Python code.

1. The Mindset of a Problem Solver

Before diving into code, professional programmers follow a mental framework:

  1. Understand the Problem: What are the inputs? What are the outputs? What are the constraints?
  2. Plan the Solution: Write pseudocode or draw a flowchart. What loop type makes sense? What variables do you need?
  3. Write the Code: Translate your plan into Python.
  4. Test and Debug: Run with sample inputs. Check edge cases (empty lists, zero, negative numbers).

This tutorial is structured as a series of challenges, each building on the concepts from the previous tutorials. Try each one yourself before looking at the solutions!

2. Challenge 1: Factorial Calculator (For Loop)

Problem Statement: Write a program that asks the user for a non-negative integer n and calculates its factorial (n!). The factorial of n is the product of all positive integers from 1 to n.

Key Concept: This is the Accumulation Pattern (specifically multiplication). Use a for loop with range().

Step-by-Step Plan:

  1. Ask the user for an integer n.
  2. Initialize an accumulator factorial = 1.
  3. Use a for loop with range(1, n+1) to iterate from 1 to n.
  4. Multiply factorial by each number.
  5. Print the result.
Solution with Detailed Trace
n = int(input("Enter a non-negative integer: ")) factorial = 1 # Handle the edge case of 0! = 1 if n == 0: print("0! = 1") else: for i in range(1, n + 1): factorial = factorial * i print(f"Step {i}: factorial = {factorial}") # Debug output print(f"{n}! = {factorial}")

Trace for n = 5:

Edge Cases to Test:

3. Challenge 2: Guessing Game (While Loop)

Problem Statement: Write a guessing game where the program generates a random number between 1 and 10 (inclusive). The user has unlimited attempts to guess the number. After each guess, tell the user if they are too high, too low, or correct. When they guess correctly, print "You got it!" and the number of attempts.

Key Concept: This is the Interactive Loop pattern with an unknown number of iterations. Use a while True loop with break when the user guesses correctly. Use a counter to track attempts.

Step-by-Step Plan:

  1. Import random and generate a secret number between 1 and 10.
  2. Initialize attempts = 0.
  3. Use while True to loop indefinitely.
  4. Ask the user for a guess.
  5. Increment attempts.
  6. Compare the guess to the secret number:
Sample Solution
import random secret = random.randint(1, 10) attempts = 0 print("I'm thinking of a number between 1 and 10.") print("Can you guess it?") while True: guess = int(input("Your guess: ")) attempts += 1 if guess < secret: print("Too low! Try again.") elif guess > secret: print("Too high! Try again.") else: print(f"You got it! The number was {secret}.") print(f"It took you {attempts} attempt(s).") break

Sample Run:

I'm thinking of a number between 1 and 10. Can you guess it? Your guess: 5 Too low! Try again. Your guess: 8 Too high! Try again. Your guess: 7 You got it! The number was 7. It took you 3 attempt(s).

Edge Cases to Test:

4. Challenge 3: Number Processor (Break and Continue)

Problem Statement: Write a program that asks the user for numbers repeatedly. The program should:

Key Concept: This combines break for the exit condition and continue for skipping invalid (negative) data. This is a Filtering + Accumulation pattern.

Step-by-Step Plan:

  1. Initialize total = 0.
  2. Use while True for an indefinite loop.
  3. Ask the user for a number (as a string first).
  4. If the input is '0', break (exit the loop).
  5. Convert the input to a float or int.
  6. If the number is negative, continue (skip the addition and go back to the top).
  7. If the number is positive, add it to total.
  8. After the loop ends (via break), print the total.
Sample Solution
total = 0 print("Enter numbers to sum. Enter 0 to stop.") print("Negative numbers will be ignored.") while True: user_input = input("Enter a number (0 to stop): ") if user_input == '0': break # Convert to float to handle decimals number = float(user_input) if number < 0: print("Negative number ignored.") continue total += number print(f"Current total: {total}") print(f"Sum of all positive numbers: {total}")

Sample Run:

Enter numbers to sum. Enter 0 to stop. Negative numbers will be ignored. Enter a number (0 to stop): 10 Current total: 10.0 Enter a number (0 to stop): -5 Negative number ignored. Enter a number (0 to stop): 20 Current total: 30.0 Enter a number (0 to stop): 0 Sum of all positive numbers: 30.0

⚠️ Important: Note how continue works. When we type -5, we skip total += number and go back to the top of the loop. The continue does not skip the if user_input == '0' check (it's already below it).

5. Challenge 4: Pyramid of Asterisks (Nested Loops)

Problem Statement: Write a program that asks the user for a height h and prints a pyramid of asterisks (*) with h rows.

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

Key Concept: Nested loops with dynamic ranges. The outer loop controls rows. The inner loops control spaces and stars. The number of spaces decreases as the number of stars increases.

Step-by-Step Plan:

  1. Ask the user for height h.
  2. For each row i from 1 to h:
Solution with Detailed Explanation
h = int(input("Enter the height of the pyramid: ")) for i in range(1, h + 1): # Print spaces (h - i spaces) for j in range(h - i): print(" ", end="") # Print stars (2*i - 1 stars) for k in range(2 * i - 1): print("*", end="") # Move to the next line print()

Trace for h = 5, Row 3 (i = 3):

Edge Cases to Test:

6. Additional Challenge 5: Infinite Loop with Break (Menu System)

Problem Statement: Create a simple calculator menu that runs indefinitely until the user chooses to exit. The menu should:

  1. Ask the user for two numbers.

  2. Display a menu:

    1. Add 2. Subtract 3. Multiply 4. Divide 5. Exit
  3. Perform the chosen operation and display the result.

  4. Use break to exit when the user chooses option 5.

Key Concept: This is a Menu-Driven Program using while True and break for exit. It combines user input validation and arithmetic operations.

Sample Solution
while True: print("\n=== Simple Calculator ===") num1 = float(input("Enter first number: ")) num2 = float(input("Enter second number: ")) print("\nChoose an operation:") print("1. Add") print("2. Subtract") print("3. Multiply") print("4. Divide") print("5. Exit") choice = input("Enter your choice (1-5): ") if choice == '1': print(f"{num1} + {num2} = {num1 + num2}") elif choice == '2': print(f"{num1} - {num2} = {num1 - num2}") elif choice == '3': print(f"{num1} * {num2} = {num1 * num2}") elif choice == '4': if num2 != 0: print(f"{num1} / {num2} = {num1 / num2}") else: print("Error: Cannot divide by zero!") elif choice == '5': print("Goodbye!") break else: print("Invalid choice. Please try again.")

7. Additional Challenge 6: Diamond Pattern (Advanced Nested)

Problem Statement: Extend the pyramid challenge to print a full diamond. For n = 5:

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

Key Concept: The diamond consists of a top pyramid (increasing) and a bottom pyramid (decreasing). Use separate sets of nested loops or a single loop with conditional logic.

Sample Solution
n = int(input("Enter an odd number for diamond height: ")) # Top half (including middle) for i in range(1, n + 1, 2): spaces = (n - i) // 2 stars = i for j in range(spaces): print(" ", end="") for k in range(stars): print("*", end="") print() # Bottom half (excluding middle) for i in range(n - 2, 0, -2): spaces = (n - i) // 2 stars = i for j in range(spaces): print(" ", end="") for k in range(stars): print("*", end="") print()

📝 Quiz: Check Your Understanding

Q1: What is the output of the factorial calculation for n = 4?
a) 24
b) 10
c) 4

Q2: In the Guessing Game, what kind of loop is used?
a) for loop with range()
b) while loop with break
c) Nested loop

Q3: In Challenge 3 (Number Processor), what happens when the user enters -3?
a) It adds -3 to the total.
b) It breaks out of the loop.
c) It skips the number using continue.

Q4: (True/False) The pyramid challenge uses nested loops where the inner loop's range is fixed and independent of the outer loop.

Q5: What does the continue statement do in the context of Challenge 3?
a) Exits the entire program.
b) Skips the rest of the current iteration and goes to the next.
c) Restarts the loop from the beginning.

Click to reveal quiz answers **Answers:** Q1: (a) 24 Q2: (b) `while` loop with `break` Q3: (c) It skips the number using `continue`. Q4: False – the range depends on the row. Q5: (b) Skips the rest of the current iteration and goes to the next.

💻 In-Tutorial Coding Exercises

(Solutions are hidden below – try each one yourself first!)

Exercise 1 (Factorial Variant - Sum of Factorials):
Write a program that calculates the sum of factorials from 1 to n. For n = 3, calculate 1! + 2! + 3! = 1 + 2 + 6 = 9.
(Hint: Use a loop to calculate each factorial and add it to a running total).

Sample Solution
n = int(input("Enter a positive integer: ")) total_sum = 0 for i in range(1, n + 1): # Calculate factorial of i fact = 1 for j in range(1, i + 1): fact *= j total_sum += fact print(f"{i}! = {fact}") # Optional debug print(f"Sum of factorials from 1 to {n} = {total_sum}")

Test: For n = 3, output is 1! = 1, 2! = 2, 3! = 6, sum = 9.

Exercise 2 (Guessing Game with Limited Attempts):
Modify the Guessing Game to give the user exactly 5 attempts. If they guess correctly, print "You win!" and the number of attempts used. If they run out of attempts, print "You lose! The number was X."
(Hint: Use a while loop with a counter attempts <= 5 and an if statement to check for a win/loss after the loop).

Sample Solution
import random secret = random.randint(1, 10) attempts = 5 won = False print("I'm thinking of a number between 1 and 10.") print(f"You have {attempts} attempts.") while attempts > 0: guess = int(input("Your guess: ")) if guess == secret: print(f"You win! The number was {secret}.") won = True break elif guess < secret: print("Too low!") else: print("Too high!") attempts -= 1 if attempts > 0: print(f"{attempts} attempts left.") if not won: print(f"You lose! The number was {secret}.")

Exercise 3 (Number Processor with Statistics):
Extend Challenge 3 to also count how many positive numbers were entered. At the end, print the total, the count, and the average (total / count). Ensure it handles the case where no positive numbers were entered.

Sample Solution
total = 0 count = 0 print("Enter numbers to sum. Enter 0 to stop.") print("Negative numbers will be ignored.") while True: user_input = input("Enter a number (0 to stop): ") if user_input == '0': break number = float(user_input) if number < 0: print("Negative number ignored.") continue total += number count += 1 print(f"Current total: {total}, Count: {count}") if count > 0: average = total / count print(f"Total: {total}, Count: {count}, Average: {average:.2f}") else: print("No positive numbers were entered.")

Exercise 4 (Inverted Pyramid):
Write a program that prints an inverted pyramid for height h.
For h=5:

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

(Hint: Start with 2*h - 1 stars and decrease by 2 each row, with increasing spaces).

Sample Solution
h = int(input("Enter height: ")) for i in range(h): # Print leading spaces for j in range(i): print(" ", end="") # Print stars for k in range(2 * (h - i) - 1): print("*", end="") print()

Trace for h=5:

Exercise 5 (Prime Number Checker with Break):
Write a program that asks the user for a number n and checks if it's prime. Use a for loop from 2 to sqrt(n). Use break as soon as you find a divisor. Use an else clause to print "Prime" if no divisor was found.

Sample Solution
import math n = int(input("Enter a positive integer: ")) if n < 2: print("Not prime") else: for d in range(2, int(math.isqrt(n)) + 1): if n % d == 0: print(f"Not prime (divisible by {d})") break else: print("Prime")

Test: n=29Prime; n=100Not prime (divisible by 2).

📚 Homework Questions

(Complete sample solutions are provided below – but try to solve them independently first!)

Question 1: The Collatz Sequence (While + Accumulation)
The Collatz sequence starts with any positive integer n:

Write a program that asks the user for a starting number and uses a while loop to:

  1. Print each number in the sequence.
  2. Count how many steps it takes to reach 1.
  3. Find the maximum value reached during the sequence.

Example for n = 6: Sequence: 6, 3, 10, 5, 16, 8, 4, 2, 1 (Steps: 8, Max: 16)

Sample Solution
n = int(input("Enter a starting number: ")) original = n steps = 0 max_val = n print(f"Collatz sequence for {n}:", end=" ") while n != 1: print(n, end=" ") if n % 2 == 0: n = n // 2 else: n = 3 * n + 1 steps += 1 if n > max_val: max_val = n print(1) # Print the final 1 print(f"Steps: {steps}") print(f"Maximum value: {max_val}")

Test: For n = 6, output matches the example.

Question 2: The Prime Factor Finder (Nested Loops + Break)
Write a program that asks the user for an integer n > 1. Find and print all of its prime factors.

Hint: Use a while loop to repeatedly divide n by its smallest prime factor. Use a for loop to find the smallest prime factor.

Sample Solution
n = int(input("Enter an integer > 1: ")) original = n print(f"Prime factors of {original}:", end=" ") d = 2 while d * d <= n: while n % d == 0: print(d, end=" ") n //= d d += 1 # If anything remains, it is a prime factor > 1 if n > 1: print(n) else: print() # newline

Test: 842 2 3 7; 1313.

Question 3: The Word Scrambler (For + String Manipulation)
Write a program that takes a word from the user and prints all its characters in reverse order, but only if the word is longer than 3 characters and does not contain the letter 'e'. If the word fails any of these conditions, print "Invalid word" and ask again (using a while loop).

Example:

Sample Solution
while True: word = input("Enter a word: ") # Check conditions if len(word) <= 3: print("Invalid word (too short)") elif 'e' in word.lower(): # case-insensitive check print("Invalid word (contains 'e')") else: # Reverse the word using a for loop reversed_word = "" for char in word: reversed_word = char + reversed_word print(f"Scrambled: {reversed_word}") break # exit the loop after a valid word

Question 4: The Student Grade Analyzer (Data Analysis)
You are given a list of dictionaries (or tuples) containing student names and grades:

students = [ ("Alice", 85), ("Bob", 72), ("Charlie", 93), ("David", 67), ("Eve", 88) ]

Write a program that:

  1. Calculates the class average (accumulation).
  2. Finds the highest grade (searching with tracking).
  3. Finds the lowest grade.
  4. Counts how many students passed (grade >= 70) using a flag or counter.
  5. Prints all students who have an 'A' grade (grade >= 90) by building a new list (filtering).
Sample Solution
students = [ ("Alice", 85), ("Bob", 72), ("Charlie", 93), ("David", 67), ("Eve", 88) ] total = 0 highest = -1 lowest = 101 passed = 0 a_students = [] for name, grade in students: # Accumulation total += grade # Search for highest and lowest if grade > highest: highest = grade if grade < lowest: lowest = grade # Count passed if grade >= 70: passed += 1 # Filter A students if grade >= 90: a_students.append(name) average = total / len(students) print(f"Class Average: {average:.2f}") print(f"Highest Grade: {highest}") print(f"Lowest Grade: {lowest}") print(f"Number of students who passed: {passed}") print(f"Students with an 'A': {a_students}")

Question 5: The Diamond Calculator (Pattern + Loops)
Write a program that prints a diamond made of numbers instead of stars. For n = 5:

1 232 34543 4567654 567898765 4567654 34543 232 1

(Hint: The numbers in each row follow a pattern: they increase to the middle of the row, then decrease. The logic requires careful calculation of the start and end values for each row).

Sample Solution
n = int(input("Enter the size (number of rows in top half): ")) # Top half (including the middle row) for i in range(1, n + 1): # Print leading spaces spaces = n - i print(" " * spaces, end="") # Start value for this row start = i # Middle value (maximum) for this row mid = 2 * i - 1 # Ascending part: from start to mid for num in range(start, mid + 1): print(num, end="") # Descending part: from mid-1 down to start for num in range(mid - 1, start - 1, -1): print(num, end="") print() # newline # Bottom half (excluding the middle row) for i in range(n - 1, 0, -1): spaces = n - i print(" " * spaces, end="") start = i mid = 2 * i - 1 for num in range(start, mid + 1): print(num, end="") for num in range(mid - 1, start - 1, -1): print(num, end="") print()

Test: For n = 5, the output matches the required diamond exactly.

8. Reflection and Next Steps

After completing these challenges, take a moment to reflect:

Key Takeaways:

  1. for loops are for known sequences (range, lists, strings).
  2. while loops are for unknown iteration counts (user input, conditions).
  3. break exits the loop immediately.
  4. continue skips the current iteration.
  5. Nested loops are for multi-dimensional data (2D lists, patterns).
  6. Always test edge cases (empty lists, zero, negatives, maximum/minimum values).

You are now ready for the next unit! The skills you've practiced here are foundational. In the next unit, you'll learn about functions, which will allow you to package these loops into reusable, organized code blocks.

Congratulations on completing six tutorials on loops! You've built a strong foundation in one of programming's most essential concepts. Keep practicing, and remember: the best way to learn programming is to write code, make mistakes, and learn from them. Happy coding! 🚀

Previous | Tutorial index | Next