3.6 Operators and expressions
In programming, operators are special symbols that represent computations like addition, multiplication, and comparison. Python provides a wide range of operators that can be used to perform various operations on variables and values.
In this chapter, we will cover the following types of operators:
- Assignment Operator
- Arithmetic Operators
- Logical and Comparison Operators
3.6.1 Assignment operator
The assignment operator (=) is used to assign a value to a variable. The variable on the left side of the assignment operator is assigned the value on the right side. For example, in the code below, the variable x is assigned the value 5:
3.6.2 Expressions
An expression is a combination of values, variables, and operators that evaluates to a single value. For example, 2 + 3 is an expression that evaluates to 5. Expressions can be simple or complex, depending on the number of values and operators involved.
Using the assignment operator, you can store the result of an expression in a variable. For example, in Listing 1, the result of the expression 2 + 3 is stored in the variable result.
2 + 3 is assigned to the variable result. First, the expression 2 + 3 is evaluated, resulting in 5. Then, the value 5 is assigned to the variable result.
You can think of result as a container in your computer's memory that holds the value 5. From now on, you can use the variable result to access the value 5.
3.6.3 Arithmetic operators
Arithmetic operators are used to perform mathematical operations like addition, subtraction, multiplication, and division. Below is a list of arithmetic operators available in Python:
| Operator Symbol | Operation |
|---|---|
+ |
Addition |
- |
Subtraction |
* |
Multiplication |
/ |
Division |
** |
Exponentiation (Power) |
// |
Floor Division (Integer Division) |
% |
Modulo (Returns the remainder of a division) |
Precedence
Precedence refers to the order in which operators are evaluated in an expression. In Python, operators have different levels of precedence, which determine the order in which they are evaluated. However, you can use parentheses to override the default precedence and control the order of evaluation. You can check the precedence of operators in the Python documentation.
For example, in Listing 2, you can see how the order of operations affects the result of an expression. Without parentheses, the order of operations is as follows:
- Exponentiation (
**) - Modulo (
%) - Multiplication (
*)
Some operators, like % and *, have the same level of precedence. In this case, the operators are evaluated from left to right.
To avoid confusion and ensure that your expressions are evaluated correctly, use parentheses to control the order of operations. This will make your code more readable and less error-prone.
In Listing 3, you can see an example of how parentheses can improve the readability of an expression involving a calculation of a grade, defined as: \[ \text{grade} = \text{min\_grade} + \left(\frac{\text{score}}{\text{max\_score}}\right) \times (\text{max\_grade} - \text{min\_grade}) \]
Syntax errors
Python has a set of rules that define the correct structure of expressions. If you violate these rules, Python will raise a SyntaxError. For example, if you forget to close a parenthesis or use an invalid operator, Python will raise an error.
In natural languages, syntax errors can occur when you use the wrong word order or violate grammar rules. For example, in Dutch, "het" and "de" are articles that precede nouns (translated simply as "the" in English). The choice between "het" and "de" depends on many factors. If you use the wrong article, the sentence will be incorrect. The compiler (or the Dutch listener) will raise an error (or figure out that you are not a native speaker) if you use the wrong article.
In Listing 4, you can see an example of a SyntaxError caused by an invalid expression. The error message indicates that the syntax is incorrect due to an invalid operator (* without a second operand).
Modulo and floor division
Besides the typical arithmetic operators, Python also provides some additional operators like:
- Floor division (
//): Returns the integer part of the division operation. - Modulo (
%): Returns the remainder of the division operation.
Why are these operators useful? One common use case is to determine if a number is divisible by another number. For example, if you want to determine if a number n is prime (i.e., only divisible by 1 and itself), you can check if n is divisible by any number between 2 and n-1. If n is divisible by any number in this range, it is not prime.
Prime numbers have a range of applications in practice. In cryptography, for example, prime numbers are used to generate secure encryption keys (e.g., RSA algorithm).
In the tables below, you can see how the % and // operators work in Python for different inputs.
% operator, you can calculate the remainder of a division operation. Using the // operator, you can calculate the integer part of the division operation.
Input (n) |
n // 3 |
n % 3 |
|---|---|---|
| 0 | 0 | 0 |
| 1 | 0 | 1 |
| 2 | 0 | 2 |
| 3 | 1 | 0 |
| 4 | 1 | 1 |
| 5 | 1 | 2 |
| 6 | 2 | 0 |
| 7 | 2 | 1 |
| 8 | 2 | 2 |
| 9 | 3 | 0 |
| 10 | 3 | 1 |
| 11 | 3 | 2 |
Input (n) |
n // 4 |
n % 4 |
|---|---|---|
| 0 | 0 | 0 |
| 1 | 0 | 1 |
| 2 | 0 | 2 |
| 3 | 0 | 3 |
| 4 | 1 | 0 |
| 5 | 1 | 1 |
| 6 | 1 | 2 |
| 7 | 1 | 3 |
| 8 | 2 | 0 |
| 9 | 2 | 1 |
| 10 | 2 | 2 |
| 11 | 2 | 3 |
Other arithmetic functions
In Python, some arithmetic functions are available to perform specific operations. For example:
pow(x, y): Returnsxraised to the powery.abs(x): Returns the absolute value ofx.round(x): Roundsxto the nearest integer.
The math module provides functions for more complex mathematical operations. For example:
math.sqrt(x): Returns the square root ofx.math.floor(x): Returns the largest integer less than or equal tox(the "floor" ofx).math.ceil(x): Returns the smallest integer greater than or equal tox(the "ceiling" ofx).
Also, the math module provides constants like math.pi and math.e for mathematical calculations.
3.6.4 Logical and comparison operators
Logical and comparison operators are used to create conditional expressions that evaluate to either True or False.
- A comparison operator compares two values and returns
Trueif the comparison is true, andFalseotherwise. For example,5 > 3isTruebecause5is greater than3. - A logical operator combines multiple conditional expressions and returns
TrueorFalsebased on the logical operation. For example,5 > 3 and 7 < 10isTruebecause both conditions are true.
In Table 3, you can see a list of logical and comparison operators available in Python.
| Operator Symbol | Operation |
|---|---|
== |
Equal |
!= |
Not Equal |
> |
Greater Than |
< |
Less Than |
>= |
Greater Than or Equal |
<= |
Less Than or Equal |
and |
Logical AND |
or |
Logical OR |
not |
Logical NOT |
Truth tables
A truth table is a table that shows the possible values of logical expressions and their results. In Table 4, you can see the truth table for the logical operators and, or, and not.
and, or, and not. The operands A and B can be either True or False.
| A | B | A and B |
A or B |
not A |
|---|---|---|---|---|
False |
False |
False |
False |
True |
False |
True |
False |
True |
True |
True |
False |
False |
True |
False |
True |
True |
True |
True |
False |
Precedence
All comparison operators have equal precedence, and all have greater precedence than the logical operators, but lower precedence than the arithmetic operators.
For logical operators, the precedence order is:
- Logical NOT (
not) - Logical AND (
and) - Logical OR (
or)
For example, in Listing 5, you can see how the order of operations affects the result of an expression.
Result 1 is calculated following the steps:
((not (x < y)) and (y < z)) or (x < z)((not (True)) and (True)) or (True)(False and True) or TrueFalse or TrueTrue
Result 2 is calculated following the steps:
not (((x < y) and (y < z)) or (x < z))not ((True and True) or True)not (True or True)not (True)False
3.6.5 Combining operators
Python provides shorthand operators that combine arithmetic operations with assignment. These operators are useful for updating the value of a variable based on its current value.
For example, in Listing 6, you can see how the shorthand operators work. The expression x += 5 is equivalent to x = x + 5.
3.6.6 Exercises
3.6.Q1 Creating functions for arithmetic operators
For each operator in Table 1, create a function that takes two numbers and returns the resulting value. Make sure your function is tested in a separate test function.
See below examples for the first three operators:
add,multiply, anddivide.
def add(num1, num2):
return num1 + num2
pass
def multiply(num1, num2):
return num1 * num2
pass
def divide(num1, num2):
return num1 / num2
pass
def test_add():
print("Result (1 + 2) =", add(1, 2))
assert add(1, 2) == 3
def test_multiply():
print("Result (1 * 2) =", multiply(1, 2))
assert multiply(1, 2) == 2
def test_divide():
print("Result (3 / 2) =", divide(3, 2))
assert divide(3, 2) == 1.53.6.Q2 Precedence of arithmetic operators
Use your arithmetic functions to calculate the following expressions:
2 + 3 * 4(2 + 3) % 42 ** 3 + 42 ** (3 + 4)2 * 30 // 4 % 2 + 5
For example, the first expression can be calculated as follows:
3.6.Q3 Testing functions
Add the programming logic to the functions defined below. Replace the pass statement with the code that implements the function's logic.
def calculate_average_two_numbers(num1, num2):`
'''Calculate the average of two numbers.
Args:
num1 (float): The first number.
num2 (float): The second number.
Returns:
float: The average of the two numbers.
'''
pass # Add code here!
def calculate_hypotenuse(a, b):
'''Calculate the hypotenuse of a right-angled
triangle given the lengths of the other
two sides.
Args:
a (float): The length of side a.
b (float): The length of side b.
Returns:
float: The length of the hypotenuse.
Examples:
>>> calculate_hypotenuse(3, 4)
5.0
'''
pass # Add code here!
def convert_pounds_to_kgs(pounds):
'''Convert pounds to kilograms.
1 pound is equal to 0.453592 kilograms.
Args:
pounds (float): The weight in pounds.
Returns:
float: The weight in kilograms.
Examples:
>>> convert_pounds_to_kgs(2.2)
1.0
'''
pass # Add code here!For each function, write useful tests to check if the function is working as expected.
For example, the template code:
Should become:
Make sure your functions are tested across a range of inputs to ensure they work correctly.
pytest
You can use the pytest library to run your tests. To install pytest, you can use the following command:
Then, you can run your tests by creating a file named test_arithmetic.py and adding your test functions to it. You can run the tests using the following command:
3.6.Q4 Check if a number is even
Write a function that takes an integer as input and returns True if it's an even number, otherwise False.
3.6.Q5 Check if a number is divisible by both 3 and 5
Write a function that takes an integer as input and returns True if it's divisible by both 3 and 5, otherwise False.
3.6.Q6 Check if a string contains a specific character
Write a function that takes a string and a character as input and returns True if the string contains the character, otherwise False.
3.6.Q7 Check if two numbers are both positive
Write a function that takes two numbers as input and returns True if both numbers are positive, otherwise False.
3.6.Q8 Check if a number is within a specific range
Write a function that takes a number and a range (minimum and maximum) as input, and returns True if the number is within that range, otherwise False.
3.6.Q9 Check if a string contains either "apple" or "banana"
Write a function that takes a string as input and returns True if it contains either "apple" or "banana" (case-insensitive), otherwise False.
3.6.Q10 Check if a number is not equal to 0
Write a function that takes a number as input and returns True if it's not equal to 0, otherwise False.
3.6.Q11 Check if a string is not empty
Write a function that takes a string as input and returns True if it's not empty, otherwise False.
3.6.Q12 Check if two boolean values are both True
Write a function that takes two boolean values as input and returns True if both are True, otherwise False.
3.6.Q13 Check if a number is greater than 10 and less than 20
Write a function that takes a number as input and returns True if it's greater than 10 and less than 20, otherwise False.
3.6.Q14 Check if two numbers have the same fractional part
Write a function that takes two numbers as input and returns True if they have the same fractional part, otherwise False.
def have_same_fractional_part(num1, num2):
pass # Add code here!
def test_have_same_fractional_part():
assert have_same_fractional_part(3.25, 7.25) == True
assert have_same_fractional_part(2.5, 2.75) == False
assert have_same_fractional_part(1.0, 2.0) == True
assert have_same_fractional_part(1, 2) == True
assert have_same_fractional_part(0, 0) == True3.6.Q15 Check if a number is a multiple of 4 and 6
Write a function that takes an integer as input and returns True if it's a multiple of both 4 and 6, otherwise False.
3.6.Q16 Check if two strings are equal (case-insensitive)
Write a function that takes two strings as input and returns True if they are equal (case-insensitive), otherwise False.
3.6.Q17 Check if a string contains a character and meets conditions
Write a function called is_valid_string that takes three parameters: a string, a boolean, and a number. The function should return True if the following conditions are met:
- The string contains the character
'A'(case-insensitive). - The boolean parameter is
True. - The number parameter is greater than or equal to
10.
Otherwise, the function should return False.
def is_valid_string(input_str, flag, num):
pass # Add code here!
def test_is_valid_string():
assert is_valid_string("Sample String", True, 15) == True
assert is_valid_string("Another String", False, 5) == False
assert is_valid_string("A String with A", True, 8) == False
assert is_valid_string("ABC", True, 10) == True