Common Precedence Mistakes

🏷️ Numbers and Mathematical Operations / Operator Precedence

🧠 Context Introduction

When working with numbers and mathematical expressions in Python, the order in which operations are performed matters a lot. Python follows a strict set of rules called operator precedence — similar to the PEMDAS rule you may remember from math class. However, even experienced engineers can make subtle mistakes when combining different operators. These mistakes often lead to bugs that are hard to spot because the code looks correct at first glance. Let's explore the most common pitfalls so you can avoid them in your daily work.


⚙️ Mistake #1: Forgetting That Multiplication and Division Come Before Addition and Subtraction

This is the most frequent error. Python always evaluates multiplication (*), division (/), floor division (//), and modulo (%) before addition (+) and subtraction (-).

  • What engineers sometimes write: result = 5 + 3 * 2
  • What they expect: 8 (thinking 5 + 3 = 8, then 8 * 2 = 16 — but that's not what happens)
  • What Python actually does: 3 * 2 = 6, then 5 + 6 = 11
  • Correct expression if you wanted addition first: result = (5 + 3) * 216

🛠️ Tip: When in doubt, use parentheses to make your intention crystal clear. It costs nothing and saves debugging time.


🕵️ Mistake #2: Confusing Exponentiation with Multiplication

The exponentiation operator () has a higher precedence than multiplication, but it also has a right-to-left** associativity, which can surprise you.

  • What engineers sometimes write: result = 2 ** 3 ** 2
  • What they expect: (2 ** 3) ** 2 = 8 ** 2 = 64
  • What Python actually does: 2 ** (3 ** 2) = 2 ** 9 = 512

📊 Comparison Table: Common Exponentiation Confusions

Expression What You Might Think What Python Actually Computes
2 ** 3 ** 2 64 512
-3 ** 2 9 -9
2 * 3 ** 2 36 18
  • For -3 ** 2: The exponentiation happens first, so it's -(3 ** 2) = -9, not (-3) ** 2 = 9
  • For 2 * 3 ** 2: Exponentiation first gives 2 * 9 = 18, not (2 * 3) ** 2 = 36

📊 Mistake #3: Mixing Division and Multiplication Without Parentheses

Division and multiplication have the same precedence, so Python evaluates them left to right. This can produce unexpected results when you assume a different grouping.

  • What engineers sometimes write: result = 8 / 4 * 2
  • What they expect: 8 / (4 * 2) = 8 / 8 = 1
  • What Python actually does: (8 / 4) * 2 = 2 * 2 = 4

🛠️ Tip: If you want to divide by a product, always wrap the denominator in parentheses: result = 8 / (4 * 2)


🛠️ Mistake #4: Overlooking the Modulo and Floor Division Precedence

The modulo operator (%) and floor division (//) share the same precedence level as multiplication and division. They are evaluated before addition and subtraction, and they follow left-to-right associativity.

  • What engineers sometimes write: result = 10 + 7 % 3
  • What they expect: (10 + 7) % 3 = 17 % 3 = 2
  • What Python actually does: 10 + (7 % 3) = 10 + 1 = 11

  • Another example: result = 20 - 15 // 4

  • What they expect: (20 - 15) // 4 = 5 // 4 = 1
  • What Python actually does: 20 - (15 // 4) = 20 - 3 = 17

🕵️ Mistake #5: Assuming Logical Operators Follow Math Precedence

When combining comparison operators (<, >, ==, etc.) with logical operators (and, or, not), the precedence order is: comparisons first, then not, then and, then or.

  • What engineers sometimes write: result = 5 > 3 and 2 < 4 or 6 == 6
  • What they might think: The expression is evaluated as 5 > 3 and (2 < 4 or 6 == 6)
  • What Python actually does: (5 > 3 and 2 < 4) or 6 == 6True or TrueTrue

This works correctly here by coincidence, but it can lead to logic errors in more complex conditions.

🛠️ Tip: Always use parentheses with logical operators when mixing them with comparisons. It improves readability and prevents subtle bugs.


📊 Quick Reference: Operator Precedence (Highest to Lowest)

Precedence Level Operators Notes
1 (Highest) ** (exponentiation) Right-to-left associativity
2 +x, -x (unary plus/minus)
3 *, /, //, % (multiplication, division, floor division, modulo) Left-to-right
4 +, - (addition, subtraction) Left-to-right
5 <, <=, >, >=, ==, != (comparisons)
6 not (logical NOT)
7 and (logical AND)
8 (Lowest) or (logical OR)

✅ Final Recommendations for Engineers

  • Use parentheses liberally — they make your intent obvious to both Python and anyone reading your code.
  • Test your assumptions with simple print statements when you are unsure about precedence.
  • Break complex expressions into multiple lines or variables. For example, instead of result = a + b * c - d / e, write:
  • product = b * c
  • quotient = d / e
  • result = a + product - quotient
  • Remember the golden rule: When in doubt, parenthesize it out.

This file shows common mistakes engineers make when Python's operator precedence causes unexpected results.


🔴 Example 1: Forgetting multiplication happens before addition

This example shows that * runs before +, so 2 + 3 * 4 is not (2 + 3) * 4.

result = 2 + 3 * 4
print(result)

📤 Output: 14


🔴 Example 2: Division before subtraction

This example shows that / runs before -, so 10 - 4 / 2 is not (10 - 4) / 2.

result = 10 - 4 / 2
print(result)

📤 Output: 8.0


🔴 Example 3: Exponentiation has higher precedence than negation

This example shows that ** runs before the unary minus, so -3 ** 2 is not (-3) ** 2.

result = -3 ** 2
print(result)

📤 Output: -9


🔴 Example 4: Modulo and floor division have same precedence as multiplication

This example shows that % and // run before +, so 10 + 7 % 3 is not (10 + 7) % 3.

result = 10 + 7 % 3
print(result)

📤 Output: 11


🔴 Example 5: Mixing comparison operators without parentheses

This example shows that comparisons chain left-to-right, so 5 > 3 > 2 is not (5 > 3) > 2.

result = 5 > 3 > 2
print(result)

📤 Output: True


🔴 Example 6: Logical and has higher precedence than or

This example shows that and runs before or, so True or False and False is not (True or False) and False.

result = True or False and False
print(result)

📤 Output: True


📊 Quick Reference: Common Precedence Rules

Operation Precedence (higher = runs first) Common Mistake
** (exponent) Highest -2**3 gives -8, not 8
*, /, //, % Medium 2 + 3 * 4 gives 14, not 20
+, - (binary) Lower 10 - 4 / 2 gives 8.0, not 3.0
==, !=, <, > Even lower 5 > 3 > 2 chains, not compares
not Lower still not True and False binds not first
and Very low True or False and False binds and first
or Lowest True or False and False gives True

🧠 Context Introduction

When working with numbers and mathematical expressions in Python, the order in which operations are performed matters a lot. Python follows a strict set of rules called operator precedence — similar to the PEMDAS rule you may remember from math class. However, even experienced engineers can make subtle mistakes when combining different operators. These mistakes often lead to bugs that are hard to spot because the code looks correct at first glance. Let's explore the most common pitfalls so you can avoid them in your daily work.


⚙️ Mistake #1: Forgetting That Multiplication and Division Come Before Addition and Subtraction

This is the most frequent error. Python always evaluates multiplication (*), division (/), floor division (//), and modulo (%) before addition (+) and subtraction (-).

  • What engineers sometimes write: result = 5 + 3 * 2
  • What they expect: 8 (thinking 5 + 3 = 8, then 8 * 2 = 16 — but that's not what happens)
  • What Python actually does: 3 * 2 = 6, then 5 + 6 = 11
  • Correct expression if you wanted addition first: result = (5 + 3) * 216

🛠️ Tip: When in doubt, use parentheses to make your intention crystal clear. It costs nothing and saves debugging time.


🕵️ Mistake #2: Confusing Exponentiation with Multiplication

The exponentiation operator () has a higher precedence than multiplication, but it also has a right-to-left** associativity, which can surprise you.

  • What engineers sometimes write: result = 2 ** 3 ** 2
  • What they expect: (2 ** 3) ** 2 = 8 ** 2 = 64
  • What Python actually does: 2 ** (3 ** 2) = 2 ** 9 = 512

📊 Comparison Table: Common Exponentiation Confusions

Expression What You Might Think What Python Actually Computes
2 ** 3 ** 2 64 512
-3 ** 2 9 -9
2 * 3 ** 2 36 18
  • For -3 ** 2: The exponentiation happens first, so it's -(3 ** 2) = -9, not (-3) ** 2 = 9
  • For 2 * 3 ** 2: Exponentiation first gives 2 * 9 = 18, not (2 * 3) ** 2 = 36

📊 Mistake #3: Mixing Division and Multiplication Without Parentheses

Division and multiplication have the same precedence, so Python evaluates them left to right. This can produce unexpected results when you assume a different grouping.

  • What engineers sometimes write: result = 8 / 4 * 2
  • What they expect: 8 / (4 * 2) = 8 / 8 = 1
  • What Python actually does: (8 / 4) * 2 = 2 * 2 = 4

🛠️ Tip: If you want to divide by a product, always wrap the denominator in parentheses: result = 8 / (4 * 2)


🛠️ Mistake #4: Overlooking the Modulo and Floor Division Precedence

The modulo operator (%) and floor division (//) share the same precedence level as multiplication and division. They are evaluated before addition and subtraction, and they follow left-to-right associativity.

  • What engineers sometimes write: result = 10 + 7 % 3
  • What they expect: (10 + 7) % 3 = 17 % 3 = 2
  • What Python actually does: 10 + (7 % 3) = 10 + 1 = 11

  • Another example: result = 20 - 15 // 4

  • What they expect: (20 - 15) // 4 = 5 // 4 = 1
  • What Python actually does: 20 - (15 // 4) = 20 - 3 = 17

🕵️ Mistake #5: Assuming Logical Operators Follow Math Precedence

When combining comparison operators (<, >, ==, etc.) with logical operators (and, or, not), the precedence order is: comparisons first, then not, then and, then or.

  • What engineers sometimes write: result = 5 > 3 and 2 < 4 or 6 == 6
  • What they might think: The expression is evaluated as 5 > 3 and (2 < 4 or 6 == 6)
  • What Python actually does: (5 > 3 and 2 < 4) or 6 == 6True or TrueTrue

This works correctly here by coincidence, but it can lead to logic errors in more complex conditions.

🛠️ Tip: Always use parentheses with logical operators when mixing them with comparisons. It improves readability and prevents subtle bugs.


📊 Quick Reference: Operator Precedence (Highest to Lowest)

Precedence Level Operators Notes
1 (Highest) ** (exponentiation) Right-to-left associativity
2 +x, -x (unary plus/minus)
3 *, /, //, % (multiplication, division, floor division, modulo) Left-to-right
4 +, - (addition, subtraction) Left-to-right
5 <, <=, >, >=, ==, != (comparisons)
6 not (logical NOT)
7 and (logical AND)
8 (Lowest) or (logical OR)

✅ Final Recommendations for Engineers

  • Use parentheses liberally — they make your intent obvious to both Python and anyone reading your code.
  • Test your assumptions with simple print statements when you are unsure about precedence.
  • Break complex expressions into multiple lines or variables. For example, instead of result = a + b * c - d / e, write:
  • product = b * c
  • quotient = d / e
  • result = a + product - quotient
  • Remember the golden rule: When in doubt, parenthesize it out.

Interactive Views

You are currently in 📚 All-in-One mode. Use the tabs at the top to switch to 📖 Theory Only or 💻 Code Only views.

This file shows common mistakes engineers make when Python's operator precedence causes unexpected results.


🔴 Example 1: Forgetting multiplication happens before addition

This example shows that * runs before +, so 2 + 3 * 4 is not (2 + 3) * 4.

result = 2 + 3 * 4
print(result)

📤 Output: 14


🔴 Example 2: Division before subtraction

This example shows that / runs before -, so 10 - 4 / 2 is not (10 - 4) / 2.

result = 10 - 4 / 2
print(result)

📤 Output: 8.0


🔴 Example 3: Exponentiation has higher precedence than negation

This example shows that ** runs before the unary minus, so -3 ** 2 is not (-3) ** 2.

result = -3 ** 2
print(result)

📤 Output: -9


🔴 Example 4: Modulo and floor division have same precedence as multiplication

This example shows that % and // run before +, so 10 + 7 % 3 is not (10 + 7) % 3.

result = 10 + 7 % 3
print(result)

📤 Output: 11


🔴 Example 5: Mixing comparison operators without parentheses

This example shows that comparisons chain left-to-right, so 5 > 3 > 2 is not (5 > 3) > 2.

result = 5 > 3 > 2
print(result)

📤 Output: True


🔴 Example 6: Logical and has higher precedence than or

This example shows that and runs before or, so True or False and False is not (True or False) and False.

result = True or False and False
print(result)

📤 Output: True


📊 Quick Reference: Common Precedence Rules

Operation Precedence (higher = runs first) Common Mistake
** (exponent) Highest -2**3 gives -8, not 8
*, /, //, % Medium 2 + 3 * 4 gives 14, not 20
+, - (binary) Lower 10 - 4 / 2 gives 8.0, not 3.0
==, !=, <, > Even lower 5 > 3 > 2 chains, not compares
not Lower still not True and False binds not first
and Very low True or False and False binds and first
or Lowest True or False and False gives True