Wednesday, August 26th, 2026¶

Last class, we familiarized ourselves with Jupyter notebook and running Python code. We saw how to perform various arithmetic operations and compared the integer and float datatypes. We also discussed working with Markdown cells.

Exercise: Add two new cells below this one.

  • Convert the first cell to a Markdown cell, then add a section header titled "Using Python to perform long division".
  • In the second cell, use Python to perform long division for $123$ divided by $13$. Use Python to check your result.

Using Python to perform long division¶

In [1]:
123 // 13
Out[1]:
9
In [2]:
123 % 13
Out[2]:
6
In [3]:
9 * 13 + 6
Out[3]:
123

Variable assignment in Python¶

Very often, we want to perform operations on some input that might change. We can define variables using the = symbol:

In [4]:
a = 123
b = 13

c = a // b
d = a % b

After defining a variable, we can refer back to its value by typing in the name.

Note: Jupyter will display the output of the last line of any cell. For example, we can display the value of a variable by "executing" the variable name as the last operation in a code cell.

In [5]:
a
b
c
Out[5]:
9
In [6]:
d
Out[6]:
6
In [7]:
c * b + d
Out[7]:
123

Variable names¶

Variable names must:

  • Start with a letter or underscore (_)
  • Contain only letters, numbers, or underscores.
In [8]:
this_is_a_variable = 5
This_is_a_2nd_variable = 8
In [9]:
_this_variable_STARTS_WITH_UNDERSCORE = -13
In [10]:
1st_variable = -3
  Cell In[10], line 1
    1st_variable = -3
    ^
SyntaxError: invalid decimal literal

Very often, we'll use underscores as spaces to separate words in our variable names. Another style (known as camelcase) uses capital letters to denote the start of a new word.

In [11]:
thisIsACamelcaseVariable = 3
this_is_a_underscored_variable = 7

In general, we want to choose concise variable names that helps the reader understand what they represent.

For example, recall the exercise above where we performed long-division:

In [12]:
a = 123
b = 13

c = a // b
d = a % b

In the above, the variable names do not help to illustrate what each variable represents. Can we come up with names that might work better?

In [13]:
numerator = 123
denominator = 13

quotient = numerator // denominator
remainder = numerator % denominator
In [14]:
quotient * denominator + remainder
Out[14]:
123
In [15]:
num = 123
den = 13

quo = num // den
rem = num % den
In [16]:
quo * den + rem
Out[16]:
123

Simultaneous variable assignment¶

We can define several variables simultaneously by separating the variables to be assigned with commas followed by an equal sign = and their respective comma-separated values.

In [17]:
num, den = 123, 13
In [18]:
num
Out[18]:
123
In [19]:
den
Out[19]:
13

Note: the divmod function can be used to simultaneously calculated the integer quotient and the remainder.

In [20]:
divmod(num,den)
Out[20]:
(9, 6)
In [21]:
quo, rem = divmod(num, den)
In [22]:
quo
Out[22]:
9
In [23]:
rem
Out[23]:
6

This can be very useful if we ever want to swap the meaning of two variables. As an example, suppose we define a = 1 and b = 2, but then want to swap their values.

In [24]:
a = 1
b = 2
In [25]:
old_a = a
a = b
b = old_a
In [26]:
a
Out[26]:
2
In [27]:
b
Out[27]:
1

Alternatively, we can use simultaneous assignment to swap them without introducing an intermediate variable.

In [28]:
a = 1
b = 2

a,b = b,a
In [29]:
a
Out[29]:
2
In [30]:
b
Out[30]:
1

Working with strings¶

In Python, strings are used to hold text data. We can define strings by surrounding some text by double quotes " or single quotes ':

In [31]:
"This is a string"
Out[31]:
'This is a string'
In [33]:
string = 'This is another string'
In [34]:
string
Out[34]:
'This is another string'

There are many operations that can be performed on strings. For example:

Addition of strings:

In [35]:
my_string = 'First string'
my_string2 = 'Second string'

my_string + my_string2
Out[35]:
'First stringSecond string'

Adding strings together concatenates them.

Multiplying a string with an integer:

In [36]:
my_string * 5
Out[36]:
'First stringFirst stringFirst stringFirst stringFirst string'

Multiplying a string by an integer contatenates that number of copies together.

Can we multiply a string with a float?

In [37]:
my_string * 1.5
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
Cell In[37], line 1
----> 1 my_string * 1.5

TypeError: can't multiply sequence by non-int of type 'float'

Can we multiply two strings?

In [38]:
my_string * my_string2
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
Cell In[38], line 1
----> 1 my_string * my_string2

TypeError: can't multiply sequence by non-int of type 'str'

Multi-line strings can be used using triple-single-quotes ''' to surround the string:

In [39]:
"I want this string
to have several lines.
This is the third line"
  Cell In[39], line 1
    "I want this string
    ^
SyntaxError: unterminated string literal (detected at line 1)
In [41]:
multiline_string = '''I want this string
to have several lines.
This is the third line.'''
In [42]:
multiline_string
Out[42]:
'I want this string\nto have several lines.\nThis is the third line.'

Notice that our multi-line string does not display the way we might hope. If we want to correctly render a multi-line string, we can use the print function. More broadly, executing a string as the last line of a cell will display the raw string, while the print function will display the rendered string.

In [43]:
print(multiline_string)
I want this string
to have several lines.
This is the third line.
In [44]:
print(my_string)
print(my_string2)
First string
Second string

The print function can be used anytime we want to display some information.

Exercise: Write a code cell that defines variables a and b, then performs long division and prints out the quotient and remainder.

In [3]:
a = 100
b = 7
q = a // b
r = a % b

print('The quotient is')
print(q)
print('The remainder is')
print(r)
print('q*b + r = ')
print(q*b+r)
The quotient is
14
The remainder is
2
q*b + r = 
100

Note: The print function can take in multiple inputs (separated by commas), and will print all inputs on the same line (separated by one space).

Exercise: For a given $a$ and $b$, perform long division and print out a statement similar to $b = q\cdot a + r$, where $q$ and $r$ are the quotient and remainder resulting from dividing $b$ by $a$.

In [4]:
print(a,b,q,r)
100 7 14 2
In [5]:
a = 123
b = 13
q = a // b
r = a % b

print(a, '=', q, '*', b, '+', r)
123 = 9 * 13 + 6

String formatting¶

Very often, we have some string template that we want to fill in with calculated data. For example, in the previous cell we wanted to print out a statement that outlines the results of long division.

There are several ways that we can accomplish this in a more slick way. One way is by using the .format method. Methods like .format are functions that are attached to objects, in this case to a string. This method can be called on some string in following way:

<some string>.format(<format options>).

In the simplest case, we can first create a string that contains placeholders denoted by curly braces {}. Once our string (with placeholders) is defined, we can use the .format method to supply values that will sequentially fill in these placeholders.

In [50]:
long_division_template = '{} = {} * {} + {}'
In [52]:
long_division = long_division_template.format(a, b, q, r)
print(long_division)
123 = 13 * 9 + 6

Types¶

So far, we've talked about integers, floats, and strings. There are often times where we might want to convert between these datatypes.

  • The int function will try to convert an input to an integer type.
  • The float function will try to convert an input to a float type.
  • The str function will try to convert an input to a string type.
In [53]:
float(4)
Out[53]:
4.0
In [54]:
int(7.0)
Out[54]:
7
In [55]:
str(3)
Out[55]:
'3'

We can use the type function to check an object's type.

In [56]:
type(4)
Out[56]:
int
In [57]:
type(-3.2)
Out[57]:
float
In [58]:
type('hello')
Out[58]:
str

The int function will truncate a float and drop any decimal part.

In [59]:
int(5.3)
Out[59]:
5
In [60]:
int(-5.6)
Out[60]:
-5

Sometimes we might want to round to the nearest integer.

In [61]:
round(5.3)
Out[61]:
5
In [62]:
round(-5.6)
Out[62]:
-6

Note: Python comes with several built-in functions, like the round function. We can see this when Jupyter changes the name round to green-text. Advice: Try to avoid using these built-in names with your own variables.

In [1]:
int(5.3)
Out[1]:
5

Working with lists in Python¶

Another datatype in Python is the list type. Lists contain ordered collections of objects. To define a list, we surround a comma-separated collection with square brackets.

In [13]:
my_list = [1,2,3,'four','five', 6.0, 7.0]
In [14]:
my_list
Out[14]:
[1, 2, 3, 'four', 'five', 6.0, 7.0]

To access elements of a list, we use square brackets again along with an index. Python is a 0-based indexing language, which means the index of each list starts at 0. That is, 0 indicates the first item in the list.

In [15]:
my_list[0]
Out[15]:
1
In [16]:
my_list[1]
Out[16]:
2
In [17]:
my_list[2]
Out[17]:
3

We can also access elements of a list by counting backward from the end using negative indices.

  • The -1st index gives the last element.
  • The -2nd index gives the second to last element.
In [18]:
my_list[-1]
Out[18]:
7.0
In [19]:
my_list[-2]
Out[19]:
6.0

Note: We will get an error if we access indices beyond the length of the list:

In [20]:
my_list[6]
Out[20]:
7.0
In [21]:
my_list[7]
---------------------------------------------------------------------------
IndexError                                Traceback (most recent call last)
Cell In[21], line 1
----> 1 my_list[7]

IndexError: list index out of range
In [23]:
my_list[-7]
Out[23]:
1
In [24]:
my_list[-8]
---------------------------------------------------------------------------
IndexError                                Traceback (most recent call last)
Cell In[24], line 1
----> 1 my_list[-8]

IndexError: list index out of range

List operations¶

What sorts of operations can we perform on lists? For arithmetic operations, lists work very similarly to strings.

Addition of lists:

In [27]:
my_list1 = [1,2,3]
my_list2 = [4,5,6,7,8]
In [28]:
my_list1 + my_list2
Out[28]:
[1, 2, 3, 4, 5, 6, 7, 8]

Multiplying a list and an integer:

In [29]:
my_list1 * 3
Out[29]:
[1, 2, 3, 1, 2, 3, 1, 2, 3]
In [30]:
my_list2 * 5
Out[30]:
[4, 5, 6, 7, 8, 4, 5, 6, 7, 8, 4, 5, 6, 7, 8, 4, 5, 6, 7, 8, 4, 5, 6, 7, 8]

Lists and strings share many properties. We can convert a string to a list using the list function:

In [31]:
my_string = 'This is MTH 337'
my_list = list(my_string)
In [32]:
my_list
Out[32]:
['T', 'h', 'i', 's', ' ', 'i', 's', ' ', 'M', 'T', 'H', ' ', '3', '3', '7']

We can find the length of a list (or string) using the len function.

In [33]:
len(my_list)
Out[33]:
15
In [34]:
len(my_string)
Out[34]:
15

What if we want to convert a list of string characters to a string? The str function can be used to convert objects to strings.

In [35]:
str_from_list = str(my_list)
In [37]:
str_from_list
Out[37]:
"['T', 'h', 'i', 's', ' ', 'i', 's', ' ', 'M', 'T', 'H', ' ', '3', '3', '7']"

Can we freely convert the string '12345' to a list and then back to a string?

In [40]:
my_string = '12345'
list_from_str = list(my_string)
str_from_list = str(list_from_str)

print(my_string)
print(list_from_str)
print(str_from_list)
12345
['1', '2', '3', '4', '5']
['1', '2', '3', '4', '5']

It does not look like this is doing quite what we want, since the resulting includes the list delimitors (brackets) and element separators (commas).

We can fix this by using the .join method on a string. The .join method takes in a list of strings and concetanates them. However, it uses the object from which it is called to separate each concatenation.

For example, calling 'abc'.join(['hello','goodbye','zzz']) will produce a string that concatenates the strings 'hello', 'goodbye', and 'zzz' separated by the string 'abc'. That is, it produces the string 'helloabcgoodbyeabczzz'.

In particular, if we call the .join method from an empty string '', we will get simple concatenation.

In [41]:
''.join(list_from_str)
Out[41]:
'12345'

Exercise: Use the .join method and string formatting to take in an integer n and it's prime factorization (as a list of strings) factors and print out a sentence stating the prime factorization.

As an example, if n=22 and factors=['2', '11'], we could print something like '22 = 2 * 11'.

In [47]:
n = 44
factors = ['2', '2', '11']
factorization_str = ' * '.join(factors)

print('{} = {}'.format(n, factorization_str))

#print(n, '=', ' * '.join(factors))
44 = 2 * 2 * 11

Working with loops in Python¶

It often happens that we want to perform the same (or similar) operations many times. We can perform iterative operations using a for loop. For example, we can iterate through the items in a list and perform some desired operations.

The syntax for writing a for loop is: for (some variable name) in (some iterable object): (do something)

The variable (some variable name) will sequentially take on each of the values stored in (some iterable object) (a list, for example), and for each value will (do something).

In [48]:
for num in [1,2,3,4,5]:
    print(num)
1
2
3
4
5
In [50]:
for num in [1,2,3,4,5]:
    print(num**2)
print('Done')
1
4
9
16
25
Done
In [51]:
for num in [1,2,3,4,5]:
    print(num**2)
    print('Done')
1
Done
4
Done
9
Done
16
Done
25
Done

Key info: The spacing in Python is critical!!!. In particular, the spacing decides what operations are part of a for loop and what operations are not.

In [1]:
for num in [1,2,3,4,5]:
    print(num**2)
print('Done')
1
4
9
16
25
Done

In the cell above, notice how the print('Done') action only occurs after the loop has completed, because it is not indented to be part of the for loop.

In [2]:
for num in [1,2,3,4,5]:
    print(num**2)
    print('Done')
1
Done
4
Done
9
Done
16
Done
25
Done

This time in the cell above, the print('Done') action occurs during every iteration of the loop, because it is indented to be part of the for loop.