Incident: One wrong character loses a rocket
Module 1 · Incident file · About 25 minutes
What happened
On 22 July 1962, NASA launched Mariner 1, a space probe meant to fly past Venus. Shortly after launch the rocket went off course and was destroyed. The cause was traced to an error in its guidance software, the program that steered it. Accounts of the failure usually describe that error as a single missing character in a formula.
The exact character matters less than the lesson. The program ran. Nothing in it stopped the computer from following it. It followed a rule that was written slightly wrong, exactly as written, and the result was a lost mission.
Lesson 1 of this module said that a computer does exactly what the words say, with no common sense to fill the gaps. Mariner 1 is that sentence at full size. This file shows how the same kind of slip looks on Amira's shelf card, and the habit that catches it.
Why it happened
Python stops for two kinds of mistake you have already met. A SyntaxError means it cannot read the code, such as a missing quotation mark. A NameError means it meets a name nobody made. Both are loud: the program stops and points at the line. Loud mistakes are the safe ones, because you cannot miss them.
The dangerous mistake is the quiet one. Change one character in a sum, a + into a -, and the line is still perfectly good Python. It reads, it runs, it produces a number. Python has no idea what the number is for, so it has nothing to complain about.
That leaves one defence: a person who knows what the answer should be and compares. If nobody works the answer out separately, a wrong number looks exactly like a right one. A printed card has no colour for "this value is wrong".
The same failure at Booknook
Here is the date part of card.py from the lab, with one character changed. The due day should be the borrow day plus the loan period. This version types a minus.
LOAN_DAYS = 14
TODAY_DAY = 44 # Wednesday 14 October 2026, as a shelf day
loan_id, member = "L04", "Jonah"
borrowed_day = 14 # shelf day: 14 September is day 14
due_day = borrowed_day - LOAN_DAYS # the slip: - where + belongs
days_late = TODAY_DAY - due_day
print("Loan", loan_id, "held by", member)
print("Due on shelf day", due_day)
print("Days late on shelf day", TODAY_DAY, "is", days_late)Code walkthrough
- Lines 1 to 4 are the rules and the loan, as in the lab.
loan_id, member = "L04", "Jonah"names two values in one line. - Line 5 is the slip.
14 - 14is0, so the due day becomes day 0, the day before the shelf opened. - Line 6 is correct, but it uses the wrong due day, so the error spreads:
44 - 0is44.
Output
Loan L04 held by Jonah
Due on shelf day 0
Days late on shelf day 44 is 44No error, no warning. The card says Jonah's book was due before the shelf existed and is 44 days late. Pinned to the shelf, it would tell Amira that Jonah is nearly three times as late as he is, and the fee in Module 2 would be worked out from that wrong number.
The fix
The fix is one character: put the + back. The real lesson is the second half of the cell. Before running it, work the two answers out by hand: 14 plus 14 is 28, and 44 minus 28 is 16. Then make Python compare its numbers with yours.
LOAN_DAYS = 14
TODAY_DAY = 44 # Wednesday 14 October 2026, as a shelf day
loan_id, member = "L04", "Jonah"
borrowed_day = 14 # shelf day: 14 September is day 14
due_day = borrowed_day + LOAN_DAYS # the due day comes after the borrow day
days_late = TODAY_DAY - due_day
print("Loan", loan_id, "held by", member)
print("Due on shelf day", due_day)
print("Days late on shelf day", TODAY_DAY, "is", days_late)
print(due_day == 28, days_late == 16) # worked out by hand first
print(due_day > borrowed_day) # a due day must come after the borrow dayCode walkthrough
- Line 5 has the
+back, and its comment now says why, so the next reader sees what the line must do. ==asks "are these two the same?" and givesTrueorFalse.due_day == 28compares Python's answer with the one you worked out by hand.>means "greater than".due_day > borrowed_daydoes not need the exact answer: it checks a rule that must always hold.
Output
Loan L04 held by Jonah
Due on shelf day 28
Days late on shelf day 44 is 16
True True
TrueRun the two check lines against the broken version and they print False False and False. The broken card looked believable; the checks did not. That is the whole point of writing them.
How you would have caught it
Two checks, each a single line, would have caught the slip before anyone printed a card. The first is an expected value: an answer worked out separately, by hand or from the paper record, compared with the program's answer. The second is a sanity check: a rule that must be true whatever the numbers, such as "a book is due after it was borrowed". The first catches a wrong answer you can predict; the second catches nonsense even when you cannot.
A third catch costs no code at all: show the card to someone who knows the shelf. Amira would see "due on shelf day 0" and ask what day 0 is. Module 6 turns these checks into assert lines that stop the program, and Module 10 into tests that run on every change.
Key points
- Python stops for code it cannot read and names it does not know. It cannot stop for a rule written wrongly, because that code is still valid.
- One wrong character can change every number that depends on it, without any error.
- Work the answer out by hand before you run the code, and compare the two with
==. - Add a sanity check for a rule that must always hold, such as a due day coming after the borrow day.
- Let someone who knows the real records read the output.
Sources
- NASA, Mariner 1 mission record, NASA Space Science Data Coordinated Archive (cited by name; launched 22 July 1962 and destroyed shortly after launch, with the failure traced to its guidance software).
- Python Software Foundation, "Errors and Exceptions", The Python Tutorial, Python 3.12 documentation. https://docs.python.org/3.12/tutorial/errors.html
- Python Software Foundation, "Comparisons", The Python Language Reference, Python 3.12 documentation. https://docs.python.org/3.12/reference/expressions.html#comparisons