0%

Errors, Validation, and Debugging · capstone

Capstone project: Project: Make the Outing Planner Resilient

In Chapter 3, you made an outing planner interactive. It asked for an activity, a number of people, a price per person, and a snack budget. Then it calculated the ticket total and overall budget.

That first version assumed every numeric answer could be converted immediately:

people = int(input("Number of people: "))

Now you can harden the same program without changing its useful report.

Separate input work from planning work

Create a reusable named read_nonnegative_integer. It receives a prompt and returns a valid integer.

Its control flow should be:

  1. start a ;

  2. collect an answer with the supplied prompt;

  3. try to convert the answer with int();

  4. if conversion raises , explain that a whole number is required and retry;

  5. if the converted number is below zero, explain that zero or more is required and retry;

  6. return the valid number.

Notice that two kinds of invalid data need different checks:

  • "many" cannot be converted to an integer;

  • "-3" converts successfully but violates the non-negative rule.

addresses the failed operation. A addresses the unacceptable result.

Let return finish the loop

The function can return as soon as it has a valid number. A separate break is unnecessary because exits both the loop and the function.

Every invalid path must collect another answer. This ensures the program makes progress instead of checking the same forever.

Reuse one tested rule

Call the helper three times:

  • number of people;

  • price per person;

  • snack budget.

This keeps the validation rule in one place. If the wording or range rule changes later, there is one function to update.

The activity remains text. Ask for it once and use .strip() to remove accidental surrounding whitespace.

Preserve the calculation

After valid values are available, keep the original formulas:

ticket_total = people * price_per_person
total_budget = ticket_total + snack_budget

Validation protects these calculations from unsuitable input. It does not replace them.

Test failures before success

A useful test does not provide only perfect answers. For each numeric prompt, try at least one invalid value before the valid one. Confirm that:

  • invalid text receives whole-number guidance;

  • a negative integer receives range guidance;

  • the prompt appears again;

  • the final report uses the accepted values;

  • no appears.

This project combines reproducible testing, specific exception handling, range validation, loops, functions, and the calculations from the earlier project.

Why should the helper check number < 0 after the try and except?

What does return number do when it runs inside the helper's loop?

Task

Make the Chapter 3 outing planner resilient.

Define read_nonnegative_integer(prompt). It must repeatedly:

  • ask using the supplied prompt;

  • attempt int() conversion;

  • catch only , print Please enter a whole number., and retry;

  • reject converted values below zero by printing Please enter zero or more.;

  • return the first valid non-negative integer.

Ask for the activity once with Activity: and strip surrounding whitespace. Use your helper for:

  • Number of people:

  • Price per person: $

  • Snack budget: $

Then calculate ticket_total and total_budget exactly as in the earlier planner and print this report:

OUTING PLAN
Activity: planetarium
People: 4
Tickets: $52
Total budget: $70

The prepared input deliberately supplies invalid answers before the valid ones. Your must recover from all of them without hiding unexpected programming errors.