Python Magic Numbers and Why Named Constants Fix Real Bugs

A bare number with no stated meaning is a bug waiting to happen the moment it needs to change.

  • Lesson 2 of 4
  • PRO
  • Ages 10+
  • 3 hands-on levels
See what PRO unlocksA one-time $49.99 purchase. Topics 1–3 are free.

The dragon explains

Magic numbers and named constants

  1. The dragon: health < 20 works fine — but why 20? Nothing about the bare number says. That's called a MAGIC NUMBER.

  2. The dragon: Naming it fixes that instantly: LOW_HEALTH_THRESHOLD = 20 puts the meaning right where the value is declared.

    example.pyPython 3
    LOW_HEALTH_THRESHOLD = 20health = 15if health < LOW_HEALTH_THRESHOLD:    print('Low health warning!')
    OutputLow health warning!
  3. The dragon: This isn't just about readability — magic numbers cause a REAL bug when the same value has to appear more than once.

  4. The dragon: Two checks, SUPPOSED to use the same threshold — but someone updated one bare number and forgot the other.

    example.pyPython 3
    health = 25if health < 30:    print('Low health warning!')if health < 20:    print('Healing needed!')
    OutputLow health warning!
  5. The dragon: Only the warning fires. The healing check is silently using an OLD threshold, because it was never actually connected to the first one — they just happened to match once.

  6. The dragon: A named constant makes that impossible: change LOW_HEALTH_THRESHOLD once, and every use of the NAME updates together, because there's only one real value to change.

    example.pyPython 3
    LOW_HEALTH_THRESHOLD = 30health = 25if health < LOW_HEALTH_THRESHOLD:    print('Low health warning!')if health < LOW_HEALTH_THRESHOLD:    print('Healing needed!')
    OutputLow health warning! Healing needed!

Quick check

Check your understanding

Say your answer out loud before reading the marked one. Every wrong option is a mistake real beginners make.

  1. Question 1 of 2

    A magic number appears in TWO places in a program, both meant to represent the same threshold. What's the real risk?

    • Someone updates one occurrence and forgets the other, and the two silently disagreeCorrect
    • Python will refuse to run the code, since the same value shouldn't appear twice

    Why: The real risk is silent disagreement — nothing connects two bare literals that happen to share a value, so updating one and forgetting the other produces code that runs fine but behaves inconsistently. A named constant used in both places makes that structurally impossible, since there's only one real value to change.

  2. Question 2 of 2

    LOW_HEALTH_THRESHOLD = 30, used in two different if checks. If you change the 30 to 25, what happens to BOTH checks?

    question.pyPython 3
    LOW_HEALTH_THRESHOLD = 25if health < LOW_HEALTH_THRESHOLD:    ...if health < LOW_HEALTH_THRESHOLD:    ...
    • Both checks now use 25 — they read the same name, so they can never disagreeCorrect
    • Only the first check updates — the second still needs its own separate change

    Why: Both checks update together — that's the whole point. They're both reading the same NAME, not two independent numbers that happen to currently match, so changing the one place the value is defined changes every use of it at once.

In the game

What you'll practice

Three levels in the game: one guided first try with the shape of the answer already there, then two to solve on your own.

  1. 1

    GuidedYour first try

    health = 15, and the warning fires when health < 20 — but nothing about the bare number 20 says WHY that's the threshold. Replace it with a named constant, LOW_HEALTH_THRESHOLD = 20, and use the name in the comparison instead of the bare number.

  2. +2

    PracticeTwo more, on your own

This lesson is part of PRO.

PRO is a one-time $49.99 purchase, no subscription, and unlocks this whole topic along with everything else. Topics 1–3 are free, start to finish.

Unlock this lesson with PRO

Stuck three times? The game offers the answer — unasked.