2.1 Expressions and Variables¶
In this note, I introduce the concept of variables - how to visualize them, how to determine its value, parallel assignment, and more.
Get back to 2. Expressions, Variables, and Functions or toc CS61A
Anatomy of Variable Assignmnet¶
In future notes, you'll be given complicated expressions that will be assigned to a variable, so you'll have to know how to break it down in to something systematic. The anatomy of variable assignment is the following:
\(\(\text{<var\_name> = <expression>}\)\)
where the \(\text{<var\_name>}\) is any name you give, such as x, y, first, last, etc., and \(\text{<expression>}\) is anything that evaluates to something. A proper variable name must have the following attributes:
1. It cannot start with a number, but numbers can appear in the variable name. So 3badname is not a valid variable name, but g0odname3 is valid.
2. There may not be any spaces in the variable name. For example, first num is not valid, but first_num is valid.
There are also conventions, which you don't necessarily have to follow, but in Python, the convention is to name the variables with snake case.
- Snake case refers to the style of writing in which each space is replaced by an underscore \((\_)\) character, and the first letter of each word is written in lowercase. For example,
snake_caseis written in snake case.
How to Determing a Variable's Value¶
You might see later in the course that variables can be assigned to many different things instead of integers, strings, booleans, etc. In fact, we will learn how to assign functions to variable names in [[4. Higher Order Functions]]. Because of this, I think a systematic way to view variable assignment is important to know.
Variable Assignment:
- Evaluate the right-hand side of the statement first
- Once you have the value, assign it to the name on the left hand side
For example
x = mul(2, 3, 5) + mul(4, add(2, 3))
One way I like to say this statement in my mind is "the variable x is being assigned the value that is the result of mul(2, 3, 5) + mul(4, add(2, 3))". More generally, "the variable named \(\text{<left\_hand\_side>}\) is being assigned the value \(\text{<right\_hand\_side>}\)". Right now, it seems like all of this is super unnecessary, but when we get to later parts in the course, having this phrase in your mind will be helpful.
Examples with Variable Assignment¶
Let's look at the example below
x = 5
y = x
y = y + 3
x = y + x
print(x)
Our goal is to determine the value of x which will be printed out to the terminal. Here are two key parts about variable assignment:
- Values are copied, however it takes the snapshot of that value at that line as it is currently defined.
- Variables can be assigned based on the variable itself. Again you must view the assignment as "the value on the right side, once fully evaluated, will be assigned ot the left side."
Let's see how these two ideas play a role in this example. I'll go through it line-by-line.
Line 1: x = 5. We will keep that value stored in x until changed. So x is bound to the value 5.
Line 2: y = x. Here, we don't bind y to the value x. We instead bind y to the value that the variable x contains (slightly different wording), Therefore y is bound to 5.
Line 3: y = y + 3. Remember the order of execution: Let's first evaluate the right side completely. Ok, that means it is y + 3 which is 5 + 3 = 8. Therefore, the value y is being bound to the value 8.
Line 4: x = y + x. Same thing, what is the right side? We ask what the values of y and x are on that line, and we see y is 8 and x is 5. Therefore, 8 + 5 = 13, and that is what is being bound to x. x is bound to the value 13.
Line 5: So we print out x, but that means we print out 13.
Things to takeaway from the example:
- The line
y = y + 1is a super common thing in computer science. Notice that this statement doesn't make any sense in mathematics, but it makes perfect sense in computer science. In fact, we use it so much, there are shorthands for this statement:y += 1is equivalent toy = y + 1, andyt += 10is equivalent tot = t + 10. - Notice that we reveal the value that is contained in the variable when we reference it on the right side. However, we will quickly see in future notes like [[4. Higher Order Functions]] and [[5. Environment Diagrams]] that they will appear in very tricky ways through the idea of pointers.
Strings¶
Strings are also things we can apply operations to, except they are handled slightly different than integers. We will learn future operations on strings like slicing in [[7. Sequences]], but for now, you should know the following operations on strings.
- Adding two strings together will concatenate them together. In other words, you just join them together.
"hello" + "world" = "helloworld". See how spaces really matter in concatenation. - Multiplying a string by a number will replicate the string. Just like how multiplication is just repeated addition, it follows exactly here.
3 * "a" = "aaa".
Another Variable Example¶
I will be working through this example now
x = "abc"
y = "def"
z = 1
z += 1
x = x + y
z = z * x
print(z)
We are tasked with finding the result that gets printed, which is the variable z in the state of line 7.
Line 1: x is bound to the string "abc"
Line 2: y is bound to the string "def"
Line 3: z is bound to the integer 1
Line 4: z is bound to the value z + 1 = 1 + 1 = 2. z is bound to 2 now.
Line 5: x is bound to the value x + y. Since x and y are strings, we concatenate them together to get the result "abcdef". Now that the right side is evaluated, it is bound to the variable named x.
Line 6: Let's evaluate the right side. z is currently 2, and x is currently "abcdef". If we replace the values on the right side, we get the expression 2 * "abcdef", which results in "abcdefabcdef". Now that the right side is evaluated completely, we will bind it to the variable name z. z is now bound to the string "abcdefabcdef".
Line 7: z is bound to the string "abcdefabcdef" so this is what gets printed.
Quick Note on Errors and the str Function¶
We now know two different types of variables, integers and strings. Now we know that multiplication of integers and strings exist, and addition of two strings exist, but an operation like an integer plus a string doesn't make sense. Because of that if you were to put a value like 1 + "hi" will lead the Python interpreter to give you an error, and the error message that pops up deals with something like TypeError: unsupported operator types(s) for +: 'int' and 'str'. When you progress to know different variable types, you may face an error like this. This means you tried to operate on two types where its operation is not defined.
Maybe you wished that it would do something like 1 + "hi" = "1hi". That seems reasonable. We can actually do such a thing by calling the str function on the integer. str will try to convert whatever gets passed in into a string, so x = str(1) results in x being bound to "1" rather than 1. Now since it is a string type, we can add together two strings. Therefore, to do what we originally wanted, we need str(1) + "hi" to get "1hi".
There is also an int function that tries to convert the thing you pass into it into an int type. For example int("5") returns the integer 5, but str(5) returns the string "5". Note the difference between these two.
Parallel Assignment¶
There is a nice shorthand that allows us to define more than one variable in the same line, and this is known as parallel assignment. Here is a quick example
x, y = 1, 2
Here, x is bound to 1, and y is bound to 2. Notice that the order of the variable assignment matters. We also can do as many assignments in one line, such as
a, b, c, d, e = 1, 2, 3, 4, 5
print(a, b, c, d, e)
Where we will print 1 2 3 4 5.
This brings another problem: how does this deal with our idea of variable assignment, for example
n = 10
m = 5
n, m = n - m, n + m
which happens first? If the first set happened first, then n is now bound to 5, and then since n is now 5, m would be bound to 10. If m was bound first, m would be 15 and n would be -5. So which one is it?
It is actually neither. They happen at the same time. Remember our phrase is to figure out what the right side is first, and then once we know everything about the right side, then we do assignment. In our case here if I were to figure out the values of the right side, they would be 5 and 15. Finally assign these values to n and m, so n is bound to 5 and m is bound fo 15. You can test your understanding of this section by figuring out the values of a, b, c, and d below
a = 1
b, c = a + 2, a - 2
d = b + a
a, b = d, d + c
b = d - c
Test this out in your terminal to see if you are correct!
Summary¶
In this note, we looked at how to deal with more complicated Python programs with variables. Variables are important because when we make more complicated programs, we would rather work in the general case of an arbitrary x value rather than a specific value. Variables are assigned with figuring out what the right side is first before you assign it to the variable named on the left. Parallel assignment follows this rule as well, however you can do multiple values in one line.
Next note: 2.2 Defining and Using Functions Get back to 2. Expressions, Variables, and Functions or toc CS61A