Python Conditional Statements

by Pyrastra Team
Python Conditional Statements

So far, the Python programs we’ve written execute statements one by one in order from top to bottom. This code structure is called sequential structure. However, sequential structure alone cannot solve all problems. For example, if we design a game where the condition for passing the first level is that the player obtains 1000 points, then after completing the first level, we need to decide based on the player’s score whether to enter the second level or tell the player “Game Over”. In this scenario, our code will have two branches, and only one will be executed. There are many similar scenarios. We call this structure a “branching structure” or “selection structure”. Give yourself one minute, and you should be able to think of at least 5 similar examples. Give it a try!

Constructing Branching Structures with if and else

In Python, the most commonly used keywords for constructing branching structures are if, elif, and else. Keywords are words with special meanings in programming languages. Obviously, you cannot use them as variable names. Of course, we don’t always use all three keywords when constructing branching structures. We’ll explain this through examples. For instance, let’s write a Body Mass Index (BMI) calculator. Body Mass Index, also called BMI, is an internationally used indicator to measure whether a person is overweight or underweight and whether they are healthy. The calculation formula is shown below. Generally, $\small{18.5 \le BMI < 24}$ is considered the normal range, $\small{BMI < 18.5}$ indicates underweight, $\small{BMI \ge 24}$ indicates overweight, and $\small{BMI \ge 27}$ falls into the obesity category.

$$ BMI = \frac{weight}{height^{2}} $$

Note: In the above formula, weight is in kilograms (kg) and height is in meters (m).

"""
BMI Calculator

Version: 1.0
Author: Luo Hao
"""
height = float(input('Height (cm): '))
weight = float(input('Weight (kg): '))
bmi = weight / (height / 100) ** 2
print(f'{bmi = :.1f}')
if 18.5 <= bmi < 24:
    print('Your body shape is great!')

Tip: There’s a : at the end of the if statement, entered in English input mode. Special characters like ', ", =, (, ) in the program are all entered in English input mode. This has been mentioned before. Many beginners often overlook this point, and when they execute the code, they see a bunch of error messages. Of course, reading the error messages carefully makes it easy to discover where the problem is, but we strongly recommend that everyone switch to English input mode when writing code. This can avoid a lot of unnecessary trouble.

In the above code, after calculating and outputting the BMI, we added a branching structure. If $\small{18.5 \le BMI < 24}$ is satisfied, the program will output “Your body shape is great!”, but if the condition is not met, this output won’t happen. This is what we just mentioned - code can have different execution paths, and some code may not necessarily be executed. We gave an expression 18.5 <= bmi < 24 after the if keyword. As mentioned before, relational operations produce boolean values. If the boolean value after if is True, then the print('Your body shape is great!') statement below the if statement, indented by four spaces, will be executed. Let’s first enter several sets of data to run the above code, as shown below.

First input set:

Height (cm): 175
Weight (kg): 68
bmi = 22.2
Your body shape is great!

Second input set:

Height (cm): 175
Weight (kg): 95
bmi = 31.0

Third input set:

Height (cm): 175
Weight (kg): 50
bmi = 16.3

Only the BMI calculated from the first input set’s height and weight falls within the range of 18.5 to 24, so the if condition was triggered, outputting “Your body shape is great”. It should be noted that unlike programming languages like C, C++, and Java, Python doesn’t use curly braces to construct code blocks but uses indentation to represent code hierarchy. If multiple statements need to be executed when the if condition is met, just keep the multiple statements with the same indentation. In other words, if several consecutive lines of statements maintain the same indentation, they belong to the same code block, equivalent to being an execution unit. Indentation can use any number of spaces, but usually 4 spaces are used. We strongly recommend that you don’t use the Tab key to indent code. If you’re already used to doing this, you can set your code editor to automatically convert 1 Tab key to 4 spaces. Many code editors support this feature, and PyCharm is set this way by default. Another point: in programming languages like C, C++, and Java, 18.5 <= bmi < 24 needs to be written as two conditions bmi >= 18.5 and bmi < 24, then connect the two conditions with an AND operator. Python can also do this. For example, the if statement just now can also be written as if bmi >= 18.5 and bmi < 24:, but there’s no need. Isn’t if 18.5 <= bmi < 24: much nicer? Below is Java code doing the same thing. It doesn’t matter if you can’t read Java code; just feel the difference between it and Python syntax.

import java.util.Scanner;

class Test {

    public static void main(String[] args) {
        try (Scanner sc = new Scanner(System.in)) {
            System.out.print("Height (cm): ");
            double height = sc.nextDouble();
            System.out.print("Weight (kg): ");
            double weight = sc.nextDouble();
            double bmi = weight / Math.pow(height / 100, 2);
            System.out.printf("bmi = %.1f\n", bmi);
            if (bmi >= 18.5 && bmi < 24) {
                System.out.println("Your body shape is great!");
            }
        }
    }
}

Note: The above is the Java code corresponding to BMI Calculator version 1.0. Many people like Python not without reason - it can usually solve the same problems with less code.

Next, let’s slightly modify the above code. When BMI doesn’t satisfy $\small{18.5 \le BMI < 24}$, we’ll also give detailed prompt information. We can add an else code block after the if code block, which will execute when the condition given by the if statement is not met, as shown below. Obviously, only one of print('Your body shape is great!') under if and print('Your body shape is not standard!') under else will be executed.

"""
BMI Calculator

Version: 1.1
Author: Luo Hao
"""
height = float(input('Height (cm): '))
weight = float(input('Weight (kg): '))
bmi = weight / (height / 100) ** 2
print(f'{bmi = :.1f}')
if 18.5 <= bmi < 24:
    print('Your body shape is great!')
else:
    print('Your body shape is not standard!')

If we want to give more accurate prompt information, we can modify the above code again, adding more branches to the branching structure through the elif keyword, as shown below.

"""
BMI Calculator

Version: 1.2
Author: Luo Hao
"""
height = float(input('Height (cm): '))
weight = float(input('Weight (kg): '))
bmi = weight / (height / 100) ** 2
print(f'{bmi = :.1f}')
if bmi < 18.5:
    print('You are underweight!')
elif bmi < 24:
    print('Your body shape is great!')
elif bmi < 27:
    print('You are overweight!')
elif bmi < 30:
    print('You are mildly obese!')
elif bmi < 35:
    print('You are moderately obese!')
else:
    print('You are severely obese!')

Let’s test the above code with the same three sets of data to see what results we get.

First input set:

Height (cm): 175
Weight (kg): 68
bmi = 22.2
Your body shape is great!

Second input set:

Height (cm): 175
Weight (kg): 95
bmi = 31.0
You are moderately obese!

Third input set:

Height (cm): 175
Weight (kg): 50
bmi = 16.3
You are underweight!

Constructing Branching Structures with match and case

Python 3.10 added a new way to construct branching structures. By using the match and case keywords, we can easily construct multi-branch structures. Python’s official documentation introduced this new syntax with an example of HTTP response status code recognition (outputting corresponding descriptions based on HTTP response status), which is very interesting. If you don’t know what HTTP response status codes are, you can check out the documentation on MDN. Below we’ll slightly modify the example from the official documentation to explain this syntax. First, let’s look at code implemented with if-else structure.

status_code = int(input('Response status code: '))
if status_code == 400:
    description = 'Bad Request'
elif status_code == 401:
    description = 'Unauthorized'
elif status_code == 403:
    description = 'Forbidden'
elif status_code == 404:
    description = 'Not Found'
elif status_code == 405:
    description = 'Method Not Allowed'
elif status_code == 418:
    description = 'I am a teapot'
elif status_code == 429:
    description = 'Too many requests'
else:
    description = 'Unknown status Code'
print('Status code description:', description)

Output:

Response status code: 403
Status code description: Forbidden

Below is code implemented using match-case syntax. Although it has exactly the same function, the code appears simpler and more elegant.

status_code = int(input('Response status code: '))
match status_code:
    case 400: description = 'Bad Request'
    case 401: description = 'Unauthorized'
    case 403: description = 'Forbidden'
    case 404: description = 'Not Found'
    case 405: description = 'Method Not Allowed'
    case 418: description = 'I am a teapot'
    case 429: description = 'Too many requests'
    case _: description = 'Unknown Status Code'
print('Status code description:', description)

Note: The case statement with _ acts as a wildcard in the code. If none of the previous branches match, the code comes to case _. case _ is optional; not every branching structure needs to provide a wildcard option. If case _ appears in branches, it can only be placed at the end of the branching structure. If there are other branches after it, those branches will be unreachable.

Of course, match-case syntax has many advanced uses. One pattern we can teach you first is combining patterns. For example, if we want to group response status codes 401, 403, and 404 into one branch, 400 and 405 into another branch, and keep others unchanged, the code can be written like this.

status_code = int(input('Response status code: '))
match status_code:
    case 400 | 405: description = 'Invalid Request'
    case 401 | 403 | 404: description = 'Not Allowed'
    case 418: description = 'I am a teapot'
    case 429: description = 'Too many requests'
    case _: description = 'Unknown Status Code'
print('Status code description:', description)

Output:

Response status code: 403
Status code description: Not Allowed

Applications of Branching Structures

Example 1: Piecewise Function Evaluation

Given the piecewise function shown below, input x and calculate y.

$$ y = \begin{cases} 3x - 5, & (x \gt 1) \\ x + 2, & (-1 \le x \le 1) \\ 5x + 3, & (x \lt -1) \end{cases} $$

"""
Piecewise function evaluation

Version: 1.0
Author: Luo Hao
"""
x = float(input('x = '))
if x > 1:
    y = 3 * x - 5
elif x >= -1:
    y = x + 2
else:
    y = 5 * x + 3
print(f'{y = }')

According to actual development needs, branching structures can be nested, meaning you can introduce branching structures again within the if, elif, or else code blocks of a branching structure. For example, if the if condition is met indicating the player passed the level, but after passing you still need to evaluate their performance based on the number of treasures or items they obtained (such as lighting up one, two, or three stars), then we need to construct a new branching structure inside the if. Similarly, we can construct new branches in elif and else. We call this nested branching structures. Following this logic, the piecewise function evaluation above can also be implemented with the following code.

"""
Piecewise function evaluation

Version: 1.1
Author: Luo Hao
"""
x = float(input('x = '))
if x > 1:
    y = 3 * x - 5
else:
    if x >= -1:
        y = x + 2
    else:
        y = 5 * x + 3
print(f'{y = }')

Note: You can feel and judge for yourself which of the above two writing styles is better. In the “Zen of Python”, there’s a saying: “Flat is better than nested”. The reason “flat” code is considered better is that if code has many nested levels, it will seriously affect code readability. So, I personally recommend the first writing style.

Example 2: Convert Percentage Grades to Letter Grades

Requirement: If the input score is 90 or above (including 90), output A; if the input score is between 80 and 90 (not including 90), output B; if the input score is between 70 and 80 (not including 80), output C; if the input score is between 60 and 70 (not including 70), output D; if the input score is below 60, output E.

"""
Convert percentage grades to letter grades

Version: 1.0
Author: Luo Hao
"""
score = float(input('Enter score: '))
if score >= 90:
    grade = 'A'
elif score >= 80:
    grade = 'B'
elif score >= 70:
    grade = 'C'
elif score >= 60:
    grade = 'D'
else:
    grade = 'E'
print(f'{grade = }')

Example 3: Calculate Triangle Perimeter and Area

Requirement: Input the lengths of three sides. If they can form a triangle, calculate the perimeter and area; otherwise, give a prompt “Cannot form a triangle”.

"""
Calculate triangle perimeter and area

Version: 1.0
Author: Luo Hao
"""
a = float(input('a = '))
b = float(input('b = '))
c = float(input('c = '))
if a + b > c and a + c > b and b + c > a:
    perimeter = a + b + c
    print(f'Perimeter: {perimeter}')
    s = perimeter / 2
    area = (s * (s - a) * (s - b) * (s - c)) ** 0.5
    print(f'Area: {area}')
else:
    print('Cannot form a triangle')

Note: The if condition above means the sum of any two sides is greater than the third side, which is a necessary condition for forming a triangle. When this condition is met, we need to calculate and output the perimeter and area, so the five statements below if all maintain the same indentation. They are a unit, and as long as the if condition is met, they will all be executed. This is the concept of code blocks we mentioned earlier. Additionally, the formula for calculating triangle area above is called Heron’s formula. Assuming there’s a triangle with side lengths $\small{a}$, $\small{b}$, $\small{c}$, then the triangle’s area $\small{A}$ can be obtained from the formula $\small{A = \sqrt{s(s-a)(s-b)(s-c)}}$, where $s=\frac{a + b + c}{2}$ represents the semi-perimeter.

Summary

Having learned branching structures and loop structures in Python, we can solve many practical problems. This lesson has helped you master methods for constructing branching structures. In the next lesson, we’ll introduce loop structures. After completing these two lessons, you’ll definitely find that you can write a lot of interesting code. Keep it up!