Previous | Tutorial index | Next

Tutorial 7: Getting User Input (input())

Learning Objective

To be able to write input statements correctly to get input from users.

1. Introduction

1.1 Purpose of input()

The input() function is Python’s primary built‑in tool for interactive input. It pauses program execution and waits for the user to type something on the keyboard and press the Enter key. Once Enter is pressed, the function returns the typed text as a string.

Why is this useful?

1.2 Basic Usage – The Prompt

You can pass an optional prompt string inside the parentheses. The prompt is displayed to the user before waiting for input. It guides the user on what to type.

Syntax:

variable = input("Please enter something: ")

Examples:

# Simple prompt name = input("Enter your name: ") print("Hello, " + name + "!") # Multi‑line prompt age = input("Enter your age:\n(only digits please): ") print("You are " + age + " years old.")

Important: input() always returns the entire line that the user types, including leading/trailing spaces. The trailing newline character (from pressing Enter) is stripped automatically.

1.3 The Critical Characteristic – It Always Returns a str

No matter what the user types—numbers, decimals, punctuation, or even nothing (just pressing Enter)—input() returns a string.

value = input("Enter something: ") print(type(value)) # <class 'str'>

Consequences:

1.4 Type Conversion – Making Numbers Useful

To use numeric input in calculations, you must explicitly convert the string to the appropriate numeric type.

Examples:

# Integer conversion age_str = input("Enter your age: ") age = int(age_str) # now age is an int next_age = age + 1 print(f"Next year you will be {next_age}") # Float conversion price_str = input("Enter the price: ") price = float(price_str) total = price * 1.07 # add 7% tax print(f"Total with tax: ${total:.2f}")

Chaining conversion in one line:

age = int(input("Enter your age: ")) # efficient, but no error handling

Potential Errors (ValueError): If the user enters something that is not a valid number (e.g., "abc" or "5.5" when using int()), Python raises a ValueError and the program crashes unless handled.

1.5 Error Handling – Graceful Recovery with try/except

To prevent crashes, you can catch the ValueError exception using a try/except block.

Basic Structure:

try: age = int(input("Enter your age: ")) print(f"Your age is {age}.") except ValueError: print("That's not a valid number! Please enter digits only.")

How It Works:

Example with Multiple Conversions:

try: salary = float(input("Enter your monthly salary: ")) bonus = float(input("Enter your bonus: ")) total = salary + bonus print(f"Total compensation: ${total:.2f}") except ValueError: print("Please enter valid numbers for salary and bonus.")

Note: You can have multiple except blocks to catch different types of errors, but for input() conversion, ValueError is the most common.

1.6 Cleaning Input – Stripping Whitespace

Users may accidentally type spaces before or after their input. This can cause problems with validation.

Use strip() to remove leading/trailing spaces:

name = input("Enter your name: ").strip()

If the user types " Alice ", it becomes "Alice".

Other useful string methods:

Example:

answer = input("Do you want to continue? (y/n): ").strip().lower() if answer == "y": print("Continuing...")

1.7 Reading Multiple Values on One Line

Sometimes you want the user to enter two or more values in a single line (e.g., "3 5" for coordinates). Use the split() method.

split() – splits a string into a list of substrings based on whitespace (by default). You can also specify a delimiter.

# Enter "10 20" x, y = input("Enter x and y (separated by space): ").split() x = int(x) y = int(y) print(f"Sum: {x + y}")

Important: The result of split() is a list of strings. You must convert each element individually.

Processing multiple numbers:

# Enter three numbers: 5 10 15 numbers = input("Enter three numbers: ").split() if len(numbers) == 3: a, b, c = map(int, numbers) # map() applies int to each print(f"Sum: {a + b + c}") else: print("Please enter exactly three numbers.")

Using map() for concise conversion:

a, b = map(int, input("Enter two numbers: ").split()) print(a + b)

But be cautious: map() returns an iterator; unpacking works only if the number of elements matches.

1.8 Validation Loops – Repeat Until Valid Input

Often you want to keep asking the user until they provide a valid value. Use a while loop.

Example – keep asking for a valid integer:

while True: user_input = input("Enter an integer: ") try: value = int(user_input) break # exit loop if conversion succeeds except ValueError: print("Invalid input. Please enter a whole number.") print(f"You entered: {value}")

Example – ask for a specific format (e.g., yes/no):

while True: choice = input("Continue? (yes/no): ").strip().lower() if choice in ("yes", "no"): break print("Please type 'yes' or 'no'.") if choice == "yes": print("Continuing...") else: print("Exiting.")

1.9 Security Considerations and Gotchas

Handling empty input gracefully:

name = input("Enter your name: ").strip() if name == "": name = "Anonymous" print(f"Hello, {name}!")

1.10 Best Practices for input()

  1. Always provide a clear prompt – tell the user what to enter.
  2. Strip whitespace – use .strip() to avoid accidental spaces.
  3. Convert explicitly – use int() or float() and handle errors.
  4. Use try/except – to make programs robust.
  5. Use validation loops – keep asking until valid input.
  6. Provide feedback – tell the user when they made a mistake and how to correct it.
  7. Use input() only for interactive command‑line programs – for GUIs or web apps, use other mechanisms.

2. Code Examples (Annotated)

# --- Basic input and type checking --- print("--- Basic Input ---") name = input("What is your name? ") print(f"Hello, {name}!") print(f"Type of name: {type(name)}") # --- Numeric input with conversion --- print("\n--- Numeric Input ---") try: age = int(input("Enter your age: ")) print(f"You are {age} years old.") print(f"In 10 years, you will be {age + 10}.") except ValueError: print("That is not a valid age. Please enter a whole number.") # --- Float conversion --- print("\n--- Float Input ---") try: price = float(input("Enter the price: $")) tax = price * 0.07 total = price + tax print(f"Price: ${price:.2f}, Tax: ${tax:.2f}, Total: ${total:.2f}") except ValueError: print("Invalid price. Please enter a number.") # --- Stripping whitespace and case handling --- print("\n--- Cleaning Input ---") response = input("Do you like Python? (yes/no): ").strip().lower() if response == "yes": print("Great!") elif response == "no": print("That's okay, you can still learn.") else: print("I didn't understand your answer.") # --- Reading multiple values --- print("\n--- Multiple Values ---") try: x, y = map(int, input("Enter two numbers separated by space: ").split()) print(f"Sum: {x + y}, Product: {x * y}") except ValueError: print("Please enter exactly two integers separated by a space.") except Exception as e: print(f"An error occurred: {e}") # --- Validation loop (keep asking until valid) --- print("\n--- Validation Loop ---") while True: try: score = float(input("Enter your test score (0-100): ")) if 0 <= score <= 100: break else: print("Score must be between 0 and 100. Try again.") except ValueError: print("Invalid input. Please enter a number.") print(f"Your score is {score:.1f}.")

3. Quiz (Check Your Understanding)

Question 1: What is the data type of the value returned by input()?
a) int
b) float
c) str
d) bool

Answer c) `str`

Question 2: What is the purpose of the prompt string in input("Enter name: ")?
a) It validates the user input.
b) It displays a message to guide the user.
c) It converts the input to the correct type.
d) It stores the input in a variable.

Answer b) It displays a message.

Question 3: How do you convert a string "25" from input() to an integer?
a) int(input())
b) float(input())
c) str(input())
d) bool(input())

Answer a) `int(input())`

Question 4: What happens if you execute int(input("Enter number: ")) and the user types "3.5"?
a) The number is converted to 3.
b) A ValueError is raised.
c) The number is converted to 3.5.
d) The program asks again.

Answer b) `ValueError` – `int()` cannot parse a string with a decimal point.

Question 5: What is the purpose of a try/except block when using input()?
a) To repeat the input prompt.
b) To handle errors like invalid number conversion gracefully.
c) To strip whitespace from the input.
d) To convert the input to uppercase.

Answer b) To handle conversion errors.

Question 6: Which method removes leading and trailing spaces from a string?
a) remove()
b) clean()
c) strip()
d) trim()

Answer c) `strip()`

Question 7: How do you read two numbers on the same line separated by a space?
a) a, b = input().split()
b) a, b = map(int, input().split())
c) Both a and b (but b also converts)
d) Only a is correct

Answer b) is the full correct way; a) would give strings. So the best answer is b.

Question 8: What is the output if user types " Alice " for name = input("Enter name: ").strip(); print(name)?
a) " Alice "
b) "Alice"
c) "Alice "
d) " Alice"

Answer b) `"Alice"`

Question 9: Which exception is raised when int() fails to convert a string?
a) TypeError
b) ValueError
c) NameError
d) SyntaxError

Answer b) `ValueError`

Question 10: What is the best practice for asking a user to enter a number?
a) num = input("Enter: ") and then use num + 5
b) num = int(input("Enter: ")) without error handling
c) Use a try/except block to handle conversion errors
d) Use eval(input("Enter: "))

Answer c) Use `try`/`except` to handle errors gracefully.

4. Exercises (In-Class / Lab Practice)

Exercise 1: Personal Information Collector
Ask for full name, age, height, weight; convert appropriately; print summary and BMI.

Sample Solution ```python name = input("Full name: ").strip() try: age = int(input("Age: ")) except ValueError: age = 0 print("Invalid age, set to 0.") try: height = float(input("Height (m): ")) except ValueError: height = 0.0 try: weight = float(input("Weight (kg): ")) except ValueError: weight = 0.0 if height > 0: bmi = weight / (height ** 2) else: bmi = 0.0 print(f"Hello {name}, you are {age} years old, {height}m tall, {weight}kg, BMI: {bmi:.2f}") ```

Exercise 2: Calculator
Ask for two numbers and an operation, perform it, handle division by zero.

Sample Solution ```python try: a = float(input("First number: ")) b = float(input("Second number: ")) op = input("Operation (+, -, *, /): ").strip() if op == '+': result = a + b elif op == '-': result = a - b elif op == '*': result = a * b elif op == '/': try: result = a / b except ZeroDivisionError: print("Cannot divide by zero.") result = None else: print("Invalid operation.") result = None if result is not None: print(f"Result: {result}") except ValueError: print("Invalid number.") ```

Exercise 3: Multi‑input Parser

Write a program that:

  1. Asks the user to enter three integers on one line, separated by spaces.
  2. Use split() to extract them.
  3. Convert each to int and calculate the sum, average, and product.
  4. If the user enters less than or more than three numbers, print an error and stop.
  5. Use map(int, ...) for conversion.
Sample Answer
""" MULTI-INPUT PARSER Demonstrates reading and processing multiple inputs on one line """ print("=" * 60) print("MULTI-INPUT PARSER") print("=" * 60) print("\nPlease enter three integers separated by spaces.") print("Example: 5 10 15") # --- Get input and split --- user_input = input("\nEnter three integers: ").strip() # --- Split the input into parts --- parts = user_input.split() print(f"\nYou entered {len(parts)} number(s): {parts}") # --- Check if exactly three numbers were entered --- if len(parts) != 3: print("\n❌ Error: You must enter exactly three numbers.") print(f" You entered {len(parts)} number(s). Please try again.") else: # --- Convert using map(int, ...) --- try: # Method 1: Using map() to convert all at once numbers = list(map(int, parts)) # Alternative: Unpack directly # a, b, c = map(int, parts) # --- Extract individual numbers --- a, b, c = numbers # --- Calculate results --- sum_result = a + b + c average = sum_result / 3 product = a * b * c # --- Display results --- print("\n" + "-" * 60) print("RESULTS") print("-" * 60) print(f"Numbers: {a}, {b}, {c}") print(f"Sum: {a} + {b} + {c} = {sum_result}") print(f"Average: {sum_result} / 3 = {average:.2f}") print(f"Product: {a} × {b} × {c} = {product}") print("-" * 60) except ValueError as e: print(f"\n❌ Error: Invalid input. Please enter integers only.") print(f" Details: {e}") print("\n" + "=" * 60)

Sample Output (Success):

============================================================ MULTI-INPUT PARSER ============================================================ Please enter three integers separated by spaces. Example: 5 10 15 Enter three integers: 5 10 15 You entered 3 number(s): ['5', '10', '15'] ------------------------------------------------------------ RESULTS ------------------------------------------------------------ Numbers: 5, 10, 15 Sum: 5 + 10 + 15 = 30 Average: 30 / 3 = 10.00 Product: 5 × 10 × 15 = 750 ------------------------------------------------------------ ============================================================

Sample Output (Wrong Number of Inputs):

============================================================ MULTI-INPUT PARSER ============================================================ Please enter three integers separated by spaces. Example: 5 10 15 Enter three integers: 5 10 You entered 2 number(s): ['5', '10'] ❌ Error: You must enter exactly three numbers. You entered 2 number(s). Please try again. ============================================================

Sample Output (Invalid Input):

============================================================ MULTI-INPUT PARSER ============================================================ Please enter three integers separated by spaces. Example: 5 10 15 Enter three integers: 5 abc 15 You entered 3 number(s): ['5', 'abc', '15'] ❌ Error: Invalid input. Please enter integers only. Details: invalid literal for int() with base 10: 'abc' ============================================================

Explanation:

  1. split() – Splits the input string into a list of substrings based on whitespace.

  2. len(parts) – Checks how many items were entered.

  3. map(int, parts) – Applies int() to each element in the list.

  4. list(map(int, parts)) – Converts the map object to a list of integers.

  5. Unpackinga, b, c = numbers assigns each value to a separate variable.

  6. Error Handlingtry/except catches ValueError if conversion fails.

Alternative Approach (Unpacking Directly):

# Alternative: Unpack directly without creating a list try: a, b, c = map(int, parts) # ... rest of code except ValueError: print("Invalid input!") except ValueError: # This catches the case where there aren't exactly 3 values print("Must enter exactly 3 values!")

Exercise 4: Validation Loop – Password Entry

Write a program that:

  1. Defines a correct password (e.g., "python123").
  2. Uses a loop to repeatedly ask the user for the password until they enter the correct one.
  3. Strip leading/trailing spaces.
  4. Print "Access granted" and break when correct.
  5. Bonus: Limit the number of attempts to 3; after that, print "Too many attempts" and exit.
Sample Answer
""" PASSWORD VALIDATION LOOP Demonstrates input validation with attempt limiting """ print("=" * 60) print("PASSWORD VALIDATION") print("=" * 60) # --- Define the correct password --- correct_password = "python123" max_attempts = 3 print(f"\nYou have {max_attempts} attempts to enter the password.") print("Type 'quit' to exit.\n") # --- Basic version: Loop until correct --- print("\n" + "-" * 60) print("BASIC VERSION (Infinite until correct)") print("-" * 60) attempts = 0 while True: password = input("Enter password: ").strip() attempts += 1 if password == correct_password: print("✅ Access granted!") print(f" You succeeded on attempt {attempts}.") break else: print("❌ Incorrect password. Try again.\n") print("\n" + "-" * 60) print("BONUS VERSION (Limited to 3 attempts)") print("-" * 60) # --- Bonus: Limited attempts version --- attempts = 0 max_attempts = 3 while attempts < max_attempts: password = input(f"Attempt {attempts + 1}/{max_attempts} - Enter password: ").strip() attempts += 1 if password == correct_password: print("✅ Access granted!") print(f" You succeeded on attempt {attempts}.") break else: remaining = max_attempts - attempts if remaining > 0: print(f"❌ Incorrect password. {remaining} attempt(s) remaining.\n") else: print("❌ Incorrect password. No more attempts.") # Check if user ran out of attempts if attempts >= max_attempts and password != correct_password: print("\n❌ Too many attempts. Access denied.") print(" Please try again later.") print("\n" + "=" * 60) print("ENHANCED VERSION (With exit option and feedback)") print("=" * 60) # --- Enhanced version with features --- correct_password = "python123" max_attempts = 3 attempts = 0 print(f"\nYou have {max_attempts} attempts.") print("Type 'quit' to exit.\n") while attempts < max_attempts: password = input(f"Attempt {attempts + 1}/{max_attempts} - Enter password: ").strip() # Allow user to quit if password.lower() == 'quit': print("❌ Exiting program.") break attempts += 1 if password == correct_password: print("✅ Access granted!") print(f" You succeeded on attempt {attempts}.") break else: remaining = max_attempts - attempts if remaining > 0: # Provide hints (optional) print(f"❌ Incorrect password. {remaining} attempt(s) remaining.") # Optional: Provide a hint based on the input if len(password) == 0: print(" Hint: You didn't enter anything.") elif len(password) < len(correct_password): print(" Hint: Too short.") elif len(password) > len(correct_password): print(" Hint: Too long.") else: print("❌ Incorrect password. No more attempts.") if attempts >= max_attempts and password != correct_password and password.lower() != 'quit': print("\n❌ Too many failed attempts. Access denied.") print(f" You used all {max_attempts} attempts.") print(" Please try again later.") print("\n" + "=" * 60) print("KEY TAKEAWAYS") print("=" * 60) print(" • Use `while` loops for repeated input validation") print(" • `strip()` removes leading/trailing spaces") print(" • `break` exits the loop when valid input is received") print(" • Track attempts with a counter variable") print(" • Provide clear feedback to guide the user") print(" • Consider allowing an exit option (e.g., 'quit')") print("=" * 60)

Sample Output:

============================================================ PASSWORD VALIDATION ============================================================ You have 3 attempts to enter the password. Type 'quit' to exit. ------------------------------------------------------------ BASIC VERSION (Infinite until correct) ------------------------------------------------------------ Enter password: hello ❌ Incorrect password. Try again. Enter password: python123 ✅ Access granted! You succeeded on attempt 2. ------------------------------------------------------------ BONUS VERSION (Limited to 3 attempts) ------------------------------------------------------------ Attempt 1/3 - Enter password: hello ❌ Incorrect password. 2 attempt(s) remaining. Attempt 2/3 - Enter password: world ❌ Incorrect password. 1 attempt(s) remaining. Attempt 3/3 - Enter password: python123 ✅ Access granted! You succeeded on attempt 3. ============================================================ ENHANCED VERSION (With exit option and feedback) ============================================================ You have 3 attempts. Type 'quit' to exit. Attempt 1/3 - Enter password: hi ❌ Incorrect password. 2 attempt(s) remaining. Hint: Too short. Attempt 2/3 - Enter password: ❌ Incorrect password. 1 attempt(s) remaining. Hint: You didn't enter anything. Attempt 3/3 - Enter password: quit ❌ Exiting program. ============================================================ KEY TAKEAWAYS ============================================================ • Use `while` loops for repeated input validation • `strip()` removes leading/trailing spaces • `break` exits the loop when valid input is received • Track attempts with a counter variable • Provide clear feedback to guide the user • Consider allowing an exit option (e.g., 'quit') ============================================================

Explanation:

  1. Loop Structurewhile True (infinite) or while attempts < max_attempts.

  2. strip() – Removes leading/trailing spaces from the password.

  3. break – Exits the loop when the correct password is entered.

  4. Attempt Counter – Tracks how many times the user has tried.

  5. Feedback – Provides clear messages about incorrect passwords and remaining attempts.

  6. Exit Option – Allows the user to type "quit" to exit gracefully.

Password Strength Hints (Optional Enhancement):

def check_password_strength(password): """Provides feedback on password strength.""" if len(password) < 8: return "Too short (min 8 characters)" if not any(c.isdigit() for c in password): return "Add at least one digit" if not any(c.isupper() for c in password): return "Add at least one uppercase letter" if not any(c.islower() for c in password): return "Add at least one lowercase letter" return "Strong password!"

Exercise 5: Grade Input with Validation

Write a program that:

  1. Asks the user to enter a grade between 0 and 100.
  2. Uses a validation loop to ensure the input is a valid number within the range.
  3. If the user enters a letter or out‑of‑range value, print a meaningful error and ask again.
  4. Once valid, print the letter grade: A (90+), B (80‑89), C (70‑79), D (60‑69), F (<60).
Sample Answer
""" GRADE INPUT WITH VALIDATION Demonstrates robust input validation and letter grade conversion """ import time print("=" * 60) print("GRADE INPUT WITH VALIDATION") print("=" * 60) print("\nPlease enter a grade between 0 and 100.") print("Enter 'quit' to exit.\n") # --- Main validation loop --- def get_valid_grade(): """ Continuously asks the user for a valid grade until one is entered. Returns the valid grade as a float. """ while True: # Get user input user_input = input("Enter grade (0-100): ").strip() # Check for exit command if user_input.lower() == 'quit': print("❌ Exiting program.") return None # --- Validate input --- try: # Convert to float (allows decimal grades) grade = float(user_input) # Check if within valid range if 0 <= grade <= 100: return grade # Valid grade found else: print(f"❌ Error: Grade must be between 0 and 100. Got: {grade}") print(" Please try again.\n") except ValueError: print(f"❌ Error: '{user_input}' is not a valid number.") print(" Please enter a numeric value.\n") # --- Letter grade function --- def get_letter_grade(score): """ Returns the letter grade for a given score. """ if score >= 90: return 'A' elif score >= 80: return 'B' elif score >= 70: return 'C' elif score >= 60: return 'D' else: return 'F' # --- Main program --- while True: grade = get_valid_grade() if grade is None: # User quit break # Convert to letter grade letter = get_letter_grade(grade) # Print result print("\n" + "-" * 40) print(f"Grade: {grade:.2f}") print(f"Letter Grade: {letter}") print("-" * 40) print() print("\n" + "=" * 60) print("ENHANCED VERSION - With Statistics") print("=" * 60) # --- Enhanced version with statistics tracking --- grades_list = [] max_grades = 5 print(f"\nEnter up to {max_grades} grades to analyze.") print("Type 'done' when finished.\n") def get_enhanced_grade(): """Get a grade with additional features.""" while True: user_input = input(f"Grade {len(grades_list) + 1}: ").strip() if user_input.lower() == 'done': return None try: grade = float(user_input) if 0 <= grade <= 100: return grade else: print(f"❌ Error: Grade must be between 0 and 100. Got: {grade}") except ValueError: print(f"❌ Error: '{user_input}' is not a valid number.") # Collect grades while len(grades_list) < max_grades: grade = get_enhanced_grade() if grade is None: # User typed 'done' break grades_list.append(grade) letter = get_letter_grade(grade) print(f" → Letter grade: {letter}") # --- Display statistics --- if grades_list: print("\n" + "-" * 60) print("GRADE STATISTICS") print("-" * 60) # Calculate statistics total = sum(grades_list) average = total / len(grades_list) highest = max(grades_list) lowest = min(grades_list) # Display all grades with letter grades print("\nGrades entered:") for i, grade in enumerate(grades_list, 1): letter = get_letter_grade(grade) print(f" Grade {i}: {grade:.2f}{letter}") print("\n" + "-" * 40) print(f"Number of grades: {len(grades_list)}") print(f"Sum: {total:.2f}") print(f"Average: {average:.2f}") print(f"Highest: {highest:.2f}") print(f"Lowest: {lowest:.2f}") # Grade distribution print("\nGrade Distribution:") letter_counts = {} for grade in grades_list: letter = get_letter_grade(grade) letter_counts[letter] = letter_counts.get(letter, 0) + 1 for letter in ['A', 'B', 'C', 'D', 'F']: count = letter_counts.get(letter, 0) percentage = (count / len(grades_list)) * 100 if count > 0: print(f" {letter}: {count} grade(s) ({percentage:.1f}%)") else: print(f" {letter}: 0 grade(s)") print("\n" + "=" * 60) print("KEY TAKEAWAYS") print("=" * 60) print(" • Use `while True` with `break` for validation loops") print(" • `strip()` removes extra whitespace") print(" • `try`/`except` handles non-numeric input") print(" • Range checking ensures values are within bounds") print(" • Provide clear, specific error messages") print(" • Allow users to exit gracefully (e.g., 'quit' or 'done')") print(" • Use functions to organize reusable code") print("=" * 60)

Sample Output:

============================================================ GRADE INPUT WITH VALIDATION ============================================================ Please enter a grade between 0 and 100. Enter 'quit' to exit. Enter grade (0-100): 95 ---------------------------------------- Grade: 95.00 Letter Grade: A ---------------------------------------- Enter grade (0-100): 82 ---------------------------------------- Grade: 82.00 Letter Grade: B ---------------------------------------- Enter grade (0-100): abc ❌ Error: 'abc' is not a valid number. Please enter a numeric value. Enter grade (0-100): 150 ❌ Error: Grade must be between 0 and 100. Got: 150.0 Please try again. Enter grade (0-100): 75 ---------------------------------------- Grade: 75.00 Letter Grade: C ---------------------------------------- Enter grade (0-100): quit ❌ Exiting program. ============================================================ ENHANCED VERSION - With Statistics ============================================================ Enter up to 5 grades to analyze. Type 'done' when finished. Grade 1: 85 → Letter grade: B Grade 2: 92 → Letter grade: A Grade 3: 78 → Letter grade: C Grade 4: 65 → Letter grade: D Grade 5: 95 → Letter grade: A ------------------------------------------------------------ GRADE STATISTICS ------------------------------------------------------------ Grades entered: Grade 1: 85.00 → B Grade 2: 92.00 → A Grade 3: 78.00 → C Grade 4: 65.00 → D Grade 5: 95.00 → A ---------------------------------------- Number of grades: 5 Sum: 415.00 Average: 83.00 Highest: 95.00 Lowest: 65.00 Grade Distribution: A: 2 grade(s) (40.0%) B: 1 grade(s) (20.0%) C: 1 grade(s) (20.0%) D: 1 grade(s) (20.0%) F: 0 grade(s) ============================================================ KEY TAKEAWAYS ============================================================ • Use `while True` with `break` for validation loops • `strip()` removes extra whitespace • `try`/`except` handles non-numeric input • Range checking ensures values are within bounds • Provide clear, specific error messages • Allow users to exit gracefully (e.g., 'quit' or 'done') • Use functions to organize reusable code ============================================================

Explanation:

Validation Loop Structure:

  1. while True – Creates an infinite loop that repeats until valid input is received.

  2. strip() – Removes leading/trailing spaces from input.

  3. try/except – Catches ValueError when input is not a number.

  4. Range Check – Verifies 0 <= grade <= 100.

  5. return grade – Exits the function and returns the valid grade.

  6. break – Exits the loop when 'quit' is entered.

Letter Grade Function:

Enhanced Features:

  1. Collect Multiple Grades – Stores grades in a list.

  2. Statistics – Calculates sum, average, highest, lowest.

  3. Grade Distribution – Counts how many of each letter grade.

  4. Percentage – Shows what percentage of grades are in each category.

Common Validation Patterns:

# Pattern 1: Simple validation with break while True: input_value = input("Enter a number: ") try: value = float(input_value) if 0 <= value <= 100: break print("Out of range!") except ValueError: print("Not a number!") # Pattern 2: Validation with function def get_valid_input(prompt, min_val, max_val): while True: try: value = float(input(prompt)) if min_val <= value <= max_val: return value print(f"Must be between {min_val} and {max_val}") except ValueError: print("Must be a number") # Pattern 3: Validation with count tracking attempts = 0 max_attempts = 3 while attempts < max_attempts: try: value = float(input("Enter: ")) if 0 <= value <= 100: break attempts += 1 print(f"{max_attempts - attempts} attempts remaining") except ValueError: attempts += 1 print("Invalid input!")

5. Homework Questions (Deep Thinking)

Question 1 (Code Analysis – Find the Bug):
The following program is supposed to calculate the sum of two numbers. It crashes when the user enters "5" and "abc". Explain why and fix it.

num1 = input("Enter first number: ") num2 = input("Enter second number: ") print("Sum:", num1 + num2)
Sample Answer The bug is that `input()` returns strings, so `+` performs concatenation, not addition. Also, when one is a non‑numeric string, trying to convert would fail. Fix by converting both to numbers using `float()` or `int()` and handling errors with `try`/`except`.

Question 2 (Defensive Programming):
Write a program that asks for a positive integer and keeps asking until valid.

Sample Answer ```python while True: s = input("Enter a positive integer: ") try: n = int(s) if n > 0: break else: print("Must be positive.") except ValueError: print("Invalid input.") print(f"Square root: {n ** 0.5}") ```

Question 3 (Real‑World Application – Order System):

Write a program for a small coffee shop:

  1. Ask the user for the number of coffees (integer) and the number of pastries (integer).
  2. Coffees cost $3.50 each, pastries cost $2.25 each.
  3. Ask if the user has a discount code. If they type "SAVE10" (case‑insensitive), apply a 10% discount.
  4. Calculate the total bill, apply a 7% sales tax, and print the final total with 2 decimal places.
  5. Use try/except for all numeric inputs and handle invalid entries gracefully (set to 0 and warn).
Sample Answer
""" COFFEE SHOP ORDER SYSTEM Demonstrates input validation, discount application, and tax calculation """ print("=" * 60) print("☕ COFFEE SHOP ORDER SYSTEM") print("=" * 60) # --- Constants --- COFFEE_PRICE = 3.50 PASTRY_PRICE = 2.25 TAX_RATE = 0.07 # 7% DISCOUNT_CODE = "SAVE10" DISCOUNT_RATE = 0.10 # 10% print("\nWelcome to the Coffee Shop!") print(f"☕ Coffee: ${COFFEE_PRICE:.2f} each") print(f"🥐 Pastry: ${PASTRY_PRICE:.2f} each") print(f"Discount code: '{DISCOUNT_CODE}' for 10% off") print(f"Sales tax: {TAX_RATE * 100:.0f}%\n") # --- Helper function for getting integer input --- def get_integer_input(prompt, item_name): """ Gets an integer input from the user with error handling. Returns 0 if invalid input is provided. """ while True: try: value = int(input(prompt)) if value < 0: print(f" ⚠️ {item_name} cannot be negative. Using 0.") return 0 return value except ValueError: print(f" ❌ Invalid input! Please enter a whole number.") print(f" ⚠️ Setting {item_name} to 0.") return 0 # --- Step 1: Get order quantities --- print("Please enter your order:") coffee_count = get_integer_input(" Number of coffees: ", "Coffee count") pastry_count = get_integer_input(" Number of pastries: ", "Pastry count") # --- Step 2: Calculate subtotal --- coffee_total = coffee_count * COFFEE_PRICE pastry_total = pastry_count * PASTRY_PRICE subtotal = coffee_total + pastry_total # --- Display order summary --- print("\n" + "-" * 40) print("ORDER SUMMARY") print("-" * 40) print(f"Coffees: {coffee_count} × ${COFFEE_PRICE:.2f} = ${coffee_total:>7.2f}") print(f"Pastries: {pastry_count} × ${PASTRY_PRICE:.2f} = ${pastry_total:>7.2f}") print("-" * 40) print(f"Subtotal: ${subtotal:>7.2f}") # --- Step 3: Apply discount if applicable --- discount = 0.0 if subtotal > 0: discount_input = input("\nDo you have a discount code? (Enter code or press Enter): ").strip() if discount_input.upper() == DISCOUNT_CODE: discount = subtotal * DISCOUNT_RATE print(f"✅ Discount applied! You saved ${discount:.2f}") elif discount_input: print(f"❌ Invalid discount code: '{discount_input}'") else: print("No discount code entered.") else: print("\nNo items ordered. No discount applied.") # --- Step 4: Calculate total with tax --- subtotal_after_discount = subtotal - discount tax = subtotal_after_discount * TAX_RATE total = subtotal_after_discount + tax # --- Display final bill --- print("\n" + "-" * 40) print("FINAL BILL") print("-" * 40) if discount > 0: print(f"Subtotal: ${subtotal:>7.2f}") print(f"Discount (10%): -${discount:>6.2f}") print(f"Subtotal after discount: ${subtotal_after_discount:>7.2f}") else: print(f"Subtotal: ${subtotal:>7.2f}") print(f"Tax ({TAX_RATE * 100:.0f}%): ${tax:>7.2f}") print("=" * 40) print(f"TOTAL: ${total:>7.2f}") print("=" * 40) # --- Additional information --- print("\n" + "-" * 40) print("ORDER DETAILS") print("-" * 40) print(f"Items ordered: {coffee_count + pastry_count}") print(f"Total items: {coffee_count + pastry_count}") if coffee_count + pastry_count > 0: avg_price = total / (coffee_count + pastry_count) print(f"Average price per item: ${avg_price:.2f}") else: print("No items ordered.") print("\n" + "=" * 60) print("KEY TAKEAWAYS") print("=" * 60) print(" • Use `try`/`except` to validate numeric input") print(" • Use `.upper()` for case‑insensitive comparisons") print(" • Calculate percentages with decimal multipliers (0.10 for 10%)") print(" • Apply tax to the discounted subtotal") print(" • Format currency with `{value:.2f}` and `>7.2f` for alignment") print(" • Always handle edge cases (empty input, negative values)") print("=" * 60)

Sample Output (With Discount):

============================================================ ☕ COFFEE SHOP ORDER SYSTEM ============================================================ Welcome to the Coffee Shop! ☕ Coffee: $3.50 each 🥐 Pastry: $2.25 each Discount code: 'SAVE10' for 10% off Sales tax: 7% Please enter your order: Number of coffees: 3 Number of pastries: 2 ---------------------------------------- ORDER SUMMARY ---------------------------------------- Coffees: 3 × $3.50 = $ 10.50 Pastries: 2 × $2.25 = $ 4.50 ---------------------------------------- Subtotal: $ 15.00 Do you have a discount code? (Enter code or press Enter): SAVE10 ✅ Discount applied! You saved $1.50 ---------------------------------------- FINAL BILL ---------------------------------------- Subtotal: $ 15.00 Discount (10%): -$ 1.50 Subtotal after discount: $ 13.50 Tax (7%): $ 0.95 ======================================== TOTAL: $ 14.45 ======================================== ---------------------------------------- ORDER DETAILS ---------------------------------------- Items ordered: 5 Total items: 5 Average price per item: $2.89 ============================================================ KEY TAKEAWAYS ============================================================ • Use `try`/`except` to validate numeric input • Use `.upper()` for case‑insensitive comparisons • Calculate percentages with decimal multipliers (0.10 for 10%) • Apply tax to the discounted subtotal • Format currency with `{value:.2f}` and `>7.2f` for alignment • Always handle edge cases (empty input, negative values) ============================================================

Sample Output (No Discount):

============================================================ ☕ COFFEE SHOP ORDER SYSTEM ============================================================ Welcome to the Coffee Shop! ☕ Coffee: $3.50 each 🥐 Pastry: $2.25 each Discount code: 'SAVE10' for 10% off Sales tax: 7% Please enter your order: Number of coffees: 2 Number of pastries: 1 ---------------------------------------- ORDER SUMMARY ---------------------------------------- Coffees: 2 × $3.50 = $ 7.00 Pastries: 1 × $2.25 = $ 2.25 ---------------------------------------- Subtotal: $ 9.25 Do you have a discount code? (Enter code or press Enter): no No discount code entered. ---------------------------------------- FINAL BILL ---------------------------------------- Subtotal: $ 9.25 Tax (7%): $ 0.65 ======================================== TOTAL: $ 9.90 ======================================== ---------------------------------------- ORDER DETAILS ---------------------------------------- Items ordered: 3 Total items: 3 Average price per item: $3.30 ============================================================ KEY TAKEAWAYS ============================================================ • Use `try`/`except` to validate numeric input • Use `.upper()` for case‑insensitive comparisons • Calculate percentages with decimal multipliers (0.10 for 10%) • Apply tax to the discounted subtotal • Format currency with `{value:.2f}` and `>7.2f` for alignment • Always handle edge cases (empty input, negative values) ============================================================

Sample Output (Invalid Input):

============================================================ ☕ COFFEE SHOP ORDER SYSTEM ============================================================ Welcome to the Coffee Shop! ☕ Coffee: $3.50 each 🥐 Pastry: $2.25 each Discount code: 'SAVE10' for 10% off Sales tax: 7% Please enter your order: Number of coffees: abc ❌ Invalid input! Please enter a whole number. ⚠️ Setting Coffee count to 0. Number of pastries: -2 ⚠️ Pastry cannot be negative. Using 0. ---------------------------------------- ORDER SUMMARY ---------------------------------------- Coffees: 0 × $3.50 = $ 0.00 Pastries: 0 × $2.25 = $ 0.00 ---------------------------------------- Subtotal: $ 0.00 No items ordered. No discount applied. ---------------------------------------- FINAL BILL ---------------------------------------- Subtotal: $ 0.00 Tax (7%): $ 0.00 ======================================== TOTAL: $ 0.00 ======================================== ---------------------------------------- ORDER DETAILS ---------------------------------------- Items ordered: 0 Total items: 0 No items ordered. ============================================================ KEY TAKEAWAYS ============================================================ • Use `try`/`except` to validate numeric input • Use `.upper()` for case‑insensitive comparisons • Calculate percentages with decimal multipliers (0.10 for 10%) • Apply tax to the discounted subtotal • Format currency with `{value:.2f}` and `>7.2f` for alignment • Always handle edge cases (empty input, negative values) ============================================================

Explanation:

  1. Input Validationget_integer_input() function uses try/except to handle invalid input.

  2. Case‑Insensitive Comparisondiscount_input.upper() == DISCOUNT_CODE handles "save10", "Save10", etc.

  3. Discount Calculationdiscount = subtotal * 0.10

  4. Tax Calculation – Tax is applied to the subtotal after discount.

  5. Currency Formatting{value:>7.2f} right‑aligns with 2 decimal places.

  6. Edge Cases – Empty input, negative numbers, no order.

Question 4 (Input Validation – Email Checker – Research):

Write a program that asks the user for an email address. It should:

  1. Strip whitespace.
  2. Validate that the email contains an @ symbol and a . after the @ (simple check, not a full regex).
  3. If invalid, ask again.
  4. When valid, print "Email accepted."
  5. Bonus: Ensure that the email does not contain spaces.
Sample Answer
""" EMAIL VALIDATOR Demonstrates input validation with string methods """ print("=" * 60) print("EMAIL VALIDATOR") print("=" * 60) print("\nPlease enter your email address.") print("Requirements:") print(" • Must contain '@' symbol") print(" • Must contain a '.' after the '@'") print(" • Must not contain spaces") print(" • Type 'quit' to exit\n") # --- Main validation function --- def validate_email(email): """ Validates an email address with basic checks. Returns True if valid, False otherwise. """ # Check 1: Not empty if not email: return False # Check 2: No spaces (bonus) if ' ' in email: return False # Check 3: Must contain '@' if '@' not in email: return False # Check 4: Must contain a '.' after the '@' at_index = email.index('@') if '.' not in email[at_index:]: return False # Check 5: '@' shouldn't be the first character if at_index == 0: return False # Check 6: Dot shouldn't be the last character if email.endswith('.'): return False # All checks passed! return True # --- Main loop --- attempts = 0 max_attempts = 5 while attempts < max_attempts: email = input(f"Attempt {attempts + 1}/{max_attempts} - Enter email: ").strip() attempts += 1 # Check for exit if email.lower() == 'quit': print("\n❌ Exiting program.") break # Validate the email if validate_email(email): print("✅ Email accepted!") print(f" Email: {email}") break else: print("❌ Invalid email address.") # Provide specific feedback if not email: print(" - Email cannot be empty.") elif ' ' in email: print(" - Email cannot contain spaces.") elif '@' not in email: print(" - Email must contain an '@' symbol.") elif email.index('@') == 0: print(" - Email must have text before the '@'.") elif '.' not in email[email.index('@'):]: print(" - Email must contain a '.' after the '@'.") elif email.endswith('.'): print(" - Email cannot end with a '.'.") else: print(" - Please check the format.") remaining = max_attempts - attempts if remaining > 0: print(f" {remaining} attempt(s) remaining.\n") else: print(" No more attempts left.\n") if attempts >= max_attempts and not validate_email(email) and email.lower() != 'quit': print("\n❌ Too many invalid attempts. Please try again later.") print("\n" + "=" * 60) print("ENHANCED VERSION - With More Validations") print("=" * 60) # --- Enhanced version with additional validations --- def validate_email_enhanced(email): """ Enhanced email validation with more checks. """ # Basic checks if not validate_email(email): return False, "Basic validation failed" # Check: Must have at least one character before '@' at_index = email.index('@') if at_index < 1: return False, "Must have text before '@'" # Check: Must have at least 2 characters after '@' before dot domain_part = email[at_index + 1:] if '.' in domain_part: dot_index = domain_part.index('.') if dot_index < 1: return False, "Must have text between '@' and '.'" else: return False, "Must contain '.' after '@'" # Check: Domain extension should be at least 2 characters after_dot = domain_part[domain_part.index('.') + 1:] if len(after_dot) < 2: return False, "Domain extension must be at least 2 characters" # Check: No multiple '@' symbols if email.count('@') > 1: return False, "Multiple '@' symbols found" return True, "Valid email" # --- Interactive enhanced version --- print("\nEnhanced validation with more checks:\n") while True: email = input("Enter email (or 'quit'): ").strip() if email.lower() == 'quit': print("Exiting.") break is_valid, message = validate_email_enhanced(email) if is_valid: print(f"✅ {message}") print(f" Email: {email}") # Extract parts at_index = email.index('@') username = email[:at_index] domain = email[at_index + 1:] print(f" Username: {username}") print(f" Domain: {domain}") break else: print(f"❌ Invalid: {message}") print("\n" + "=" * 60) print("KEY TAKEAWAYS") print("=" * 60) print(" • Use `strip()` to remove whitespace") print(" • Use `'@' in email` to check for character presence") print(" • Use `email.index('@')` to find the position of a character") print(" • Use slicing `email[at_index:]` to check after a position") print(" • Use `email.endswith('.')` to check the ending") print(" • Provide specific error messages for better user experience") print(" • Basic validation is better than no validation!") print("=" * 60)

Sample Output:

============================================================ EMAIL VALIDATOR ============================================================ Please enter your email address. Requirements: • Must contain '@' symbol • Must contain a '.' after the '@' • Must not contain spaces • Type 'quit' to exit Attempt 1/5 - Enter email: alice@emailcom ❌ Invalid email address. - Email must contain a '.' after the '@'. 4 attempt(s) remaining. Attempt 2/5 - Enter email: alice@.com ❌ Invalid email address. - Email must contain a '.' after the '@'. 3 attempt(s) remaining. Attempt 3/5 - Enter email: alice email@.com ❌ Invalid email address. - Email cannot contain spaces. 2 attempt(s) remaining. Attempt 4/5 - Enter email: alice@email.com ✅ Email accepted! Email: alice@email.com ============================================================ ENHANCED VERSION - With More Validations ============================================================ Enhanced validation with more checks: Enter email (or 'quit'): alice@email.com ✅ Valid email Email: alice@email.com Username: alice Domain: email.com ============================================================ KEY TAKEAWAYS ============================================================ • Use `strip()` to remove whitespace • Use `'@' in email` to check for character presence • Use `email.index('@')` to find the position of a character • Use slicing `email[at_index:]` to check after a position • Use `email.endswith('.')` to check the ending • Provide specific error messages for better user experience • Basic validation is better than no validation! ============================================================

Explanation:

Basic Validation Checks:

  1. Not Emptyif not email: return False

  2. No Spacesif ' ' in email: return False

  3. Contains '@'if '@' not in email: return False

  4. Dot After '@'if '.' not in email[at_index:]: return False

  5. Text Before '@'if at_index == 0: return False

  6. Not Ending with Dotif email.endswith('.'): return False

Enhanced Validation Checks:

  1. Multiple '@'if email.count('@') > 1: return False

  2. Text Between '@' and '.' – Check that domain part has content.

  3. Domain Extension Length – At least 2 characters (e.g., ".com", ".org").

  4. Username Length – At least 1 character before '@'.

String Methods Used:

Simple vs. Full Validation:

This program provides basic validation (enough for learning). Real email validation is much more complex and typically uses regular expressions:

import re def validate_email_regex(email): pattern = r'^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$' return bool(re.match(pattern, email))

Question 5 (Advanced – Interactive Menu):

Write a program that presents a menu of options to the user:

1. Add two numbers 2. Subtract two numbers 3. Multiply two numbers 4. Divide two numbers 5. Exit

The program should:

Sample Answer
""" INTERACTIVE MENU CALCULATOR Demonstrates menu-driven program with error handling """ import math print("=" * 60) print("🖩 INTERACTIVE MENU CALCULATOR") print("=" * 60) # --- Helper functions for arithmetic operations --- def add(a, b): return a + b def subtract(a, b): return a - b def multiply(a, b): return a * b def divide(a, b): if b == 0: raise ValueError("Cannot divide by zero!") return a / b # --- Helper function to get a number from user --- def get_number(prompt): """ Gets a valid number from the user. Returns the number as a float. """ while True: try: return float(input(prompt)) except ValueError: print(" ❌ Invalid input! Please enter a number.") print(" Try again.\n") # --- Helper function to get menu choice --- def get_menu_choice(): """ Gets a valid menu choice from the user. Returns the choice as an integer. """ while True: try: choice = int(input("\nEnter your choice (1-5): ").strip()) if 1 <= choice <= 5: return choice else: print(" ❌ Invalid choice! Please enter a number between 1 and 5.") print(" Try again.") except ValueError: print(" ❌ Invalid input! Please enter a number.") print(" Try again.") # --- Main program loop --- def main(): """ Main program loop for the interactive calculator. """ while True: # Display the menu print("\n" + "=" * 50) print(" MENU") print("=" * 50) print(" 1. Add two numbers") print(" 2. Subtract two numbers") print(" 3. Multiply two numbers") print(" 4. Divide two numbers") print(" 5. Exit") print("=" * 50) # Get user choice choice = get_menu_choice() # Handle exit if choice == 5: print("\n👋 Thank you for using the calculator. Goodbye!") break # --- Get two numbers --- print("\n" + "-" * 40) print(f"OPERATION: {['', 'Addition', 'Subtraction', 'Multiplication', 'Division'][choice]}") print("-" * 40) num1 = get_number("Enter first number: ") num2 = get_number("Enter second number: ") # --- Perform the operation --- operation_names = ['', 'Adding', 'Subtracting', 'Multiplying', 'Dividing'] try: if choice == 1: result = add(num1, num2) symbol = '+' elif choice == 2: result = subtract(num1, num2) symbol = '-' elif choice == 3: result = multiply(num1, num2) symbol = '×' elif choice == 4: result = divide(num1, num2) symbol = '÷' # Display result print("\n" + "-" * 40) print("RESULT") print("-" * 40) print(f" {num1} {symbol} {num2} = {result}") print("-" * 40) except ValueError as e: print(f"\n❌ Error: {e}") print(" Please try again.\n") except Exception as e: print(f"\n❌ An unexpected error occurred: {e}") # --- Run the program --- if __name__ == "__main__": main() print("\n" + "=" * 60) print("ENHANCED VERSION - With History and More Features") print("=" * 60) # --- Enhanced version with calculation history --- def enhanced_calculator(): """ Enhanced calculator with history tracking and more features. """ history = [] calculation_count = 0 def add_to_history(operation, num1, num2, result): """Adds a calculation to the history.""" history.append({ 'operation': operation, 'num1': num1, 'num2': num2, 'result': result }) while True: # Display menu with history count print("\n" + "=" * 50) print(" ENHANCED CALCULATOR") print("=" * 50) print(" 1. Add two numbers") print(" 2. Subtract two numbers") print(" 3. Multiply two numbers") print(" 4. Divide two numbers") print(" 5. View History") print(" 6. Clear History") print(" 7. Exit") print("=" * 50) print(f"Total calculations: {calculation_count}") # Get choice try: choice = int(input("\nEnter your choice (1-7): ").strip()) except ValueError: print("❌ Invalid input! Please enter a number.") continue # Handle choices if choice == 7: print("\n👋 Thank you! Goodbye!") break elif choice == 5: # View history if not history: print("\n📋 No calculations in history.") else: print("\n" + "-" * 40) print("CALCULATION HISTORY") print("-" * 40) for i, entry in enumerate(history, 1): operation = entry['operation'] num1 = entry['num1'] num2 = entry['num2'] result = entry['result'] print(f" {i}. {num1} {operation} {num2} = {result}") print("-" * 40) continue elif choice == 6: # Clear history history = [] calculation_count = 0 print("\n🗑️ History cleared!") continue elif choice not in [1, 2, 3, 4]: print("❌ Invalid choice! Please select 1-7.") continue # --- Get numbers and perform calculation --- print("\n" + "-" * 40) operation_names = ['', 'Addition', 'Subtraction', 'Multiplication', 'Division'] print(f"OPERATION: {operation_names[choice]}") print("-" * 40) try: num1 = float(input("Enter first number: ")) num2 = float(input("Enter second number: ")) except ValueError: print("❌ Invalid input! Please enter numbers.") continue # Perform operation try: if choice == 1: result = num1 + num2 symbol = '+' op_name = 'addition' elif choice == 2: result = num1 - num2 symbol = '-' op_name = 'subtraction' elif choice == 3: result = num1 * num2 symbol = '×' op_name = 'multiplication' elif choice == 4: if num2 == 0: print("\n❌ Error: Cannot divide by zero!") continue result = num1 / num2 symbol = '÷' op_name = 'division' # Store in history add_to_history(symbol, num1, num2, result) calculation_count += 1 # Display result print("\n" + "-" * 40) print(f"Result: {num1} {symbol} {num2} = {result}") print("-" * 40) # Optional: Additional statistics print(f"\n Calculation #{calculation_count}") print(f" Operation: {op_name.title()}") if choice == 4: print(f" Quotient: {num1 / num2}") print(f" Remainder: {num1 % num2}") except Exception as e: print(f"\n❌ Error: {e}") # Uncomment to run enhanced version # enhanced_calculator() print("\n" + "=" * 60) print("KEY TAKEAWAYS") print("=" * 60) print(" • Use `while True` with `break` for menu loops") print(" • Use functions to organize code") print(" • Validate menu choices with range checking") print(" • Use `try`/`except` for number conversion") print(" • Use `try`/`except` for division by zero") print(" • Provide clear feedback for all inputs") print(" • Consider adding history for better usability") print("=" * 60)

Sample Output:

============================================================ 🖩 INTERACTIVE MENU CALCULATOR ============================================================ ================================================== MENU ================================================== 1. Add two numbers 2. Subtract two numbers 3. Multiply two numbers 4. Divide two numbers 5. Exit ================================================== Enter your choice (1-5): 1 ---------------------------------------- OPERATION: Addition ---------------------------------------- Enter first number: 15 Enter second number: 10 ---------------------------------------- RESULT ---------------------------------------- 15.0 + 10.0 = 25.0 ---------------------------------------- ================================================== MENU ================================================== 1. Add two numbers 2. Subtract two numbers 3. Multiply two numbers 4. Divide two numbers 5. Exit ================================================== Enter your choice (1-5): 4 ---------------------------------------- OPERATION: Division ---------------------------------------- Enter first number: 10 Enter second number: 0 ❌ Error: Cannot divide by zero! Please try again. ================================================== MENU ================================================== 1. Add two numbers 2. Subtract two numbers 3. Multiply two numbers 4. Divide two numbers 5. Exit ================================================== Enter your choice (1-5): 4 ---------------------------------------- OPERATION: Division ---------------------------------------- Enter first number: 10 Enter second number: 3 ---------------------------------------- RESULT ---------------------------------------- 10.0 ÷ 3.0 = 3.3333333333333335 ---------------------------------------- ================================================== MENU ================================================== 1. Add two numbers 2. Subtract two numbers 3. Multiply two numbers 4. Divide two numbers 5. Exit ================================================== Enter your choice (1-5): 5 👋 Thank you for using the calculator. Goodbye! ============================================================ ENHANCED VERSION - With History and More Features ============================================================ ================================================== ENHANCED CALCULATOR ================================================== 1. Add two numbers 2. Subtract two numbers 3. Multiply two numbers 4. Divide two numbers 5. View History 6. Clear History 7. Exit ================================================== Total calculations: 0 Enter your choice (1-7): 1 ---------------------------------------- OPERATION: Addition ---------------------------------------- Enter first number: 100 Enter second number: 50 ---------------------------------------- Result: 100.0 + 50.0 = 150.0 ---------------------------------------- Calculation #1 Operation: Addition ================================================== ENHANCED CALCULATOR ================================================== 1. Add two numbers 2. Subtract two numbers 3. Multiply two numbers 4. Divide two numbers 5. View History 6. Clear History 7. Exit ================================================== Total calculations: 1 Enter your choice (1-7): 5 ---------------------------------------- CALCULATION HISTORY ---------------------------------------- 1. 100.0 + 50.0 = 150.0 ----------------------------------------

Explanation:

Menu Structure:

  1. Display Menu – Shows options to the user.
  2. Get Choice – Validates input is a number between 1-5.
  3. Process Choice – Calls appropriate function or exits.
  4. Get Numbers – Asks for two numbers with validation.
  5. Perform Operation – Calculates and displays result.
  6. Loop – Returns to menu until exit.

Error Handling:

  1. Invalid Menu Choice – Handles numbers outside 1-5.
  2. Invalid Number Input – Catches ValueError from float().
  3. Division by Zero – Checks and handles with try/except.

Enhanced Features:

  1. Calculation History – Stores all calculations in a list.
  2. History Display – Shows all past calculations.
  3. Clear History – Resets the history.
  4. Calculation Counter – Tracks total calculations.

Menu Choice Validation Patterns:

# Pattern 1: Simple validation while True: choice = input("Enter choice: ") if choice in ['1', '2', '3', '4', '5']: choice = int(choice) break print("Invalid choice!") # Pattern 2: Try/except with range while True: try: choice = int(input("Enter choice: ")) if 1 <= choice <= 5: break print("Choice must be 1-5") except ValueError: print("Must enter a number")

Operation Execution Patterns:

# Pattern 1: If-elif-else if choice == 1: result = num1 + num2 elif choice == 2: result = num1 - num2 elif choice == 3: result = num1 * num2 elif choice == 4: result = num1 / num2 # Pattern 2: Using a dictionary (advanced) operations = { 1: lambda a, b: a + b, 2: lambda a, b: a - b, 3: lambda a, b: a * b, 4: lambda a, b: a / b } result = operations[choice](num1, num2)

6. Summary Checklist (For Student Self-Review)

7. Additional Challenge: The Input Master Program

Learning Objective

Write a program that asks the user for a list of numbers (comma‑separated), sums them, and calculates the average, but handles all possible input errors.

Instructions:

  1. Ask the user to enter numbers separated by commas (e.g., "10, 20, 30").
  2. Split the input by commas.
  3. For each part, strip whitespace, try to convert to float.
  4. If any part is not a number, print a warning and skip it.
  5. Display the count of valid numbers, the sum, and the average (if count > 0).
  6. If no valid numbers, print "No valid numbers entered."
  7. Use a loop to allow the user to try again if they want.

Sample Run:

Enter numbers separated by commas: 10, abc, 20, 30.5 Skipping invalid: abc Valid numbers: 3 Sum: 60.5 Average: 20.17 Do you want to enter another list? (y/n): n

Previous | Tutorial index | Next