1 of 60

COMPUTER

PROGRAMMING

Deck 3

How Can a Program

Make Decisions?

Conditions, branches, and tests that challenge AI-generated code

Guan-Ju Peng @ AM, NCHU

Deck 3 | 1

2 of 60

Last time, the data had to behave

Deck 2 assumed valid inputs. Today the program checks the rules.

Bridge from Deck 2

Deck 3 | 2

DECK 2 · WHAT HAPPENS WITH ZERO MINUTES?

distance_km = 12.5

duration_min = 0

duration_h = duration_min / 60

speed_kmh = distance_km / duration_h

The missing choice

Calculate a report

or

explain why not.

A written assumption is not the same as a check that runs.

3 of 60

One tool, two different responses

Driving problem: accept valid trip data; reject invalid data before calculating.

Driving problem

Deck 3 | 3

12.5 km / 45 min

Route: Campus

Distance: 7.77 miles

Average speed: 16.67 km/h

Trip band: Medium

12.5 km / 0 min

Error: duration must be positive.

​

No speed. No report.

No division by zero.

Today’s added policy: Short ≤ 30 min; Medium ≤ 60 min; Long > 60 min.

4 of 60

Today’s inquiry ladder

Driving question: How can a program make decisions?

Roadmap

Deck 3 | 4

01

How can a computer answer a yes/no question?

02

How can several conditions work together?

03

How does a condition choose what runs?

04

What if there are more than two possible outcomes?

05

Why does the order of conditions matter?

06

How can we test decisions, with AI as an assistant?

Build: Trip Summary v0.3 | AI skill: test-case design | Foundations: compare + branch

5 of 60

How can a computer answer a yes/no question?

Q1 · Start with the decision the program must make.

Q1 · Driving sub-question

Deck 3 | 5

Q1

“Duration must be positive.”

What expression can answer that question

for 45, 0, and −5 minutes?

A condition is an expression whose truth value guides a choice.

6 of 60

Make the rules explicit before coding

Extend the existing contract. Do not silently change the meaning of the inputs.

Q1 · Decision contract

Deck 3 | 6

Input / result

Version 0.3 rule

route_name : str

Reject the empty string ""; otherwise preserve the label.

distance_km : float

Reject non-finite values and negative distances.

duration_min : int

Reject 0 and negative minutes.

Invalid input

Report the first validation error; do not calculate.

Valid input

Keep the Deck 2 report and add one duration band.

Core scope: conversions succeed first. Handling text such as "abc" is an optional extension.

7 of 60

Comparisons turn values into yes/no answers

Use the operators to express the rule, including its boundary.

Q1 · Comparison operators

Deck 3 | 7

[P1]

Operator

Question

Example

Result

>

Greater than?

45 > 0

True

>=

At least?

0 >= 0

True

<

Less than?

30 < 30

False

<=

At most?

30 <= 30

True

==

Equal in value?

45 == 45

True

!=

Different in value?

"" != ""

False

Use duration_min > 0 for positive time; use distance_km >= 0 to allow zero distance.

8 of 60

“=” stores a binding; “==” asks a question

A Boolean result is a value you can name and print.

Q1 · Assignment versus comparison

Deck 3 | 8

[P1] [P4]

PYTHON

duration_min = 45

time_ok = duration_min > 0

print(time_ok) # True

​

duration_min = 0

print(time_ok) # Still True

print(duration_min > 0) # False

A saved condition does not automatically update when its input variable changes.

9 of 60

Predict first: a number or a piece of text?

Pair check · 2 minutes. Explain the result before using Run.

Q1 · Quick challenge

Deck 3 | 9

[P1]

PREDICT EACH LINE SEPARATELY

print(30 <= 30)

print(0 > 0)

print("30" == 30)

print("9" > "30")

print("30" > 0)

Discuss

Which lines return a bool?

Which raises an error?

​

Why do types matter?

Type conversion and domain validation answer different questions.

10 of 60

A number can be non-finite

A small standard-library helper makes the existing contract testable.

Q1 · Finite-value check

Deck 3 | 10

[P5]

PYTHON

import math

​

print(math.isfinite(12.5)) # True

print(math.isfinite(0.0)) # True

print(math.isfinite(float("inf"))) # False

print(math.isfinite(float("nan"))) # False

Conversion success does not guarantee a meaningful distance.

11 of 60

How can several conditions work together?

Q2 · Start with the decision the program must make.

Q2 · Driving sub-question

Deck 3 | 11

Q2

A valid trip needs more than valid time.

The label, distance, and duration

must all satisfy the contract.

Build small named conditions, then combine them.

12 of 60

Use “and” when every condition must hold

Both requirements must be true.

Q2 · Conjunction

Deck 3 | 12

[P1]

ASSUME FINITE DISTANCE FOR THIS SMALL EXAMPLE

distance_ok = distance_km >= 0

time_ok = duration_min > 0

valid_numbers = distance_ok and time_ok

distance_ok

time_ok

valid_numbers

True

True

True

True

False

False

False

True

False

False

False

False

All requirements satisfied → and. One valid input is not enough.

13 of 60

Use “or” when any failure is enough

A single invalid numeric input must prevent the calculation.

Q2 · Disjunction

Deck 3 | 13

[P1]

PYTHON

bad_numbers = (distance_km < 0) or (duration_min <= 0)

Distance

Minutes

Must reject?

-1

30

Yes: distance fails

5

0

Yes: duration fails

-1

0

Yes: both fail

0

30

No: both satisfy these rules

Do not confuse “all checks must pass” with “all checks must fail.”

14 of 60

Use “not” to reverse a condition

Logical negation is not a bitwise operation.

Q2 · Negation

Deck 3 | 14

[P1]

PYTHON

time_ok = duration_min > 0

print(not time_ok)

​

valid = distance_ok and time_ok

invalid = not valid

Logical or bitwise?

Boolean conditions:

and or not

​

Integer bit operations:

& | ~

For Boolean negation, write not. Do not replace it with ~.

15 of 60

Make the grouping visible

For Boolean combinations: not before and before or. Parentheses remove doubt.

Q2 · Precedence and ranges

Deck 3 | 15

[P4]

DO THESE REQUIRE THE SAME THING?

valid and duration_min <= 30 or duration_min == 60

valid and (duration_min <= 30 or duration_min == 60)

TWO WAYS TO EXPRESS THIS RANGE

0 < duration_min <= 30

(duration_min > 0) and (duration_min <= 30)

Read a complex condition aloud. Does it say what the contract says?

16 of 60

Short-circuit evaluation can protect an operation

Python may not evaluate the second operand. The order is observable.

Q2 · Short-circuit reasoning

Deck 3 | 16

[P1] [P4]

PYTHON

duration_min = 0

​

can_compute = (duration_min > 0) and (

distance_km / (duration_min / 60) >= 0

)

print(can_compute) # False; no division occurs

Left side false for and → skip the right side. Put a guard before the risky operation.

17 of 60

Every option needs its own comparison

Prepared misconception example — this condition is not what it looks like.

Q2 · Common pitfall

Deck 3 | 17

[P1]

WRONG FOR “30 OR 60 MINUTES”

duration_min == 30 or 60

COMPARE BOTH POSSIBILITIES

(duration_min == 30) or (duration_min == 60)

The number 60 is truthy; it is not an abbreviation for duration_min == 60.

18 of 60

Lab 1: express validity without “if”

Six-minute pair task. We are still computing Boolean values, not selecting a branch.

Q2 · Practice · 6 minutes

Deck 3 | 18

[P1] [P5]

01

Define label_ok, distance_ok, time_ok, and valid.

02

Include both finite and non-negative checks for distance.

03

Predict the four results below, then run the expressions.

Route

km

min

Your prediction

Campus

12.5

45

?

Campus

12.5

0

?

""

1

30

?

Campus

inf

30

?

Save a Boolean expression you can explain, not just an answer copied from AI.

19 of 60

How does a condition choose what runs?

Q3 · Start with the decision the program must make.

Q3 · Driving sub-question

Deck 3 | 19

Q3

Printing False does not prevent a division.

We need a statement that controls

whether the calculation executes.

A comparison produces a value; if uses a truth value to choose a path.

20 of 60

The “if” statement controls an indented block

The colon begins the block; indentation shows which statements belong to it.

Q3 · Conditional execution

Deck 3 | 20

[P2] [P3]

PYTHON

if duration_min > 0:

duration_h = duration_min / 60

speed_kmh = distance_km / duration_h

print(f"Average speed: {speed_kmh:.2f} km/h")

​

print("End of this run")

The indented lines run only when the condition is true. The dedented line is outside the block.

21 of 60

“if / else” expresses two alternative paths

Exactly one of these two blocks runs, assuming the condition evaluates normally.

Q3 · Selection

Deck 3 | 21

[P3]

duration_min

> 0 ?

True

False

Calculate and

print the report

Print an error

(no division)

Continue after the selection

An error message is one branch, not an automatic command to stop the entire program.

22 of 60

Trace the same code with two inputs

Follow the selected path; do not execute both blocks in your head.

Q3 · Execution trace

Deck 3 | 22

[P3]

PYTHON

if duration_min > 0:

speed_kmh = distance_km / (duration_min / 60)

print(f"Average speed: {speed_kmh:.2f} km/h")

else:

print("Error: duration must be positive.")

distance_km

duration_min

Selected block

Division?

15

30

if

Yes

15

0

else

No

What proves the zero case is safe? The calculation is inside the valid-input branch.

23 of 60

A warning alone does not guard the calculation

Both snippets are syntactically valid. Only one protects the division.

Q3 · Indentation changes behavior

Deck 3 | 23

[P3]

UNGUARDED · STILL RUNS

if duration_min <= 0:

print("Error")

speed = 60 / duration_min

GUARDED · EXCLUSIVE PATHS

if duration_min <= 0:

print("Error")

else:

speed = 60 / duration_min

Indentation can be legal Python and still express the wrong algorithm.

24 of 60

Three different failures need different repairs

Read the error or observed behavior before changing the code.

Q3 · Debugging categories

Deck 3 | 24

[P3] [P6]

Problem

Example

What to inspect

Syntax

if duration_min > 0

Missing colon / invalid block structure.

Runtime

"30" > 0

Types of the operands; parse first.

Logic

duration_min >= 0

The code accepts zero, contrary to the rule.

A program that runs without an exception can still violate its specification.

25 of 60

Lab 2: reject before dividing

Six-minute guided task. Use a single if / else.

Q3 · Practice · 6 minutes

Deck 3 | 25

01

Read distance_km and duration_min using the Deck 2 types.

02

If time is not positive, print an explanatory error.

03

Otherwise calculate speed in km/h and print it.

04

Before running, predict the cases: (15, 30), (15, 0), (15, −1).

Success: valid data produce a report; invalid time produces only an error.

26 of 60

What if there are more than two outcomes?

Q4 · Start with the decision the program must make.

Q4 · Driving sub-question

Deck 3 | 26

Q4

Valid trips still need different labels.

Our tool should label a trip Short, Medium, or Long

using its duration in minutes.

First define the categories. Then choose a control-flow structure.

27 of 60

A category needs a complete boundary rule

These are invented classroom labels, not travel or safety advice.

Q4 · Classification specification

Deck 3 | 27

Category

Allowed duration

Boundary examples

Short

0 < duration_min <= 30

1 and 30 are Short

Medium

30 < duration_min <= 60

31 and 60 are Medium

Long

duration_min > 60

61 is Long

An invalid duration belongs to none of these categories.

28 of 60

“elif” adds an alternative, not another independent test

The first true branch in the chain wins.

Q4 · Multi-way selection

Deck 3 | 28

[P2] [P3]

PYTHON

if duration_min <= 30:

trip_band = "Short"

elif duration_min <= 60:

trip_band = "Medium"

else:

trip_band = "Long"

​

print(f"Trip band: {trip_band}")

Within the valid domain, one chain produces exactly one trip_band.

29 of 60

Separate “if” statements may all run

Use a chain for one exclusive label; use separate if statements for independent actions.

Q4 · Exclusive versus independent decisions

Deck 3 | 29

[P3]

INDEPENDENT CHECKS

if duration_min <= 30:

print("Short")

if duration_min <= 60:

print("Medium")

ONE EXCLUSIVE CHOICE

if duration_min <= 30:

print("Short")

elif duration_min <= 60:

print("Medium")

Predict both snippets with duration_min = 20. They do not mean the same thing.

30 of 60

Validation and classification are different decisions

First ask whether a report is allowed. Then ask which label it should contain.

Q4 · Nested selection

Deck 3 | 30

[P3]

PYTHON

if duration_min <= 0:

print("Error: duration must be positive.")

else:

if duration_min <= 30:

trip_band = "Short"

elif duration_min <= 60:

trip_band = "Medium"

else:

trip_band = "Long"

print(f"Trip band: {trip_band}")

Do not classify invalid data and then try to explain the label afterward.

31 of 60

Lab 3: turn the category table into code

Five-minute task. Classify positive integer minutes without loops or functions.

Q4 · Practice · 5 minutes

Deck 3 | 31

01

Read one positive integer duration.

02

Assign exactly one trip_band using if / elif / else.

03

Try 1, 29, 30, 31, 60, and 61 minutes.

04

Explain why the second branch can use only <= 60.

Use the original integer minutes to classify. Formatting is a separate output step.

32 of 60

Why does the order of conditions matter?

Q5 · Start with the decision the program must make.

Q5 · Driving sub-question

Deck 3 | 32

Q5

True does not mean “the best matching branch.”

Python selects the first true branch.

The programmer must choose a suitable order.

The order of a chain is part of its meaning.

33 of 60

A broad condition can hide a narrower one

Prepared logic bug. Trace the code for a 20-minute trip.

Q5 · Unreachable category

Deck 3 | 33

[P3]

WRONG ORDER · RUNNABLE PYTHON

if duration_min <= 60:

trip_band = "Medium"

elif duration_min <= 30:

trip_band = "Short"

else:

trip_band = "Long"

Find one input that proves the contract is violated: 20 should be Short, not Medium.

34 of 60

Read each later condition under the earlier failures

The second branch inherits information from the path used to reach it.

Q5 · Path reasoning

Deck 3 | 34

[P3]

Reached branch

What is already known?

Resulting interval

if t <= 30

t > 0 was validated

0 < t <= 30

elif t <= 60

Earlier test failed: t > 30

30 < t <= 60

else

Both earlier tests failed

t > 60

Order is correct when the reachable paths match the intended categories.

35 of 60

When several fields fail, choose an error policy

Version 0.3 reports the first failure in this order, after successful parsing.

Q5 · Validation priority

Deck 3 | 35

01

Empty label → "Error: route label must not be empty."

02

Non-finite distance → "Error: distance must be finite."

03

Negative distance → "Error: distance must be non-negative."

04

Non-positive time → "Error: duration must be positive."

“Report the first error” and “report all errors” are different product requirements.

36 of 60

Make the outcomes complete and non-overlapping

Check both the invalid domain and the valid categories.

Q5 · Completeness

Deck 3 | 36

Parsed data

›

Validity check

›

One allowed outcome

Domain

Required output

Any validation rule fails

One error; no report

Valid + duration <= 30

Report + Short

Valid + 30 < duration <= 60

Report + Medium

Valid + duration > 60

Report + Long

A single output is not enough: it must be the correct output for that input.

37 of 60

Checkpoint: defend the chosen path

Three-minute trace. No execution yet.

Q5 · Reasoning check

Deck 3 | 37

Case A

route_name = ""

distance_km = −1

duration_min = 0

​

Which error appears first?

Case B

route_name = "Rest"

distance_km = 0

duration_min = 60

​

Error, or a valid report?

For each case, name the condition that chooses the path and one statement that must not run.

38 of 60

How does a branch appear at a lower level?

Computer foundations · a six-minute bridge from if to machine-level control flow.

Foundations · Compare + branch

Deck 3 | 38

Compare values

›

Choose next instruction

›

Continue execution

Python level

if score >= 60:

print("pass")

else:

print("fail")

Lower-level idea

Compare the score with 60.

Jump to one output path.

Skip the other output path.

The next instruction need not be the next line in the written program.

39 of 60

A tiny compare-and-branch program

Toy instruction set for explanation — not actual Python compilation.

Foundations · Teaching assembly

Deck 3 | 39

TEACHING ASSEMBLY · NOT PYTHON

LOAD R0, score

CMP R0, 60

JLT fail

OUT "pass"

JMP done

fail: OUT "fail"

done: HALT

Read the instructions

LOAD → put a value in R0

CMP → compare

JLT → jump if less

OUT → print

JMP → jump always

HALT → stop

Labels identify destinations. A branch changes which instruction executes next.

40 of 60

Trace score = 59 and score = 60

The boundary changes the path, not the instruction set.

Foundations · Two traces

Deck 3 | 40

Step

score = 59

score = 60

Compare

59 < 60

60 is not < 60

JLT fail

Jump taken

Jump not taken

Print

"fail"

"pass"

Finish

HALT

JMP done → HALT

Quick check: without JMP done, what would the score = 60 path print?

41 of 60

How can we test decisions with AI as an assistant?

Q6 · Start with the decision the program must make.

Q6 · Driving sub-question

Deck 3 | 41

Q6

A program can run and still choose the wrong branch.

Our job is to find inputs that challenge the rules,

not just inputs that make the demonstration look good.

AI suggests cases; the specification determines what should happen.

42 of 60

Choose tests from the specification

Do not derive the expected answer by copying the program’s output.

Q6 · Test design

Deck 3 | 42

Boundaries

29, 30, 31 minutes

59, 60, 61 minutes

​

Just below, at, and above.

Invalid fields

Empty label

Negative distance

Zero or negative time

NaN / infinity

Interactions

Two failures at once

Zero distance + valid time

​

Check priority and over-rejection.

A useful test explains which rule or likely mistake it is designed to challenge.

43 of 60

Predict the result before running the tool

Worked examples from the contract; the full test sheet adds more boundaries.

Q6 · Independent expected results

Deck 3 | 43

Route

km

min

Expected outcome

Campus

12.5

45

7.77 miles; 16.67 km/h; Medium

Rest

0

30

0.00 miles; 0.00 km/h; Short

Campus

−1

30

Distance error; no report

Campus

1

0

Duration error; no report

""

−1

0

Label error first; no report

Campus

1

60

Medium

Campus

1

61

Long

Test case = input + expected result + actual result + a reasoned pass/fail judgment.

44 of 60

Ask AI to challenge the rules before writing more code

Reusable test-design prompt. Live responses vary.

Q6 · AI demonstration

Deck 3 | 44

PROMPT · TEST FIRST

Do not write code yet. Use the attached v0.3 contract.

Propose 10 tests: valid cases, 30/60-minute boundaries,

zero and negative inputs, non-finite distance,

and simultaneous failures.

For each: input, expected outcome, rule challenged.

Respect the stated first-error priority.

Mark cases outside the core parsing scope.

Explain expected outcomes from the rules, not code.

Human review: Is each expectation justified? Did AI omit a boundary or invent a requirement?

45 of 60

Find a counterexample to this candidate

Prepared faulty teaching example — not a recorded AI response.

Q6 · Adversarial code review

Deck 3 | 45

[P3]

ISOLATED EXERCISE · FINITE NUMBERS; PARSING ALREADY SUCCEEDED

if distance_km < 0 and duration_min <= 0:

print("Error: invalid trip data.")

else:

speed_kmh = distance_km / (duration_min / 60)

if duration_min < 30:

trip_band = "Short"

elif duration_min <= 60:

trip_band = "Medium"

else:

trip_band = "Long"

print(f"Average speed: {speed_kmh:.2f} km/h")

print(f"Trip band: {trip_band}")

Which inputs expose the wrong guard? Which input exposes the wrong category boundary?

46 of 60

Repair the rule, then rerun the evidence

A small patch is easier to review than an unexplained replacement script.

Q6 · Minimal repair

Deck 3 | 46

Counterexample

Failure observed

Minimal repair

1 km / 0 min

Division is reached

Guard: and → or

−1 km / 30 min

Invalid distance is reported

Same guard repair

5 km / 30 min

Medium instead of Short

Boundary: < 30 → <= 30

Do not change a correct expected answer just to make the candidate pass.

47 of 60

Assemble the tool: validate before calculating

Part 1 of one file. Keep the existing inputs and add import math.

Q6 · Integration · trip_decisions.py

Deck 3 | 47

[P3] [P5]

VALIDATION CHAIN · AFTER THE THREE INPUT CONVERSIONS

if route_name == "":

print("Error: route label must not be empty.")

elif not math.isfinite(distance_km):

print("Error: distance must be finite.")

elif distance_km < 0:

print("Error: distance must be non-negative.")

elif duration_min <= 0:

print("Error: duration must be positive.")

No calculation occurs above. The valid-input else block continues on the next slide.

48 of 60

Assemble the tool: calculate and choose one band

Part 2 of the same file. Attach this else to the validation chain on the previous slide.

Q6 · Integration · valid-input branch

Deck 3 | 48

[P3]

CONTINUATION · COMPLETE SCRIPT IS IN THE CLASSROOM PACK

else:

miles = distance_km * MILES_PER_KM

duration_h = duration_min / 60

speed_kmh = distance_km / duration_h

if duration_min <= 30:

trip_band = "Short"

elif duration_min <= 60:

trip_band = "Medium"

else:

trip_band = "Long"

print(f"Trip band: {trip_band}")

Keep the three Deck 2 report prints inside this else, before the final Trip band line.

49 of 60

Build, challenge, explain

Twelve-minute lab. Keep the earlier tool and add one tested improvement.

Q6 · Build task · 12 minutes

Deck 3 | 49

01

Complete trip_decisions.py in the existing repository.

02

Preserve the Deck 2 report for valid inputs; add one band.

03

Reject invalid inputs in the stated priority, with no report.

04

Record at least six tests, including 30, 60, 0, and two failures.

05

Explain one condition, one execution path, and one repair.

No loops, menus, external packages, or user-defined functions yet. Finish one understandable tool.

50 of 60

Push the tested change and its evidence

Use the existing repository and the same GitHub Desktop workflow.

Q6 · Project continuity

Deck 3 | 50

[G1] [G2]

01

Keep main.py and trip_summary.py. Add trip_decisions.py.

02

Record spec_deck3.md, tests_deck3.md, and ai_use_deck3.md.

03

Run the saved script; inspect the selected Changes/diff.

04

Commit: “Add trip validation and boundary-tested bands”.

05

Push origin; verify the latest commit and files online.

A pushed code file is not the whole deliverable: include expected/actual results and a short explanation.

51 of 60

A project starts with a rule you can defend

Transfer the same pattern to a small problem you actually care about.

Project motivation

Deck 3 | 51

Study-time planner

Compare estimated work

with available minutes.

​

Can the plan fit?

Printing estimator

Reject negative page counts.

Apply a stated price rule.

​

What happens at the threshold?

Your own utility

One input rule.

One useful choice.

Two boundary tests.

​

Explain your policy.

Do not ask AI to invent the goal. Choose the decision, define its rule, then ask for help.

52 of 60

Can we answer today’s driving question?

Decisions become trustworthy when their rules and execution paths can be explained.

Synthesis

Deck 3 | 52

01

Compare values to ask a precise yes/no question.

02

Combine requirements with and, or, and not.

03

Use if / else to control whether a block runs.

04

Use elif to select one of several outcomes.

05

Order conditions to match categories and error priority.

06

Challenge the logic with independent expected outcomes.

Human responsibility today: define the logic, justify the expected behavior, and inspect the evidence.

53 of 60

Exit ticket: explain before pressing Run

Three-minute individual check. Answers are in the instructor notes.

Exit ticket · 3 minutes

Deck 3 | 53

01

What is the difference between = and ==?

02

Reject if distance is negative OR time is non-positive: write the condition.

03

Why can checking <= 60 before <= 30 hide the Short category?

04

Give three tests around the 30-minute boundary, with expected bands.

05

In the toy program, trace score = 60. Why is JMP done needed?

You should be able to explain your code even when AI helped you produce it.

54 of 60

Next: can the program handle more than one trip?

Deck 4 · How can a program repeat work without repeating code?

After class / next driving question

Deck 3 | 54

Finish v0.3

Complete the required tests.

Record any remaining limitation.

Commit, push, verify online.

Keep your own project idea.

The next question

What if the user wants

to enter another trip?

​

How should the program

repeat — and eventually stop?

Do not copy the whole script ten times. We will learn a better abstraction in Deck 4.

55 of 60

Optional: truth values are broader than bool objects

Reference only. Explicit comparisons remain the default in the core lesson.

Appendix · Truthiness

Deck 3 | 55

[P1]

PYTHON

print(bool(0)) # False

print(bool("0")) # True

print(bool("False")) # True

print(0 or 7) # 7

print("ok" and 5) # 5

print(not "") # True

A truthy value need not be the object True. Use == for value equality; is is not its replacement.

56 of 60

Optional: parsing can fail before validation begins

This extension introduces try / except. It is not required for the core task.

Appendix · Input robustness

Deck 3 | 56

[P6]

PYTHON

raw_minutes = input("Minutes: ")

try:

duration_min = int(raw_minutes)

except ValueError:

print("Error: enter minutes as an integer.")

else:

if duration_min <= 0:

print("Error: duration must be positive.")

else:

print("Valid duration")

Parsing: can this text become the required type? Validation: is that value allowed?

57 of 60

Optional: do not quietly widen or narrow the contract

Record a change of requirement separately from a repair of the existing code.

Appendix · Scope and edge cases

Deck 3 | 57

[P1] [P5]

Input / issue

Current handling

Possible later change

"" route

Rejected

Already required

" " route

Accepted as nonempty

Reject whitespace-only labels after agreement

"abc" numeric text

Core: parse error

try / except extension

nan / inf distance

Rejected by isfinite

Already required

Extreme numeric sizes

Outside classroom scope

Define bounds / numerical error policy

A new policy needs new tests. It should not be smuggled into an AI-generated “fix.”

58 of 60

Reference: a compact validation and boundary test set

All numeric inputs below parse successfully. Use the stated first-error priority.

Appendix · Test reference

Deck 3 | 58

Case

Route

km

min

Expected

Normal

Campus

12.5

45

Report; Medium

Before 30

Campus

1

29

Short

At 30

Campus

1

30

Short

After 30

Campus

1

31

Medium

Before 60

Campus

1

59

Medium

At 60

Campus

1

60

Medium

After 60

Campus

1

61

Long

Zero distance

Rest

0

30

Report; Short

Zero time

Campus

1

0

Duration error

Two failures

Campus

−1

0

Distance error first

Empty label

""

−1

0

Label error first

Not finite

Campus

nan

30

Finite-distance error

For every rejected case, also confirm that no Route/Distance/Speed/Trip band report is printed.

59 of 60

Technical references

Primary documentation for the semantics used in this deck. Links are also in the notes.

Appendix · References

Deck 3 | 59

[P1]

Truth testing, Boolean operations, comparisons

docs.python.org/3/library/stdtypes.html

[P2–P3]

if / elif / else and compound statements

docs.python.org/3/tutorial/controlflow.html

[P4]

Expression grouping and precedence

docs.python.org/3/reference/expressions.html

[P5]

math.isfinite

docs.python.org/3/library/math.html

[P6]

Errors and exception handling

docs.python.org/3/tutorial/errors.html

60 of 60

Course continuity and provenance

The project, teaching examples, and technology references are kept distinct.

Appendix · Sources and adaptation

Deck 3 | 60

Course sources [U1–U4]

Deck 2: same inputs, units, and repository.

Legacy Operators / Loop: core concepts.

Foundations map: toy compare + branch.

​

New: validation policy, labs, and tests.

GitHub and teaching conventions

[G1] Review and commit changes.

[G2] Push and verify online.

​

Faulty examples are teacher-prepared.

AI prompts are templates, not transcripts.

Toy assembly is explicitly labeled.

Original definitions are not copied blindly: the legacy ~ / not error is corrected, not propagated.