Introduction to Python

This section includes many cells which contain Python code. The output from each cell is visible directly below the cell. We provide an explanation for each piece of code as well as some suggestions for the reader to experiment with. In order to engage with the notebook and see new results, edit the code cell, then press ‘Shift + Enter’.

Calculations, variable assignments, and printing

The first thing we might try is the use of code cells as a calculator. Indeed this works in a straightforward way. Run the cell below to see how it works. Experiment with the input to see how to enter various operations. (Note that you can get exponents by using the ** operator.)

42*1.2
50.4

The next thing to learn is how to assign names to numbers and other objects. For this task we use a command like \(\texttt{b=32/5}\). This code computes the value of \(\texttt{32/5}\), stores this value as an object, and then assigns the name \(\texttt{b}\) to that object.

b = 32/5

Since the result was stored, the actual value of \(\texttt{b}\) is not displayed as ouput from the code cell. Indeed, nothing is displayed when the cell is executed. Typically, when we want to display the results of a computation, we have to use a command called \(\texttt{print}\).

b=32/5
print(b)
6.4

If we print the results of many calculations, it becomes difficult to determine which number is which. We will often want to print text with numerical results to provide descriptions. The text to be printed must be placed in quotes. It is also possible to provide multiple items to the \(\texttt{print}\) command by separating them with commas.

print("The calculation is complete.")
print("The result of the calculation 32/5 is",b)
The calculation is complete.
The result of the calculation 32/5 is 6.4

The text within the quotes is a Python object known as a string. Just as with the value of \(\texttt{b}\), we could assign the string object a name if we plan to reuse it. Python offers many powerful ways to manipulate and process strings, but our primary use of strings is to display informative messages about our numerical results.

result_message = "The result of the calculation is"
print(result_message,b)
print(result_message,b*37)
The result of the calculation is 6.4
The result of the calculation is 236.8

It is sometimes easier to read output if there are extra space to break up the lines. We frequently print out the special string \(\texttt{'\n'}\), which adds an extra line break.

print(result_message,b,'\n')
print(result_message,b*37)
The result of the calculation is 6.4 

The result of the calculation is 236.8

The \(\texttt{print}\) command offers several other ways to manipulate the basic format of the output it produces. We will comment on these options as they are used.

Functions

Quite often we write a bit of code that we would like to reuse. Maybe it was tricky to figure out, or just tedious to type, and we want to save time and effort by making use of the code we’ve already written. We could just copy and paste code from here to there, but that quickly becomes a chore as the amount of code we need continues to grow.

One simple way to reuse code is to define a function. We can think of a function as a new command that will carry out whatever instructions we would like to include. Sometimes we will find it useful to provide the function with information in order for it to do its job. Other times we might ask that the function return some information to us when it has finished its job. Let’s look at a couple of examples.

In the first example, we won’t exchange information with the function, we will just ask it to display a message. To define a function we use the keyword \(\texttt{def}\). We then list any instructions that we want the function to carry out. The \(\texttt{def}\) command must end with a colon (:), and all instructions that are part of the function must be indented with a ‘Tab’ key.

def InchConversionFactor():
    print("There are 2.54 centimeters in 1 inch.")

Note that when we execute the cell, the message is not printed. This statement only defines the function. In order to execute the commands in the function, we have to call it.

InchConversionFactor()
There are 2.54 centimeters in 1 inch.

When we call the function, we need to include the parentheses () as part of the call. In this example the parentheses are empty because we are not passing any information to the function. Let’s write another function that allows us to provide it with a measurement in inches, and have it print out the measurement in centimeters.

def InchtoCentimeterConversion(inches):
    cm = inches*2.54
    print(inches,"inches equals",cm,"centimeters.")  

Again, nothing actually happens until we call the function. This time when we call though, we will need to provide a number that the function will interpret as the variable \(\texttt{inches}\). The objects that we pass into functions are known as arguments.

InchtoCentimeterConversion(2.3)
2.3 inches equals 5.842 centimeters.

In the final example we will provide the function with the measurement in centimeters, and it will return to us the measurement in centimeters without printing anything.

def ReturnInchtoCentimeterConversion(inches):
    cm = inches*2.54
    return cm

And again we must call the function to carry out the code. This time however, the function creates an object that represents the value being returned. In order to make use of this object we must assign it a name as before.

result = ReturnInchtoCentimeterConversion(2.3)
print("Our result is",result,"centimeters.")
Our result is 5.842 centimeters.

Conditional statements

It is quite common that we will want some commands to be carried out only in certain conditions. If we are carrying out division for example, we might want to be certain we are not dividing by zero. The \(\texttt{if}\) keyword lets us check a condition before proceeding with any associated commands. The structure of an if block is similar to that of a function definition. The \(\texttt{if}\) keyword is followed with a condition and a colon, then all associated commands are indented to indicate that they are only to be executed when the condition is true.

a = 2
b = 5
c = 0

if (b != 0):
    result1 = a/b
    print(result1)
    
if (c != 0):
    result2 = a/c
    print(result2)
0.4

In this case only the value of \(\texttt{result1}\) was computed. The condition in the second if block (\(c\) not equal to 0) is not true, so the instructions in this block are not executed. Note that the conditions have their own precise syntax as well. Here are a few common conditions.

  • \(\texttt{a > b}\) (Is \(a\) greater than \(b\)?)

  • \(\texttt{a == b}\) (Does \(a\) equal \(b\)?)

  • \(\text{a != b}\) (Does \(a\) not equal \(b\)?)

Sometimes we will want some commands executed if a condition is true, but other commands executed if the condition is not true. In this scenario we use the \(\texttt{else}\) keyword to define an else block, which forms the alternative to the if block. Let’s suppose \(a\) has been assigned a value, and we want to compute \(|a|\), the absolute value of \(a\).

a = -8

if (a > 0):
    abs_value = a
else:
    abs_value = -a
    
print("The absolute value of a is",abs_value)
The absolute value of a is 8

Try changing the value of \(a\). What happens if \(a=0\) ?

At other times we will want to repeat commands while a condition is true. This is done with the \(\texttt{while}\) command, and a corresponding while block of code. We demonstrate with code that totals all the integers from \(a\) to \(b\).

a = 3
b = 20

count = a
sum = 0

while(count <= b):
    sum = sum + count
    count = count + 1

print("The total is",sum)
The total is 207

Blocks of code that get repeated like this are known as loops. The commands in the while block are said to be “inside the loop”.

Iterations

The most common type of loop that we will use is created with the \(\texttt{for}\) keyword, and is thus known as a for loop. The commands inside a for loop get repeated once for each object in a specified collection. For our purposes, the collection of objects will almost always be a set of numbers generated using the \(\texttt{range}\) command. The combination of \(\texttt{for}\) and \(\texttt{range}\) is easiest to understand by looking at some examples.

for number in range(5):
    print(number)
0
1
2
3
4

In this first example every number in \(\texttt{range(5)}\) gets printed. We can see that \(\texttt{range(5)}\) contains the numbers from 0 to 4. In general \(\texttt{range(n)}\) will generate the numbers 0 to \(n-1\). It may appear strange that the collection is 0 to 4 instead of 1 to 5, but counts beginning with zero are common in programming languages. We can specify any starting number we like by providing another argument to the \(\texttt{range}\) function.

for number in range(3,10):
    print(number)
3
4
5
6
7
8
9

We can also provide the \(\texttt{range}\) function a third argument to specify the spacing between numbers.

for number in range(4,12,2):
    print(number)
4
6
8
10

With \(\texttt{for}\) and \(\texttt{range}\) we can create another loop that totals the numbers from \(a\) to \(b\) as we did earlier using \(\texttt{while}\).

a = 3
b = 20

sum = 0

for i in range(a, b+1):
    sum = sum + i
    
print("The total is",sum)
The total is 207

One difference between using a \(\texttt{for}\) loop and a \(\texttt{while}\) loop is that we do not need to explicitly increment a variable to track the number of iterations when using a \(\texttt{for}\) loop. In general, we tend to use a \(\texttt{for}\) loop when we want to iterate once for each item in a collection, such as the numbers in \(\texttt{range(5)}\). We use a \(\texttt{while}\) loop when we want the number of iterations to remain flexible.

Comments

Often it is useful to include some plain text inside the code cell to help provide a description or explanation. Such text is called a comment. Comments are not interpreted as Python code, so we can write anything we like to help us document the code. There are two ways to accomplish this.

  • Any portion of a line that follows the \(\texttt{#}\) symbol is ignored by the interpretor.

a = 142
c = a**2  # c is the square of a
print("The square of",a,"is",c)
The square of 142 is 20164
  • Any portion of the code cell within triple quotes is ignored.

''' 
We can write 
several lines
worth of comments to explain
the purpose of the code
'''
a = 142
c = a**2  # c is the square of a
print("The square of",a,"is",c)
The square of 142 is 20164

The important point here is that the previous two cells do exactly the same thing. The comments have no effect on the calculation or the output. The following cell with no comments also does exactly the same thing.

a = 142
c = a**2
print("The square of",a,"is",c)
The square of 142 is 20164

Importing libraries

The core of the Python language does not contain all the functionality that we will need for linear algebra. In order to access more tools we will import some Python modules. For example, some basic functions that you might find on a scientific calculator are not part of the Python language, but are included in the math module. A simple way to import this module is with the code \(\texttt{import math}\). The cell below shows some examples of how we might use the module.

import math
s = math.sqrt(2)
print("The square root of 2 is approximately",s)
PI = math.pi
print("Pi is approximately", PI)
print("The cosine of pi/10 is approximately",math.cos(PI/10))
The square root of 2 is approximately 1.4142135623730951
Pi is approximately 3.141592653589793
The cosine of pi/10 is approximately 0.9510565162951535

Note that when we use the square root function, we need to use the call \(\texttt{math.sqrt}\) instead of just \(\texttt{sqrt}\). This is because the square root function is actually a part of the \(\texttt{math}\) module, and is not in the basic set of Python commands. The use of this dot notation is ubiquitous in Python. Whenever \(\texttt{object2}\) is contained within \(\texttt{object1}\), we access \(\texttt{object2}\) by using \(\texttt{object1.object2}\).

In the Jupyter Guide to Linear Algebra, we will create our own module that contains all of the functions we develop as we work through the material. This module is named \(\texttt{laguide}\). We will import it in later sections when we want to make use of functions that we create in the earlier sections. Note that unlike the \(\texttt{math}\) module, the \(\texttt{laguide}\) module is not in the Python standard library. This means that in order to use \(\texttt{laguide}\) outside of the Jupyter Guide to Linear Algebra, the source code must be copied from the repository github.com/bvanderlei/jupyter-guide-to-linear-algebra before it can be imported.

Exercises

  • Write a function that accepts 5 numbers as arguments and returns the average of those numbers.

## Code solution here.
  • Write a function that takes accepts a single integer and displays whether the integer is odd or even.

## Code solution here.
  • Write a function that accepts a single argument \(N\), and returns the largest square number that is less than or equal to \(N\).

## Code solution here.
  • Write a function that accepts two arguments, \(\texttt{a}\) and \(\texttt{b}\), and returns the remainder of \(\texttt{a/b}\). (There is a built-in Python operator that does this, but try to come up with a way to do it for yourself.)

## Code solution here
  • Write a function that accepts a single integer \(N\), as an argument, and returns the number of factors of \(N\). (For example, 18 has factors 1, 2, 3, 6, 9, 18. If the function receives 18 as an argument, it should return 6.)

## Code solution here.
  • Write a function that accepts a single argument that represents a date, and returns the number of days that have passed between January 1, 2000, and the date provided. (For example, if the function receives the number 020100 (February 1, 2000), it should return the number 31. If the function receives the number 01012001 (January 1, 2001), it should return 366 since the year 2000 was a leap year.) This exercise is more challenging that it may first appear. Try splitting the problem in to simpler tasks.

## Code solution here.