Week 3: Advanced Conditionals & Decision Trees

4316 words
22 min read
2026-09-12T00:00:00.000Z
Python Week 1: the first filter for runtime behavior
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)**.

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:
python
if
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:
translate an English rule into exact Boolean logic\boxed{ \text{translate an English rule into exact Boolean logic} }

1. Conditionals as decision trees

Consider:
python
if marks >= 40:
    if attendance >= 75:
        print("Pass")
    else:
        print("Attendance shortage")
else:
    print("Fail")
This is equivalent to the decision structure:
text
            marks >= 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.
python
if A:
    if B:
        action
The inner condition B is evaluated only when A is true.

3. Example

python
age = 20
has_ticket = True

if age >= 18:
    if has_ticket:
        print("Allowed")
Trace:
text
age >= 18 → True
has_ticket → True
Output:
text
Allowed

4. Inner branch may never be reached

python
age = 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

python
if 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:
text
age = 20
has_id = False
Trace:
20≥1820\geq18
→ True.
Then:
text
has_id
→ False.
Therefore:
text
ID required
prints.
Do not evaluate the outer else.

7. Nested condition vs and

This:
python
if age >= 18:
    if has_id:
        print("Allowed")
can often be simplified to:
python
if age >= 18 and has_id:
    print("Allowed")
Both require:
A∧B.A\land B.

8. But nested logic is not always equivalent

Consider:
python
if age >= 18:
    print("Adult")

    if has_id:
        print("Verified")
Here "Adult" requires only:
python
age >= 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:
python
if condition_1:
    ...
elif condition_2:
    ...
elif condition_3:
    ...
else:
    ...
Exactly one branch executes.

10. Range classification

Example:
python
score = 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:
python
elif score >= 75:
really means:
75≤score<9075\leq score<90
because reaching that branch already tells us:
python
score >= 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:
python
if score >= 40:
    grade = "D"
elif score >= 90:
    grade = "A"
A score of 95 gets "D" because the first true branch wins.

13. Correct

python
if 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:
python
if 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 > 0
  • x < 0
  • otherwise x == 0
No number belongs to more than one branch.
This makes the decision structure clean.

16. Detecting gaps

Consider:
python
if marks > 80:
    print("High")
elif marks < 50:
    print("Low")
Values:
50≤marks≤8050\leq marks\leq80
produce no output.
That might be intentional, but often signals a missing case.

17. Detecting overlap

Consider separate ifs:
python
if x >= 0:
    print("Non-negative")

if x >= 10:
    print("At least ten")
For:
x=20,x=20,
both print.
That is fine if both descriptions should apply.

18. Independent conditions

Use separate ifs when multiple properties may simultaneously be true.
Example:
python
if n % 2 == 0:
    print("Even")

if n > 0:
    print("Positive")
For:
n=8,n=8,
output:
text
Even
Positive

19. Alternative categories

Use if/elif/else when exactly one category should be selected.
Example:
python
if 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:
python
if age >= 18 and score >= 60 and (citizen or permanent_resident):
    print("Eligible")
Break complex conditions into logical pieces.

21. Parentheses help

Compare:
python
A and B or C
with:
python
A and (B or C)
They may produce different results.
Even when you know precedence, parentheses improve clarity.

22. Boolean precedence

Python broadly evaluates:
text
not
and
or
in that precedence order.
So:
python
A or B and C
is interpreted like:
python
A or (B and C)
not:
python
(A or B) and C

23. Truth table practice

For:
python
A and (B or C)
suppose:
text
A = True
B = False
C = True
Then:
text
B or C
→ True
Therefore:
text
A and True
→ True

24. Negating conditions

Suppose:
python
age >= 18
means adult.
Its opposite is:
python
age < 18
This is often clearer than:
python
not age >= 18
Prefer direct complementary comparisons when possible.

25. Negating an interval

Inside:
10≤x≤2010\leq x\leq20
Python:
python
10 <= x <= 20
Outside:
python
x < 10 or x > 20
This follows De Morgan-style logic.

26. and for intersection

Suppose a number must satisfy:
x>5x>5
and:
x<10.x<10.
Use:
python
x > 5 and x < 10
Both conditions must hold.

27. or for alternatives

Suppose valid commands are:
text
"quit"
"exit"
Use:
python
if command == "quit" or command == "exit":
    ...
Either is sufficient.

28. A classic wrong expression

Wrong:
python
if command == "quit" or "exit":
This does not mean:
text
command is quit OR command is exit
The comparison must be explicit:
python
if command == "quit" or command == "exit":

29. Membership form

Once comfortable with collections, Python can express the same idea as:
python
if command in ("quit", "exit"):
But the core logic remains:
command must equal one of the allowed values.

30. Chained comparisons

Python allows:
python
0 <= x <= 100
This is a clean way to express:
python
x >= 0 and x <= 100

31. More chained comparisons

python
a < b < c
means conceptually:
python
a < b and b < c
Useful when describing ordered values.

32. Comparing three numbers

Suppose:
python
a = 2
b = 5
c = 9
Then:
python
a < b < c
is:
text
True

33. Largest of three

A robust algorithm:
python
maximum = 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:
text
a = 5
b = 9
c = 12
After checking b:
text
maximum = 9
We still need to check c.
So the second comparison must happen independently.

35. Smallest of three

python
minimum = 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:
python
if (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:
python
n = int(input())
We might classify:
python
if 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:
python
x = 10

if x > 5:
    x = x - 7

if x > 5:
    print("A")
else:
    print("B")
First condition:
10>510>5
so:
x=3.x=3.
Second condition:
3>53>5
is false.
Output:
text
B
Always use updated state.

39. Never evaluate all conditions from initial state

A common tracing mistake is to write:
text
initial 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:
python
value_if_true if condition else value_if_false
Example:
python
result = "Pass" if marks >= 40 else "Fail"
This is sometimes called a ternary conditional expression.

41. When conditional expressions are useful

Good:
python
status = "Adult" if age >= 18 else "Minor"
Less readable:
python
x = 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:
python
if marks >= 40:
    result = "Pass"
else:
    result = "Fail"
Expression form:
python
result = "Pass" if marks >= 40 else "Fail"
Both can represent the same decision.

43. Character classification

Suppose input:
python
ch = input()
You may classify a character using conditions.
Example:
python
if 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:
python
ch.isdigit()
ch.isalpha()
ch.islower()
ch.isupper()
Example:
python
if ch.isdigit():
    print("Digit")
These are Python-specific conveniences.

45. Vowel test

Simple form:
python
ch = 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:
text
YES
Yes
yes
Normalize:
python
answer = input().strip().lower()
Then test:
python
if answer == "yes":
    ...
This separates preprocessing from decision logic.

47. .strip()

python
text.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:
0≤p≤100.0\leq p\leq100.
Python:
python
if 0 <= p <= 100:
    print("Valid")
else:
    print("Invalid")

49. Validation before processing

Better structure:
python
if 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:
python
if 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
python
if 0 <= marks <= 100 and 0 <= attendance <= 100:
    print("Valid")
else:
    print("Invalid")
Both constraints must hold.

52. Invalid condition form

Alternatively:
python
if 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:
python
if 0 <= marks <= 100 and 0 <= attendance <= 100:
you could write:
python
valid_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:
python
year = 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:
20002000
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:
python
if 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:
python
a
b
c
First validate triangle:
a+b>c,a+c>b,b+c>a.a+b>c,\quad a+c>b,\quad b+c>a.
Then classify.

58. Triangle code

python
if 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:
  1. validation
  2. special case
  3. broader case
  4. default case

59. Why equilateral comes before isosceles

An equilateral triangle satisfies:
python
a == b or b == c or a == c
too.
If isosceles were checked first, equilateral triangles would be classified too early.
Again:
specific case before general overlapping case\boxed{ \text{specific case before general overlapping case} }

60. Eligibility problem

Suppose eligibility requires:
  • age 18–60 inclusive
  • score ≥ 70
  • attendance ≥ 75
python
if 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
python
normal = 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

python
if denominator != 0 and numerator / denominator > 10:
If denominator is zero:
python
denominator != 0
is false.
Because an and expression is already false, Python need not evaluate the division.

63. Safe ordering in and

This:
python
denominator != 0 and numerator / denominator > 10
is safe.
Reversing:
python
numerator / 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:
python
if 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:
python
x == 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:
python
if 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

python
adult = 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:
python
False
None
0
0.0
""
[]
and many non-empty/non-zero values as true-like.
So:
python
name = ""

if name:
    print("Has text")
does not print.

70. Explicit vs truthy checks

These can often express similar intent:
python
if name != "":
and:
python
if 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:
python
None
representing the absence of a normal value in many contexts.
You may encounter:
python
if result is None:
    ...
Detailed object identity semantics are beyond basic conditionals, but recognize None as distinct from:
python
0
False
""

72. Avoid over-complicated conditions

Instead of:
python
if not (x < 0 or x > 100):
often clearer:
python
if 0 <= x <= 100:
Correctness and readability both matter.

73. Simplification example

This:
python
if x > 10:
    result = True
else:
    result = False
can simply be:
python
result = x > 10
because the comparison already produces a Boolean.

74. Another redundant pattern

Verbose:
python
if is_valid == True:
usually clearer:
python
if is_valid:
And:
python
if is_valid == False:
can often be:
python
if not is_valid:

75. Branch-local assignments

Consider:
python
if x > 0:
    message = "Positive"

print(message)
If:
x≤0,x\leq0,
then message was never assigned.
This can produce an error.

76. Ensure variables are assigned on every path

Better:
python
if 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

python
x = 5
y = 8

if x < y:
    x = x + 4

if x > y:
    y = y + 2
else:
    y = y - 2

print(x, y)
Start:
x=5, y=8.x=5,\ y=8.
First:
5<85<8
true:
x=9.x=9.
Second:
9>89>8
true:
y=10.y=10.
Output:
text
9 10

79. Another worked trace

python
a = 4
b = 7

if a + b > 10:
    a = b

if a == b:
    b = b + 3
else:
    a = a + 3

print(a, b)
First:
4+7=11>10.4+7=11>10.
So:
a=7.a=7.
Now:
a=b=7.a=b=7.
Second condition is true.
Thus:
b=10.b=10.
Final:
a=7, b=10\boxed{a=7,\ b=10}
Common mistake: assuming
else belongs to visually nearest idea
Python associates else according to indentation/block structure.
Example:
python
if A:
    if B:
        X
    else:
        Y
The else belongs to:
python
if B:
not:
python
if A:
Indentation resolves the structure.

Common mistake: missing a boundary
Suppose categories are:
python
if x < 10:
    ...
elif x > 10:
    ...
What happens at:
x=10?x=10?
Neither branch.
Always test boundary values explicitly.

Common mistake: duplicated branches
python
if x >= 50:
    print("A")
elif x >= 50:
    print("B")
Second branch is unreachable.

Common mistake: broader case first
python
if 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:
text
Adult
Student
Using:
python
if 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:
python
age >= 18 and citizen
its negation is not simply:
python
age < 18 and not citizen
Correct logical negation:
python
age < 18 or not citizen
Because failure of either requirement makes the original false.

Common mistake: equality where range is needed
Suppose adult age is:
age≥18.age\geq18.
Wrong:
python
age == 18
That accepts only exactly 18.

Common mistake:
and for alternatives
Suppose valid codes are "A" or "B".
Impossible:
python
code == "A" and code == "B"
for a single ordinary string value.
Correct:
python
code == "A" or code == "B"

Common mistake:
or for simultaneous requirements
Suppose both age and marks criteria are mandatory.
Wrong:
python
age >= 18 or marks >= 60
This accepts people satisfying only one requirement.
Correct:
python
age >= 18 and marks >= 60

Common mistake: adding unnecessary
== True
Instead of:
python
if x > 10 == True:
write:
python
if x > 10:
The comparison already produces True or False.

90. Conditional problem-solving workflow

For a word problem:
  1. Identify all possible outcomes.
  2. Identify conditions leading to each outcome.
  3. Check whether cases overlap.
  4. Check whether any cases are missing.
  5. Put more specific overlapping cases before general ones.
  6. Decide between independent ifs and an if/elif/else chain.
  7. Translate conditions into Boolean expressions.
  8. Test boundaries.
  9. Trace sample inputs manually.

91. Boundary test set

Suppose rule is:
python
60 <= score < 80
Useful tests:
text
59
60
79
80
Why?
They test just below, exactly at, just inside, and exactly beyond the boundaries.

92. Test all logical combinations

For:
python
A and B
test:
text
A=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:
text
How does an if statement work?
Week 3:
text
How 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

python
if condition:
    ...

Two-way

python
if condition:
    ...
else:
    ...

Multi-way

python
if condition_1:
    ...
elif condition_2:
    ...
else:
    ...

Compound conditions

python
A and B
A or B
not A

Range

python
low <= x <= high

Conditional expression

python
a if condition else b

95. What you should actually master

By the end of Python Week 3, you should be able to:
  1. Design nested conditional structures.
  2. Simplify appropriate nested conditions using Boolean operators.
  3. Build correct multi-way elif chains.
  4. Order overlapping conditions correctly.
  5. Identify mutually exclusive and exhaustive cases.
  6. Detect gaps and unreachable branches.
  7. Use compound and, or, and not expressions.
  8. Use chained comparisons.
  9. Translate verbal rules into Boolean conditions.
  10. Handle exceptions and special cases.
  11. Validate multiple input constraints.
  12. Trace changing program state through multiple branches.
  13. Understand short-circuit evaluation.
  14. Handle branch-dependent variable initialization.
  15. Test boundary cases systematically.
  16. Distinguish category selection from independent properties.
  17. 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 20 evaluate to? :: Answer: 20 — Since 3 > 5 is False, the ternary expression returns the else branch value: 20.
  • Week 3 Diagnostic: In Python, is the chained comparison 1 < 3 < 2 valid syntax, and what does it return? :: Answer: C — Python allows chained comparisons: 1 < 3 < 2 is equivalent to (1 < 3) and (3 < 2), which evaluates to True 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

Active Recall Session

Document outline

Keep your place and jump directly to a heading.

Table of contents

No note selected

Open a chapter to see its outline, backlinks, and sources here.