4. Basic Mathematical Operations#

4.1. Lesson overview#

Python is a popular data science and numerical methods programming language for engineering applications. As one would expect, these applications require Python to perform many mathematical operations. Fortunately, Python comes equipped to handle many of the basic, but important mathematical operations within its own standard library. This lesson will teach you how to implement many of these basic mathematical operations so you can start calculating numbers for your numerical analysis needs.

4.3. Addition#

The addition / summation of numbers is handled using the + operator and is written out using the command x + y. Python can perform this operation on all three numeric classes. The block of code below provides four examples of adding two or more numbers:

sum_int = 1 + 4
sum_float = 125.3 + 235.6
sum_complex = (2.4 + 2.5j) + (1.0 + 0.5j)
sum_mix = 10 + 4.2 + 2.5

print(sum_int)
print(sum_float)
print(sum_complex)
print(sum_mix)
5
360.9
(3.4+3j)
16.7

4.4. Subtraction#

The subtraction / difference of numbers is handled using the - operator and is written out using the command x - y. Similar to addition, Python can perform this operation on all three numeric classes. The block of code below provides four examples of subtracting two or more numbers:

diff_int = 1 - 4
diff_float = 125.3 - 235.6
diff_complex = (2.4 + 2.5j) - (1.0 + 0.5j)
diff_mix = 10 - 4.2 - 2.5

print(diff_int)
print(diff_float)
print(diff_complex)
print(diff_mix)
-3
-110.3
(1.4+2j)
3.3

4.5. Multiplication#

The multiplication of numbers to obtain a product is handled using the * operator. Similar to addition and subtraction, Python can perform this operation between all three numeric classes using the command x * y. Below are four examples of multiplying two numbers together:

product_int = 1 * 4
product_float = 125.3 * 235.6
product_complex = (2.4 + 2.5j) * (1.0 + 0.5j)

print(product_int)
print(product_float)
print(product_complex)
4
29520.68
(1.15+3.7j)

4.6. Division#

There are three division-based mathematical operations in the Python standard library. The / operator is used to obtain the quotient between two numbers in the form of x / y. This operator accepts all three numeric data types. Try running the cell below that provides three examples of obtaining the quotient between two numbers:

quotient_int = 1 / 4
quotient_float = 125.3 / 235.6
quotient_complex = (2.4 + 2.5j) / (1.0 + 0.5j)

print(quotient_int)
print(quotient_float)
print(quotient_complex)
0.25
0.5318336162988115
(2.92+1.04j)

In addition to obtaining the quotient, Python can also perform an integer-based division using the operator // in the form of x // y, or can provide the remainder of a division operation using the operator % in the form of x % y. Both of these operations are restricted to the int and the float numeric classes. The cell below compares the three different division operations between two float objects:

x = 5.0
y = 2.0

print(x / y)
print(x // y)
print(x % y)
2.5
2.0
1.0

The divmod() function is a one-step route to get the results from integer division and remainder operations simultaneously. The overall format of this function is divmod(x, y) where x is the numerator and y is the denominator. The output is a tuple pair of ( x // y, x % y). To see this function in action, the code below uses divmod() on our x and y variables from before:

print(divmod(x, y))
(2.0, 1.0)

4.6.1. Example: Unit conversion#

Convert the density 7.9 g/cm3 into units of lb/in3. Recall that 1 g = 0.0022 lb and 1 cm3 = 0.061 in3. Report the converted density to the terminal using the print() function.


Solution:

We use unit conversion to convert our density’s unit basis from g/cm3 to lb/in3. Mathematically this looks like,

\[ 7.9 \hspace1ex \frac{\mathrm{g}}{\mathrm{cm^3}} \cdot \frac{1 \hspace1ex \mathrm{cm^3}}{0.061 \hspace1ex \mathrm{in^3}} \cdot \frac{0.0022 \hspace1ex \mathrm{lb}}{1 \hspace1ex \mathrm{g}} = 0.29 \hspace1ex \frac{\mathrm{lb}}{\mathrm{in^3}} \]

Our equivalent Python code is:

density = 7.9
convert = density * (0.0022 / 0.061)
print(convert)
0.28491803278688527

This example demonstrates both how to use the / operator for floating point division and that multiple mathematical operations can be chained together.


4.7. Negated, unchanged, and absolute value#

To quickly take the negative of a number, one places the - operator just before typing a variable (e.g., the negative of x is -x). Conversely, the + operator just before a variable leaves that variable unchanged (e.g., +x is x). While using +x instead of x seems somewhat excessive, the use of -x is a useful command rather than issuing -1 * x. The block of code below uses the x and y variables from before, but now with the negated and unchanged operators:

x = 2.5
y = -13

print(x)
print(y)

print(-x)
print(-y)

print(+x)
print(+y)
2.5
-13
-2.5
13
2.5
-13

The absolute value of a number can be determined by issuing the abs() function. This function takes the form of abs(x), where x is the number that we want to know its absolute value. Below is a block of code that outputs the absolute value for our previously defined x and y variables:

print(abs(x))
print(abs(y))
2.5
13

Note

Remember that the absolute value of a complex number is its magnitude. For example, the magnitude / absolute value of the complex number \(x + iy\) is \(\sqrt{x^2 + y^2}\). This is equivalent to the distance between the origin (0, 0) and the point (x, y) on the complex plane.

4.8. int and float casting#

In a previous lesson we discussed the concept of casting, which is the process of changing an object’s data class to another. Casting a variable into either an int or a float are common tasks when performing numerical analysis, and are handled using the int() and float() functions, respectively (see our previous lesson on casting for details on these functions). The code below demonstrates how these two functions can be used to cast our current variables x and y (an int and float object, respectively) into the other class:

print(int(x))
print(float(y))
2
-13.0

4.9. Complex number operations#

As we have already discussed, a complex object can be created two ways: it can be directly typed out directly into the terminal or by issuing the complex() function. The conjugate of a complex number can be found by running the .conjugate() method, which is a special function associated with the complex class. If you recall in a previous lesson, methods are issued in a special way by first typing out the variable name, followed by the . symbol, then the function’s name.

In the example below, the complex variable position is first created using the complex() function. Next, a new variable called position_complex is created, which represents the complex conjugate of position. Therefore, the .conjugate() method is issued on position using the command position.conjugate(). All of this is detailed in the block of code below:

position = complex(5.2, 2.6)
print(position)

position_conjugate = position.conjugate()
print(position_conjugate)
(5.2+2.6j)
(5.2-2.6j)

4.10. Power raising#

The Python standard library provides two routes to raise the number \(x\) to the power of \(y\) (i.e., \(x^y\) ). The first route is to use the pow() function that accepts two input arguments: (1) the base number x and (2) the power value y. The overall functional form is pow(x, y). All three numeric classes are compatible with pow(). The code below shows two examples of using pow() with int and float objects:

base_int = 2
exponent_int = 3
power_int = pow(base_int, exponent_int)

base_float = 25.2
exponent_float = 0.5
power_float = pow(base_float, exponent_float)

print(power_int)
print(power_float)
8
5.019960159204453

The second route is through the use of the ** operator and takes the form of x ** y. This is equivalent to using the pow() function but now done directly with an operator. The block of code below repeats the example above but now using the ** operator:

print(base_int ** exponent_int)
print(base_float ** exponent_float)
8
5.019960159204453

4.10.1. Example: Cylinder volume#

Calculate the volume of a cylinder that has a radius of 2.4 cm and a length of 12.1 cm. Recall that the volume of a cylinder is,

\[ V = \pi r^2 L \]

where \(V\) is the volume, \(r\) is the radius, and \(L\) is the length. For this calculation approximate \(\pi\) as 3.14.


Solution:

This example demonstrates the use of power raising when calculating floating point numbers. Here we will use the ** operator to square the radius.

radius = 2.4
length = 12.1

volume = (3.14) * (radius ** 2) * (length)
print(volume)
218.84544

Equivalently, we could have used the pow(radius, 2) command to square the radius.


4.11. Power of 10 raising#

Representing numbers in the base 10 format (i.e., 10x format, also called scientific notation) is common in science and engineering applications. This formatting style is especially useful when typing out large numbers. For example, it is much faster to type out 100 million as 1.0 · 108 than 100,000,000. Python accepts base 10 number formatting in numeric data types with the E operator. Therefore, if we needed to assign the value 100 million to a variable called number we can type it out as:

number = 1E8
print(number)
100000000.0

Notice that while the shell reads the number correctly, it outputs the number in a floating point style notation. As we will see in the next lesson, Python offers numerous ways to display numbers when cast to the strdata type, including in scientific notation.

4.11.1. Example: Math with large & small numbers#

The velocity of a wave (e.g., sound, light, water) is related to its spatial wavelength and temporal frequency via the relationship,

\[ v = \lambda \nu \]

where \(v\) is the wave’s velocity (i.e., its speed, unit: m/s), \(\lambda\) is it wavelength (unit: m), and \(\nu\) is its frequency (unit: 1/s = Hz).

Calculate the frequency of a wavefront of light that is traveling in a vacuum that has a wavelength of 550 nm. Recall that the speed of a light wave traveling in a vacuum is 3.0 · 108 m/s.


Solution:

This example highlights the usefulness of the E operator when entering both very large and small numbers into Python code. The overall calculation is straightforward as we simply need to use the \ operator and remember that 1 nm = 1 · 10-9 m. Mathematically the calculation is,

\[ \frac{3.0 \cdot 10^8 \hspace1ex \mathrm{m/s}}{550 \cdot 10^{-9} \hspace1ex \mathrm{m}} = 5.45 \cdot 10^{14} \hspace1ex \mathrm{Hz} \]

The equivalent Python code is:

wavelength = 550E-9
velocity = 3.0E8

frequency = velocity / wavelength
print(frequency)
545454545454545.44

Again, we see that with our current knowledge on how print() works, the returned number is a bit hard to read. As we become more proficient with Python, we will be able to display numbers in more human-readable fashion. The calculation though is correct as we get 5.45 · 1014 Hz = 545 THz.


4.12. Rounding#

Python can round the number \(x\) to a desired precision level using the round() function. This function accepts two arguments: (1) the number to be rounded, x, and (2) the rounding precision level after a decimal point, ndigits. This precision level can be either positive or negative and by default ndigits = 0. The overall format of this function is round(x , ndigits = value), where value is the precision level. The code below demonstrates how round() is used to round the number 6832.36043 to various precision levels:

x = 6832.36043

print(x)
print(round(x, 1))
print(round(x, ndigits = 2))
print(round(x, ndigits = -2))
6832.36043
6832.4
6832.36
6800.0

Hey! Listen!

Notice that in the second example, ndigits is not explicitly typed out. Python can often use the position of the arguments inside the ( ) symbols to know the meaning of each argument. Since this example just has 1 is the second argument position, the Python shell assumes it is the desired value for ndigits. We will revisit this concept in a later lesson about functions.

4.12.1. Example: Keeping significant figures sane#

The ideal gas law relates the number of gas particles (atoms or molecules) to the pressure, the temperature, and the volume of space the gas resides in via the equation,

\[ PV = nRT \]

where \(P\) is the pressure, \(V\) is the volume the gas resides in, \(n\) is the number of gas particles, \(T\) is the temperature of the gas, and \(R\) is called the “ideal gas constant”.

Calculate the moles (unit: mol) of Ar atoms needed to fill a 2.2 m3 vessel to 0.2 MPa of pressure at 23 oC = 297 K. For this problem, use the ideal gas constant form of \( 8.3145 m^3 \cdot Pa \cdot mol^{-1} \cdot K^{-1} \) to keep unit conversions to a minimum. Recall that the mole (unit: mol) is an SI unit for amount. Report the moles first without any rounding considerations and then after rounding to the hundredths position.


Solution:

The actual calculation setup should be familiar by now, and the new feature demonstrated here is utilizing the round() function. Mathematically the calculation is,

\[ \frac{(0.2 \cdot 10^6 \hspace1ex \mathrm{Pa}) \cdot (2.2 \hspace1ex \mathrm{m^3})}{(8.3145 \hspace1ex \mathrm{\frac{m^3 \cdot Pa}{mol \cdot K})(297 \hspace1ex \mathrm{K})}} = 178.18 \hspace1ex \mathrm{mol} \]

Notice the use of Pa instead of MPa for pressure units and K for temperature units to keep everything consistent with the form of the ideal gas constant that is provided. The equivalent Python code is:

pressure = 0.2E6
volume = 2.2
gas_constant = 8.3145
temperature = 297

mol = (pressure * volume) / (gas_constant * temperature)

print(mol)
print(round(mol, 2))
178.18046563010182
178.18

We can see that the Python shell is storing mol with an excessive level of precision, much more than what we care for. The round() function allows us to report the number of moles in an easier to read format.


4.13. Concluding thoughts#

This lesson covered many of the basic, but important, mathematical operations provided in the Python standard library. These include operations such as addition, subtraction, multiplication, division, and ways to raise and round numbers. You may have noticed however the absence of other important mathematical concepts like trigonometric functions, exponential functions, and statistical operations. While Python’s standard library does not provide these operations outright, additional libraries can be imported into Python to increase its usefulness as a scientific language. For example, both the math and NumPy libraries for Python provide many additional mathematical operations and the ability to create numbered arrays. We will explore both of these libraries in later lessons after we introduce how to import and create Python libraries. For now, happy calculating!

4.14. Want to learn more?#

Python Software Foundation - Standard Library Numeric Types
Python Software Foundation - Built-in Functions