Python in the physical world · Day 2
Turn inputs into decisions, then build a reaction-time challenge with a button, a potentiometer, and clear Python choices.
Mission: turn numbers and button signals into behaviour you can predict, test, and explain.
Learning goals
Tell the difference between whole-number, decimal, and Boolean values.
Use int(...) to turn a calculated decimal into a whole number.
Explain how a comparison becomes True or False.
Use if, elif, and else for different outcomes.
Store several reaction times in a list with append, len, and min.
Use while conditions that end when the state changes.
Today’s route
not andEach circuit appears right before you need to build or test it.
Part 1 · Start with values
Before a program can decide, it needs values in forms Python understands.
Kinds of values
Watch and discuss · Say what each line stores
raw_value = 32768
fraction = raw_value / 65535
print(type(raw_value))
print(type(fraction))
intA whole number such as 32768. Useful for counts, pin numbers, and many sensor readings.
floatA number with a decimal part, such as the result of dividing one number by another.
Casting
Try in Thonny · Run the lines and inspect each result
raw_value = 32768
fraction = raw_value / 65535
percent = int(fraction * 100)
print(fraction)
print(percent)
print(type(percent))
Casting means asking Python to make a new value in a different form. Here int(...) drops the decimal part.
Part 2 · Ask a question
Comparisons produce Boolean values, and Boolean values guide later choices in the code.
Boolean values
Try in Thonny · Predict before pressing Run
score = 347
print(score < 350)
print(score >= 350)
print(score == 347)
TrueThe question is correct.
FalseThe question is not correct.
<, >=, and == compare values and produce a Boolean answer.
A common mix-up
= stores a value; == asks whether two values matchWatch and discuss · Read each line aloud in words
| Code | Read it as… | Job |
|---|---|---|
reaction_ms = 412 | “Store 412 in reaction_ms.” | Assignment |
reaction_ms == 412 | “Is reaction_ms equal to 412?” | Comparison |
reaction_ms != 412 | “Is reaction_ms different from 412?” | Comparison |
Use = to store. Use == to ask “equal?” and != to ask “different?”
not and active-low input
On paper · Fill in the last column before checking
| Physical state | button.value() | not button.value() | Meaning we want |
|---|---|---|---|
| Released | 1 | False | not pressed |
| Pressed | 0 | True | pressed |
Active-low means the important event makes the signal low. not turns that electrical reading into a natural Python answer.
Choosing a branch
if, elif, and else choose one pathWatch and discuss · Which branch runs at 10%, 45%, and 92%?
if percent < 20:
led.duty_u16(0)
elif percent <= 70:
led.duty_u16(20000)
else:
led.duty_u16(65535)
Python checks from top to bottom and runs only the first branch whose condition is True.
Part 3 · Build an active-low input
Now the code and the circuit meet: GP13 reads the question, and GP15 shows the answer.
Build while unplugged · Task 1
Run the button program
Test the circuit · Reconnect only after the partner check
pressed = not button.value()
if pressed:
led.on()
else:
led.off()
Pressed: True.Ctrl+C: the LED turns off.If the program behaves as if the button is always pressed, unplug USB and check the button orientation and the 10 kΩ pull-up before changing code.
Part 4 · Use one number to choose a brightness
A potentiometer does not answer yes or no; it gives a range of numbers you can classify.
Build while unplugged · Task 2
Read the knob
Test the circuit · Turn the shaft slowly from one end to the other
Find readings close to 0%, 25%, 50%, 75%, and 100%. The LED should fade smoothly as the numbers change.
Your measured values do not need to be exact. The important pattern is low knob position → small number, high knob position → large number.
Choose brightness zones
Try in Thonny · Edit the same file and test each zone
if percent < 20:
led.duty_u16(0)
elif percent <= 70:
led.duty_u16(20000)
else:
led.duty_u16(65535)
Part 5 · Remember and repeat
A reaction game needs several results, and every loop must know when to stop.
Lists
Try in Thonny · Run each line and explain the result
times = [410, 375, 522]
print(times[0])
times.append(330)
print(len(times))
print(min(times))
print(times[-1])
times[0] asks for the first item.
append adds one new result at the end.
lenlen(times) counts how many results are stored.
minThe workshop adds this built-in tool today to find the fastest score.
Conditional while
On paper · Match each loop to the moment it stops
| Loop | Read it as… | Stops when… |
|---|---|---|
while len(scores) < ROUNDS: | repeat while we still need more scores | the list already holds ROUNDS results |
while not button.value(): | wait while the button is pressed | the button is released |
while button.value(): | wait while the button is released | the button is pressed |
These loops stop because the condition changes. You do not need an endless loop for every job.
Reaction game circuit reminder
Build while unplugged · Rebuild only if you took the circuit apart
Plan the game first
On paper · Number the steps from first to last
The imports, pin setup, scores = [], and LED cleanup are already supplied.
reaction_ms and turn the LED off.scores.Build the starter
pass with working game logicTry in Thonny · Get one round working before you add all three
try:, delete pass.scores.append(reaction_ms).if reaction_ms < 350 → Quick!, else Keep practising!.while len(scores) < ROUNDS:.
wait_ms = randint(1000, 3000)
sleep_ms(wait_ms)
start_ms = ticks_ms()
end_ms = ticks_ms()
reaction_ms = ticks_diff(end_ms, start_ms)
The timing tools and the try/except/finally cleanup are already provided. Today you focus on the game logic inside them.
Check the result
Test the circuit · Run the full three-round version
Quick! or Keep practising!.min(scores).wait_ms and confirm the program is still waiting.01_button_decisions.py.start_ms and reaction_ms for one round.Exit ticket
On paper · Answer before packing away the hardware
Write a condition that is true when reaction_ms is at least 200 and below 500. Then explain what happens exactly at 200 and exactly at 500.
Source reference
Types and casting, Boolean values, comparison operators, = versus ==, not, if/elif/else, lists, and while loops with clear stopping conditions.
Active-low button input on GP13, PWM LED on GP15, potentiometer reading on GP26 / ADC0, and the student-built reaction game starter using supplied timing and cleanup code.
Workshop links used in this deck: ../code/day-2/01_button_decisions.py, ../code/day-2/02_potentiometer_led.py, ../code/day-2/03_reaction_game_starter.py, ../diagrams/button-and-led.html, and ../diagrams/potentiometer-and-led.html.