📚 Python Conditional Logic
Brief Overview
This note covering conditionals was created from the CS50P - Lecture 1 - Conditionals
video. The content examines control flow through Python syntax and program design.
Key Concepts
if statements and their structure
Understanding comparison operators in practice
if‑elif‑else chain for efficient decision making
📊 Conditional Statements Overview
🔤 Keywords & Comparison Operators
if – introduces a condition.
elif – “else if”, checks another condition only if previous ones were false.
Comparison operators
Symbol LaTeX Meaning
> greater than
>= greater than or equal to
< less than
<= less than or equal to
== equal to (equality)
!= not equal to
Boolean expression – an expression that evaluates to either True or False (e.g., ).
🧩 Structure of an if Statement
Ends with a colon (:).
The following block must be indented (four spaces or one tab).
🛠️ Implementing Conditionals in Python
📂 Creating [Link]
1. Prompt the user for two integers.
2. Convert the input strings to integers using int().
# [Link]
x = int(input("What's x? "))
y = int(input("What's y? "))
✅ First Version – Multiple Independent ifs
if x < y:
print("x is less than y")
if x > y:
print("x is greater than y")
if x == y:
print("x is equal to y")
Each if is evaluated independently.
The program asks all three questions regardless of earlier results.
🔀 Control‑Flow Illustration
Condition True Branch False Branch
prints “x is less than y” proceeds to next test
prints “x is greater than y” proceeds to next test
prints “x is equal to y” program ends
The flowchart uses a diamond shape for each condition and arrows for
true/false outcomes.
Even when a condition is true, later conditions are still checked, leading to
redundant evaluations.
🔧 Improving Design with elif
📈 Refactored Code – Mutually Exclusive Branches
if x < y:
print("x is less than y")
elif x > y:
print("x is greater than y")
else: # only possible remaining case is x == y
print("x is equal to y")
elif ensures the second test runs only if the first was false.
else captures the remaining possibility, eliminating the need for a third explicit
comparison.
🗒️ Benefits
Fewer comparisons → more efficient execution.
Clearer logic – the program’s intent (mutually exclusive outcomes) is evident.
Reduces repetitive code, making maintenance easier.
📊 Comparison of Approaches
Aspect Multiple ifs if‑elif‑else
Number of evaluations Up to 3 (all run) Up to 2 (stops after first
true)
Readability Repetitive, harder to see Concise, shows exclusive
exclusivity branches
Performance Slightly slower for large Faster due to early exit
programs
Design quality Considered “not Preferred pattern for
well‑designed” for simple exclusive conditions
mutually exclusive cases
📚 Conditional Logic with if, elif, else
Definition of an if statement
If statement – a control‑flow construct that evaluates a condition; if the condition is
true, the associated block of code executes.
Using elif for multiple exclusive conditions
Elif – short for “else if”; allows checking additional conditions only when previous if/elif
tests have been false.
The else catch‑all
Else – executes when none of the preceding conditions are true; provides a default
action.
Typical comparison pattern
Conditions are mutually exclusive:
1.
2.
3. (implicitly covered by else)
Flow without else
Each condition checked with separate if statements, which may evaluate up to
three questions even when the first is true.
Example (inefficient):
if x < y:
print("x is less than y")
if x > y:
print("x is greater than y")
if x == y:
print("x is equal to y")
Results in unnecessary checks.
Improved flow with elif
Stops checking after the first true condition:
if x < y:
print("x is less than y")
elif x > y:
print("x is greater than y")
else:
print("x is equal to y")
Benefits
Fewer condition evaluations.
Simpler control‑flow diagram (fewer nodes/arrows).
Easier to read and maintain.
Using logical or for “not equal” test
To determine inequality in one step:
if x < y or x > y:
print("x is not equal to y")
else:
print("x is equal to y")
Logic
If either or is true → .
Only when both are false → .
Comparison Table
Approach Conditions Maximum Readability
Checked Evaluations
Three separate ifs ,, 3 (worst case) Low
if → elif → else , 2 (worst case) High
if with or + else or 1 (inequality) / 0 Medium‑High
(equality)
Key Takeaways
Use elif to create mutually exclusive branches and avoid redundant checks.
else serves as a logical default, eliminating the need for an explicit equality
test.
Combining conditions with or can succinctly express “not equal” logic.
Fewer condition evaluations improve performance in larger programs and
reduce the chance of bugs.
📊 Simplifying Conditional Logic
Definition: A conditional statement executes different code blocks based on whether a
Boolean expression evaluates to True or False.
Original approach checks three separate questions:
1. Is ?
2. Is ?
3. Otherwise .
Refined approach asks only one question:
If → print “ is not equal to ”.
Else → print “ is equal to ”.
Flowchart Comparison
Version Questions Asked Flowchart Complexity
Original , , (implied) Branch left/right twice
Refined only Single decision node
The refined flowchart has fewer branches, making it easier to read and
maintain.
🧩 Python Syntax Essentials
Indentation: In Python, indentation defines code blocks. Missing or inconsistent
indentation causes a SyntaxError.
Colon (:): Terminates the header of control structures (if, for, while, def). It signals the
start of an indented block.
if x != y:
print("x is not equal to y")
else:
print("x is equal to y")
Both indentation and the colon are mandatory; Python does not use curly
braces {} like C/Java.
🔀 Combining Conditions with Logical Operators
Python allows chaining of comparisons:
can be written as 90 <= score <= 100.
Logical conjunction (and) combines multiple Boolean expressions:
if score >= 80 and score < 90: → grade B.
Example Refactor
Original (two checks) Refactored (chained)
if score >= 90 and score <= 100: if 90 <= score <= 100:
if score >= 80 and score < 90: if 80 <= score < 90:
The refactored version is more concise and mirrors natural mathematical
notation.
📚 Grade Assignment Program
Goal: Map a numeric score (0–100) to a letter grade using conditional statements.
Grade Ranges (U.S. style)
Score Range Letter Grade
A
B
C
D
otherwise F (E is omitted)
Sample Implementation
score = int(input("Enter score (0‑100): "))
if 90 <= score <= 100:
print("Grade: A")
elif 80 <= score < 90:
print("Grade: B")
elif 70 <= score < 80:
print("Grade: C")
elif 60 <= score < 70:
print("Grade: D")
else:
print("Grade: F")
The program:
1. Prompts the user for an integer score.
2. Evaluates the appropriate range using chained comparisons.
3. Prints the corresponding letter grade.
Possible Simplifications
Reverse the logic: check for the lowest grade first and use else for higher
grades.
Use a list or dictionary to map ranges to grades for more scalable solutions (not
shown in transcript).
🔧 Improving Readability & Efficiency
Ask fewer questions: Reduce the number of Boolean checks where possible
(e.g., use instead of separate and ).
Chain comparisons: a <= b <= c replaces a <= b and b <= c.
Consistent ordering: Whether you test “greater than or equal to” or “less than
or equal to” is a matter of style; choose the one that makes the code clearer.
Maintainability: Simpler conditionals lead to fewer bugs and easier future
modifications.
🎯 Grading Logic with Conditional Statements
Definition: Conditional statements execute different blocks of code based on whether
a given condition evaluates to True or False.
Threshold‑based grading (scores 0–100):
if score >= 90: → A
elif score >= 80: → B
elif score >= 70: → C
elif score >= 60: → D
else: → F
Using elif (else‑if) ensures that only one grade is assigned; once a condition is
met, the remaining checks are skipped.
Optimization:
Checking from highest to lowest bound reduces the number of
comparisons.
Example: a score of 85 triggers the elif score >= 80 branch; lower
bounds (70, 60) are never evaluated.
Grade Range Table
Score Range Grade
≥ 90 A
80–89 B
70–79 C
60–69 D
< 60 F
Common Pitfall
Writing separate if statements without elif makes the conditions non‑mutually
exclusive, causing multiple branches (e.g., A, B, C, D) to execute for a single
score.
🔁 Parity Check Using the Modulo Operator
Definition: The modulo operator % returns the remainder after dividing one integer by
another.
Example remainders when dividing by 3:
Determining Even vs. Odd
An integer is even if it divides cleanly by 2 (remainder 0).
Otherwise, it is odd (remainder 1).
Sample Implementation ([Link])
def is_even(n: int) -> bool:
"""Return True if *n* is even, False otherwise."""
return n % 2 == 0
def main():
x = int(input("What's x? "))
if is_even(x):
print("even")
else:
print("odd")
if __name__ == "__main__":
main()
is_even returns a boolean (True or False).
Python’s bool type has exactly two possible values: True and False
(capitalized).
Key Points
% is essential for modular arithmetic and common checks such as parity.
Encapsulating the logic in a function (is_even) promotes reusability and
readability.
Defining a main function isolates program execution from importable code.
🧩 Defining a Simple Boolean Function
Function – a reusable block of code that can take arguments and return a value.
Goal: Create is_even that tells whether a number is even.
Logic: An integer is even when it has no remainder when divided by 2.
def is_even(n):
if n % 2 == 0:
return True # ✅ even
else:
return False # ❌ odd
📐 Mathematical Basis
Remainder operation:
Even ⇔
🐍 Pythonic Refinements
Version Code Description
Verbose if n % 2 == 0: return True Four‑line explicit
else: return False conditional
Ternary return True if n % 2 == 0 Single line using Python’s
else False ternary syntax
Direct return n % 2 == 0 Most concise – returns the
boolean result of the
expression
Boolean expression – an expression that evaluates to True or False.
Using a function call as the condition in another if statement is valid because the function
itself returns a boolean.
if is_even(x):
print("even")
else:
print("odd")
📚 Passing Arguments in Python
Argument passing – Python always passes references to objects; there is no separate
“address‑of” syntax as in C/C++ or Java.
All values are objects.
Mutability determines whether a called function can modify the original object.
🔤 String Methods & Custom Functions
Built‑in string methods (e.g., .strip(), .title(), .capitalize()) operate only on string
objects.
They cannot be called on a boolean result (True/False).
Note – If a custom function returns a string, you may chain string methods on that
return value.
⚡ Improving Conditional Logic
Consolidating Multiple Checks
Instead of separate if statements for each name belonging to the same house, combine
them with the logical or operator:
if name == "harry" or name == "hermione" or name == "ron":
print("Gryffindor")
elif name == "draco":
print("Slytherin")
else:
print("Who?")
Using match (Python 3.10+)
match works like a switch statement in other languages, allowing pattern‑matching on
values. (The transcript mentions it but does not show concrete syntax.)
🏰 Example: Hogwarts House Assignment
Input name House printed
"harry" Gryffindor
"hermione" Gryffindor
"ron" Gryffindor
"draco" Slytherin
any other Who?
name = input("What's your name? ")
if name == "harry" or name == "hermione" or name == "ron":
print("Gryffindor")
elif name == "draco":
print("Slytherin")
else:
print("Who?")
The input function captures user input as a string.
The conditional chain determines the appropriate house or falls back to a
default case.
🛠️ Key Takeaways
Use boolean expressions directly when possible; they are already True/False.
Pythonic code favors readability that resembles plain English.
Consolidate redundant conditions with logical operators (or, and).
Remember that Python’s argument passing is always by object reference, not
by address.
String methods are exclusive to string objects; they cannot be applied to
non‑string return values.
🔀 Match Statement Overview
match – A control‑flow keyword that evaluates a target value and selects the first case
pattern that fits.
Provides a more compact alternative to long chains of if‑elif‑else.
Introduced in Python 3.10.
📋 Syntax Details
case – Defines a pattern to compare against the value supplied to match.
Each case line ends with a colon (:) and its suite is indented.
Patterns are written as literals (e.g., strings) or more complex structures.
No need for break statements; only one case runs.
Basic Structure
match <value>:
case <pattern1>:
<action1>
case <pattern2>:
<action2>
...
✅ Handling Specific Cases
Literal strings are quoted: case "Harry":.
The action can be any valid Python statement, e.g., print("Gryffindor").
Example Cases
"Harry" → Gryffindor
"Hermione" → Gryffindor
"Ron" → Gryffindor
"Draco" → Slytherin
🎯 Default Case with Underscore
_ – A wildcard pattern that matches any value not captured by previous cases (acts like
else).
case _:
print("Who?")
Placed as the final case to ensure all unmatched inputs receive a response.
📐 Combining Cases with | (Vertical Bar)
Multiple literals can be matched in a single case using |.
case "Harry" | "Hermione" | "Ron":
print("Gryffindor")
Reduces duplication and keeps the code concise.
📊 Comparison: if‑elif‑else vs. match‑case
Feature if‑elif‑else match‑case
Syntax length Repetitive if, elif, else Single match with multiple
keywords case lines
Pattern flexibility Simple boolean Supports literal, wildcard,
expressions only and compound patterns
Default handling else: block case _: wildcard
Readability Can become cluttered with More structured, resembles
many conditions switch statements
🧪 Example Code (Full Implementation)
# [Link]
name = input("Enter a name: ")
match name:
case "Harry" | "Hermione" | "Ron":
print("Gryffindor")
case "Draco":
print("Slytherin")
case _:
print("Who?")
Running python [Link] and entering Harry, Hermione, or Ron prints
Gryffindor.
Entering Draco prints Slytherin.
Any other name triggers the default response Who?.