Class 4A: Introduction to Programming in Python#

We will begin soon! Until then, feel free to use the chat to socialize, and enjoy the music!

../../../_images/programming3.jpg


Photo by Christina Morillo from Pexels
Firas Moosvi

Class Outline:#

  • Announcements (5 mins)

    • GitHub Classroom link for projects is now released!

    • Details of the Contract Grading are now closer to final version

    • Test 1 details are here

    • Reminder: Milestone 1 is due on Thursday at 6 PM!

    • If you do not yet have a group, you’re VERY far behind!

    • I need to leave my student hours from 11:15 - 11:45 today, but I’ll be here till 12:30 PM

  • Finish up last Friday’s class (10 mins)

    • Booleans

    • Comparison Operators

    • Casting

  • Digging Deeper into Python syntax

    • Lists and tuples (10 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)
Cell In[12], line 1
----> 1 my_list[5]

IndexError: list index out of range
today[4]

We use negative indices to count backwards from the end of the list.

my_list
my_list[-1]
my_list[4]
my_list[len(my_list)-1]

We use the colon : to access a subsequence. This is called “slicing”.

my_list[1: ]
my_list[1:3]
  • 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]
my_list[:3]
my_list[3:]
my_list[:] # *almost* same as my_list - more details next week (we might not, just a convenience thing)

Strings behave the same as lists and tuples when it comes to indexing and slicing.

alphabet = "abcdefghijklmnopqrstuvwyz"
alphabet[0]
alphabet[-1]
alphabet[-3]
alphabet[:5]
alphabet[12:20]

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
len(primes)
primes.append(13)
primes
len(primes)
max(primes)
min(primes)
# 2 is a semi-prime number
sum(primes)
my_list
my_list = [1, 2, 'THREE', 4, 0.5]
my_list.append(primes)
my_list
my_list[-1][-1]
my_list = [1, 2, 'THREE', 4, 0.5]
my_list.extend(primes)
my_list
my_list[-1]
[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
names_list[0] = "Cool guy"
names_list
names_tuple = ("Indiana","Fang","Linsey")
names_tuple
names_tuple[0] = "Not cool guy" 

Same goes for strings. Once defined we cannot modifiy the characters of the string.

my_name = "Firas"
my_name[-1] = 'q'
x = ([1,2,3],5)
x[1] = 7
x
x[0][1] = 4
x

String Methods#

  • There are various useful string methods in Python.

all_caps = "HOW ARE YOU TODAY?"
print(all_caps)
new_str = all_caps.lower()
new_str

Note that the method lower doesn’t change the original string but rather returns a new one.

all_caps

There are many string methods. Check out the documentation.

all_caps.split()
all_caps.split()[3]
all_caps.count("O") 

One can explicitly cast a string to a list:

caps_list = list(all_caps)
caps_list
len(all_caps)
all_caps = all_caps + 'O' + 'o' 
all_caps
all_caps.count('O')
len(caps_list)

Pick up on friday here

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 dictionaries ; operations in f-strings

  • ROUND Brackets () : create tuples ; also use functions this way

  • SQUARE 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
condo['location']
---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
Input In [38], in <cell line: 1>()
----> 1 condo['location']

KeyError: 'location'

is shorthand for

condo.get("bedrooms")
2

With this syntax you can also use default values:

condo.get("location", "unknown")
'unknown'
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
set()

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.")

elif name.lower() == 'harry':
    print('Jack in the box')

else:
    print(f"Hello {name}! That's a cool name.")

    print('Nice to meet you!')
That's my name too!
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!')
What's your name?Isabella
Hello Isabella! That's a cool name.
Nice to meet you!
bool(None)
False

The main points to notice:

  • Use keywords if, elif and else

  • The colon : ends each conditional expression

  • Indentation (by 4 empty space) defines code blocks

  • In an if statement, the first block whose conditional statement returns True is executed and the program exits the if block

  • if statements don’t necessarily need elif or else

  • elif lets us check several conditions

  • else lets us evaluate a default block if all other conditions are False

  • the end of the entire if statement is where the indentation returns to the same level as the first if 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!')
What's your name?superfiras
Hello superfiras! That's a cool name.
Do you have superpowers?
Nice to meet you!

That’s it!#

You’re done for today!

See you next class.

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"]