Preparation#

A note about the reading material and preparation exercises. The reading material and preparation exercises both cover the same programming concepts but with slightly different approaches. The reading material aims to explain the concepts, while we designed the preparation exercises for you to try things out. You can decide which to start with. Some prefer reading the chapters from the book first to feel more prepared for the exercises, while others may dive into the exercises and use the book to clarify things as needed. If you’re finding programming challenging, you might benefit from reading the chapters first, then doing the exercises, and returning to the book for clarification.

Reading material#

The content of this week corresponds to Think Python (TP), Chapter 2 Variables and Statements supplemented with the first three sections of Chapter 5 Conditionals and Recursion. In Chapter 2, you can skip the part about the state diagram, as we do not use state diagrams in our course.

You can also find the content of this week in the lecture notes for the CS50 course, Lecture 0 Functions, Variables. We cover sections on integers, floats (two sections), and strings (two sections).

Copy-and-run preparation exercises#

Explanation of the Copy-and-Run exercises. In Copy-and-Run (CaR) exercises, you’ll be provided with a few lines of code that you should copy into your Python environment and run. You will then observe the outcome, which is usually a printed result. In some exercises, you’ll be asked to modify parts of the code to see how it changes the output. The goal is to understand the connection between the code and the resulting output. These exercises are designed for you to complete on your own, at home, with the code already provided.

Recap#

In last week’s exercises, you executed Python scripts involving numbers and text. This week’s reading material provided definitions of basic terms like variables, data types, and operators. Here is a quick summary:

  • Variables are used to store values. A variable has a name and a value of a certain type. The name is used to access the variable. The value is the actual content of the variable, and the type indicates what kind of variable it is.

  • For now, you have been using three types of variables: int, float, and string.

  • You can perform operations on variables using operators and functions.

  • You can use the print() function to display the value of a variable.

Prep 2.1: The anatomy of an assignment statement#

Consider the following code. Try to predict what will happen when you run it. Then run it and observe what happens.

side_length = 4
surface_area = 6 * side_length ** 2
volume = side_length ** 3

An assignment statement has the following structure:

  • On the left, a variable name.

  • In the middle, the assignment operator =.

  • On the right, a value or an expression which Python evaluates to a value.

The behavior of the assignment operator:

  • If the variable does not exist, it is created with the assigned value.

  • The value and type of the variable are determined from the expression.

  • Nothing is printed when an assignment statement is executed.

Looking at the example above, identify all assignment statements in the code. For each assignment statement, identify the variable name and the value or expression on the right side. Confirm that nothing is printed when the code is executed.

Add the following lines to the code above. Try to predict what will happen when you run it. Then run the code again and observe the printed outputs.

print(side_length)
print(surface_area)
print(volume)

Prep 2.2: Variable types#

Run the following code and observe what happens.

a = "42"
print(a)
print(type(a))

Python uses different types to represent different sorts of data. You can check the type of a variable using the type() function. Change the first line of the code above to each of the following lines. Try to predict the type of the variable a in each case. Then run the code and confirm your predictions.

a = 42
a = 42.0
a = float(42)
a = int("42")
a = str(42.0)

Python will determine the type of a variable based on the way the value is written or computed. The last three examples show you that you can use int(), float(), and str() to specify a type of a variable.

Prep 2.3: Printing multiple things at once#

Run the following code and observe what happens.

first_part = "Hello"
second_part = "World"
print(first_part, second_part)  

Some Python functions, such as the print function, accept multiple arguments. Arguments are the values or variables passed to the function when it is called. In the example above, the arguments passed to the print function are the variables first_part and second_part with the values "Hello" and "World". Confirm that the two values get printed on the same line with a space between them.

Try running the following code.

a = 0.99
print(a, type(a))

This is handy, as we can use one print statement to print the value and the type of a variable on one line.

Run now this code.

number = 9000000
word = "bicycles"
print("There are", number, word, "in Beijing.")

The print function can support any number of arguments of any type. Now, try the following.

activity = "ride a bike"
print("Learning to", activity, "is straightforward!")

Change the value of the variable activity to "print in Python" and run the code again.

Prep 2.4: Reassignments#

Consider the following code. Run the code and observe what happens.

my_var = 42
print(my_var, type(my_var))
my_var = 128
print(my_var, type(my_var))

This code demonstrates that you can reassign a variable to a new value. Change the reassignment line my_var = 128 to each of the following lines. Try to predict the new value and the type of the variable my_var in each case. For each case, run the code and confirm your predictions.

my_var = 'something else'
my_var = my_var + 42
my_var = 3 * my_var
my_var = 0.5 * my_var
my_var = str(my_var)

Which of the reassignments changes only the value of the variable my_var, and which changed both the value and the type of the variable my_var? Which of the reassignments used the old value of the variable my_var in the expression on the right side of the assignment operator?

Notice that the old value of the variable my_var is lost. If you want to keep the old value, you need to store it in another variable before the reassignment. For example, if you want to change the value of a, but also keep the old value, you could do the following.

a = 14
old_a = a
a = 5

Prep 2.5: Operators on strings#

Consider the code below and try to predict what will happen when you run it. Then copy the code, run it, and observe what happens.

a = "10.0"
b = "5"
result = a + b
print(result, type(result))

This example shows that the behavior of the operator + depends on the type of the variables. When given strings, the + operator concatenates them. This shows the importance of understanding the types of variables you are working with.

Run the following code, which shows the use of + in more complex examples.

first_name = "John"
last_name = "Doe"
age = 29
full_name = first_name + " " + last_name
print(full_name)
sentence = "My name is " + full_name + " and I am " + str(age) + " years old."
print(sentence)

In the last assignment, we used str() to convert a number to a string. Let’s investigate whether the code works without that conversion. Try running this code to test it.

age = 31
short_sentence = "I am " + age + " years old."
print(short_sentence)

Read the error message and try to understand what it means. This is how Python tells you that it cannot use the + operator between a string and a number.

Now, try the following code.

age = 31
print("I am", age, "years old.")

As you can see, when you give multiple arguments to the print function, each is converted to a string before being printed. Later in the course, we will sometimes ask you to write code that prints something, and sometimes we will ask you to create a string. It is important to know the difference between the two.

Finally, copy and run the code below, which showcases the effect of using * on a string.

start = "I am " 
middle = "really "
end = "happy to see you!"

message = start + 4 * middle + end
print(message)

Prep 2.6: Boolean variables#

Boolean variables can only have one of two values: True or False. Consider the following code, run the code, and observe what happens.

bool_true = True
bool_false = False
test = "True"
print(bool_true, type(bool_true))
print(bool_false, type(bool_false))
print(test, type(test))

Notice that the last variable test is a string, despite its value being True. This is because boolean values need to be written without quotation marks.

Prep 2.7: Comparison operators#

Most often, boolean values occur as the results of comparisons. We commonly use the comparison operators ==, !=, <, >, <=, and >= which, in programming, all return boolean values.

Run the following code.

1a = 10
2b = 2
3c = 5
4result = a > b
5print(result, type(result))

In the code above, for the assignment in line 4, Python needs to evaluate (compute) the expression a > b. The result of this computation is then assigned to the variable result.

It is important to understand that the expression a > b is something that Python computes, similar to the expression a + b. The difference is that the result of the expression a > b is a boolean value, while the result of a + b is a number.

Change the expression result = a > b in the code above to each of the following lines. Run the code for each expression. Try to predict what will happen before running the code.

result = c - b >= a
result = b / a != 0
result = a + b + c >= a + b + c
result = a > c > b 

The table below summarizes the comparison operators in Python.

Operator

Meaning

Syntax

==

equal

x == y

!=

not equal

x != y

>

strictly greater than

x > y

<

strictly less than

x < y

>=

greater than or equal

x >= y

<=

less than or equal

x <= y

Every boolean variable may be treated as a numeric variable where True is equal to 1 and False is equal to 0. Therefore, everything that can be done with numbers can also be done with booleans.

With this in mind, consider the code given below and try to predict what will happen when you run it. Copy and run the code, then observe the outputs.

print((5 > 4) + (3 > 2) + (1 > 0))
print((5 > 4) > (2 > 1))

As you can see, things can easily become confusing. In the code above, the code inside all parentheses evaluates to True. The + operator implicitly casts it to an integer, thus, the whole expression in the first line is equivalent to 1 + 1 + 1, and in the second line, we have 1 > 1. This again shows that it is important to keep track of the types of variables you are working with. If you are in doubt, use print to test smaller parts of your code.

Look at the following code and try to predict the output. Copy and run the code, then observe the outputs.

lie = False
fact = True

exp1 = lie == fact
print(exp1)

exp2 = fact >= lie
print(exp2)

exp3 = fact - fact == lie - lie
print(exp3)

Now run this code.

print('Yes' == 'Yes')
print('Yes' == 'yes')
print('Yes' != 'yes')

This shows that the comparison operator == can be used to compare strings, returning True if and only if the two strings match. Try to predict the output of the following code. Copy and run the code, then observe the outputs.

fruit = "tomato"
bool1 = fruit == "cucumber"
print(bool1)
bool2 = fruit == "tomato"
print(bool2)

Prep 2.8: Logical operators#

We often need to combine multiple boolean values. Run the following code.

true_value = 18
guessed_value = 18
number_of_tries = 5
maximal_number_of_tries = 20

win = (number_of_tries <= maximal_number_of_tries) and (true_value == guessed_value)
print(win)

Now run the code with the following values:

  • guessed_value = 18, number_of_tries = 25

  • guessed_value = 19, number_of_tries = 15

  • guessed_value = 19, number_of_tries = 5

To understand what the conjunction and does in this case, let’s break down the expression on the right side of the last assignment. Add the following two lines to your code, and run the code again, with all the combinations of number_of_tries and guessed_value you have tried before.

print(number_of_tries <= maximal_number_of_tries)
print(true_value == guessed_value)

Notice that the value of win is True only when the two print statements both print True.

Now repeat all those experiments, but with the or operator instead of the and operator.

Finally, look at the code below and notice the use of the operator not in the last assignment. Run the code with all the combinations of number_of_tries and guessed_value you have tried before, and observe the values of win and keep_trying.

true_value = 18
guessed_value = 28
number_of_tries = 5
maximal_number_of_tries = 20

win = (number_of_tries <= maximal_number_of_tries) and (true_value == guessed_value)
print('win is', win)

keep_trying = (not win) and (number_of_tries < maximal_number_of_tries)
print('keep_trying is', keep_trying) 

The table below summarizes the logical operators when used with boolean values.

Operator

Result

Syntax

and

True if both operands are True, else False

x and y

or

True if either operands is True, else False

x or y

not

True if the operand is False, else False

not x

For additional practice with boolean variables, consider the examples given below. Before running the code, try to predict what will be printed. Afterwards, copy and run the code to verify your predictions.

solution_added = True
titration_done = True
report_written = False
experiment_finished = (solution_added or titration_done) and report_written
print(experiment_finished)
num1 = 10 
num2 = 100
result  = num1 > num2 or num1 > 0
print(result)
a = 2

print("Can this be " + str(a * 2 == a ** 2) + "?")

Prep 2.9: Useful numeric operators and functions#

The code below contains two operators which you may not have seen before. Run the code and observe what happens.

n = 17
a = 4

result1 = n // a
print("When using // we get", result1)

result2 = n % a
print("When using % we get:", result2)

print('Is this the same as n?', result1 * a + result2)

This example illustrates how the integer division operator // and the modulus operator % work. The integer division operator returns the whole number part of the division, discarding the remainder. The modulus operator % returns the remainder of the division.

Change the values of n and a to see how the output changes. Try at least the following combinations:

  • n = 16, a = 4

  • n = 15, a = 4

  • n = 15, a = 3

Try also running the code above with negative integers and observe the results.

To see how modulus and integer division may be used for solving programming problems, consider the following code. Try to predict the output before running the code.

days = 23
weeks = days // 7
leftover_days = days % 7
print("Number of full weeks:", weeks)  
print("Number of leftover days:", leftover_days) 

Modify the value of the variable days and observe the change in output when you run the code.

Now run the following code and confirm that it prints True only when the value of number is divisible by 100.

number = 1000
print(number % 100 == 0)

Now copy and run this code.

x = 17
y = 4

result_min = min(x, y)
print("When using min we get", result_min)

result_max = max(x, y)
print("When using max we get:", result_max)

Change the values of x and y to see how the output changes. Try using negative numbers. Try using decimal numbers as well.

The functions min and max can accept any number of arguments. Try to predict the values of the variables minimum and maximum in the following code. Then copy the code and run it to verify your assumptions.

val1 = 0.21
val2 = 0.47
val3 = -0.32
val4 = 0.69

minimum = min(val1, val2, val3, val4)
maximum = max(val1, val2, val3, val4)

print("Maximum and minimum:", maximum, minimum)

Prep 2.10: The math module#

Python has a built-in module called math that provides functions and constants useful for mathematical calculations.

We will explain what a module is later in the course. For now, you should know that a module needs to be imported before you can use it. One way to import it is shown below, with the import statement placed at the beginning of your code.

import math

Importing modules

When you import a module, Python will first look in the current directory. If you have a file called math.py in your folder, Python will import that file instead of the built-in math module. Therefore, you should avoid naming your files the same as the modules you want to import. For now, remember not to use math.py as a file name.

You can use the functions and constants from the math module by writing math., followed by the function or constant name. Here are some commonly used functions and constants:

  • math.sin(x): The sine of x, where x is in radians.

  • math.cos(x): The cosine of x, where x is in radians.

  • math.pow(x, y): The value of x raised to the power of y.

  • math.exp(x): The value of \(e\) raised to the power of x.

  • math.log(x): The natural logarithm of x.

  • math.sqrt(x): The square root of x.

  • math.ceil(x): Rounds a number x up to the nearest integer.

  • math.floor(x): Rounds a number x down to the nearest integer.

  • math.pi: The value of \(\pi\).

A more complete list can be found here: W3schools: Python math Module.

Try copying and running the following code, which uses the math module to compare the left and right sides of the equation

\[\cos(45^\circ) = \frac{\sqrt{2}}{2}\]
import math

degrees = 45
radians = math.pi * degrees / 180

print(math.cos(radians))
print(math.sqrt(2) / 2)

To see further use of the math module, download this file week2_exercise_scripts.zip.

  • Unzip the file using your preferred method.

  • Open the extracted folder named week2_exercise_scripts and open the script math_module_demo.py.

  • Run the file and observe the printed outputs.

Prep 2.11: Handling errors#

You have tried running code that contained errors. Try running the code below to remind yourself of what will happen.

good_string = "This is a good string!"
print(good_string)
bad_string = "This is a string which never ends
print(bad_string)

The code above has a syntax error. A syntax error occurs when the code is not written according to the basic rules of the programming language. When the code contains a syntax error, Python will not start executing it.

Try running this code:

good_string = "This is a good string!"
print(good_string)
bad_string = good_string + 5
print(bad_string)

Look carefully at what gets printed out. Did the first print statement execute? What about the second one? What does the error message say?

The fact that the first print statement executed shows that Python started executing the code but encountered an error during execution. When this happens, the program stops, and Python prints a message. Let’s look at some of the error messages you might encounter.

Copy and run the following code, which intentionally contains an error:

message = "Hello, world!"

prit(message)

What did the error message say? Try to understand what it means.

When Python writes NameError, it indicates that there is something in the code that it does not recognize. Python might also suggest a valid variable or function with a similar name.

When you previously tried to add a string and a number, you encountered a different error. Try running

print('a' + 5)

to see the error message again. When Python writes TypeError, it indicates that you are trying to use an operator on an incorrect type of variable. Investigate whether you get the same error message when you try running

print(5 + 'a')

Try running the following code to learn about another common error:

a = 12
b = 6
print((a + b) / (a - 2 * b))

When Python encounters an error during execution, it will always inform you about:

  • The name of the file where the error was raised.

  • The line that led to the error being raised.

  • The type of error.

  • A description of the error.

Look back at the error messages you have seen so far and try to identify these four parts in each of them.

When fixing errors, you can:

  • Inspect and check the syntax of the code line at which the exception was raised.

  • Insert print statements above the faulty line of code to check the values and types of all variables used in the line where the error occurred.

  • Ask Google or ChatGPT about the type of exception raised.

Consider the code below. Copy the code into a new Python script and run it.

Use the guidelines above to fix the errors one by one.

# First error
skill = "ComputerProgramming"
print(my_skill == "ErrorFinding")

# Second error
message = "What will the next line do"
prut(message)

# Third error
weeks = 2
result = "I have been programming for " + weeks + " weeks now!"
print(result)

print("Congratulations, you fixed all the errors!")

Self quiz#

A small note about self quizzes. Some questions allow you to enter only one answer, while others let you select multiple answers. You can distinguish between them based on the shape and behavior of the input fields where you click to select your answer.

Question 2.1#

What is the value of the variable a after you have executed the line of code a = 3 + 5 ?

Question 2.2#

What is the value of the variable a after you have executed the line a = (2 * 2) ** 2 + 2 ?

Question 2.3#

After which of these assignment statements will the variable var have the integer value 2?

Question 2.4#

After which of these assignment statements will the variable var have a string value?

Question 2.5#

What is the value of the expression str(5)?

Question 2.6#

What is the value of the expression 5 + 2 + int("10")?

Question 2.7#

What is the value of the variable i after executing the following lines of code?

i = 1
i = 2 + 2

Question 2.8#

After which of these assignment statements will the variable text have string value "It takes 2 to tango"?

Question 2.9#

What is the printed output of the code below?

congratulations = 3
text = "Hurra" * congratulations
print(text)

Question 2.10#

What is printed by the code below:

a = "3"
b = "6"
c = "1.0"
print(a + b + c)

Question 2.11#

You want the code below to prints the message The summer of 1969. Which of the values can you assign to the variable val to achieve this?

message = "The summer of " + val
print(message)

Question 2.12#

What is printed when the code given below is executed?

is_friday = True
no_more_beers = False
time_to_party = is_friday and (not no_more_beers)
print(time_to_party)

Question 2.13#

After which of the following assignment statements will the variable test have the boolean value True?

Question 2.14#

What is printed when the code given below is executed?

val = "DTU" + str(101) 
print(val, type(val))

Question 2.15#

What is printed when the code given below is executed?

num1 = 10
num2 = 20
num3 = 30
val = max(num1, num3) + min(num2, num3)
print(val)

Question 2.16#

After the code below is executed, which of the variables will have the value 5?

val1 = 15 // 3
val2 = 17 // 3
val3 = 15 % 3
val4 = 15 % 10
val5 = (25 % 5) // 1

Question 2.17#

Which of the following lines of code will correctly import the math module?

Question 2.18#

Assume you have imported the math module using import math. What is the correct syntax to compute the cosine of a using the math module?

Question 2.19#

Which lines will result in an error when executed?

Question 2.20#

Which of the following claims about errors in Python are correct?