Operators#
Learning Objectives#
- Explain conceptually what an operator is and what it does.
- List each arithmetic operator and explain what it does.
- Given an expression containing an arithmetic operator and two values, e.g. 5 / 3, predict the type of the computed value.
- List each comparison operator and explain what it does.
- Explain why = and == are different in Python.
- State that the return type of any comparison is always bool.
- List each logical operator and explain what it does.
- Write the truth table for each logical operator.
- List the membership operators.
- Understand that Python evaluates operators in order of precedence. Understand that if two operators have the same precedence, then Python goes from left to right.
- Given an expression with multiple operators of different precendence, compute the resulting value (on paper, without a computer).
- Use parentheses to modify an expression to force a particular order of evaluation.
Overview of Operators#
When we use the term operator, we are not referring to surgeons. We are not referring to people who operate machinery. And we are definitely not referring to smooth operators.
All joking aside, in programming operators are symbols that act on values. There are four types of operators you need to know about to work with data:
Arithmetic operators (for doing simple math)
Comparison operators (for comparing values)
Logical operators (for working with Boolean values)
Membership operators (for checking whether something is part of a collection)
Arithmetic operators#
When we say arithmetic, we are referring to simple math that you learned as a child. Python (and all programming languages) support simple math. The following table shows Python’s arithmetic operators.
Operator |
What it does |
Example |
Result |
---|---|---|---|
+ |
Addition |
5 + 3 |
8 |
- |
Subtraction |
4.0 - 19.3 |
-15.3 |
* |
Multiplication |
2 * 3 |
6 |
/ |
Division |
3.1415 / 2 |
1.57075 |
// |
Floor division |
7 // 2 |
3 |
% |
Mod (remainder) |
14 % 3 |
2 |
** |
Exponentiation |
3 ** 4 |
81 |
Many of these operators are simple and do not require explanation. Instead, we will explain a few subtleties that arise when working with mixed data types. We will also describe the operators that may be unfamiliar.
Working with mixed data types#
Addition, subtraction, and multiplication#
When working with the addition (+), subtraction (+), and multiplication (*) operators, if both values are integer, the result will be an integer. However, if either value is a float, the result will be a float. So:
3 + 2 # Evaluates to 5, an int.
3 - 2.0 # Evaluates to 1.0, a float.
Division and “Floor Division”#
When working with the division operator (/), Python always returns a float, even if both values are integers.
print(6 / 2)
3.0
Sometimes, you may want to divide integers and return an integer. Or you may wish to divide two floats and discard the fractional portion. Python provides the “floor division” operator for this purpose. If you execute x // y
, Python divides x
by y
and rounds down to the nearest integer. If both values are integers, it returns an integer. If one or both is a float, it returns a float.
Examples:
6 // 2 # Evaluates to 3
7.5 // 2 # Evaluates to 3.0
The mod operator (%) for remainders#
The mod operator is super useful. It returns the remainder from division. Remember when you first learned division as a kid? Before you learned about decimals, they had you use remainders. If you had to divide 93 by 10, your answer would be 9, Remainder 3. The mod operator computes the remainder.
93 % 10
3
Why is this useful, you ask? It comes in handy more often than you would think. In ACCY 575, students had a fraud case where they looked for “round number transactions”. The easiest way to do that was with the mod operator. We told them that suspiscious amounts end in 000. Let’s say I have the following financial statement line items:
Item |
Amount |
---|---|
Revenue |
$1,000,000 |
COGS |
351,035 |
SG&A |
51,234 |
To select items that end in 000, you would use the mod operator and 1000. 1000000 % 1000
would give you 0, 351035 % 1000
would give you 35, and 51234 % 1000
would give you 234. Then you might investigate any item that had an ouput of 0 after using the mod operator.
Here’s some code to do that:
revenue = 1000000
COGS = 351035
SGA = 51234
print(f'The remainder for Revenue after dividing by 1000 is {revenue % 1000}')
print(f'The remainder for COGS after dividing by 1000 is {COGS % 1000}')
print(f'The remainder for SG&A after dividing by 1000 is {SGA % 1000}')
The remainder for Revenue after dividing by 1000 is 0
The remainder for COGS after dividing by 1000 is 35
The remainder for SG&A after dividing by 1000 is 234
Exponentiation#
x ** y
raises x to the power y (i.e. \(x^y\)). x and y can be integers or floats. If both are integers, the result is an integer. Otherwise the result is a float.
Comparison operators#
Comparison operators are used to … wait for it … compare two values. We bet you never would have guessed. Some of these operators are straightforward while others will appear strange. We will briefly discuss the strange ones. Importantly, all of these operators compare two values and return a Boolean (True or False).
Operator |
What it does |
Example |
---|---|---|
> |
Greater than |
x > y |
>= |
Greater than or equal to |
x >= y |
< |
Less than |
x < y |
<= |
Less than or equal to |
x <= y |
== |
Equal to |
x == y |
!= |
Not equal to |
x != y |
The first four operators (>, >=, <, <=) are probably obvious (if not, please ask us about them!).
The Equal to (==
) and Not Equal To (!=
) operators#
You are probably wondering why comparing two numbers for equality requires two equals signs. The reason is so that Python can distinguish between assigning a value to a variable and comparing two values.
x = 5 # Create x if it doesn't exist. Set the value of x to 5.
x == 5 # Compare x to 5. If x equals 5, return True. Otherwise return False.
You will use the ==
and !=
operators very often when we start working with real datasets, so memorize them now!
Logical operators#
You will use logical operators very frequently when working with data. Logical operators are needed when you have more than one condition to test. For example, say you have a dataset of company financial statements and you want to filter it so you only have financial statements after 2010, and only for companies with revenue in excess of $1 billion. You would create two conditions and join them with an and
operator.
Python’s logical operators are:
Operator |
What it does |
Example |
---|---|---|
and |
Returns True if both conditions are true |
x and y |
or |
Returns True if either or both conditions are true |
x or y |
not |
Reverse the value. |
not x |
Logical and
operator#
As its name suggests, x and y
will only return True if both x and y are true. We can write out all the possibilities using what’s called a “truth table.”
x |
y |
x and y |
---|---|---|
False |
False |
False |
False |
True |
False |
True |
False |
False |
True |
True |
True |
Example using and
operator#
Let’s revisit the raspberry example from above. We only want to buy raspberries that are attractive (condition 1) and cheap (condition 2). In the code below, the first condition is represented as a Boolean variable; we set its value to True
. The second condition is also represented as a Boolean variable, but its value is based on a test of whether the spot price for raspberries, 3.99, is less than our threshold. This second condition will evaluate to false.
Since the first condition is true and the second is false, according to the truth table, the and
will evaluate to False and we will not buy raspberries. :-(
raspberries_look_good = True
raspberry_price = 3.99
raspberries_are_cheap = raspberry_price < 2.99
if raspberries_look_good and raspberries_are_cheap:
print("I'm buying raspberries.")
else:
print('No raspberries today.')
No raspberries today.
Logical or
operator#
As its name suggests, x or y
will only return True if either x is true, y is true, or both x and y are true. The truth table for or
is:
x |
y |
x or y |
---|---|---|
False |
False |
False |
False |
True |
True |
True |
False |
True |
True |
True |
True |
Example using or
operator#
Let’s repeat the raspberry example. We will change the and
to or
. Since the first condition is true, the or
will evaluate to true and we will buy raspberries. :-)
raspberries_look_good = True
raspberry_price = 3.99
raspberries_are_cheap = raspberry_price < 2.99
# On the next line, we changed "and" to "or".
if raspberries_look_good or raspberries_are_cheap:
print("I'm buying raspberries.")
else:
print('No raspberries today.')
I'm buying raspberries.
Logical not
operator#
The not
operator reverses the value you give it. The truth table for not
is:
x |
not x |
---|---|
False |
True |
False |
True |
The not
operator is typically used when you have a variable and you want to reverse it. You can often write your logic without using the not
operator, but sometimes it makes your code easier to understand. Here’s an example:
raspberries_look_good = False
if not raspberries_look_good:
print("Complain to manager!")
Complain to manager!
In this example, we want to test whether the variable is false, and the not
operator makes that very easy.
We could rewrite the above code without using not
, but it’s ugly and confusing.
raspberries_look_good = False
if raspberries_look_good:
pass # This command tells Python to do nothing. You do not need to know it for this class.
else:
print("Complain to manager!")
Complain to manager!
We could also explicitly test whether the condition is false. This isn’t as complicated as the previous example, but we still maintain that using the not
operator is the simplest way to write this code.
raspberries_look_good = False
if raspberries_look_good == False:
print("Complain to manager!")
Complain to manager!
Membership operators#
Membership operators test whether something is part of a collection, such as a list. We will learn about lists and other collections later in this unit.
Operator |
What it does |
Example |
---|---|---|
in |
Returns true if x is in the collection y |
x in y |
not in |
Returns true if x is not in the collection y |
x not in y |
Some sample code:
myList = [1,2,3]
if 5 in myList:
print('5 is in the list.')
else:
print('5 is not in the list.')
5 is not in the list.
myList = [1,2,3]
for x in myList:
print(x)
1
2
3
Operator Precedence / Order of Operations#
Consider an expression such as this:
not -5 + 3 * 1 * 2 == 1
How will Python evaluate this expression? There are six operators (not, -, +, *, *, ==). Will Python assign them equal priority or will it evaluate some operators before others?
The answer is that Python, like most programming languages, has rules for operator precedence. These rules are similar to what you learned in algebra. The following table shows Python’s operator precedence:
Precedence |
Operator |
Description |
---|---|---|
Highest |
** |
Exponentiation |
|
- |
Negative sign, e.g. -3 |
|
*, /, //, % |
Multiplication, division, remainder |
|
+, - |
Addition and subtraction |
|
in, not in, <, <=, >, >=, !=, == |
Comparisons and membership operators |
|
not |
Boolean NOT |
|
and |
Boolean AND |
Lowest |
or |
Boolean OR |
When Python sees any expression, it evaluates the expression using the table above. If it sees two operators of equal precedence, it goes from left-to-right.
Let’s work through the above expression, not -5 + 3 * 1 * 2 == 1
. According to the table, the operator with the highest precedence in the expression is the negative sign next to the 5. Python evaluates that and gets -5. The operator with the next highest precedence is *; there are two of them so Python goes from left-to-right. When it wants to evaluate an operator like *, it takes the two values next to the operator. In this case, those values are 3 and 1.
Under the hood, Python makes one evaluation at a time. This continues until the expression is reduced to a single value. So inside Python, it reduces the expression as follows:
not -5 + 3 * 1 * 2 == 1 #Starting expression
not -5 + 3 * 1 * 2 == 1 #The - is applied to the 5 to get -5.
not -5 + 3 * 2 == 1 #Python multiplied 3 * 1 to get 3.
not -5 + 6 == 1 #Python multiplied 3 * 2 to get 6.
not 1 == 1 #The + was the next highest precedence, so -5+6 reduces to 1.
not True #== has higher precedence than not
False # not is then applied to the true boolean
Summary of operator predence#
Python has rules for operator precedence. When it sees an expression, it evaluates the operators in order of precedence by grabbing the closest values to an operator.
When there are two or more operators with the same precedence, Python evaluates the leftmost one first.
To see the official rules for operator precedence, click here. If you do, you will also see some operators we haven’t taught you.
Use Parentheses to Get What You Want#
The above expression, not -5 + 3 * 1 * 2 == 1
is ugly and confusing. Never write something like that! Instead, use parentheses to clarify your meaning.
Parentheses can also be used to override the default operator precedence. So if you rewrote the above expression as:
not (-5 + 3) * 1 * 2 == 1
you would get a different result because Python would evaluate (-5 + 3) first.