BASIC Python (Beginner Level) 📂 Basic Python Programming · 3 of 15 51 min read

Python Operators — Complete Guide with Precedence

Master every Python operator: arithmetic, comparison, logical, assignment, bitwise, membership, and identity. Covers real code examples for each operator, the complete precedence table (BODMAS-style), common traps like float equality and -2**2, hands-on exercises including a leap-year detector and password checker, plus a full operators sandbox program that ties every concept together.

Section 01

The Story That Explains Operators

The Kitchen Tools of Programming
Imagine walking into a professional kitchen. You see a chef with a countertop full of tools: a knife for chopping, a whisk for mixing, a scale for weighing, a thermometer for checking heat. Each tool does one specific job — and combined, they turn raw ingredients into a finished dish.

In Python, operators are those kitchen tools. Numbers, strings, and booleans are your ingredients. Operators are the symbols that do something with them — add them, compare them, combine them, invert them. Without operators, your data just sits there. With operators, it becomes a working program.

You cannot build any meaningful program without operators. Every calculation, every decision, every loop — powered by operators working behind the scenes.

An operator is a special symbol that performs an operation on one or more values (called operands). In the expression 5 + 3, the plus sign + is the operator, and 5 and 3 are the operands. Python has seven categories of operators, each designed for a specific purpose.

💡
The Big Picture

Python operators fall into seven neat categories: Arithmetic, Comparison, Logical, Assignment, Bitwise, Membership, and Identity. Each category solves a different class of problem — from doing maths to checking if a value exists in a list. Master them, and you master the mechanics of Python.


Section 02

The Seven Categories of Python Operators

Before diving into each category, here is the complete map. Every operator you will ever use in Python belongs to one of these seven groups.

Arithmetic
Do the Maths
Perform mathematical calculations: addition, subtraction, multiplication, division, modulo, exponentiation. Works on numbers, and some also work on strings and lists.
⚖️
Comparison
Ask Questions
Compare two values and return a boolean: is A greater than B, are they equal, are they different. Foundation of every conditional statement.
🧠
Logical
Combine Conditions
Combine multiple boolean conditions with and, or, not. Essential for complex decision-making.
🖉
Assignment
Store Values
Assign values to variables. Includes the simple = and compound versions like +=, -=, *= for shorthand updates.
🔐
Bitwise
Manipulate Bits
Work directly on the binary representation of integers. Used in cryptography, network programming, and low-level optimisation. Rarely needed in day-to-day code.
🔍
Membership & Identity
Check Belonging
in / not in check if a value exists in a collection. is / is not check if two variables point to the same object.

Section 03

Arithmetic Operators — The Mathematics Toolkit

Arithmetic operators are the ones you learned in primary school — plus a few Python-specific bonuses. They work on numbers (int and float) and some behave surprisingly well on strings and lists.

Operator Name Example Result Notes
+ Addition 10 + 3 13 Also joins strings and lists
- Subtraction 10 - 3 7 Also negates: -x
* Multiplication 10 * 3 30 Repeats strings/lists: "ab"*3
/ Division 10 / 3 3.333... Always returns a float
// Floor Division 10 // 3 3 Drops the decimal (rounds down)
% Modulo 10 % 3 1 The remainder after division
** Exponentiation 10 ** 3 1000 10 to the power of 3
# ─── ARITHMETIC IN ACTION ───────────────────────────────
a, b = 17, 5

print(f"a + b  = {a + b}")      # 22
print(f"a - b  = {a - b}")      # 12
print(f"a * b  = {a * b}")      # 85
print(f"a / b  = {a / b}")      # 3.4      (float)
print(f"a // b = {a // b}")     # 3        (floor)
print(f"a %% b  = {a % b}")      # 2        (remainder)
print(f"a ** b = {a ** b}")     # 1419857  (17^5)

# ─── ARITHMETIC ON STRINGS AND LISTS ────────────────────
print("Ha" * 3)                 # HaHaHa
print("Hello, " + "World!")      # Hello, World!
print([1, 2] + [3, 4])           # [1, 2, 3, 4]
print([0] * 5)                 # [0, 0, 0, 0, 0]

# ─── MODULO: MOST USEFUL "HIDDEN" OPERATOR ──────────────
# Check if a number is even or odd
print(14 % 2 == 0)              # True  (even)
print(15 % 2 == 0)              # False (odd)

# Convert 150 minutes to hours and minutes
total_min = 150
hours   = total_min // 60       # 2
minutes = total_min % 60        # 30
print(f"{hours}h {minutes}min")   # 2h 30min
OUTPUT
a + b = 22 a - b = 12 a * b = 85 a / b = 3.4 a // b = 3 a % b = 2 a ** b = 1419857 HaHaHa Hello, World! [1, 2, 3, 4] [0, 0, 0, 0, 0] True False 2h 30min
🔑
Modulo Is Secretly Powerful

The % operator looks trivial but appears in almost every real program: checking odd/even, wrapping around clock values (23:00 + 3 hours → (23+3) % 24 = 2), rotating array indices, distributing work evenly across servers, and generating cyclic patterns. Learn it well.


Section 04

Comparison Operators — Asking Questions

Comparison operators compare two values and always return a boolean — True or False. They are the foundation of every if statement, every while loop, and every filter in your code.

Operator Name Example Result
==Equal to5 == 5True
!=Not equal to5 != 3True
>Greater than7 > 4True
<Less than3 < 8True
>=Greater than or equal5 >= 5True
<=Less than or equal4 <= 3False
# ─── BASIC COMPARISONS ──────────────────────────────────
print(10 == 10)             # True
print(10 == "10")           # False (int vs str)
print(10 != 7)              # True
print("apple" < "banana")    # True  (alphabetical order)
print("Apple" < "apple")     # True  (uppercase comes first)

# ─── CHAINED COMPARISONS (Python superpower!) ───────────
age = 25

# Instead of this (works but ugly):
print(age >= 18 and age <= 65)   # True

# Write this (clean and mathematical):
print(18 <= age <= 65)          # True

# Chain even further
x = 50
print(0 < x < 100 < 1000)      # True

# ─── USING COMPARISONS IN LOGIC ─────────────────────────
score = 85
if score >= 90:
    grade = "A"
elif score >= 80:
    grade = "B"
elif score >= 70:
    grade = "C"
else:
    grade = "F"
print(f"Score {score} → Grade {grade}")
OUTPUT
True False True True True True True True Score 85 → Grade B
⚠️
Never Confuse = with ==

= is assignment (put a value into a variable). == is comparison (check if two values are equal). Writing if x = 5: is a SyntaxError — Python protects you. But if x == 5: is what you meant. Remember: double equals asks a question, single equals gives an answer.


Section 05

Logical Operators — Combining Conditions

Logical operators combine boolean values into more complex conditions. Python uses English words — and, or, not — instead of the cryptic symbols (&&, ||, !) used by C, Java, and JavaScript.

and
A and B
Returns True only if both A and B are True. If either is False, returns False.
or
A or B
Returns True if at least one of A or B is True. Returns False only when both are False.
not
not A
Inverts the value: True becomes False, False becomes True. The single-operand operator.
Short-Circuit
A and B / A or B
Python stops evaluating as soon as the answer is known. In False and X, X is never checked.

Truth Tables

✅ AND Truth Table
ABA and B
TrueTrueTrue
TrueFalseFalse
FalseTrueFalse
FalseFalseFalse
✅ OR Truth Table
ABA or B
TrueTrueTrue
TrueFalseTrue
FalseTrueTrue
FalseFalseFalse
# ─── LOGICAL OPERATORS IN ACTION ────────────────────────
age = 25
has_license = True
has_car = False

# and — all conditions must be True
can_drive = age >= 18 and has_license
print(f"Can drive: {can_drive}")         # True

# or — at least one condition must be True
needs_transport = not has_car or age < 16
print(f"Needs transport: {needs_transport}")  # True

# not — inverts the value
is_minor = not (age >= 18)
print(f"Is minor: {is_minor}")             # False

# ─── COMBINING ALL THREE ────────────────────────────────
username = "alice"
password = "secret123"
is_locked = False

can_login = (username == "alice" and
             password == "secret123" and
             not is_locked)
print(f"Can login: {can_login}")          # True

# ─── SHORT-CIRCUIT EVALUATION ───────────────────────────
# Python stops as soon as it knows the answer
x = 0

# This is SAFE — the division never runs because x == 0 is True first
if x == 0 or (10 / x) > 1:
    print("Safe division — no crash")
OUTPUT
Can drive: True Needs transport: True Is minor: False Can login: True Safe division — no crash

Section 06

Assignment Operators — Store and Update

The basic assignment is = — it stores a value into a variable. Python also provides compound assignment operators that combine an arithmetic operation with assignment. They save typing and make code cleaner.

Operator Example Equivalent To Meaning
=x = 5Store 5 in x
+=x += 3x = x + 3Add and reassign
-=x -= 3x = x - 3Subtract and reassign
*=x *= 3x = x * 3Multiply and reassign
/=x /= 3x = x / 3Divide and reassign
//=x //= 3x = x // 3Floor divide and reassign
%=x %= 3x = x % 3Modulo and reassign
**=x **= 3x = x ** 3Power and reassign
:=(n := 10)Walrus operatorAssign inside an expression (Python 3.8+)
# ─── COMPOUND ASSIGNMENT IN A COUNTER ──────────────────
score = 0

score += 10       # same as: score = score + 10  → 10
score += 25       # → 35
score -= 5        # → 30
score *= 2        # → 60
score //= 3       # → 20
print(f"Final score: {score}")

# ─── COMPOUND ASSIGNMENT ON STRINGS ─────────────────────
message = "Hello"
message += ", "          # append
message += "World!"
print(message)                # Hello, World!

# ─── COMPOUND ASSIGNMENT ON LISTS ───────────────────────
tasks = ["wake up"]
tasks += ["eat", "code"]      # extend the list
tasks *= 2                       # duplicate the list
print(tasks)

# ─── WALRUS OPERATOR := (Python 3.8+) ───────────────────
# Assign a value AND use it in the same expression
numbers = [3, 7, 15, 22, 31]

if (n := len(numbers)) > 3:
    print(f"List has {n} items — that's plenty")
OUTPUT
Final score: 20 Hello, World! ['wake up', 'eat', 'code', 'wake up', 'eat', 'code'] List has 5 items — that's plenty

Section 07

Bitwise Operators — Working with Binary

Bitwise operators work directly on the binary representation of integers. Every integer inside your computer is stored as a sequence of bits (0s and 1s). Bitwise operators manipulate those bits directly. You will rarely need them in day-to-day code, but they are essential in networking, cryptography, permissions, and hardware programming.

Operator Name Example Binary Result
&AND12 & 101100 & 10108 (1000)
|OR12 | 101100 | 101014 (1110)
^XOR12 ^ 101100 ^ 10106 (0110)
~NOT (invert)~12~1100-13
<<Left shift3 << 211 → 110012
>>Right shift12 >> 21100 → 113
# ─── BITWISE OPERATIONS ─────────────────────────────────
a = 12     # 1100 in binary
b = 10     # 1010 in binary

print(f"a & b  = {a & b}")     # 8   (1000)  bit is 1 only if BOTH are 1
print(f"a | b  = {a | b}")     # 14  (1110)  bit is 1 if EITHER is 1
print(f"a ^ b  = {a ^ b}")     # 6   (0110)  bit is 1 only if DIFFERENT
print(f"~a     = {~a}")        # -13         inverts all bits

# ─── SHIFTS ARE MULTIPLICATION/DIVISION BY POWERS OF 2 ──
print(5 << 1)                   # 10  (5 * 2)
print(5 << 3)                   # 40  (5 * 8)
print(40 >> 2)                  # 10  (40 / 4)

# ─── VIEW BINARY REPRESENTATION ─────────────────────────
print(bin(12))                   # 0b1100
print(bin(10))                   # 0b1010
print(bin(12 & 10))              # 0b1000
OUTPUT
a & b = 8 a | b = 14 a ^ b = 6 ~a = -13 10 40 10 0b1100 0b1010 0b1000
💡
When Would You Actually Use These?

Real-world uses: permission flags (Unix file permissions use bitwise ops), network programming (IP address subnetting), compression algorithms, emoji/unicode handling, and competitive programming (fast math tricks). For everyday app development, you'll rarely touch bitwise operators — but knowing they exist matters.


Section 08

Membership Operators — Does It Contain This?

Membership operators in and not in check whether a value exists inside a collection (list, tuple, string, set, dictionary). They return a boolean and are one of the most-used features in Python.

# ─── MEMBERSHIP IN LISTS ────────────────────────────────
fruits = ["apple", "banana", "cherry"]

print("apple" in fruits)        # True
print("mango" in fruits)        # False
print("mango" not in fruits)    # True

# ─── MEMBERSHIP IN STRINGS (checks substrings) ──────────
sentence = "Python is awesome"

print("Python" in sentence)     # True
print("python" in sentence)     # False (case-sensitive!)
print("awe" in sentence)        # True (substring match)

# ─── MEMBERSHIP IN DICTIONARIES (checks KEYS, not values) ──
user = {"name": "Alice", "age": 30, "role": "admin"}

print("name" in user)          # True  (key exists)
print("Alice" in user)         # False (Alice is a VALUE, not a key)
print("Alice" in user.values())  # True  (check values explicitly)

# ─── PRACTICAL USE ──────────────────────────────────────
valid_roles = ["admin", "editor", "viewer"]
current_role = input("Enter your role: ")

if current_role in valid_roles:
    print(f"Access granted as {current_role}")
else:
    print("Invalid role")
OUTPUT
True False True True False True True False True

Section 09

Identity Operators — Same Object or Just Equal?

Identity operators check whether two variables point to the exact same object in memory — not just whether their values are equal. This is a subtle but critical distinction.

✅ == (Equality)
ChecksMeaning
Value equalityDo they hold the same value?
Uses __eq__Compares content
Fast for primitivesSlower for large objects
✅ is (Identity)
ChecksMeaning
Object identityAre they the same object in memory?
Uses id()Compares memory address
Always fastConstant time
# ─── == vs is ───────────────────────────────────────────
a = [1, 2, 3]
b = [1, 2, 3]         # same values, but a DIFFERENT list
c = a                    # c and a point to the SAME list

print(a == b)             # True  — same contents
print(a is b)             # False — different objects
print(a is c)             # True  — same object

print(id(a), id(b), id(c))  # a and c share the same id

# ─── THE ONE PLACE TO ALWAYS USE 'is' ───────────────────
# Checking against None, True, or False — always use 'is'
value = None

if value is None:              # ✓ Pythonic and correct
    print("No value provided")

# NOT this (works but discouraged):
# if value == None:

# ─── SUBTLE GOTCHA — SMALL INTEGER CACHING ──────────────
x = 256
y = 256
print(x is y)             # True  (Python caches small ints -5 to 256)

x = 257
y = 257
print(x is y)             # May be False — outside cache range!

# Lesson: NEVER use 'is' to compare numbers or strings.
# Use 'is' ONLY for None, True, False.
OUTPUT
True False True 140234563 140234789 140234563 No value provided True False
⚠️
The Golden Rule for is

Use is only when comparing to None, True, or False. For everything else (numbers, strings, lists, dicts), use ==. Getting this wrong causes subtle, hard-to-find bugs that pass all your tests and then fail in production.


Section 10

Operator Precedence — Who Goes First?

BODMAS in the Wild
Remember school maths? You learned BODMAS or PEMDAS: Brackets → Orders (exponents) → Division/Multiplication → Addition/Subtraction. When you see 2 + 3 × 4, you know the answer is 14, not 20 — multiplication happens first.

Python follows the exact same rule. Every operator has a precedence rank. When multiple operators appear in one expression, Python evaluates the highest-precedence ones first. If two operators have the same precedence, Python uses associativity (usually left-to-right) to decide.

Get this wrong and your calculation returns a wildly incorrect answer with no error message. Nothing crashes — you just get the wrong result. This is why parentheses are your friend.

The Complete Precedence Table (High to Low)

Rank Operator Category Associativity
1 (highest)()Parentheses — force priorityN/A
2**ExponentiationRight-to-left
3+x -x ~xUnary plus, minus, bitwise NOTRight-to-left
4* / // %Multiplication, division, moduloLeft-to-right
5+ -Addition, subtractionLeft-to-right
6<< >>Bitwise shiftsLeft-to-right
7&Bitwise ANDLeft-to-right
8^Bitwise XORLeft-to-right
9|Bitwise ORLeft-to-right
10== != > < >= <= is is not in not inComparisons, identity, membershipLeft-to-right
11notLogical NOTRight-to-left
12andLogical ANDLeft-to-right
13 (lowest)orLogical ORLeft-to-right

Precedence in Action — Trace These Examples

# ─── EXAMPLE 1: Basic arithmetic order ──────────────────
result = 2 + 3 * 4
# Step 1: 3 * 4 = 12   (multiplication has higher precedence)
# Step 2: 2 + 12 = 14
print(result)                    # 14

# ─── EXAMPLE 2: Parentheses override precedence ─────────
result = (2 + 3) * 4
# Step 1: 2 + 3 = 5    (parens win)
# Step 2: 5 * 4 = 20
print(result)                    # 20

# ─── EXAMPLE 3: Exponent is right-associative ───────────
result = 2 ** 3 ** 2
# NOT (2 ** 3) ** 2 = 64
# Correct: 2 ** (3 ** 2) = 2 ** 9 = 512
print(result)                    # 512

# ─── EXAMPLE 4: Unary minus vs exponent ─────────────────
result = -2 ** 2
# ** has higher precedence than unary -
# = -(2 ** 2) = -4    NOT (-2) ** 2 = 4
print(result)                    # -4

# ─── EXAMPLE 5: Mixing comparison and logical ───────────
x = 10
result = x > 5 and x < 20 or x == 100
# Comparisons first: True and True or False
# and before or:     (True and True) or False
# =                  True or False = True
print(result)                    # True

# ─── EXAMPLE 6: The classic trap ────────────────────────
avg = 10 + 20 + 30 / 3
# / happens FIRST → 30 / 3 = 10
# Then 10 + 20 + 10 = 40    (NOT 20 as you might think!)
print(avg)                       # 40.0

# The correct way:
avg = (10 + 20 + 30) / 3
print(avg)                       # 20.0
OUTPUT
14 20 512 -4 True 40.0 20.0
🔑
The Golden Rule of Precedence

When in doubt, use parentheses. Nobody has ever been fired for adding extra parentheses. They cost zero performance, make your intent crystal clear, and eliminate every precedence bug. Write (a * b) + c instead of trusting your memory of the precedence table. Your future self reading the code at 2 AM will thank you.


Section 11

Common Operator Traps & Pitfalls

= vs ==
if x = 5: # SyntaxError
if x == 5: # Correct
Integer vs Float Division
10 / 3 = 3.333... (float)
10 // 3 = 3 (int)
-2 ** 2 Gotcha
-2 ** 2 = -4 (not 4!)
(-2) ** 2 = 4
is vs ==
if x is 100: # unreliable
if x == 100: # correct
and/or return values
0 or "hi" → "hi"
1 and "hi" → "hi"
Float Equality
0.1 + 0.2 == 0.3 → False
math.isclose(a, b)
# ─── AND/OR RETURN THE ACTUAL VALUE, NOT True/False ─────
# This surprises many beginners

print(5 and 10)              # 10   (both truthy → returns last)
print(0 and 10)              # 0    (short-circuits at 0)
print(5 or 10)               # 5    (first truthy value)
print(0 or 10)               # 10   (0 is falsy, so returns 10)
print("" or "default")       # "default"  (useful pattern!)

# PATTERN: default values with or
name = ""
display = name or "Anonymous"
print(display)                # Anonymous

# ─── FLOAT EQUALITY TRAP ────────────────────────────────
print(0.1 + 0.2 == 0.3)      # False !!!

# The correct way:
import math
print(math.isclose(0.1 + 0.2, 0.3))  # True

Section 12

Complete Practice Program — Operators Sandbox

This program uses every category of operator in a single working script. Type it out, run it, and modify values to see how the results change.

# operators_sandbox.py — All Python operators in one place

def main():
    # ─── ARITHMETIC ─────────────────────────────────────
    price = 99.99
    quantity = 3
    tax_rate = 0.15

    subtotal = price * quantity
    tax      = subtotal * tax_rate
    total    = subtotal + tax

    print("=== ORDER SUMMARY ===")
    print(f"Subtotal: ${subtotal:.2f}")
    print(f"Tax:      ${tax:.2f}")
    print(f"Total:    ${total:.2f}")

    # ─── ASSIGNMENT (compound) ──────────────────────────
    balance = 500.00
    balance -= total                  # subtract purchase
    balance += 50.00                  # add refund
    print(f"Balance:  ${balance:.2f}")

    # ─── COMPARISON & LOGICAL ───────────────────────────
    is_vip     = True
    order_size = quantity

    qualifies_for_discount = (
        (order_size >= 3 or is_vip) and
        balance > 0 and
        not (total > 1000)
    )
    print(f"Discount: {qualifies_for_discount}")

    # ─── MEMBERSHIP ─────────────────────────────────────
    payment_methods = ["card", "paypal", "cash"]
    chosen = "card"

    if chosen in payment_methods:
        print(f"Paying via: {chosen}")
    else:
        print("Unsupported payment method")

    # ─── IDENTITY ──────────────────────────────────────
    error = None
    if error is None:
        print("Order processed successfully")

    # ─── PRECEDENCE DEMO ────────────────────────────────
    # Without parens: * happens before +
    a = 2 + 3 * 4                 # = 14

    # With parens: + happens first
    b = (2 + 3) * 4               # = 20

    # Exponent is right-associative
    c = 2 ** 3 ** 2                # = 512, not 64

    print(f"Precedence: {a}, {b}, {c}")

    # ─── BITWISE (flag system) ──────────────────────────
    READ    = 0b100    # 4
    WRITE   = 0b010    # 2
    EXECUTE = 0b001    # 1

    permissions = READ | WRITE       # combine flags → 6
    print(f"Can read?    {bool(permissions & READ)}")
    print(f"Can write?   {bool(permissions & WRITE)}")
    print(f"Can execute? {bool(permissions & EXECUTE)}")

if __name__ == "__main__":
    main()
OUTPUT
=== ORDER SUMMARY === Subtotal: $299.97 Tax: $45.00 Total: $344.97 Balance: $205.03 Discount: True Paying via: card Order processed successfully Precedence: 14, 20, 512 Can read? True Can write? True Can execute? False

Section 13

Exercises — Test Your Understanding

Try each exercise on paper first — predict the output before running the code. This is how you truly learn operators. Answers follow at the end of each exercise.

🎯 Exercise 1 — Arithmetic Prediction
Task
Predict the output of each of these expressions without running the code.
Q1
7 + 3 * 2 = ?
Q2
(7 + 3) * 2 = ?
Q3
17 % 5 = ?
Q4
17 // 5 = ?
Q5
2 ** 3 ** 2 = ?
Q6
-3 ** 2 = ?
Answers
Q1=13, Q2=20, Q3=2, Q4=3, Q5=512, Q6=-9
🎯 Exercise 2 — Even or Odd?
Task
Write a program that takes a number from the user and prints whether it is even or odd. Use the modulo operator.
Hint
A number is even if n % 2 == 0, otherwise it is odd.
Bonus
Extend the program to also tell if the number is divisible by 3, 5, or both.
# Solution to Exercise 2
n = int(input("Enter a number: "))

if n % 2 == 0:
    print(f"{n} is even")
else:
    print(f"{n} is odd")

# Bonus — FizzBuzz-style
if n % 15 == 0:
    print(f"{n} is divisible by both 3 and 5")
elif n % 3 == 0:
    print(f"{n} is divisible by 3")
elif n % 5 == 0:
    print(f"{n} is divisible by 5")
🎯 Exercise 3 — Logical Truth Table
Task
Predict each output before running.
Q1
True and False or True = ?
Q2
not True or False = ?
Q3
not (True or False) = ?
Q4
5 > 3 and 2 < 1 = ?
Q5
"a" or "b" = ?
Q6
0 and "hello" = ?
Answers
Q1=True, Q2=False, Q3=False, Q4=False, Q5="a", Q6=0
🎯 Exercise 4 — Simple Calculator
Task
Build a calculator that takes two numbers and an operator (+, -, *, /, //, %, **) from the user, then prints the result. Handle division by zero.
Requirement
Use in to check if the operator is valid before computing.
# Solution to Exercise 4
a = float(input("First number:  "))
op = input("Operator (+ - * / // %% **): ")
b = float(input("Second number: "))

valid_ops = ["+", "-", "*", "/", "//", "%", "**"]

if op not in valid_ops:
    print("Invalid operator!")
elif op in ["/", "//", "%"] and b == 0:
    print("Cannot divide by zero!")
else:
    if   op == "+":  result = a + b
    elif op == "-":  result = a - b
    elif op == "*":  result = a * b
    elif op == "/":  result = a / b
    elif op == "//": result = a // b
    elif op == "%":  result = a % b
    elif op == "**": result = a ** b
    print(f"{a} {op} {b} = {result}")
🎯 Exercise 5 — Password Strength Checker
Task
Given a password string, check if it is strong: at least 8 characters, contains a digit, contains an uppercase letter, contains a lowercase letter.
Requirement
Use logical operators to combine all four conditions into ONE boolean expression.
# Solution to Exercise 5
password = input("Enter password: ")

is_strong = (
    len(password) >= 8 and
    any(c.isdigit() for c in password) and
    any(c.isupper() for c in password) and
    any(c.islower() for c in password)
)

if is_strong:
    print("Strong password ✓")
else:
    print("Weak password — must have 8+ chars, digit, upper, lower")
🎯 Exercise 6 — Leap Year Detector
Task
A year is a leap year if it is divisible by 4, EXCEPT for years divisible by 100, UNLESS also divisible by 400. Write a program that determines leap year status.
Test Cases
2000 → leap, 2020 → leap, 2100 → NOT leap, 2024 → leap
# Solution to Exercise 6
year = int(input("Enter a year: "))

is_leap = (year % 4 == 0 and year % 100 != 0) or year % 400 == 0

if is_leap:
    print(f"{year} is a leap year")
else:
    print(f"{year} is not a leap year")

Section 14

Golden Rules

🐍 Python Operators — Non-Negotiable Rules
1
When in doubt, use parentheses. They cost nothing, make intent clear, and eliminate every precedence bug. (a + b) * c is always safer than trusting the precedence table from memory.
2
Never use == to compare floats. 0.1 + 0.2 != 0.3. Always use math.isclose(a, b) or check abs(a - b) < 1e-9.
3
Use is only for None, True, False. For every other value, use ==. Getting this wrong causes silent bugs that pass all tests and fail in production.
4
Prefer // over / for integer results. Regular division always returns a float, even when the result is whole. Use floor division when you need an integer.
5
Chain your comparisons. Write 18 <= age <= 65, not age >= 18 and age <= 65. Cleaner, faster, more Pythonic.
6
Remember: ** is right-associative. 2 ** 3 ** 2 equals 512, not 64. And -2 ** 2 equals -4, not 4 — unary minus has lower precedence than exponent.
7
Use in for membership, not manual loops. if x in valid_list: is cleaner and often faster than writing a for loop to check.
8
Master modulo %. It appears everywhere: even/odd checks, clock arithmetic, cyclic patterns, hash tables, load balancing. It looks trivial but is one of the most-used operators in real code.