Boolean Logic
In Lesson 03, we learned about operators, including the logical operators
and,or,not. In this lesson, we'll focus on true/false judgments — the most fundamental concept in computer science. Boolean logic is the foundation of all conditional statements, loop controls, and permission checks.
1. Boolean Values: True and False
There are only two boolean values: True and False. They are named after the British mathematician George Boole, who founded Boolean algebra — the theoretical basis of modern computing's "0 and 1."
print(True) # Output: True
print(False) # Output: False
print(type(True)) # <class 'bool'>
Comparison operators produce boolean results:
print(5 > 3) # True
print(10 == 5) # False
print(7 <= 7) # True
print(3 != 3) # False
Booleans are Also Numbers
In Python, True and False are actually subclasses of int — True is equivalent to 1, False to 0:
print(True + True) # 2 (True=1, two Trues = 2)
print(True * 10) # 10
print(False * 100) # 0
Warning: Although
True == 1andFalse == 0hold in Python (soTrue + Trueequals 2), never use them this way. Boolean values are meant for logical judgment, not arithmetic. Writing code likescore + Truewill leave readers confused.
Example: Health Check Results (Difficulty: Star)
# Generate boolean values with comparison operators
age = 25
height = 175
weight = 70
is_adult = age >= 18 # True
is_tall = height > 170 # True
is_heavy = weight > 80 # False
print(f"Adult: {is_adult}")
print(f"Tall: {is_tall}")
print(f"Overweight: {is_heavy}")
# Directly output boolean values — they are values, not text
print(f"Adult AND Tall: {is_adult and is_tall}")
Output:
Adult: True
Tall: True
Overweight: False
Adult AND Tall: True
2. not: Negation
not means "reverse" — black becomes white, white becomes black.
print(not True) # False
print(not False) # True
print(not (5 > 3)) # False (5>3 is True, negated is False)
not is commonly used in two scenarios:
Scenario 1: Checking "not meeting a condition"
# Not an admin — cannot enter the backend
is_admin = False
if not is_admin:
print("You do not have admin access.")
# Output: You do not have admin access.
Scenario 2: Checking if a variable is empty
# Check if user didn't provide a name
username = ""
if not username:
print("Username cannot be empty!")
# Output: Username cannot be empty!
There's a Python "implicit boolean conversion" trick here — the empty string "" is equivalent to False in condition checks. So not username is True when username is an empty string. We'll cover which values are "falsy" later.
Tip:
notmeans "negation." In code,if not is_admin:reads as "if not admin."
3. and: Both Must Be True
and means "both" — both conditions must be true for the result to be True. If either is false, the result is False.
| Left | Right | Result |
|---|---|---|
| True | True | True |
| True | False | False |
| False | True | False |
| False | False | False |
age = 22
has_id = True
# Both conditions must be met
can_buy_alcohol = age >= 18 and has_id
print(can_buy_alcohol) # True (both of age and have ID)
# Another scenario: applying for a credit card requires income >= 50k AND credit score >= 600
income = 80 # thousands
credit_score = 650
qualified = income >= 50 and credit_score >= 600
print(f"Credit card application: {qualified}") # True
Example: Login Check (Difficulty: Star)
# Simulate login — correct username AND correct password
username_correct = True
password_correct = False
can_login = username_correct and password_correct
print(f"Login result: {can_login}") # False — wrong password
# Add another layer: account must not be locked
account_locked = True
can_login = username_correct and password_correct and not account_locked
print(f"Final result: {can_login}") # False — account is locked
Output:
Login result: False
Final result: False
4. or: At Least One True
or means "either" — if at least one condition is true, the result is True. Only when both are false is the result False.
| Left | Right | Result |
|---|---|---|
| True | True | True |
| True | False | True |
| False | True | True |
| False | False | False |
# Can rest on weekends or holidays
is_weekend = True
is_holiday = False
can_rest = is_weekend or is_holiday
print(can_rest) # True (it's the weekend)
# Subway security: if you have water OR a drink, you need a check
has_water = True
has_drink = False
need_check = has_water or has_drink
print(f"Security check needed: {need_check}") # True
Exercise: Complete Truth Table Verification
# Verify the truth table with code — all combinations of and and or
a = True
b = True
print(f"{a} and {b} = {a and b}")
print(f"{a} or {b} = {a or b}")
a = True
b = False
print(f"{a} and {b} = {a and b}")
print(f"{a} or {b} = {a or b}")
a = False
b = True
print(f"{a} and {b} = {a and b}")
print(f"{a} or {b} = {a or b}")
a = False
b = False
print(f"{a} and {b} = {a and b}")
print(f"{a} or {b} = {a or b}")
Output:
True and True = True
True or True = True
True and False = False
True or False = True
False and True = False
False or True = True
False and False = False
False or False = False
5. Short-Circuit Evaluation
We mentioned this in Lesson 03, but it's so important that we'll dive deeper. Python's logical operators stop evaluating immediately once the result is determined, without executing the remaining expression.
and Short-Circuit: Left is False -> Right Not Executed
def check_right():
print("-> check_right was called!")
return True
print("False and check_right():")
result = False and check_right() # check_right will NOT execute
print(f"Result: {result}\n")
print("True and check_right():")
result = True and check_right() # check_right will execute
print(f"Result: {result}")
Output:
False and check_right():
Result: False
True and check_right():
-> check_right was called!
Result: True
or Short-Circuit: Left is True -> Right Not Executed
print("True or check_right():")
result = True or check_right() # check_right will NOT execute
print(f"Result: {result}")
Classic Uses of Short-Circuit Evaluation
1. Safe Access: Preventing None Errors
# Suppose user could be None (user doesn't exist)
user = None
# user.get("name") would error — None has no get method
# Use short-circuit to protect:
name = user and user.get("name")
print(name) # None — user is falsy, short-circuited, user.get() not called
# If user exists:
user = {"name": "Xiao Ming"}
name = user and user.get("name")
print(name) # Xiao Ming
2. Setting Default Values
# If the user didn't enter a name, use a default
user_input = "" # Empty string (falsy)
name = user_input or "guest"
print(f"Welcome, {name}") # Welcome, guest
user_input = "Zhang San"
name = user_input or "guest"
print(f"Welcome, {name}") # Welcome, Zhang San
Tip: The pattern
user_input or "default"is very Pythonic — if the left side is falsy (empty string), use the right; if truthy (has content), use the left. It leverages the short-circuit behavior ofor.
6. Truthy and Falsy Values
In Python, any value can be used as a boolean in a condition. Some values are considered "falsy," and everything else is "truthy."
Common Falsy Values
# These values are equivalent to False in conditions
print(bool(False)) # False — boolean false
print(bool(0)) # False — zero
print(bool(0.0)) # False — float zero
print(bool("")) # False — empty string
print(bool([])) # False — empty list (covered later)
print(bool(None)) # False — null value
Everything else is truthy:
print(bool(1)) # True — non-zero number
print(bool(-5)) # True — negative numbers are also truthy!
print(bool("Python")) # True — non-empty string
print(bool(" ")) # True — a space is a character, non-empty is truthy
print(bool([1, 2])) # True — non-empty list
Warning:
-5and" "(space) are both truthy, which may surprise you.-5is a non-zero integer, so it's truthy. A space is a character, making the string non-empty, so it's truthy. Only an empty string""is falsy.
Using Truthiness to Simplify Code
# Not recommended (verbose)
name = "Xiao Ming"
if name != "":
print(f"Hello, {name}")
# Recommended (concise)
name = "Xiao Ming"
if name:
print(f"Hello, {name}")
# Not recommended
score = 85
if score != 0:
print(f"Score: {score}")
# Recommended
score = 85
if score:
print(f"Score: {score}")
Tip: Leveraging truthiness makes code cleaner.
if name:is more "Pythonic" thanif name != "":. But be careful not to overuse it —if score:won't execute whenscore=0. If you need to distinguish between "score is 0" and "no score," useis not None.
7. is and is not: Identity Comparison
is compares whether two variables point to the same object (the same space in memory), not whether their values are equal. We mentioned this in Lesson 03; here are more examples to reinforce.
# == compares values, is compares identity
a = [1, 2, 3]
b = [1, 2, 3]
c = a
print(a == b) # True — same values
print(a is b) # False — but not the same list object
print(a is c) # True — c is a, points to the same list
# Small integer caching (Python internal optimization)
x = 256
y = 256
print(x is y) # Might be True — small integers are cached
x = 1000
y = 1000
print(x is y) # Might be False — large integers are not cached
Warning: Never use
isto compare integers or strings by value. Although small integers may sometimes returnTruewithisdue to Python's internal optimization, this is an implementation detail and unreliable. Always use==for value comparison.
The Correct Usage: Checking for None
The Python community has a convention — when checking if a value is None, always use is, never ==:
# Correct approach
result = None
if result is None:
print("No result")
# Not recommended
if result == None:
print("No result")
Common Use Cases
- Permission control:
is_admin or (is_logged_in and has_permission)— combine multiple conditions to decide what a user can do. - Input validation:
username and password— check if the user provided both. - Optional parameter defaults:
timeout or 30— if timeout is not set, use the default of 30 seconds. - Safe access chain:
user and user.address and user.address.city— layer-by-layer safe access; short-circuit at any falsy step. - Toggle control:
is_enabled and is_connected— both conditions must be met for the operation to proceed.
FAQ
True and "True"?True (without quotes) is a boolean value; "True" (with quotes) is a string. They are different: type(True) is <class 'bool'>, type("True") is <class 'str'>. In a condition, if "True": is always True (non-empty string is truthy), and if "False": is also always True (also non-empty). So never put quotes around boolean values in conditions.is vs ==?== in 99% of cases. is is only conventional in one scenario — checking for None: if result is None:. Use == for all other value comparisons. Remember: == compares "value," is compares "identity."and/or have?and or or, it may not execute due to short-circuiting, and you won't know it was skipped. If that function has side effects (logging, sending emails, updating counters), short-circuiting can cause inconsistent behavior. Good practice: if the right-side expression has side effects, don't rely on short-circuiting — write them separately.not not "hello" return True?not "hello" first evaluates "hello" as a boolean (non-empty string is truthy), negates it to get False. Then not not "hello" negates False again, getting True. So not not x is equivalent to bool(x) — converting x to a boolean. But this pattern is uncommon; use bool(x) directly for clarity.Summary
- Booleans have only two values:
TrueandFalse; they are subclasses ofint(True=1,False=0), but don't use them for arithmetic notnegates: true becomes false, false becomes trueandrequires both to be trueorrequires at least one to be true- Python falsy values include:
False,0,0.0,"",[],None— everything else is truthy - Short-circuit:
andwith left false -> right not executed;orwith left true -> right not executed - Short-circuit enables two classic patterns: "safe access" and "default values"
iscompares identity,==compares value; useisforNonechecks
Exercises
-
Beginner (Difficulty: Star): Predict the values of these expressions, then verify:
not (10 > 5)True and False or Truenot False and True(5 > 3) or (2 > 10) and (8 == 8)— Hint: Watch precedence —andis higher thanor
-
Intermediate (Difficulty: Star-Star): Write code to validate a user's input string:
- If the input is empty, output "Input cannot be empty"
- If the input is all spaces, also treat as "Input cannot be empty" (Hint: use
strip()) - If the input length is less than 6, output "Input must be at least 6 characters"
- Otherwise, output "Input is valid"
-
Advanced (Difficulty: Star-Star-Star): Write a "three-digit number checker." Given a 3-digit number
num(e.g., 153), determine:- Is it even? (use
%) - Is it divisible by both 3 and 5?
- Is it a palindrome? (hundreds digit equals units digit, e.g., 121, 353)
- How many of the above conditions are met? Output the count.
Use only boolean expressions for all checks — no if statements (save that for the next lesson).
- Is it even? (use



