Class 4C: Introduction to Programming in Python
Contents
Class 4C: Introduction to Programming in Python¶
We will begin soon! Until then, feel free to use the chat to socialize, and enjoy the music!

Firas Moosvi
Class Outline:¶
Digging Deeper into Python syntax
Announcements (5 min)
Thursday labs will be cancelled this week (Nat’l day of truth and reconciliation)
Project 1 Milestone Feedback has now been released
Project Details are also released
Test details
Test 1 will be from Friday 6 PM - Sunday 6 PM (48 hour window)
You can start the test at any time during this window
You will have 1 hour to do the test (Canvas Quiz)
Content: Terminal & Git commands & Markdown syntax
Gradescope and finding your grades
Lists and tuples (15 min)
String methods (5 min)
Dictionaries (10 min)
Conditionals (10 min)
Lists and Tuples¶
Lists and tuples allow us to store multiple things (“elements”) in a single object.
The elements are ordered.
my_list = [1, 2, "THREE", 4, 0.5]
print(my_list)
[1, 2, 'THREE', 4, 0.5]
type(my_list)
list
You can get the length of the list with len
:
len(my_list)
5
today = (1, 2, "THREE", 4, 0.5)
print(today)
(1, 2, 'THREE', 4, 0.5)
type(today)
tuple
len(today)
5
Indexing and Slicing Sequences¶
We can access values inside a list, tuple, or string using the bracket syntax.
Python uses zero-based indexing, which means the first element of the list is in position 0, not position 1.
my_list
[1, 2, 'THREE', 4, 0.5]
my_list[0]
1
my_list[4]
0.5
my_list[5]
---------------------------------------------------------------------------
IndexError Traceback (most recent call last)
/tmp/ipykernel_1865/303719451.py in <module>
----> 1 my_list[5]
IndexError: list index out of range
today[4]
0.5
We use negative indices to count backwards from the end of the list.
my_list
[1, 2, 'THREE', 4, 0.5]
my_list[-1]
0.5
my_list[len(my_list)-1]
0.5
We use the colon :
to access a subsequence. This is called “slicing”.
my_list[1: ]
[2, 'THREE', 4, 0.5]
my_list[1:3]
[2, 'THREE']
Above: note that the start is inclusive and the end is exclusive.
So
my_list[1:3]
fetches elements 1 and 2, but not 3.In other words, it gets the 2nd and 3rd elements in the list.
We can omit the start or end:
my_list[0:3]
[1, 2, 'THREE']
my_list[:3]
[1, 2, 'THREE']
my_list[3:]
[4, 0.5]
my_list[:] # *almost* same as my_list - more details next week (we might not, just a convenience thing)
[1, 2, 'THREE', 4, 0.5]
Strings behave the same as lists and tuples when it comes to indexing and slicing.
alphabet = "abcdefghijklmnopqrstuvwyz"
alphabet[0]
'a'
alphabet[-1]
'z'
alphabet[-3]
'w'
alphabet[:5]
'abcde'
alphabet[12:20]
'mnopqrst'
List Methods (Functions)¶
A list is an object and it has methods for interacting with its data.
For example,
list.append(item)
appends an item to the end of the list.See the documentation for more list methods.
primes = [2,3,5,7,11]
primes
[2, 3, 5, 7, 11]
len(primes)
5
primes.append(13)
primes
[2, 3, 5, 7, 11, 13]
len(primes)
6
max(primes)
13
min(primes)
2
sum(primes)
41
my_list
[1, 2, 'THREE', 4, 0.5]
my_list = [1, 2, 'THREE', 4, 0.5]
my_list.append(primes)
#my_list.extend(primes)
my_list
[1, 2, 'THREE', 4, 0.5, [2, 3, 5, 7, 11, 13]]
my_list[-1][-1]
13
[1,2,3] + ["Hello", 7]
[1, 2, 3, 'Hello', 7]
Mutable vs. Immutable Types¶
Strings and tuples are immutable types which means they cannot be modified.
Lists are mutable and we can assign new values for its various entries.
This is the main difference between lists and tuples.
names_list = ["Indiana","Fang","Linsey"]
names_list
['Indiana', 'Fang', 'Linsey']
names_list[0] = "Cool guy"
names_list
['Cool guy', 'Fang', 'Linsey']
names_tuple = ("Indiana","Fang","Linsey")
names_tuple
('Indiana', 'Fang', 'Linsey')
names_tuple[0] = "Not cool guy"
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
/var/folders/64/bfv2dn992m17r4ztvfrt93rh0000gn/T/ipykernel_40107/1910523450.py in <module>
----> 1 names_tuple[0] = "Not cool guy"
TypeError: 'tuple' object does not support item assignment
Same goes for strings. Once defined we cannot modifiy the characters of the string.
my_name = "Firas"
my_name[-1] = 'q'
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
/var/folders/64/bfv2dn992m17r4ztvfrt93rh0000gn/T/ipykernel_40107/666829765.py in <module>
----> 1 my_name[-1] = 'q'
TypeError: 'str' object does not support item assignment
x = ([1,2,3],5)
x[1] = 7
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
/var/folders/64/bfv2dn992m17r4ztvfrt93rh0000gn/T/ipykernel_40107/214141108.py in <module>
----> 1 x[1] = 7
TypeError: 'tuple' object does not support item assignment
x
([1, 2, 3], 5)
x[0][1] = 4
x
([1, 4, 3], 5)
String Methods¶
There are various useful string methods in Python.
all_caps = "HOW ARE YOU TODAY?"
print(all_caps)
HOW ARE YOU TODAY?
new_str = all_caps.lower()
new_str
'how are you today?'
Note that the method lower doesn’t change the original string but rather returns a new one.
all_caps
'HOW ARE YOU TODAY?'
There are many string methods. Check out the documentation.
all_caps.split()
['HOW', 'ARE', 'YOU', 'TODAY?']
all_caps.split()[3]
'TODAY?'
all_caps.count("O")
3
One can explicitly cast a string to a list:
caps_list = list(all_caps)
caps_list
['H',
'O',
'W',
' ',
'A',
'R',
'E',
' ',
'Y',
'O',
'U',
' ',
'T',
'O',
'D',
'A',
'Y',
'?']
len(all_caps)
18
all_caps = all_caps + 'O' + 'o'
all_caps
'HOW ARE YOU TODAY?OoOoOoOo'
all_caps.count('O')
7
len(caps_list)
String formatting¶
Python has ways of creating strings by “filling in the blanks” and formatting them nicely.
There are a few ways of doing this. See here and here for some discussion.
F-Strings are the NEW and RECOMMENDED way of doing string formatting
F-Strings (aka magic)¶
New formatting style (see this article):
name = "Sasha"
age = 4
template_new = f"Hello, my name is {name}. I am {age} years old."
template_new
'Hello, my name is Sasha. I am 4 years old.'
Dictionaries¶
A dictionary is a mapping between key-values pairs.
Reminders: Bracket Notation¶
CURLY Brackets
{}
: create dictionariesROUND Brackets
()
: create tuples ; also use functions this waySQUARE Brackets
[]
: create lists ; also index/slice this way
house = {'bedrooms': 3,
'bathrooms': 2,
'city': 'Vancouver',
'price': 2499999,
'date_sold': (1,3,2015)}
condo = {'bedrooms' : 2,
'bathrooms': 1,
'city' : 'Burnaby',
'price' : 899999,
'date_sold': (27,8,2011)
}
We can access a specific field of a dictionary with square brackets:
house['price']
2499999
condo['price']
899999
condo['city']
'Burnaby'
We can also edit dictionaries (they are mutable):
condo['price'] = 5 # price already in the dict
condo
{'bedrooms': 2,
'bathrooms': 1,
'city': 'Burnaby',
'price': 5,
'date_sold': (27, 8, 2011)}
condo['flooring'] = "wood"
condo
{'bedrooms': 2,
'bathrooms': 1,
'city': 'Burnaby',
'price': 5,
'date_sold': (27, 8, 2011),
'flooring': 'wood'}
A sometimes useful trick about default values:
condo["bedrooms"]
2
is shorthand for
condo.get("bedrooms")
With this syntax you can also use default values:
condo.get("bedrooms", "unknown")
2
condo.get("fireplaces", "unknown")
'unknown'
Empties¶
lst = list() # empty list
lst
lst = [] # empty list
lst
tup = tuple() # empty tuple
tup
tup = () # empty tuple
tup
dic = dict() # empty dict
dic
dic = {} # empty dict
dic
st = set() # emtpy set
st
Conditionals¶
Conditional statements allow us to write programs where only certain blocks of code are executed depending on the state of the program.
Let’s look at some examples and take note of the keywords, syntax and indentation.
Check out the Python documentation and Think Python (Chapter 5) for more information about conditional execution.
name = "firas"
if name.lower() == 'firas':
print("That's my name too!")
elif name.lower() == 'santa':
print("That's a fun name.")
else:
print(f"Hello {name}! That's a cool name.")
print('Nice to meet you!')
name = input("What's your name?")
if name.lower() == 'firas':
print("That's my name too!")
elif name.lower() == 'santa':
print("That's a fun name.")
else:
print(f"Hello {name}! That's a cool name.")
print('Nice to meet you!')
bool(None)
The main points to notice:
Use keywords
if
,elif
andelse
The colon
:
ends each conditional expressionIndentation (by 4 empty space) defines code blocks
In an
if
statement, the first block whose conditional statement returnsTrue
is executed and the program exits theif
blockif
statements don’t necessarily needelif
orelse
elif
lets us check several conditionselse
lets us evaluate a default block if all other conditions areFalse
the end of the entire
if
statement is where the indentation returns to the same level as the firstif
keyword
If statements can also be nested inside of one another:
name = input("What's your name?")
if name.lower() == 'mike':
print("That's my name too!")
elif name.lower() == 'santa':
print("That's a funny name.")
else:
print("Hello {0}! That's a cool name.".format(name))
if name.lower().startswith("super"):
print("Do you have superpowers?")
print('Nice to meet you!')
Preview of next week: loading data with Pandas¶
Introducing DataFrames¶
At the very basic level, Pandas objects can be thought of as enhanced versions of NumPy structured arrays in which the rows and columns are identified with labels rather than simple integer indices.
As we will see during the course of this chapter, Pandas provides a host of useful tools, methods, and functionality on top of the basic data structures, but nearly everything that follows will require an understanding of what these structures are.
Thus, before we go any further, let’s introduce these three fundamental Pandas data structures: the Series
, DataFrame
, and Index
.
We will start our code sessions with the standard NumPy and Pandas imports:
import numpy as np
import pandas as pd
The fundamental structure in Pandas is the DataFrame
.
Like the Series
object discussed in the previous section, the DataFrame
can be thought of either as a generalization of a NumPy array, or as a specialization of a Python dictionary.
We’ll now take a look at each of these perspectives.
Creating a DataFrame¶
There are several ways of creating DataFrames in Python using Pandas and though it can end up with the same end product, the method of creating them can depend on the format of your data.
Let’s look at a few examples:
DataFrame from URL¶
If your dataset exists on the web as a publicly accessible file, you can create a DataFrame directly from the URL to the CSV.
read_csv(path)
is a function from the Pandas package that creates a DataFrame from a CSV file.The argument
path
can be a URL or a reference to a local file.
import pandas as pd
pd.read_csv("https://github.com/firasm/bits/raw/master/fruits.csv")
Fruit Name | Mass(g) | Colour | Rating | |
---|---|---|---|---|
0 | Apple | 200 | Red | 8 |
1 | Banana | 250 | Yellow | 9 |
2 | Cantoloupe | 600 | Orange | 10 |
I can store the dataframe as an object like this:
fruits = pd.read_csv("https://github.com/firasm/bits/raw/master/fruits.csv")
fruits
Fruit Name | Mass(g) | Colour | Rating | |
---|---|---|---|---|
0 | Apple | 200 | Red | 8 |
1 | Banana | 250 | Yellow | 9 |
2 | Cantoloupe | 600 | Orange | 10 |
Attribution¶
This notebook contains an excerpt from the Python Data Science Handbook by Jake VanderPlas; the content is available on GitHub.
The text is released under the CC-BY-NC-ND license, and code is released under the MIT license. If you find this content useful, please consider supporting the work by buying the book!
Extra Stuff¶
Inline if/else¶
words = ["the", "list", "of", "words"]
x = "long list" if len(words) > 10 else "short list"
x
if len(words) > 10:
x = "long list"
else:
x = "short list"
x
Sets¶
Another built-in Python data type is the
set
, which stores an un-ordered list of unique items.
s = {2,3,5,5,11}
s
{1,2,3} == {3,2,1}
[1,2,3] == [3,2,1]
s.add(2) # does nothing
s
s[0]
Above: throws an error because elements are not ordered.
st = {} # NOT an empty set!
type(st)
st = {1}
type(st)
Deleting fields in dictionaries¶
We can delete fields entirely (though I rarely use this):
del condo["city"]
condo
condo[5] = 443345
condo
condo[(1,2,3)] = 777
condo
condo["nothere"]