CoursePython from Scratch to Intermediate · Module 1: Getting Started · part 12 of 75
Part 12 · Module 1: Getting Started

Incident: One wrong character loses a rocket

6 min read·14 Oct 2026
Module 1 · Incident file · About 25 minutes

What happened

MARINER 1, IN FOUR STEPS launch 22 July 1962 off course shortly after destroyed mission lost cause traced guidance code
Mariner 1 left the pad as planned (blue), went off course (amber), was destroyed (red), and the cause was traced afterwards to its guidance software.

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.

WHAT THE COMPUTER DOES WITH A RULE rule written slightly wrong followed exactly wrong result no complaint no common sense fills the gap
A computer follows a slightly wrong rule (amber, uncertain) exactly as written, so the result is wrong (red) and nothing complains.

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

MISTAKES PYTHON STOPS FOR print("Frankenstein) SyntaxError print(tilte) NameError loud: the program stops and points at the line
A missing quotation mark and a misspelt name both stop the program with an error (red), so you cannot miss them.

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.

ONE CHARACTER, BOTH VALID PYTHON borrowed_day + LOAN_DAYS 28 borrowed_day - LOAN_DAYS 0 both run; only one is the rule
Swapping + for - keeps the line valid Python, so it runs and gives 0 instead of 28 (red, wrong; green, right) without any error.

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.

THE ONLY DEFENCE FOR A QUIET MISTAKE by hand 28 and 16 the program its numbers compare same trust it different find the slip
A quiet mistake is found only by comparing the program's numbers with an answer worked out separately: the same (green) or different (red).

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

LINE 5 OF THE BROKEN CARD due_day = borrowed_day - LOAN_DAYS should be +
The whole fault is one character: a minus (red) where the rule needs a plus.

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.

python
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 - 14 is 0, 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 - 0 is 44.

Output

text
Loan L04 held by Jonah
Due on shelf day 0
Days late on shelf day 44 is 44
ONE SLIP, TWO WRONG NUMBERS due_day 0, not 28 days_late 44, not 16 printed card no error shown every number built on the slip is wrong too
The wrong due day feeds the days late, and both wrong numbers (red) reach the printed card with no error to warn anyone.

No 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

BEFORE: THE SLIP AFTER: THE FIX due on shelf day 0 44 days late due on shelf day 28 16 days late checks: False False, False checks: True True, True
With the + restored the card says due on day 28 and 16 days late, and the same check lines that print False before print True after.

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.

python
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 day

Code 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 gives True or False. due_day == 28 compares Python's answer with the one you worked out by hand.
  • > means "greater than". due_day > borrowed_day does not need the exact answer: it checks a rule that must always hold.

Output

text
Loan L04 held by Jonah
Due on shelf day 28
Days late on shelf day 44 is 16
True True
True
THE CHECKS, RUN ON THE BROKEN CARD due_day == 28 False days_late == 16 False due_day > borrowed_day False the slip is caught
On the broken card all three checks print False (red), so a believable but wrong card is caught before anyone pins it up.

Run 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

EXPECTED VALUE SANITY CHECK due_day == 28 worked out by hand due_day > borrowed_day always true catches a wrong answer you can predict catches nonsense even when you cannot
An expected value compares the program with a known answer, and a sanity check tests a rule that must always hold; together they catch most quiet slips.

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