⚡ TechVani: AI, Technology, Apps, Coding & Digital World
TechVaniAI • Technology • Apps • Coding • Digital World
HomeAI & TechAppsCodingFree AI ToolsStudent TechSecurityAboutContactPrivacy
TECHVANI // LEARN. BUILD. TEST.

Learn the tech. Build the idea.

Clear study notes, tested lab files and practical guides for coding, AI and digital safety.

Explore Latest →
šŸ¤– AI & TechAI news, tools & guides šŸ“± Apps & ToolsUseful apps & websites šŸ’» CodingProgramming & web development šŸŽ“ Student TechStudy & career technology šŸ” Cyber SecuritySafety & awareness

Latest Posts

Circuit Notebook theme

Exam Notes

šŸ“š BTech CSE Exam Notes

Find Semester 1-8 subjects in one place. Choose a semester and open the notes you need. This is a general study guide, not an official syllabus.

Open Exam Notes →🧪 Open Lab Files →

Exam Numericals & Study Series

Practice CPU scheduling and explore OS and DBMS topics in separate, easy-to-follow parts. New topics will appear in the hub as they are published.

Open Numericals Hub →

Start here and stay in touch

New to TechVani? Start with our free AI tools guide for students. It covers which tools to try and what to check before relying on an answer.

For step-by-step videos, visit SiteSudhar on YouTube.

Join TechVani on WhatsApp

Get new AI tools and coding guides in your WhatsApp Updates tab.

Browse Topics

Popular Posts

TechVani

Python Truthiness, and/or and Short-Circuiting: 7 Tested Examples

Why does 0 or 10 produce 10? Why does "False" pass an if condition? Python conditions test truth values, not the English meaning of a word. This Proof Lab uses seven small, independently executed programs to separate truthiness, returned operands and short-circuit evaluation.

1. Definition: truthiness

Truthiness is the truth value Python obtains from an object when it is used in a condition. Built-in falsy values include None, False, numeric zero and empty sequences or collections. Most other built-in values are truthy. User-defined objects can control their truth test with __bool__ or __len__. Python uses __bool__ first, then __len__ if __bool__ is absent. If neither exists, an instance is truthy by default. Truth testing can also raise an exception.

A condition does not require an expression that already contains True or False. You can test a string, list or number directly. The built-in bool function gives the explicit Boolean result. Keep the value and its truth value separate: an empty list is not the Boolean False, but bool([]) is False.

2. How the decision flows

x or y
Test x. Truthy? Return x without evaluating y.
Falsy? Evaluate and return y.

x and y
Test x. Falsy? Return x without evaluating y.
Truthy? Evaluate and return y.
Original evaluation diagram. Both and/or operators return an operand; the not operator always returns a Boolean.

Follow the returned value

x or y                         x and y
  |                              |
truth-test x                   truth-test x
  |                              |
  +-- truthy -> return x          +-- falsy -> return x
  +-- falsy  -> evaluate y        +-- truthy -> evaluate y
               return y                       return y

Last operand: returned as-is, not converted to bool.
An enclosing if/bool(...) may truth-test that result.

3. Falsy is not the same as missing

values = [None, False, 0, "", [], "0", "False"]
for value in values:
    print(repr(value), bool(value))

Checked output:

None False
False False
0 False
'' False
[] False
'0' True
'False' True

None, False, zero and empty containers are falsy. A non-empty string is truthy even when its text is "0" or "False". Truth testing does not parse the meaning of a word.

4. or returns an operand

print(repr("" or "guest"))
print(repr("Ada" or "guest"))
print(repr(0 or []))

Checked output:

'guest'
'Ada'
[]

or returns its first operand if that operand is truthy; otherwise it returns the second operand. It does not automatically convert that result to True or False.

5. and also returns an operand

print(repr([] and "ready"))
print(repr([1] and "ready"))
print(repr("yes" and 0))

Checked output:

[]
'ready'
0

and returns its first operand if it is falsy; otherwise it evaluates and returns the second operand. This explains why a logical expression can produce a list, a string or an integer.

6. Short-circuiting can avoid a call

def probe():
    print("probe called")
    return True

print(False and probe())
print(True or probe())
print(True and probe())

Checked output:

False
True
probe called
True

The first expression does not need its second operand because False already determines and. The second does not need its second operand because True already determines or. Only the final expression calls probe.

7. Preserve zero with an explicit None check

def bad_default(value):
    return value or 10

def keep_zero(value):
    return 10 if value is None else value

for value in [None, 0, 5]:
    print(value, bad_default(value), keep_zero(value))

Checked output:

None 10 10
0 10 0
5 5 5

Using or as a default treats every falsy value as absent. If zero is a valid setting, test is None so zero survives. Whether empty text is valid is a separate application decision.

8. Guard a division before evaluating it

for denominator in [0, 2]:
    safe = denominator != 0 and 10 / denominator > 2
    print(denominator, safe)

Checked output:

0 False
2 True

and evaluates left to right. With denominator zero, the second expression is not evaluated, so no division by zero occurs. A guard must come before the operation it protects.

9. Use membership instead of the always-true trap

for choice in ["yes", "no", "maybe"]:
    wrong = bool(choice == "yes" or "no")
    right = choice in ("yes", "no")
    print(choice, wrong, right)

Checked output:

yes True True
no True True
maybe True False

choice == "yes" or "no" means (choice == "yes") or "no". The non-empty string "no" is truthy, so the wrong condition accepts every shown choice. Membership expresses the intended test clearly.

10. Quick comparison

ExpressionReturned valueSecond operand evaluated?
x or yx if x is truthy; otherwise yOnly when x is falsy
x and yx if x is falsy; otherwise yOnly when x is truthy
not xTrue or FalseNo second operand
bool(x)True or FalseNo second operand

11. Common mistakes and better choices

  • Do not use value or fallback when zero, False or empty text is valid data. Decide what missing means and test it explicitly.
  • Do not assume that input containing "False" becomes False. input returns text; validate the text against the values your program accepts.
  • Do not write x == a or b when you mean either value. Use x in (a, b) or repeat the full comparison.
  • Do not place a dangerous call before its guard. Short-circuiting works left to right.
  • Do not swap and/or with bitwise &/|. The operators have different purposes and evaluation behaviour.

Operator precedence also matters: not has higher priority than and, and has higher priority than or. Parentheses are often worth using when several tests are combined. For example, (is_student or is_teacher) and has_access states the grouping directly.

Boundary lab: precedence, selection and custom objects

The seven original programs and this separate lab were run with Python 3.10.12. No package installation is needed. Notice that a selected final operand is returned without an extra truth test: False or Bad() returns an object, but bool(Bad()) raises TypeError.

print('1. Precedence:', True or False and False)
print('   Regrouped:', (True or False) and False)
print('2. Legacy selection:', True and 0 or 10)
print('   Conditional:', 0 if True else 10)
print('3. Three operands:', repr('' or 0 or 'guest'))
print('4. Truth hooks:')
class Both:
    def __bool__(self):
        print('   __bool__ called')
        return False
    def __len__(self):
        print('   __len__ called')
        return 5
print('   result:', bool(Both()))
class Empty:
    def __len__(self):
        return 0
print('   len-only:', bool(Empty()))
class Plain:
    pass
print('   no hook:', bool(Plain()))
print('5. Invalid truth hook:')
class Bad:
    def __bool__(self):
        return 1
try:
    print(bool(Bad()))
except TypeError:
    print('   TypeError: __bool__ must return bool')
print('6. Final operand is returned without a truth test:')
answer = False or Bad()
print('   returned Bad object:', isinstance(answer, Bad))

Checked boundary output:

1. Precedence: True
   Regrouped: False
2. Legacy selection: 10
   Conditional: 0
3. Three operands: 'guest'
4. Truth hooks:
   __bool__ called
   result: False
   len-only: False
   no hook: True
5. Invalid truth hook:
   TypeError: __bool__ must return bool
6. Final operand is returned without a truth test:
   returned Bad object: True

__bool__ must return True or False, not an integer such as 1. When that method is absent, __len__ supplies a non-negative integer length; zero makes the object falsy. Do not use the old condition and a or b selection pattern when a may be falsy: it can unexpectedly choose b. Use a if condition else b.

Truth-test decision table

ObjectWhat Python usesResult
Both in the lab__bool__; __len__ is not calledFalse
Empty in the lab__len__ returns 0False
Plain in the labNeither hook existsTrue
Bad in the lab__bool__ returns an invalid intTypeError
False or Bad()Test False, then return the final operandBad object; no truth test on it yet

12. Practice before checking

Predict bool("0"), 0 and "ready" and [] or [1]. Then run them. Answers: True, 0 and [1]. The text "0" is non-empty. The integer zero stops and immediately. The empty list makes or choose its second operand.

print(bool("0"))
print(0 and "ready")
print([] or [1])

Checked practice output:

True
0
[1]

13. Exam questions with short answers

Q. What is truthiness?
The truth value an object has when tested in a condition.

Q. Name four built-in falsy values.
None, False, numeric zero and an empty list are examples.

Q. Is the string "False" falsy?
No. It is a non-empty string, so it is truthy.

Q. Does or always return True or False?
No. It returns one of its operands.

Q. When does and evaluate its second operand?
When the first operand is truthy.

Q. Why can value or 10 lose a valid zero?
Zero is falsy, so or chooses 10.

Q. How do you test only for a missing None value?
Use value is None, rather than a general truthiness test.

Q. Which truth hook has priority?

__bool__ first. Only when it is absent does Python use __len__. With neither, an instance is truthy by default.

Q. Does True and 0 or 10 select 0?

No, it returns 10. The first part yields 0, then or treats zero as falsy. Use 0 if condition else 10 for a real selection.

Q. Is the final operand always truth-tested?

No. It is returned as-is. Using that result later in if, not or bool() can trigger a truth test.

Read next and sources

Comments