Week 3: Advanced Conditionals & Decision Trees
4316 words
22 min read
2026-09-12T00:00:00.000Z
Visual companion
Python
Type and operator map
Python Week 1: the first filter for runtime behavior
View
Revision summary
What this note is really saying
Short form
Nested conditionals, chained comparison operators, boundary testing, defensive checks, and ternary expressions. # Programming in Python — Week 3: Advanced Conditionals & Decision Trees The official IITM syllabus lists **Week 3: Conditionals (Continued)**.

Visual strip
Relevant recall pieces for this note
Programming in Python — Week 3: Advanced Conditionals & Decision Trees
The official IITM syllabus lists Week 3: Conditionals (Continued). It does not provide a finer topic breakdown in the syllabus file, so the detailed material below is a standard continuation of Week 2 conditional programming, rather than a claim about exact lecture ordering.
TL;DR
Week 2 introduced:
pythonif else elif and or not
Week 3 is mainly about using those ideas in more complicated decision problems:
- nested conditionals
- multi-way decisions
- carefully ordered conditions
- compound Boolean expressions
- validating several constraints
- character/string classification
- comparing several values
- simplifying Boolean logic
- tracing branches with changing state
- avoiding subtle logical errors
The key skill is no longer syntax.
It is:
1. Conditionals as decision trees
Consider:
pythonif marks >= 40: if attendance >= 75: print("Pass") else: print("Attendance shortage") else: print("Fail")
This is equivalent to the decision structure:
textmarks >= 40? / \ No Yes | | Fail attendance >= 75? / \ No Yes | | Attendance Pass shortage
Nested
if statements are essentially decision trees written as code.2. Nested conditionals
A conditional can contain another conditional.
pythonif A: if B: action
The inner condition
B is evaluated only when A is true.3. Example
pythonage = 20 has_ticket = True if age >= 18: if has_ticket: print("Allowed")
Trace:
textage >= 18 → True has_ticket → True
Output:
textAllowed
4. Inner branch may never be reached
pythonage = 15 has_ticket = True if age >= 18: if has_ticket: print("Allowed")
The first condition is false.
Therefore Python never evaluates the inner
if.No output is produced.
5. Nested if/else
pythonif age >= 18: if has_id: print("Allowed") else: print("ID required") else: print("Not old enough")
Three possible outcomes arise from two tests.
6. Trace carefully by branch
For:
textage = 20 has_id = False
Trace:
→ True.
Then:
texthas_id
→ False.
Therefore:
textID required
prints.
Do not evaluate the outer
else.7. Nested condition vs and
This:
pythonif age >= 18: if has_id: print("Allowed")
can often be simplified to:
pythonif age >= 18 and has_id: print("Allowed")
Both require:
8. But nested logic is not always equivalent
Consider:
pythonif age >= 18: print("Adult") if has_id: print("Verified")
Here
"Adult" requires only:pythonage >= 18
while
"Verified" requires both conditions.You cannot replace the entire structure with one combined
and without changing behaviour.9. Multi-way selection
A common pattern is:
pythonif condition_1: ... elif condition_2: ... elif condition_3: ... else: ...
Exactly one branch executes.
10. Range classification
Example:
pythonscore = int(input()) if score >= 90: grade = "A" elif score >= 75: grade = "B" elif score >= 60: grade = "C" elif score >= 40: grade = "D" else: grade = "F" print(grade)
11. Implicit ranges
Notice:
pythonelif score >= 75:
really means:
because reaching that branch already tells us:
pythonscore >= 90
was false.
This is an important way to read
elif chains.12. Condition order
For overlapping threshold conditions, test the strongest/highest threshold first.
Bad:
pythonif score >= 40: grade = "D" elif score >= 90: grade = "A"
A score of 95 gets
"D" because the first true branch wins.13. Correct
pythonif score >= 90: grade = "A" elif score >= 40: grade = "D" else: grade = "F"
Ordering is part of the algorithm.
14. Exhaustive cases
A decision structure is exhaustive if every valid input reaches some case.
Example:
pythonif x > 0: print("Positive") elif x < 0: print("Negative") else: print("Zero")
Every real number fits exactly one branch.
15. Mutually exclusive cases
The branches above are also mutually exclusive:
x > 0x < 0- otherwise
x == 0
No number belongs to more than one branch.
This makes the decision structure clean.
16. Detecting gaps
Consider:
pythonif marks > 80: print("High") elif marks < 50: print("Low")
Values:
produce no output.
That might be intentional, but often signals a missing case.
17. Detecting overlap
Consider separate
ifs:pythonif x >= 0: print("Non-negative") if x >= 10: print("At least ten")
For:
both print.
That is fine if both descriptions should apply.
18. Independent conditions
Use separate
ifs when multiple properties may simultaneously be true.Example:
pythonif n % 2 == 0: print("Even") if n > 0: print("Positive")
For:
output:
textEven Positive
19. Alternative categories
Use
if/elif/else when exactly one category should be selected.Example:
pythonif n < 0: category = "Negative" elif n == 0: category = "Zero" else: category = "Positive"
20. Complex Boolean conditions
Suppose eligibility requires:
- age at least 18
- score at least 60
- citizen or permanent resident
Condition:
pythonif age >= 18 and score >= 60 and (citizen or permanent_resident): print("Eligible")
Break complex conditions into logical pieces.
21. Parentheses help
Compare:
pythonA and B or C
with:
pythonA and (B or C)
They may produce different results.
Even when you know precedence, parentheses improve clarity.
22. Boolean precedence
Python broadly evaluates:
textnot and or
in that precedence order.
So:
pythonA or B and C
is interpreted like:
pythonA or (B and C)
not:
python(A or B) and C
23. Truth table practice
For:
pythonA and (B or C)
suppose:
textA = True B = False C = True
Then:
textB or C → True
Therefore:
textA and True → True
24. Negating conditions
Suppose:
pythonage >= 18
means adult.
Its opposite is:
pythonage < 18
This is often clearer than:
pythonnot age >= 18
Prefer direct complementary comparisons when possible.
25. Negating an interval
Inside:
Python:
python10 <= x <= 20
Outside:
pythonx < 10 or x > 20
This follows De Morgan-style logic.
26. and for intersection
Suppose a number must satisfy:
and:
Use:
pythonx > 5 and x < 10
Both conditions must hold.
27. or for alternatives
Suppose valid commands are:
text"quit" "exit"
Use:
pythonif command == "quit" or command == "exit": ...
Either is sufficient.
28. A classic wrong expression
Wrong:
pythonif command == "quit" or "exit":
This does not mean:
textcommand is quit OR command is exit
The comparison must be explicit:
pythonif command == "quit" or command == "exit":
29. Membership form
Once comfortable with collections, Python can express the same idea as:
pythonif command in ("quit", "exit"):
But the core logic remains:
command must equal one of the allowed values.
30. Chained comparisons
Python allows:
python0 <= x <= 100
This is a clean way to express:
pythonx >= 0 and x <= 100
31. More chained comparisons
pythona < b < c
means conceptually:
pythona < b and b < c
Useful when describing ordered values.
32. Comparing three numbers
Suppose:
pythona = 2 b = 5 c = 9
Then:
pythona < b < c
is:
textTrue
33. Largest of three
A robust algorithm:
pythonmaximum = a if b > maximum: maximum = b if c > maximum: maximum = c print(maximum)
This directly implements the "maximum so far" pattern from CT.
34. Why these are separate ifs
Suppose:
texta = 5 b = 9 c = 12
After checking
b:textmaximum = 9
We still need to check
c.So the second comparison must happen independently.
35. Smallest of three
pythonminimum = a if b < minimum: minimum = b if c < minimum: minimum = c print(minimum)
Same pattern with reversed comparison.
36. Middle of three values
A slightly richer conditional problem:
Given three distinct numbers, determine the middle value.
One approach:
pythonif (a < b < c) or (c < b < a): middle = b elif (b < a < c) or (c < a < b): middle = a else: middle = c
This demonstrates compound conditions and chained comparisons.
37. Sign and parity together
Suppose:
pythonn = int(input())
We might classify:
pythonif n > 0: if n % 2 == 0: print("Positive even") else: print("Positive odd") elif n < 0: if n % 2 == 0: print("Negative even") else: print("Negative odd") else: print("Zero")
This combines multiple dimensions of classification.
38. State changes inside branches
Consider:
pythonx = 10 if x > 5: x = x - 7 if x > 5: print("A") else: print("B")
First condition:
so:
Second condition:
is false.
Output:
textB
Always use updated state.
39. Never evaluate all conditions from initial state
A common tracing mistake is to write:
textinitial x = 10
and use 10 for every later condition.
Assignments change state.
The program is sequential.
40. Conditional expressions
Python also has a compact conditional expression:
pythonvalue_if_true if condition else value_if_false
Example:
pythonresult = "Pass" if marks >= 40 else "Fail"
This is sometimes called a ternary conditional expression.
41. When conditional expressions are useful
Good:
pythonstatus = "Adult" if age >= 18 else "Minor"
Less readable:
pythonx = complicated_expression_A if huge_condition else complicated_expression_B
Use compact form for genuinely simple two-way choices.
42. Conditional expression vs statement
Statement form:
pythonif marks >= 40: result = "Pass" else: result = "Fail"
Expression form:
pythonresult = "Pass" if marks >= 40 else "Fail"
Both can represent the same decision.
43. Character classification
Suppose input:
pythonch = input()
You may classify a character using conditions.
Example:
pythonif ch >= "0" and ch <= "9": print("Digit")
This depends on character ordering and assumes appropriate input shape.
44. Safer high-level string methods
Python strings provide methods such as:
pythonch.isdigit() ch.isalpha() ch.islower() ch.isupper()
Example:
pythonif ch.isdigit(): print("Digit")
These are Python-specific conveniences.
45. Vowel test
Simple form:
pythonch = input().lower() if ch == "a" or ch == "e" or ch == "i" or ch == "o" or ch == "u": print("Vowel") else: print("Not vowel")
Later collection membership allows a shorter version.
46. Input normalization
Suppose user may type:
textYES Yes yes
Normalize:
pythonanswer = input().strip().lower()
Then test:
pythonif answer == "yes": ...
This separates preprocessing from decision logic.
47. .strip()
pythontext.strip()
removes surrounding whitespace.
For example:
text" yes "
becomes:
text"yes"
This can make user-input comparisons more robust.
48. Validation
Suppose percentage must satisfy:
Python:
pythonif 0 <= p <= 100: print("Valid") else: print("Invalid")
49. Validation before processing
Better structure:
pythonif total <= 0: print("Invalid total") else: percentage = obtained / total * 100 print(percentage)
This avoids performing invalid computation.
50. Guard condition
A condition that prevents unsafe or inappropriate execution is often called a guard.
Example:
pythonif denominator != 0: result = numerator / denominator
The check protects the division.
51. Multiple validation rules
Suppose:
- marks must be 0–100
- attendance must be 0–100
pythonif 0 <= marks <= 100 and 0 <= attendance <= 100: print("Valid") else: print("Invalid")
Both constraints must hold.
52. Invalid condition form
Alternatively:
pythonif marks < 0 or marks > 100 or attendance < 0 or attendance > 100: print("Invalid") else: print("Valid")
Both approaches can express the same rule.
53. Boolean variable for readability
Instead of:
pythonif 0 <= marks <= 100 and 0 <= attendance <= 100:
you could write:
pythonvalid_marks = 0 <= marks <= 100 valid_attendance = 0 <= attendance <= 100 if valid_marks and valid_attendance: print("Valid")
Intermediate Boolean variables can clarify complex rules.
54. Leap year — good compound-condition example
Gregorian leap-year rule:
- divisible by 400 → leap
- otherwise divisible by 100 → not leap
- otherwise divisible by 4 → leap
- otherwise → not leap
Python:
pythonyear = int(input()) if year % 400 == 0: print("Leap year") elif year % 100 == 0: print("Not leap year") elif year % 4 == 0: print("Leap year") else: print("Not leap year")
55. Why order matters in leap years
Year:
is divisible by:
- 4
- 100
- 400
The special 400-year rule must override the century rule.
This is exactly why carefully ordered
elif conditions matter.56. Equivalent leap-year condition
The rule can also be expressed as:
pythonif year % 400 == 0 or (year % 4 == 0 and year % 100 != 0): print("Leap year") else: print("Not leap year")
This is a useful Boolean-expression exercise.
57. Triangle classification
Suppose side lengths are:
pythona b c
First validate triangle:
Then classify.
58. Triangle code
pythonif a <= 0 or b <= 0 or c <= 0: print("Invalid") elif a + b <= c or a + c <= b or b + c <= a: print("Invalid") elif a == b and b == c: print("Equilateral") elif a == b or b == c or a == c: print("Isosceles") else: print("Scalene")
This is a good example of:
- validation
- special case
- broader case
- default case
59. Why equilateral comes before isosceles
An equilateral triangle satisfies:
pythona == b or b == c or a == c
too.
If isosceles were checked first, equilateral triangles would be classified too early.
Again:
60. Eligibility problem
Suppose eligibility requires:
- age 18–60 inclusive
- score ≥ 70
- attendance ≥ 75
pythonif 18 <= age <= 60 and score >= 70 and attendance >= 75: print("Eligible") else: print("Not eligible")
This is a direct conjunction of constraints.
61. Exception rule
Suppose eligible if:
- normal rule passes
- or candidate has special exemption
pythonnormal = 18 <= age <= 60 and score >= 70 and attendance >= 75 if normal or special_exemption: print("Eligible")
This illustrates combining a main rule with an exception.
62. Short-circuit evaluation revisited
pythonif denominator != 0 and numerator / denominator > 10:
If denominator is zero:
pythondenominator != 0
is false.
Because an
and expression is already false, Python need not evaluate the division.63. Safe ordering in and
This:
pythondenominator != 0 and numerator / denominator > 10
is safe.
Reversing:
pythonnumerator / denominator > 10 and denominator != 0
can attempt division first.
So Boolean operand order may matter when evaluation has errors or side effects.
64. Short-circuit or
Suppose:
pythonif cached or expensive_check():
If
cached is already true, Python need not evaluate expensive_check().This can improve efficiency and affect program behaviour.
65. Conditions involving floating-point values
Avoid assuming every computed decimal is represented exactly.
For example, direct equality between calculated floating-point values can sometimes be fragile.
At this course stage, follow the problem's intended arithmetic model, but remember:
pythonx == y
may deserve care when both come from floating-point calculations.
66. String ordering
Python can compare strings:
python"apple" < "banana"
based on lexicographic character ordering.
But do not assume this always corresponds to human dictionary/cultural sorting rules.
For basic exercises, follow Python semantics.
67. Condition can call a function/method
Example:
pythonif name.isalpha(): print("Letters only")
The method returns a Boolean, which becomes the condition.
Any expression yielding truth/false-like value can be used in
if.68. Conditions can be stored
pythonadult = age >= 18 qualified = score >= 60 eligible = adult and qualified if eligible: print("Yes")
Boolean values are ordinary values that can be assigned to variables.
69. Truthiness
Python treats certain values as false-like, including commonly:
pythonFalse None 0 0.0 "" []
and many non-empty/non-zero values as true-like.
So:
pythonname = "" if name: print("Has text")
does not print.
70. Explicit vs truthy checks
These can often express similar intent:
pythonif name != "":
and:
pythonif name:
The second relies on Python truthiness.
For exam tracing, use the semantics shown by the course/question.
71. None intuition
Python has a special value:
pythonNone
representing the absence of a normal value in many contexts.
You may encounter:
pythonif result is None: ...
Detailed object identity semantics are beyond basic conditionals, but recognize
None as distinct from:python0 False ""
72. Avoid over-complicated conditions
Instead of:
pythonif not (x < 0 or x > 100):
often clearer:
pythonif 0 <= x <= 100:
Correctness and readability both matter.
73. Simplification example
This:
pythonif x > 10: result = True else: result = False
can simply be:
pythonresult = x > 10
because the comparison already produces a Boolean.
74. Another redundant pattern
Verbose:
pythonif is_valid == True:
usually clearer:
pythonif is_valid:
And:
pythonif is_valid == False:
can often be:
pythonif not is_valid:
75. Branch-local assignments
Consider:
pythonif x > 0: message = "Positive" print(message)
If:
then
message was never assigned.This can produce an error.
76. Ensure variables are assigned on every path
Better:
pythonif x > 0: message = "Positive" else: message = "Not positive" print(message)
Now every possible branch assigns
message.77. Control-flow reasoning
Before using a variable after a conditional, ask:
Is this variable definitely initialized regardless of which branch executes?
This is a major debugging skill.
78. Worked trace
pythonx = 5 y = 8 if x < y: x = x + 4 if x > y: y = y + 2 else: y = y - 2 print(x, y)
Start:
First:
true:
Second:
true:
Output:
text9 10
79. Another worked trace
pythona = 4 b = 7 if a + b > 10: a = b if a == b: b = b + 3 else: a = a + 3 print(a, b)
First:
So:
Now:
Second condition is true.
Thus:
Final:
Common mistake: assuming
else belongs to visually nearest ideaPython associates
else according to indentation/block structure.Example:
pythonif A: if B: X else: Y
The
else belongs to:pythonif B:
not:
pythonif A:
Indentation resolves the structure.
Common mistake: missing a boundary
Suppose categories are:
pythonif x < 10: ... elif x > 10: ...
What happens at:
Neither branch.
Always test boundary values explicitly.
Common mistake: duplicated branches
pythonif x >= 50: print("A") elif x >= 50: print("B")
Second branch is unreachable.
Common mistake: broader case first
pythonif x > 0: print("Positive") elif x > 100: print("Very large")
Very large is unreachable because every value above 100 is already above 0.Common mistake: confusing multiple properties with categories
Suppose a person can be both:
textAdult Student
Using:
pythonif adult: ... elif student: ...
forces only one label.
Independent
ifs may be appropriate instead.Structure should match the logical relationship between properties.
Common mistake: negating only part of a condition
If original:
pythonage >= 18 and citizen
its negation is not simply:
pythonage < 18 and not citizen
Correct logical negation:
pythonage < 18 or not citizen
Because failure of either requirement makes the original false.
Common mistake: equality where range is needed
Suppose adult age is:
Wrong:
pythonage == 18
That accepts only exactly 18.
Common mistake:
and for alternativesSuppose valid codes are
"A" or "B".Impossible:
pythoncode == "A" and code == "B"
for a single ordinary string value.
Correct:
pythoncode == "A" or code == "B"
Common mistake:
or for simultaneous requirementsSuppose both age and marks criteria are mandatory.
Wrong:
pythonage >= 18 or marks >= 60
This accepts people satisfying only one requirement.
Correct:
pythonage >= 18 and marks >= 60
Common mistake: adding unnecessary
== TrueInstead of:
pythonif x > 10 == True:
write:
pythonif x > 10:
The comparison already produces
True or False.90. Conditional problem-solving workflow
For a word problem:
- Identify all possible outcomes.
- Identify conditions leading to each outcome.
- Check whether cases overlap.
- Check whether any cases are missing.
- Put more specific overlapping cases before general ones.
- Decide between independent
ifs and anif/elif/elsechain. - Translate conditions into Boolean expressions.
- Test boundaries.
- Trace sample inputs manually.
91. Boundary test set
Suppose rule is:
python60 <= score < 80
Useful tests:
text59 60 79 80
Why?
They test just below, exactly at, just inside, and exactly beyond the boundaries.
92. Test all logical combinations
For:
pythonA and B
test:
textA=True, B=True A=True, B=False A=False, B=True A=False, B=False
For complicated rules, systematic testing beats intuition.
93. Week 2 → Week 3 progression
Week 2:
textHow does an if statement work?
Week 3:
textHow do I design the correct decision structure for a complicated rule?
So the difficulty moves from syntax to logic.
94. Compact cheat sheet
Single condition
pythonif condition: ...
Two-way
pythonif condition: ... else: ...
Multi-way
pythonif condition_1: ... elif condition_2: ... else: ...
Compound conditions
pythonA and B A or B not A
Range
pythonlow <= x <= high
Conditional expression
pythona if condition else b
95. What you should actually master
By the end of Python Week 3, you should be able to:
- Design nested conditional structures.
- Simplify appropriate nested conditions using Boolean operators.
- Build correct multi-way
elifchains. - Order overlapping conditions correctly.
- Identify mutually exclusive and exhaustive cases.
- Detect gaps and unreachable branches.
- Use compound
and,or, andnotexpressions. - Use chained comparisons.
- Translate verbal rules into Boolean conditions.
- Handle exceptions and special cases.
- Validate multiple input constraints.
- Trace changing program state through multiple branches.
- Understand short-circuit evaluation.
- Handle branch-dependent variable initialization.
- Test boundary cases systematically.
- Distinguish category selection from independent properties.
- Simplify redundant Boolean code.
If these are comfortable, Programming in Python Week 3 is under control.
Quick Recall & Flashcards
Test your active recall before proceeding to practice problems. Format:
Question :: Answer.- Week 3 Diagnostic: What does the expression
10 if 3 > 5 else 20evaluate to? :: Answer: 20 — Since3 > 5is False, the ternary expression returns theelsebranch value: 20. - Week 3 Diagnostic: In Python, is the chained comparison
1 < 3 < 2valid syntax, and what does it return? :: Answer: C — Python allows chained comparisons:1 < 3 < 2is equivalent to(1 < 3) and (3 < 2), which evaluates toTrue and False->False.
Practice & Self-Check
Attempt these diagnostic questions to verify your operational understanding.
1
Question 1
What does the expression
10 if 3 > 5 else 20 evaluate to?NAT
3 Unit Assessment
2
Question 2
In Python, is the chained comparison
1 < 3 < 2 valid syntax, and what does it return?MCQ
3 Unit Assessment
A. SyntaxError
B. True
C. False
D. TypeError