Conditional Statements
CSCI 1470

by K. Yue

1. Conditional Statements

1.1 Simple if statement

if condition:
    block_of_statements

cond_1.py: download, execute and tinker with it.

#   conditional statements.

#   Examples of a simple if statement.

#   score passing?
score = int(input("Your exam score: "))
if score >= 70:
    print("Congratulations! You passed the exam.")
    print("Keep up the good work.")
   
#   version 2: improper identation.
score = int(input("Your exam score: "))
if score >= 70:
    print("Congratulations! You passed the exam.")
print("Keep up the good work.")

#   membership discount
price = float(input("price: "))
is_member = True    #   Assume to be a member.
if is_member:
    price *= 0.9  # Apply 10% discount
    print(f"Final member price: ${price:.2f}")

#   Add free chocolate for coupon.   
shopping_cart = ["milk", "bread"]
is_member = True
if is_member:
    shopping_cart.append("chocolate")
print(f"Your shopping cart: {shopping_cart}")

#   set is_hot_day. v1
temperature = float(input("current temperature: "))
is_hot_day = False
if temperature > 85:
    is_hot_day = True
print(f"Is it a hot day ({temperature} C)? {is_hot_day}")

#   set is_hot_day. v2
temperature = float(input("current temperature: "))
if temperature > 85:
    is_hot_day = True
else:
    is_hot_day = False
print(f"Is it a hot day ({temperature} C)? {is_hot_day}")

#   set is_hot_day. v3
temperature = float(input("current temperature: "))
is_hot_day = temperature > 85
print(f"Is it a hot day ({temperature} C)? {is_hot_day}")

1.2 if-else statement

if condition:
    block_1_of_statements
else:
    block_2_of statements

Tool:

breakpoint_1.py:

This tool accepts a command line argument as the name of an input Python program and executes the input program. It processes a Python comment line "#breakpoint" as a breakpoint. A breakpoint is handled by showing:

  1. The block of statements with line numbers since the last breakpoint or the beginning of the program.
  2. The output produced by the block.
  3. The changes in variable values from the last breakpoint or the beginnig of the program.

Consider bk_test.py:

#   bk_test.py
a = 1
print(f"a: {a}")
#breakpoint
b = 2
a = b + 2
print(f"a: {a}")
print(f"b: {b}")
#breakpoint
a = a * b
print(f"a: {a}")
print(f"b: {b}")
#breakpoint
 

Try:

python breakpoint_1.py bk_test.py

1.3 if-elif-else statement

if condition_1:
    block_1_of_statements
elif condition_2:
    block_2_of_statements
elif condition_3:
    block_3_of_statements
...
else:
    block_else_of statements

Example:

score = 75
if score >= 90:
    grade = 'A'
elif score >= 80:
    grade = 'B'
elif score >= 70:
    grade = 'C'
elif score >= 60:
    grade = 'D'
else:
    grade = 'F'
print(f"Grade: {grade}")

output:

Grade: C

Example:

cond_2.py

#   conditional statements

# simple if then else
#breakpoint  (#breakpoint is for use of the program breakpoint_1.py)
age = 21
if age >= 18:
    print("You may vote.")
#breakpoint

# simple if then else
#breakpoint
predicted_value = 0.85
threshold = 0.7
if predicted_value >= threshold:
    prediction_outcome = "Positive"
else:
    prediction_outcome = "Negative"
print(f"Prediction outcome: {prediction_outcome}")
#breakpoint

# using short hand form.
#breakpoint
predicted_value_2 = 0.85
threshold_2 = 0.7
prediction_outcome_2 = "Positive" if predicted_value_2 >= threshold_2 else "Negative"
print(f"Prediction outcome (shorthand): {prediction_outcome_2}")
#breakpoint

# DS: Long form
text_data = "Data science is fascinating."
keyword = "science"
if keyword in text_data:
    contains_keyword = True
else:
    contains_keyword = False
print(f"Contains keyword: {contains_keyword}")
#breakpoint

# DS: Short form
text_data = "Data science is very fascinating."
keyword = "science"
contains_keyword_2 = True if keyword in text_data else False
print(f"Contains keyword (shorthand): {contains_keyword_2}")
#breakpoint

# DS: Not using conditionals.
text_data = "Data science is very, very fascinating."
keyword = "science"
contains_keyword_3 = keyword in text_data
print(f"Contains keyword (shorthand): {contains_keyword_3}")
#breakpoint

#   elif
score = 75
if score >= 90:
    grade = 'A'
elif score >= 80:
    grade = 'B'
elif score >= 70:
    grade = 'C'
elif score >= 60:
    grade = 'D'
else:
    grade = 'F'
print(f"Grade: {grade}")
 

For you to do:

Run python breakpoint_1.py cond_2.py

and ensure you thoroughly understand the output.

1.4 Nested if statement

Try out grade_point.py, which compute the grade point of a score in three ways: [1] if-elif-else, [2] nested if, and [3] dict.

1.5 Short hand if-else expression

value_if_true if condition else value_if_false

Example:

cond_expr_ex.py:

# conditional expressions
(3+7) if 7 <= 3 else 2
(3+7) if 7 > 3 else 2
"hello world" if True else "Eat ice cream"
"hello world" if False else "Eat ice cream"
mood = 'good'
"hello world" if mood=='good' else "Eat ice cream"
mood = 'bad'
action = "hello world" if mood=='good' else "Eat ice cream"
f"To do: {action}"

Running python eval_expr.py cond_expr_ex.py:

C:\...\examples>python eval_expr.py cond_expr_ex.py
#   conditional expressions
[line 2] (3+7) if 7 <= 3 else 2: 2
[line 3] (3+7) if 7 > 3 else 2: 10
[line 4] "hello world" if True else "Eat ice cream": hello world
[line 5] "hello world" if False else "Eat ice cream": Eat ice cream
mood = 'good'
[line 7] "hello world" if mood=='good' else "Eat ice cream": hello world
mood = 'bad'
action = "hello world" if mood=='good' else "Eat ice cream"
[line 10] f"To do: {action}": To do: Eat ice cream


2. Operator Precedence Revisited

Examples: arithmetic operations for integer mathematics

10 - 5 - 4: 1 (not 9)
10 – (5 – 4): 9
10 – 3 * 2: 4 (not 14)
3 * 2 ** 2: 12 (not 25)

2.1 Python Operator precedence

The precedence order of common Python operators starting from the highest precedence is shown below.

  1. Parenthesis
  2. Arithmetic operators:
    1. Exponentiation: ** (right associative: right ** evaluated first)
    2. Unary operators: -, +, ~ (bitwise not); left associative
    3. Multiplication, Division, Floor Division, Modulus *, /, //, %: These have equal precedence and are evaluated from left to right (i.e. left associative)
    4. Addition and subtract; + and -: left associative.
  3. Bitwise operators (other than ~):
    1. Left and right shift, >> and <<: left associative.
    2. Bitwise AND &.
    3. Bitwise XOR ^.
    4. Bitwise OR |.
  4. Comparison operators ==, !=, >, >=, <, <=, is, is not, in, not in: left associative.
  5. Logical operators:
    1. Logical NOT, not.
    2. Logical AND, and.
    3. Logical OR, or.
  6. Assignment operators =, :=, +=, -=, etc.: lowest precedence, left associative.

Tools:

eval_expr.py:

This simple program reads an input python file name as the command line argument and shows the result of evaluating the expressions in the file. If no command line argument is provided, it defaults to the file expr_ex.py. The input Python file should contain only Python expressions. You may not need to know the logic of this program.

If a line in the input Python file is a Python comment, it is echoed. Otherwise, the line is assumed to be a Python expression and is evaluated. The result is shown with a line number in the input file. A good way to study is to construct Python expressions with explanatory comments to highlight precedence and associativity.

The program has limitations.

You can try it out with expr_examples.py or create your own example file.

expr_precedence.py:

The program shows the intermediate steps and results in executing expressions in Python, highlight precedence and associativity. If a command line argument is provided, it is assumed to be a Python program containing only expressions. The expression will be executed one by one. If there is no command line argument, it will prompt user for input expression until user indicating quite.

You do not need to understand the logic of this program. The program has limitations.

You can try it out with expr_examples.py or create your own example file.

expr_examples.py:

#   - is left associative
9 - 3 - 1
#   a parenthesis is needed if the right - is required to be executed first
9 - (3 - 1)
#   * has higher precedence than + or 1.
4 + 2 * 5 - 6
#   //, / and * are left associative.
6 // 4 / 2
#   //, / and * are left associative.
4 * 8 // 5
#   () is needed with the right // should be executed first. It returns a different result.
4 * (8 // 5)
#  ** is right associative
2 ** 3 ** 2
#   () is needed if the left ** should be executed first.
(2 ** 3) ** 2
#   bitwise left shift is left associative.
6 >> 3 >> 1
#  a pair of parentheis is need if the right >> should be executed first.
6 >> (3 >> 1)
#   comparison operators have a higher precedence than relational operators. and has a higher precedence than or.
1 < 2 or 3 < 4 and 4 > 6
(1 < 2 or 3 < 4) and 4 > 6
1 < 2 or (3 < 4 and 4 > 6)

3. The match-case Statement

match subject:
    case pattern1:
        # Code to execute if subject matches pattern1
    case pattern2:
        # Code to execute if subject matches pattern2
    case _:
        # Default case (if no other pattern matches)

switch (expression) {
    case value1:
        // Code to execute if expression matches value1
        break; // Optional: exits the switch block
    case value2:
        // Code to execute if expression matches value2
        break;
    // ... more case statements ...
    default:
        // Optional: Code to execute if no case matches
        break;
}

  • Note that in Java, the terms "expression", "value1", etc., are used. An expression is evaluated and compared to the values value1, value2, and so on. Pattern matching is not supported.

Example:

match_1.py:

def check_http_status(status_code):
    """Prints a message based on the HTTP status code."""
    match status_code:
        case 200:
            print("200. Status: OK")
        case 403:
            print("403. Status: Forbidden")
        case 404:
            print("404. Status: Page Not Found")
        case 405:
            print("405. Status: Method not supported")
        case 500:
            print("500. Status: Server Error")
        case _:  # The wildcard case for any other value
            print("Other code. Status: Unknown")

check_http_status(200)
check_http_status(403)
check_http_status(404)
check_http_status(405)
check_http_status(500)
check_http_status(999)

#   This is a more advanced example that will not appear in exams.
def process_command(command):
    """Parses and executes a command represented as a list of strings."""
    match command:
        case ["quit"]:
            print("Exiting...")
        case ["go", direction]:  # the second argument of 'command' is stored in the variable direction
            print(f"Moving in direction: {direction}")
        case ["get", *item]:    # the second and following arguments of 'command', if exist, is stored in the list item.
            if item:
                print(f"Picking up item {item}")
            else:
                print("What do you want to get?")
        case _:
            print("Invalid command.")

print(f"process_command(['go', 'east']): ", end='')
process_command(['go', 'east'])
print(f"process_command(['get', 'sword']): ", end='')
process_command(['get', 'sword'])
print(f"process_command(['get']): ", end='')
process_command(['get'])
print(f"process_command(['use', 'sword']): ", end='')
process_command(['use', 'sword'])
print(f"process_command(['quit']): ", end='')
process_command(['quit'])

Example:

if_else_match.py: run to see and understand the output. You do not need to know the module itertools and its function product.

from itertools import product

# Scenario: Determine a user's access level based on their role and subscription status.
# Roles: 'admin', 'editor', 'member'
# Subscription Status: 'premium', 'standard', 'free'

role = 'editor'
subscription = 'premium'

def print_access(role, subscription):
    print("   using nested If Statement: ", end="")
    if role == 'admin':
        if subscription == 'premium':
            print("Admin with Premium Access: Full control.")
        else: # Admin with standard or free subscription
            print("Admin with Basic Access: Limited control.")
    else:
        if role == 'editor':
            if subscription == 'premium':
                print("Editor with Premium Access: Advanced editing features.")
            else:
                if subscription == 'standard':
                    print("Editor with Standard Access: Basic editing features.")
                else: # Editor with free subscription
                    print("Editor with Free Access: Read-only access.")
        else: # Member role
            if subscription == 'premium':
                print("Member with Premium Access: Ad-free content.")
            else:
                if subscription == 'standard':
                    print("Member with Standard Access: Limited ads.")
                else: # Member with free subscription
                    print("Member with Free Access: Ad-supported content.")

    print("   using elsif: ", end="")
    if role == 'admin' and subscription == 'premium':
        print("Admin with Premium Access: Full control.")
    elif role == 'admin': # Admin with standard or free subscription
        print("Admin with Basic Access: Limited control.")
    elif role == 'editor' and subscription == 'premium':
        print("Editor with Premium Access: Advanced editing features.")
    elif role == 'editor' and subscription == 'standard':
        print("Editor with Standard Access: Basic editing features.")
    elif role == 'editor': # Editor with free subscription
        print("Editor with Free Access: Read-only access.")
    elif role == 'member' and subscription == 'premium':
        print("Member with Premium Access: Ad-free content.")
    elif role == 'member' and subscription == 'standard':
        print("Member with Standard Access: Limited ads.")
    else: # Member with free subscription
        print("Member with Free Access: Ad-supported content.")

    print("   using match and case (Python 3.10+): ", end="")

    match (role, subscription):
        case ('admin', 'premium'):
            print("Admin with Premium Access: Full control.")
        case ('admin', _): # Any subscription for admin
            print("Admin with Basic Access: Limited control.")
        case ('editor', 'premium'):
            print("Editor with Premium Access: Advanced editing features.")
        case ('editor', 'standard'):
            print("Editor with Standard Access: Basic editing features.")
        case ('editor', _): # Any other subscription for editor
            print("Editor with Free Access: Read-only access.")
        case ('member', 'premium'):
            print("Member with Premium Access: Ad-free content.")
        case ('member', 'standard'):
            print("Member with Standard Access: Limited ads.")
        case ('member', _): # Any other subscription for member
            print("Member with Free Access: Ad-supported content.")
        case _: # Fallback for any other unhandled cases
            print("Unknown role or subscription combination.")

def main():
# Roles: 'admin', 'editor', 'member'
# Subscription Status: 'premium', 'standard', 'free'
    roles = ['admin', 'editor', 'member']
    subscriptions = ['premium', 'standard', 'free']
    for role, subscription in product(roles, subscriptions):
        print(f"role: {role}; subscription: {subscription} =>")
        print_access(role, subscription)
if __name__ == '__main__':
    main()