Branching and Loops in Practice
Branching and Loops in Practice
We've learned a lot of theory — now it's time to build some real projects. This is a hands-on lesson. Using the if statements, for loops, while loops, break, continue, and other concepts we've learned, we'll build four complete programs step by step.
For each project, we'll analyze the requirements, write the code, and discuss possible improvements.
Project 1: Number Guessing Game (Enhanced)
In Lesson 08, we wrote a basic number guessing game. Now let's upgrade it with difficulty selection, attempt limits, and a "play again" feature.
Requirements
1. Player selects difficulty: Easy (1-50, unlimited), Normal (1-100, 10 tries), Hard (1-200, 7 tries)
2. System randomly generates a target number
3. After each guess, hint "too high" or "too low" and display remaining attempts
4. After guessing correctly or running out of attempts, ask "play again?"
5. Enter q to quit
Complete Code (Star-Star-Star)
Example: Number Guessing Game
import random
print("=" * 30)
print("Number Guessing Game (Enhanced)")
print("=" * 30)
while True: # Outer loop: controls "play again"
# Select difficulty
print("\nSelect difficulty:")
print("1. Easy (1~50, unlimited)")
print("2. Normal (1~100, 10 tries)")
print("3. Hard (1~200, 7 tries)")
choice = input("Enter 1/2/3: ")
if choice == "1":
max_num = 50
max_attempts = float("inf") # Unlimited
elif choice == "2":
max_num = 100
max_attempts = 10
elif choice == "3":
max_num = 200
max_attempts = 7
else:
print("Invalid choice, defaulting to Normal")
max_num = 100
max_attempts = 10
# Generate target number
target = random.randint(1, max_num)
attempts = 0
print(f"\nNumber generated between 1~{max_num}. Start guessing!")
# Inner loop: game main logic
while True:
# Check if attempts are exhausted
if attempts >= max_attempts:
print(f"\nOut of attempts! The answer was {target}")
break
# Get player input
guess_str = input(f"{max_attempts - attempts} tries left, enter your guess: ")
if guess_str.lower() == "q":
print("Quitting game.")
max_attempts = -1 # Flag to notify outer loop
break
# Validate input
if not guess_str.isdigit():
print("Please enter a valid number!")
continue
guess = int(guess_str)
attempts += 1
# Check guess
if guess < target:
print("Too low, try higher!")
elif guess > target:
print("Too high, try lower!")
else:
print(f"\nCongratulations! The answer was {target}!")
print(f"You got it in {attempts} tries.")
break
# Check if we should exit entirely
if max_attempts == -1: # Player entered q
break
# Ask for another round
again = input("\nPlay again? (y/n): ")
if again.lower() != "y":
print("Thanks for playing, goodbye!")
break
Design highlight: The outer loop controls "play again," the inner loop controls the "guess process." The
max_attempts = -1flag solves the issue of breaking out of both loops when the player enters q. A more elegant approach would be to encapsulate the game logic in a function and usereturnto exit once.
Project 2: Multiplication Table (Multiple Styles)
In Lesson 08, we printed a standard multiplication table. A good programmer should be able to flexibly control loop structures to output any style.
Style 1: Standard Lower Triangle (Star-Star)
Example: Standard Lower Triangle
print("=== Standard Lower Triangle ===")
for i in range(1, 10):
for j in range(1, i + 1):
print(f"{j}x{i}={i*j}", end="\t")
print()
Style 2: Full Rectangle (Star-Star)
Example: Full Rectangle
print("=== Full Rectangle ===")
for i in range(1, 10):
for j in range(1, 10):
print(f"{j}x{i}={i*j}", end="\t")
print()
Style 3: Upper Triangle (Star-Star-Star)
Example: Upper Triangle
print("=== Upper Triangle ===")
for i in range(1, 10):
# Print leading spaces for alignment
for k in range(1, i):
print(end="\t\t")
# Print multiplication formulas
for j in range(i, 10):
print(f"{i}x{j}={i*j}", end="\t")
print()
Output:
=== Upper Triangle ===
1x1=1 1x2=2 1x3=3 ... 1x9=9
2x2=4 2x3=6 ... 2x9=18
3x3=9 ... 3x9=27
...
9x9=81
Key insight: The challenge of the upper triangle is the "space alignment" — each row needs
(i-1) * 2tab characters of indentation. This uses two inner loops: the first prints spaces, the second prints the formulas.
Project 3: Simple Calculator (Enhanced)
In the Lesson 08 exercises, we wrote a basic calculator. Now let's make an enhanced version supporting continuous operations with history.
Requirements
1. Start with current result = 0
2. User enters: operator number, e.g., "+ 5"
3. Supported operators: + - * / ** // % clear exit
4. clear resets the result to 0
5. exit quits the program
6. After each operation, show the current result and history
Complete Code (Star-Star-Star)
Example: Enhanced Calculator
print("=" * 40)
print("Enhanced Calculator")
print("Format: operator number, e.g., + 5")
print("Supported: + - * / ** // %")
print("Special commands: clear reset exit quit")
print("=" * 40)
result = 0.0
history = [] # Store operation history
while True:
# Display current result
print(f"\nCurrent result: {result}")
# Get user input
cmd = input(">>> ").strip()
# Handle special commands
if cmd.lower() in ("exit", "quit"):
print("Thanks for using!")
break
if cmd.lower() == "clear":
result = 0.0
history.clear()
print("Reset to 0")
continue
# Parse regular operation commands
parts = cmd.split()
if len(parts) != 2:
print("Invalid format! Enter: operator number")
continue
op, num_str = parts
# Validate number
if not num_str.replace(".", "").isdigit() or num_str.count(".") > 1:
print("Invalid number!")
continue
num = float(num_str)
# Execute operation
old_result = result
if op == "+":
result += num
elif op == "-":
result -= num
elif op == "*":
result *= num
elif op == "/":
if num == 0:
print("Error: Cannot divide by zero!")
continue
result /= num
elif op == "**":
result **= num
elif op == "//":
if num == 0:
print("Error: Cannot divide by zero!")
continue
result //= num
elif op == "%":
if num == 0:
print("Error: Cannot divide by zero!")
continue
result %= num
else:
print(f"Invalid operator: {op}")
continue
# Record history
history.append(f"{old_result} {op} {num} = {result}")
# Display result
print(f"= {result}")
# Show last 3 history entries
if len(history) >= 1:
print("--- Recent History ---")
for item in history[-3:]:
print(f" {item}")
Sample run:
>>> + 10
= 10.0
--- Recent History ---
0.0 + 10.0 = 10.0
>>> * 3
= 30.0
--- Recent History ---
0.0 + 10.0 = 10.0
10.0 * 3.0 = 30.0
>>> / 0
Error: Cannot divide by zero!
>>> clear
Reset to 0
Programming mindset: This example shows the classic interplay of loops and conditions —
while Truekeeps the program running,if-elif-elsehandles various inputs,continueskips invalid input, andbreakexits normally.
Project 4: Prime Number Finder
Let the user input a range, output all prime numbers within that range, and count them.
Requirements
1. User inputs start and end values
2. Program outputs all primes in that range
3. Display 10 per line, neatly aligned
4. Show the total count of primes
Complete Code (Star-Star-Star)
Example: Prime Number Finder
print("Prime Number Finder")
print("Enter a range, and I'll find all primes within it.")
# Get range
start_str = input("Start value (>=2): ")
end_str = input("End value: ")
# Validate input
if not (start_str.isdigit() and end_str.isdigit()):
print("Please enter valid positive integers!")
else:
start = int(start_str)
end = int(end_str)
if start < 2:
start = 2
print("Start value adjusted to 2 (primes start from 2)")
if start > end:
print("Start value cannot be greater than end value!")
else:
primes = [] # Store found primes
# Check each number in the range
for num in range(start, end + 1):
# Check if num is prime
is_prime = True
for i in range(2, int(num ** 0.5) + 1):
if num % i == 0:
is_prime = False
break
if is_prime:
primes.append(num)
# Output results
print(f"\nFound {len(primes)} primes between {start} and {end}:")
for i, prime in enumerate(primes, 1):
print(f"{prime:5d}", end="")
if i % 10 == 0: # Newline every 10
print()
print() # Final newline
Sample output:
Start value (>=2): 50
End value: 200
Found 34 primes between 50 and 200:
53 59 61 67 71 73 79 83 89 97
101 103 107 109 113 127 131 137 139 149
151 157 163 167 173 179 181 191 193 197
199
Optimization tip: When checking if a number is prime, you don't need to divide up to
num-1— only up tosqrt(num). Ifnumhas a factor larger thansqrt(num), it must have a paired factor smaller thansqrt(num). This optimization is very effective for large ranges (100,000+).
Project 5: BMI Health Index + Password Strength Checker
This project ties together arithmetic operators, comparison operators, logical operators, conditionals, and string methods to solve two common real-world problems.
Part 1: BMI Health Index (Star-Star)
BMI (Body Mass Index) is an internationally used measure of body fat. The formula is simple:
BMI = weight(kg) / height(m)^2
Example: BMI Calculator
# BMI Health Index Calculator
# Input data
weight = 68
height = 1.75
# Calculate BMI
bmi = weight / (height ** 2)
print("=== BMI Health Index ===")
print(f"Weight: {weight} kg")
print(f"Height: {height} m")
print(f"BMI: {bmi:.1f}")
# Use chained comparison and if-elif to determine category
if bmi < 18.5:
print("Category: Underweight")
elif 18.5 <= bmi < 24:
print("Category: Normal")
elif 24 <= bmi < 28:
print("Category: Overweight")
else:
print("Category: Obese")
Output:
=== BMI Health Index ===
Weight: 68 kg
Height: 1.75 m
BMI: 22.2
Category: Normal
Tip: Chained comparisons like
18.5 <= bmi < 24are much cleaner thanbmi >= 18.5 and bmi < 24.
Part 2: Password Strength Checker (Star-Star-Star)
Write a program to determine if a user's password is secure. Password strength depends on its length and the types of characters it contains.
Example: Password Strength Checker
# Password Strength Checker
password = "Py3#thon"
# Analyze password characteristics
length = len(password) # Length
has_digit = any(c.isdigit() for c in password) # Contains digit
has_letter = any(c.isalpha() for c in password) # Contains letter
has_special = not password.isalnum() # Contains special character
print("=== Password Strength Checker ===")
print(f"Password: {password}")
print(f"Length: {length}")
print(f"Contains digit: {has_digit}")
print(f"Contains letter: {has_letter}")
print(f"Contains special char: {has_special}")
# Combine conditions with logical operators to determine strength
if length < 6:
strength = "Weak"
elif length >= 10 and has_digit and has_letter and has_special:
strength = "Strong"
elif length >= 8 and has_digit and has_letter:
strength = "Medium"
else:
strength = "Weak"
print(f"Password strength: {strength}")
Output:
=== Password Strength Checker ===
Password: Py3#thon
Length: 8
Contains digit: True
Contains letter: True
Contains special char: True
Password strength: Medium
Details:
len()gets string length,isdigit()checks for digits,isalpha()checks for letters,isalnum()checks if only letters and digits (returnsFalseif special chars exist — negated withnotbecomes "contains special char"). These methods will be covered systematically in the strings lesson.
Common Branching/Looping Mistakes
Everyone makes mistakes when writing code, especially loop beginners. Here are the most typical pitfalls.
Mistake 1: Infinite Loop — Forgetting to Update the Condition Variable
# Wrong way
n = 1
while n <= 10:
print(n)
# forgot n += 1 — never ends
# Correct way
n = 1
while n <= 10:
print(n)
n += 1
Mistake 2: Confusing = with ==
# Wrong way
if score = 100: # This is assignment, not comparison!
print("Perfect!")
# Correct way
if score == 100:
print("Perfect!")
Mistake 3: Modifying a List While Iterating
# Wrong way — deleting during iteration causes skipping
numbers = [1, 2, 3, 4, 5]
for num in numbers:
if num % 2 == 0:
numbers.remove(num)
print(numbers) # May not be what you expect
# Correct way — create a new list
numbers = [1, 2, 3, 4, 5]
odd_numbers = [num for num in numbers if num % 2 != 0]
print(odd_numbers)
Mistake 4: Misunderstanding range() End Value
# Wrong: expecting range(5) to output 1 2 3 4 5
for i in range(5):
print(i) # Actual output: 0 1 2 3 4
# Correct way
for i in range(1, 6):
print(i) # Output: 1 2 3 4 5
Common Use Cases
| Scenario | Loop/Branch Technique | Description |
|---|---|---|
| Data processing (filtering, cleaning) | for + continue |
Skip invalid data |
| User interaction menu | while True + break |
Show menu repeatedly until exit |
| Pagination loading | while + condition |
Until no more data |
| Search/lookup | for + break + else |
Stop on found; else if not found |
| Batch file processing | for + nested logic |
Iterate every file in a directory |
| Game main loop | while True + event handling |
Continuous rendering and input response |
FAQ
False? 2) Does the loop body modify the condition variable? 3) Does while True have a corresponding break? Adding print() to output key variable values is the most effective way to debug infinite loops.range() or iterating over a list?range() returns a lazy sequence without generating all numbers at once. range(1000000) uses almost no memory, while list(range(1000000)) uses a lot. For large iteration counts, use range() directly for better memory efficiency.Summary
- Enhanced Guessing Game: Outer loop for "play again," inner loop for "guessing," use
while True+breakfor multi-level loop exit management - Multiplication Table Styles: Control inner loop's
range()boundaries to output lower triangle, upper triangle, rectangle, and more - Enhanced Calculator:
continueto skip invalid input, list to store history,split()to parse user input - Prime Number Finder: Optimize to check up to
sqrt(num)for efficiency;enumerate(primes, 1)for numbered output - Debugging Tips: Three elements for infinite loop checks, distinguish
=from==, don't modify lists while iterating
Exercises
Star: Narcissistic Numbers
A "narcissistic number" is a 3-digit number where the sum of the cubes of its digits equals the number itself. For example: 153 = 1^3 + 5^3 + 3^3.
Use a for loop to find all narcissistic numbers (there are 4).
Hint: Use range(100, 1000) to iterate all 3-digit numbers; use // and % to extract hundreds, tens, and units digits.
Star-Star: Print a Diamond
Accept an odd number n from the user, then output a diamond made of * in the console.
Example (n=5):
*
***
*
***
*
Hint: A diamond has an upper and lower half. For the upper half, loop i from 1 to n//2 + 1, decreasing spaces and increasing asterisks.
Star-Star-Star: Student Score Management System
Write a program that implements the following features:
1. Enter student scores (enter q to stop)
2. Calculate total, average, highest, and lowest scores
3. Count students in each range: 90-100 (Excellent), 80-89 (Good), 70-79 (Average), 60-69 (Pass), <60 (Fail)
4. Output scores sorted from highest to lowest
Requirements:
- Use
while Trueloop to collect scores - Use a list to store scores
- Use
forloop to count score ranges - Use
sorted(..., reverse=True)for sorting
This project comprehensively applies loops, lists, sorting, and statistics. Completing it means you truly master Python's basic control flow.



