QTM 151 - Introduction to Statistical Computing II

Lecture 05 - Conditional Statements

Danilo Freire

Emory University

Hello again! 😊

Today’s class 📚

Today’s class

Today we will:

  • Understand how to use conditional statements in Python
  • Explore the if, elif, and else statements
  • Practice writing conditional statements in Python
  • Learn how to combine conditions using logical operators
  • Understand how to use nested if statements
  • Learn more about lists and how to create them

Let’s get started! 🚀

Flow control: conditional statements 🐍

Flow control: conditional statements

If, elif, else

  • Conditional statements are used to make decisions in programming
  • The if statement is used to execute a block of code if a condition is True
  • The elif statement is used to execute a block of code if the first condition is False and the second condition is True
  • The else statement is used to execute a block of code if all other conditions are False
  • We use this a lot in data cleaning or data analysis to filter out data!

If statements

  • Test expression
    • We type “if” followed by a logical condition and the “:” symbol.
    • The “:” says: run the following command
  • Body of expression
    • The “body” of the “if” statement needs to indented with four spaces
    • You can indent text by pressing the “tab” button in your keyboard.
  • If the condition is true, a message will appear.
  • If the condition is false, then nothing happens
  • The if statement syntax is as follows:
if condition:
    Body
  • Another example:
# We start by defining a string
any_questions = "yes"

if any_questions == "yes":
    print("Need to give more explanations")
Need to give more explanations

If/else statements

When you have two possible outcomes

  • The else statement is used to execute a block of code if the condition is False
  • The else statement is always used in conjunction with the if statement
  • The else statement syntax is as follows:
if condition:
    Body
else:
    Body
  • For example, let’s say you want to know whether someone can vote in the US
    • First, the person needs to be a national
    • Second, the person needs to be at least 18 years old
age = 22
national = False

if national & (age >= 18):
    print("This person can vote in the US")
else:
    print("This person cannot vote in the US")
This person cannot vote in the US

Another example

# Here we want to change the colour of the histogram 
# based on a conditional statement
import numpy as np
import matplotlib.pyplot as plt

is_graph_red = False
how_many_classes = np.array([7,1,2,3,3,3,4,5,6])

if is_graph_red:
    plt.hist(x = how_many_classes, color="red")
    plt.title("Count of students in each category")
    plt.xlabel("How many classes are you taking?")
    plt.show() 
else:
    plt.hist(x = how_many_classes, color="purple")
    plt.title("Count of students in each category")
    plt.xlabel("How many classes are you taking?")
    plt.show()
  • The histogram will be red if is_graph_red is True, and purple otherwise

Try it out! 🚀

What happens if … ? Try the following:

  • Rerun the above code but change the value of is_graph_red.
  • What happens if you set a non-boolean value of is_graph_red?
  • Don’t include :
  • Don’t indent the body of the if Appendix 04

If/elif/else statements

  • The last conditional statement is the elif statement
  • The elif statement is used to execute a block of code if the first condition is False and the second condition is True
  • It is just like another if statement, but it is used when you have more than two possible outcomes
  • The elif statement syntax is as follows:
if condition:
    Body
elif condition:
    Body
else:
    Body

Example

years_in_program = 1

if years_in_program == 1:
    print("This student is a freshman")
elif years_in_program == 2:
    print("This student is a sophomore")
elif years_in_program == 3:
    print("This student is a junior")
else:
    print("This student is a senior")
This student is a freshman

Combining conditions and logical operators 🤓

Combining conditions and logical operators

  • You can combine conditions using logical operators too!
  • Remember what we learned about logical operators?
  • The logical operators are:
    • & (and)
    • | (or)
    • ~ (not)
    • == (equal)
    • != (not equal)
    • > (greater than), < (less than), etc
  • For example, let’s say you want to know whether someone is a freshman or a sophomore
years_in_program = 1
if years_in_program == 1 or years_in_program == 2:
    print("This student is a freshman or a sophomore")
else:
    print("This student is not a freshman or a sophomore")
This student is a freshman or a sophomore

Combining conditions and logical operators

  • You can combine several conditions at once
  • It is good practice to use parentheses to group conditions, so that the code is easier to read
  • For example, let’s say you want to know if a student is eligible for a program discount
  • The student is eligible if:
    • They are under 25 years old and a student
    • Or they have a scholarship
age = 22
is_student = True
has_scholarship = False

# Eligible if (under 25 AND a student) OR 
# if has a scholarship
if (age < 25 and is_student) or has_scholarship:
    print("Eligible for program discount.")
else:
    print("Not eligible for program discount.")
Eligible for program discount.

Nested if statements 🪆

Nested if statements

When one condition depends on another

  • An if statement can be placed inside another if (or elif/else) statement. This is called nesting.
  • Used for more granular decision-making where one check depends on the outcome of a previous one.
  • Caution: Nesting too deeply (more than 2-3 levels) can make code hard to read and debug.
  • Syntax example:
if condition1:
    # Outer if body
    print("Condition 1 is True")
    if condition2:
        # Inner if body 
        # Executes if condition1 AND condition2 are True
        print("Condition 2 is also True")
    else:
        # Inner else body
        # Executes if condition1 is True BUT condition2 is False
        print("Condition 2 is False")
else:
    # Outer else body
    print("Condition 1 is False")

The path is like a tree: 1. Check condition1 (outer if). 2. If True, check condition2 (inner if). 3. If False, go to the inner else. 4. If condition1 is False, go to the outer else.

Nested if example: ticket pricing

Scenario: Ticket price depends on age group, and then on the day of the week for adults.

age = 30
day = "Saturday" # Try "Monday"
price = 0

if age < 18: # Child
    price = 10
    category = "Child"
elif age >= 18 and age < 65: # Adult
    category = "Adult"
    if day == "Saturday" or day == "Sunday":
        price = 20 # Weekend adult price
    else:
        price = 15 # Weekday adult price
else: # Senior
    price = 12
    category = "Senior"

print(f"Category: {category}, Day: {day}, Price: ${price}")
Category: Adult, Day: Saturday, Price: $20

Try it yourself! 🧠

Modify the ticket pricing example:

  • Add a “student” category: if age is between 18 and 25 (inclusive) AND an assumed variable is_student = True, their price is always $13. This should take precedence over the standard adult pricing.
  • Appendix 05

Conditional expressions (ternary operator) ✨

Conditional expressions (ternary operator)

A concise way to assign based on condition

  • Python offers a more compact way to write simple if/else statements that assign a value to a variable or return a value. This is known as a conditional expression or a “ternary operator”.
  • It’s a one-liner!
    • Syntax: value_if_true if condition else value_if_false
    • This expression evaluates the condition:
      • If True, the whole expression evaluates to value_if_true.
      • If False, the whole expression evaluates to value_if_false.

Conditional expression examples

Standard if/else for assignment:

age = 20
status = ""
if age >= 18:
    status = "Adult"
else:
    status = "Minor"
print(f"Status (standard if/else): {status}")
Status (standard if/else): Adult

Using Conditional Expression:

age = 20 # Same age
status_ternary = "Adult" if age >= 18 else "Minor"
print(f"Status (ternary operator): {status_ternary}")
Status (ternary operator): Adult

Another Example (Setting a discount):

is_member = True
# is_member = False # Try this
base_price = 100

discount_rate = 0.10 if is_member else 0.0
final_price = base_price * (1 - discount_rate)

print(f"Is member: {is_member}")
print(f"Discount rate: {discount_rate*100}%")
print(f"Final price: ${final_price}")
Is member: True
Discount rate: 10.0%
Final price: $90.0

Pitfall: Order of elif Statements

Specificity Matters

  • Conditions in an if...elif...else chain are evaluated in order from top to bottom
  • The first condition that evaluates to True will have its block of code executed, and the rest of the chain is skipped
  • Therefore, you should generally place more specific conditions before more general ones

Problematic Order (Grading):

score = 95
grade = ""
# This is problematic because score >= 60 is true for 95
if score >= 60: 
    grade = "D" 
elif score >= 70:
    grade = "C"
elif score >= 80:
    grade = "B"
elif score >= 90:
    grade = "A" # This will never be reached if score is >= 60
else:
    grade = "F"
print(f"Score: {score}, Problematic Grade: {grade}")
Score: 95, Problematic Grade: D

Correct Order (Grading):

score = 95 # Same score
grade = ""
# More specific conditions first
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"Score: {score}, Correct Grade: {grade}")
Score: 95, Correct Grade: A

A bit more about lists in Python 📝

Lists with blank elements

How to create an empty list?

  • You can create an empty list using the None object
  • None is a special object in Python that represents the absence of a value
  • The type of None is NoneType. It is the only instance of this type
  • None is often used to represent missing values or, in our case today, placeholders
  • Please note that None is not the same as 0, False, or an empty string ''
  • You should also not use quotes with None, as it is not a string
  • Let’s see how to create an empty list using None:
# Simply type "None"
list_answers = [None,None,None]
print(list_answers)
[None, None, None]

Note

You can read more about None at https://realpython.com/null-in-python/.

Assigning or replacing values to lists

  • You can assign or replace values in a list using the index of the element
  • The index of a list starts at 0
  • We use the following syntax:
# What's the name of your hometown?
list_answers[0] = "Nashville"

print(list_answers)
['Nashville', None, None]

Appending values to lists

The list.append() method

  • You can add elements to a list using the list.append() command
  • This command adds the element to the end of the list
  • You can only add one element at a time
# We can start an empty list with []
# Use the command "new_list.append(item)" with the function "append()"
# and an arbitrary value of "item"

new_list = []
new_list.append("Nashville")
new_list.append("Bogota")
# new_list.append()

print(new_list)
['Nashville', 'Bogota']

Extending lists

The list.extend() method

  • You can also add multiple elements to a list using the list.extend() command
  • Here you can add multiple elements at once
my_list = ["Nashville", "Bogota"]
my_list.extend(["Atlanta", "São Paulo", "Rio de Janeiro"])
print(my_list)
['Nashville', 'Bogota', 'Atlanta', 'São Paulo', 'Rio de Janeiro']

Lists with repetition 🔄

Lists with repeated values

  • You can create a list with repeated values using the * operator
  • The syntax is very simple and is as follows:
    • list = [value] * n
# Check our previous list
list_answers
['Nashville', None, None]
  • Now, let’s create a list with repeated values
    • Repeat a single value 30 times
    • Repeat a list 4 times
    • Repeat 8 null values
# Repeat a single value 30 times
list_two_rep = [7] * 30
print(list_two_rep)
[7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7]
# Repeat a list 4 times
list_answers_rep = list_answers * 4 
print(list_answers_rep)
['Nashville', None, None, 'Nashville', None, None, 'Nashville', None, None, 'Nashville', None, None]
# Repeat 8 null values
list_none_rep = [None] * 8 
print(list_none_rep)
[None, None, None, None, None, None, None, None]

Common pitfalls with lists

  • A common mistake is to confuse lists and np.array objects when doing operations
  • Lists are not arrays, and you cannot perform operations like addition or multiplication
  • You can only concatenate lists using the + operator
# When you multipy a list times a number you repeat the list
list_a = [1,2,3]
print(list_a * 4)
[1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3]
# When you add two lists, you concatenate them
list_b = [4,5,6]
print(list_a + list_b)
[1, 2, 3, 4, 5, 6]
# When you multipy an array times a number, you multiply each element
import numpy as np

vec_a = np.array(list_a)
print(vec_a * 4)
[ 4  8 12]
  • Is that clear? 🤓

Counting the length of a list

  • You can count the length of a list using the len() function
# Count the length of the list
print(len(list_answers))
3
print(len(list_two_rep))
30
print(len(list_answers_rep))
12

Try it yourself! 😊

  • Create an empty list called “list_personal”
  • Add two more values using “.append”
  • Find the total length of the list
  • Change the last value to “Last element” using the index
  • Appendix 06

And that’s it for today! 🎉

Questions? 🤔

Try this at home! 🏠

  • Practice writing conditional statements in Python
  • Create a variable called “points” with a value between 0 and 100
  • Write a flow with “if”, “elif” and “else” to assign the letter grade
  • In the body, store the output in a new variable called “letter_grade”
  • Print the letter grade at the end

Important

Check that it works by trying different values of “points”!

Thank you very much and see you next time! 🙏

Appendix 01

colors = ["red","green","yellow","orange"]

"red" in colors
True

Back to the main text

Appendix 02

x = -1

x**2 + 2*x + 1 == 0
True

Back to the main text

Appendix 03

  • Whether age (age = 31) is strictly less than 20, or greater than 30
  • Not in the age range 25-27
age = 31

(age < 20) | (age > 30) 
True
(age < 25) | (age > 27)
True

The second answer uses | because & evaluates both statements at the same time, and one cannot be less than 25 and greater than 27 at the same time. Therefore, it must be |.

Back to the main text

Appendix 04

What happens if is_graph_red is set to True?

is_graph_red = True
how_many_classes = np.array([7,1,2,3,3,3,4,5,6])

if is_graph_red:
    plt.hist(x = how_many_classes, color="red")
    plt.title("Count of students in each category")
    plt.xlabel("How many classes are you taking?")
    plt.show() 
else:
    plt.hist(x = how_many_classes, color="purple")
    plt.title("Count of students in each category")
    plt.xlabel("How many classes are you taking?")
    plt.show()

Back to the main text

Appendix 04 - Continued

What happens if you set a non-boolean value of is_graph_red?

It is considered True if it is not zero

is_graph_red = 39
how_many_classes = np.array([7,1,2,3,3,3,4,5,6])

if is_graph_red:
    plt.hist(x = how_many_classes, color="red")
    plt.title("Count of students in each category")
    plt.xlabel("How many classes are you taking?")
    plt.show() 
else:
    plt.hist(x = how_many_classes, color="purple")
    plt.title("Count of students in each category")
    plt.xlabel("How many classes are you taking?")
    plt.show()

Back to the main text

Appendix 04 - Continued

What happens if you don’t include :?

You will get a syntax error

is_graph_red = True
how_many_classes = np.array([7,1,2,3,3,3,4,5,6])

if is_graph_red
    plt.hist(x = how_many_classes, color="red")
    plt.title("Count of students in each category")
    plt.xlabel("How many classes are you taking?")
    plt.show() 
else:
    plt.hist(x = how_many_classes, color="purple")
    plt.title("Count of students in each category")
    plt.xlabel("How many classes are you taking?")
    plt.show()

Back to the main text

Appendix 04 - Continued

What happens if you don’t indent the body of the if?

You will get another syntax error

is_graph_red = True
how_many_classes = np.array([7,1,2,3,3,3,4,5,6])

if is_graph_red:
plt.hist(x = how_many_classes, color="red")
plt.title("Count of students in each category")
plt.xlabel("How many classes are you taking?")
plt.show() 
else:
plt.hist(x = how_many_classes, color="purple")
plt.title("Count of students in each category")
plt.xlabel("How many classes are you taking?")
plt.show()

Back to the main text

Appendix 05

age = 22
is_student = True
day = "Saturday" # Try "Monday"
price = 0

if age < 18: # Child
    price = 10
    category = "Child"
elif (age >= 18 and age <= 25) and is_student: # Student
    price = 13
    category = "Student"
elif age >= 18 and age < 65: # Adult
    category = "Adult"
    if day == "Saturday" or day == "Sunday":
        price = 20 #
elif age >= 18 and age < 65: # Adult
    category = "Adult"
    if day == "Saturday" or day == "Sunday":
        price = 20 # Weekend adult price
    else:
        price = 15 # Weekday adult price
else: # Senior
    price = 12
    category = "Senior"

print(f"Category: {category}, Day: {day}, Price: ${price}")
Category: Student, Day: Saturday, Price: $13

Back to the main text

Appendix 06

  • Create an empty list called “list_personal”
  • Add two more values using “.append”
  • Find the total length of the list
  • Change the last value to “Last element”
list_personal = []

list_personal.append("First element")
list_personal.append("Second element")

print(len(list_personal))
2
# Here I used the index -1 to change the last element
# You could also use the index 1
list_personal[-1] = "Last element" 
print(list_personal)
['First element', 'Last element']
  • Did you get it right? 🤓

Appendix 06 - Continued

  • Here is another way to solve the exercise, now using list.extend() and [1] index
list_personal = []

list_personal.extend(["First element", "Second element"])
print(list_personal)
print(len(list_personal))
['First element', 'Second element']
2
list_personal[1] = "Last element"
print(list_personal)
['First element', 'Last element']

Back to the main text