DS2000 (Spring 2019, NCH) :: Python Reference

Output

In [2]:
# Use print(expression) to output a value to the screen
print(3.14159)
print("abc")
print([1, 2, 3])

# Use print() to just output an empty line (potentially useful for spacing)
print()

Input

In [3]:
# Use input(string) to request a string from the keyboard
result_string = input("prompt: ")
print(result_string)
prompt: word
word

Data Types

In [4]:
# Use type(expression) to get the type of the result of an expression
print(type(5))
print(type(5.0))

x = 7
print(type(x))
print(type(x + 5.0))
<class 'int'>
<class 'float'>
<class 'int'>
<class 'float'>
In [5]:
# Integers are just written as sequences of digits (possibly with +/- preceding)
x = 42
print(type(x))

# Floats either use scientific notation or a decimal point
x = 42.
print(type(x))

x = 6.02e23
print(type(x))

# Booleans represent either True or False
x = True
print(type(x))

x = False
print(type(x))

# Strings are surrounded by quotes (single or double, as long as consistent)
x = "hello"
print(type(x))

# Lists are surrounded by square brackets with contents comma-separated
x = [1, 2, 3]
print(type(x))

# Tuples are surrounded by paren's (or not) with contents comma-separated
# (basically read-only lists)
x = (1, 2, 3)
print(type(x))

x = 1, 2, 3
print(type(x))

# Dictionaries are surrounded by {}'s with comma-separated key:value pairs
x = {'a':1, 'b':2, 'c':3}
print(type(x))
<class 'int'>
<class 'float'>
<class 'float'>
<class 'bool'>
<class 'bool'>
<class 'str'>
<class 'list'>
<class 'tuple'>
<class 'tuple'>
<class 'dict'>
In [6]:
# Data types commonly have functions to convert values
print(int(4.2)) # simply "truncates", or removes, decimal part (i.e. always rounds down)
print(float(4))
print(int("42"))
print(float("4.2"))

print(int(False)) # False = 0
print(int(True)) # True = 1
print(bool(0))
print(bool(1))

print(type("42"))
print(type(int("42")))
print(type(float("42")))

print(type(42))
print(type(str(42)))

print(list("abc"))

print(tuple("abc"))

print(dict([('a', 1), ('b', 2), ('c', 3)]))
4
4.0
42
4.2
0
1
False
True
<class 'str'>
<class 'int'>
<class 'float'>
<class 'int'>
<class 'str'>
['a', 'b', 'c']
('a', 'b', 'c')
{'a': 1, 'b': 2, 'c': 3}
In [7]:
# Adding works for many types
print(1 + 2)
print(1 + 2.5)

print("a" + "b")
print("A" + str("1"))

print([1, 2] + [3, 4])
3
3.5
ab
A1
[1, 2, 3, 4]
In [8]:
# Division (/): order matters and by default floating-point
print(11 / 4)

# For integer division, use // (and modulo, %, for remainder)
print(11 // 4)
print(11 % 4)
2.75
2
3
In [9]:
# Multiplication works for many data types
print(2 * 5)
print(3 * 2.5)

print("a" * 5)
print([1, 2] * 3)
print((1, 2) * 3)

# Exponentiation is achieved via **
print(2 ** 5)
10
7.5
aaaaa
[1, 2, 1, 2, 1, 2]
(1, 2, 1, 2, 1, 2)
32
In [10]:
# The assignment operator (=) evaluates the right-hand side and
# stores it into the left (which should be a variable)
x = 1 + 2
print(x)

print()

# Tuples allow for multiple concurrent assignment via "unpacking"
a, b = 1, 2
print(a)
print(b)

print()

# There are shorthand operators for common variable-updating tasks
x = 1
print(x)
x += 1 # same as x = x + 1
print(x)
x *= 2 # same as x = x * 2
print(x)
3

1
2

1
2
4
In [11]:
# Finding an element in a sequence/container is achieved via []
# (remember indexes start at 0; negatives start at the end)
print([1, 2, 3][0])
print([1, 2, 3][2])
print([1, 2, 3][-1])
print([1, 2, 3][-2])

print()

print((1, 2, 3)[0])
print((1, 2, 3)[2])
print((1, 2, 3)[-1])
print((1, 2, 3)[-2])

print()

print("abc"[0])
print("abc"[2])
print("abc"[-1])
print("abc"[-2])

print()

# This also works for keys within a dictionary
print({'a':1, 'b':2, 'c':3}['b'])
1
3
3
2

1
3
3
2

a
c
c
b

2
In [12]:
# Slicing gets a subsequence via start:end:step
# default start = beginning
# default end = end
# default step = 1
print([1, 2, 3, 4, 5, 6][1:4:2])
print([1, 2, 3, 4, 5, 6][3:])
print([1, 2, 3, 4, 5, 6][:3])
print([1, 2, 3, 4, 5, 6][::-1])
[2, 4]
[4, 5, 6]
[1, 2, 3]
[6, 5, 4, 3, 2, 1]
In [13]:
# Comparison operators return a Boolean to answer a question
print(0 == 1) # equal to?
print(0 != 1) # not equal to?
print(0 > 1)
print(0 <= 1)

print()

print("a" < "b")
print("aa" < "ab")
print("B" < "a") # note: uppercase comes "before" lowercase

print()

# Particular to sequences/containers: in
print("i" in "team")
print("i" in ["t", "e", "a", "m"])
print("i" in ("t", "e", "a", "m"))
print("a" in {'a':1, 'b':2, 'c':3}) # by key!

print()

# Logical operators are used to create expressions combining values/operators
print(not True) # not: flips True to False and vice-versa
print(("m" in "team") and ("e" in "team")) # and: returns True if ALL are True
print((len("team") == 4) or (len("team") == 5)) # or: returns True if ANY are True
False
True
False
True

True
True
True

False
False
False
True

False
True
True

Strings

Note: strings are immutable, meaning they cannot be changed (but you can create a new string based upon the contents of an old one)

In [14]:
# Within a string, backslash is used to indicate special characters
print("line 1\nline 2") # new line
print("column 1\tcolumn2") # tab
print("windows key above enter: \\") # backslash
line 1
line 2
column 1	column2
windows key above enter: \
In [15]:
# Use len(string) to find out how many characters are in the string
print(len("abcd"))
4
In [16]:
# Use string.split(optional_string) to create a list of strings separated by the argument
# If no argument is supplied, whitespace is assumed
print("these are words".split())
print("these are words".split(' '))

print("first.last".split('.'))
['these', 'are', 'words']
['these', 'are', 'words']
['first', 'last']
In [17]:
# Use string.join(list) to create a string by joining each list element with the string
print("-".join(['nameA', 'nameB', 'nameC']))
nameA-nameB-nameC
In [18]:
# Use string.format(...) to produce a string based upon 
# a template and expression(s) whose value are inserted at 
# particular locations in the string, potentially formatted,
# based upon relative ordering of {} in the template and
# comma-separated arguments to format
print('{} inches = {} foot'.format(2 * 6, 1))

# Within the {}'s in the template string are additional commands
# generally starting with : and ending with a one-character
# representation of data type (e.g., f=float, s=string, d=integer)

print("{:s}".format("foo"))

# Between : and data type may come useful formatting commands...

print("One million: {}".format(1000000))
print("One million: {:d}".format(1000000))
print("One million: {:,d}".format(1000000))

print("Pi: {}".format(3.14159))
print("Pi: {:f}".format(3.14159))
print("Pi: {:.1f}".format(3.14159))
print("Pi: {:.2f}".format(3.14159))
print("Pi: {:.3f}".format(3.14159))
print("Pi: {:.4f}".format(3.14159))
print("Pi: {:.5f}".format(3.14159))
print("Pi: {:.6f}".format(3.14159))

# Using values within {} is doable, but unintuitive
print("Pi: {:.{}f}".format(3.14159, 4))
12 inches = 1 foot
foo
One million: 1000000
One million: 1000000
One million: 1,000,000
Pi: 3.14159
Pi: 3.141590
Pi: 3.1
Pi: 3.14
Pi: 3.142
Pi: 3.1416
Pi: 3.14159
Pi: 3.141590
Pi: 3.1416
In [19]:
# Use string.upper()/lower() to change case
print("Howdy".upper())
print("Howdy".lower())
HOWDY
howdy
In [20]:
# Use string.strip() to remove whitespace at the beginning/end of a string
print("<" + "      Howdy    ".strip() + ">")
<Howdy>

Lists

Note: lists are mutable, meaning they can be changed

In [21]:
# You can create an empty list a couple ways...
print([])
print(list())
[]
[]
In [22]:
# The + operator creates a new list by concatenating existing lists
# The list.append(expression) function allows you to add to an existing list
mylist = []
print(mylist)
mylist.append('a')
print(mylist)
mylist.append(1)
print(mylist)
mylist.append([3, 1, 4, 1, 5, 9])
print(mylist)
[]
['a']
['a', 1]
['a', 1, [3, 1, 4, 1, 5, 9]]
In [23]:
# The list.pop(index) function allows you to remove from an existing list by index
# and returns the removed value

mylist = [8, 6, 7, 5, 3, 0, 9]
print(mylist)

removed = mylist.pop(5)
print(removed)
print(mylist)
[8, 6, 7, 5, 3, 0, 9]
0
[8, 6, 7, 5, 3, 9]
In [24]:
# The [] operator allows you to change an element within a list
mylist = ['a', 1, [3, 1, 4, 1, 5, 9]]
print(mylist)
mylist[1] += 1
print(mylist)
mylist[2].append(2)
print(mylist)
['a', 1, [3, 1, 4, 1, 5, 9]]
['a', 2, [3, 1, 4, 1, 5, 9]]
['a', 2, [3, 1, 4, 1, 5, 9, 2]]
In [25]:
# Use len(list) to count the number of elements in a list
mylist = ['a', 1, [3, 1, 4, 1, 5, 9]]
print(len(mylist))
print(len(mylist[2]))
3
6
In [26]:
# For lists of numbers...
print(sum([1, 3, 2])) # add up the elements
print(min([1, 3, 2])) # find the smallest value
print(max([1, 3, 2])) # find the biggest value
6
1
3
In [27]:
# Sorting/reversing lists come in two flavors: change an existing or create a new one

mylist = [1, 2, 3]

print(mylist)
print(list(reversed(mylist))) # doesn't change mylist
print(mylist)

mylist.reverse() # changes mylist (doesn't return anything)
print(mylist)

print()

mylist = [8, 6, 7, 5, 3, 0, 9]

print(mylist)
print(list(sorted(mylist))) # doesn't change mylist
print(mylist)

mylist.sort() # changes mylist (doesn't return anything)
print(mylist)
[1, 2, 3]
[3, 2, 1]
[1, 2, 3]
[3, 2, 1]

[8, 6, 7, 5, 3, 0, 9]
[0, 3, 5, 6, 7, 8, 9]
[8, 6, 7, 5, 3, 0, 9]
[0, 3, 5, 6, 7, 8, 9]
In [28]:
# A list comprehension allows you to create a list via
# [func(x) for x in list if check(x)]
# (where check is optional)

print([x**2 for x in range(5)])
print([x**2 for x in range(5) if x % 2 == 1])
[0, 1, 4, 9, 16]
[1, 9]

Dictionaries

Dictionaries are unordered collections of key-value pairs, where keys are unique and immutable

In [29]:
# Create an empty dictionary
print({})
print(dict())

# Create a dictionary with content
mydict = {'a':1, 'b':2}
print(mydict)

# Create a dictionary from a list/tuple of key/value pairs
mydict = dict([(1, 'one'), (2, 'two'), (3, 'three')])
print(mydict)
{}
{}
{'a': 1, 'b': 2}
{1: 'one', 2: 'two', 3: 'three'}
In [30]:
# Add to a dictionary simply by indexing based upon a key
mydict = {'a':1, 'b':2}
print(mydict)
mydict['c'] = 3
print(mydict)

# Note that since keys are unique, accessing the same key *changes* the value
mydict['c'] = 300
print(mydict)
{'a': 1, 'b': 2}
{'a': 1, 'b': 2, 'c': 3}
{'a': 1, 'b': 2, 'c': 300}
In [31]:
# Reading using an invalid index will result in
# an error, so check
myvotes = {"alice":300, "bob":111, "carol":22}
x = 0

if "carol" in myvotes:
    x = myvotes["carol"]


# OR a common pattern: get with default
# Get the value, or a default value if invalid

print(myvotes.get('carol', 0))
print(myvotes.get('dan', 0))
22
0
In [32]:
# As with lists, .pop() is useful for removal
myvotes = {"alice":300, "bob":111, "carol":22}

print(myvotes)
removed_votes = myvotes.pop("bob")
print(myvotes)
print(removed_votes)
{'alice': 300, 'bob': 111, 'carol': 22}
{'alice': 300, 'carol': 22}
111
In [33]:
myvotes = {"alice":300, "bob":111, "carol":22}

# You can individually get the dictionary keys...
print(list(myvotes.keys()))

# You can individually get the dictionary values...
print(list(myvotes.values()))

# Or both...
print(list(myvotes.items()))

# len works!
print(len(myvotes))
['alice', 'bob', 'carol']
[300, 111, 22]
[('alice', 300), ('bob', 111), ('carol', 22)]
3
In [34]:
myvotes = {"alice":300, "bob":111, "carol":22}

# Looping defaults to keys
for element in myvotes:
    print(element)
    
# Commonly you loop over items
for key, value in myvotes.items():
    print("{} = {}".format(key, value))
alice
bob
carol
alice = 300
bob = 111
carol = 22
In [35]:
# And yes, there are dictionary comprehensions
print({x:x**2 for x in range(11) if x % 2 == 0})
{0: 0, 2: 4, 4: 16, 6: 36, 8: 64, 10: 100}

Conditional Execution

Used to execute one or more lines only if a condition holds

In [36]:
# Simplest: if by itself
if True:
    print("execute me")
    print("and me!")
print("me too, me too!")

if False:
    print("not me")
    print("nor me :(")
print("one is the loneliest number...")
execute me
and me!
me too, me too!
one is the loneliest number...
In [37]:
# Can optionally add a single else (what to do if condition is false)
if True:
    print("I'm in!")
    print("I am Sparticus!")
else:
    print("But not I")
    
if False:
    print("No one here")
    print("Nope")
else:
    print("Freedom!")
    print("I'm here too!")
I'm in!
I am Sparticus!
Freedom!
I'm here too!
In [38]:
# Full form: if, optionally any number of elif (condition required), optional else
# Tries each condition in sequence, once it finds a match
# action(s) performed then exit the if/elif/else
x = 1

if x == 1:
    print("I win")
elif x == 2:
    print("No dice")
elif x > 0:
    print("You'd think, but no")
else:
    print("Not a chance")
print("Yup!")

if x != 1:
    print("So close!")
elif x < 2:
    print("My turn!")
elif x > 0:
    print("One of these days...")
else:
    print("I never win :(")
print("Hehe :)")

if x != 1:
    print("Not again :(")
elif x > 2:
    print("Not I")
elif x > 0:
    print("Finally :')")
else:
    print("Biding my time...")
print("Always!")

if x != 1:
    print("It was an honor to be nominated")
elif x > 2:
    print("I had my 15 minutes")
elif x < 0:
    print("It was fine while it lasted")
else:
    print("Buhahahaha!")
print("It's good to be the king!")
I win
Yup!
My turn!
Hehe :)
Finally :')
Always!
Buhahahaha!
It's good to be the king!

Iteration

Fancy word for doing things over and over

In [39]:
# The for loop instructs Python to execute any number of lines
# FOR EACH element in a sequence/container;
# during each "iteration" (element in the sequence/container)
# call the "current" element X (where X is the variable name)
# supplied immediately after for

for X in [1, 2, 3]:
    print("Value of X is {}".format(X))
    
for another_name in "team":
    if another_name == "i":
        print("Well that's shocking...")
    print(another_name)
Value of X is 1
Value of X is 2
Value of X is 3
t
e
a
m
In [40]:
# Use range([start], end, [step]) to efficiently create a numerical sequence

for num in range(1, 5, 2):
    print(num)
    
# If you don't care about the numbers (e.g., want to repeat a code block
# some number of times), use _ after for

for _ in range(10):
    print("Repeated action")
    
# You *can* convert range into a list, but don't unless you need to (saves time/memory)
1
3
Repeated action
Repeated action
Repeated action
Repeated action
Repeated action
Repeated action
Repeated action
Repeated action
Repeated action
Repeated action
In [41]:
# Use enumerate(list) to get both the list index and value

for index, value in enumerate(['a', 'b', 'c']):
    print("list[{}] = {}".format(index, value))
list[0] = a
list[1] = b
list[2] = c
In [42]:
# Use zip(list1, list2, ...) to walk multiple lists in parallel

for el1, el2, el3 in zip(['a', 'b', 'c'], [1, 2, 3], ['i', 'ii', 'iii']):
    print("{} {} {}".format(el1, el2, el3))
a 1 i
b 2 ii
c 3 iii
In [43]:
# The while loop instructs Python to execute any number of lines
# WHILE a condition holds

counter = 0

while counter < 10:
    print(counter)
    counter += 1

print("escaped!")
0
1
2
3
4
5
6
7
8
9
escaped!

Functions

In [44]:
# Defines a function named "myfunc"
# that takes two parameters (first named param1,
# second named param2)
def myfunc(param1, param2):
    if param1 > param2:
        return 1
    elif param2 > param1:
        return 2
    else:
        return 0

print(myfunc(3, 5))
print(myfunc(7, 5))
print(myfunc(4, 4))
2
1
0
In [45]:
# Functions can be supplied as parameters
def myfunc2(value, func):
    return func(value)

print(myfunc2("hello", len))
5
In [46]:
# Parameters can have "default" values,
# which makes their presence optional
def myfunc(a, b=5):
    return a + b

print(myfunc(1, 2))
print(myfunc(1))
3
6
In [47]:
# Parameters can be supplied by name

def myfunc(a, b=5, c=7, d=11):
    return sum((a, b, c, d))

print(myfunc(1))
print(myfunc(1, d=10))
print(myfunc(a=1, b=2, c=3, d=4))
24
23
10

Modules

In [48]:
# import a module to gain access to its contents
import string

print(string.ascii_lowercase)
print(string.ascii_uppercase)
print(string.digits)
print(string.punctuation)
abcdefghijklmnopqrstuvwxyz
ABCDEFGHIJKLMNOPQRSTUVWXYZ
0123456789
!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~
In [49]:
# use from to select specific functions
from string import ascii_lowercase, ascii_uppercase # just get lower/uppercase, no need to string.

print(ascii_lowercase)
print(ascii_uppercase)
abcdefghijklmnopqrstuvwxyz
ABCDEFGHIJKLMNOPQRSTUVWXYZ
In [50]:
# you can rename modules/contents
import string as silly_name # rename the module
from string import punctuation as silly_punctuation # rename the variable

print(silly_name.digits)
print(silly_punctuation)
0123456789
!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~
In [51]:
# when you need a random number...
import random

# a random "seed" allows you to get the same sequence reproducibly
random.seed(123)

print(random.random()) # 0-1
print(random.random()) # 0-1
print(random.random()) # 0-1

random.seed(123)

print(random.random()) # 0-1
print(random.random()) # 0-1
print(random.random()) # 0-1

random.seed(123)

for _ in range(10):
    print(random.randint(1, 3)) # integer in [1, 3]

print()
random.seed(123)

for _ in range(10):
    print(random.randint(1, 3)) # integer in [1, 3]
0.052363598850944326
0.08718667752263232
0.4072417636703983
0.052363598850944326
0.08718667752263232
0.4072417636703983
1
2
1
2
2
1
1
2
3
3

1
2
1
2
2
1
1
2
3
3
In [52]:
# When writing a program that has executable code, check that
# __name__ is "__main__"

def main():
    print('Code to be executed when running via python (but not import)')

if __name__ == "__main__":
    main()
Code to be executed when running via python (but not import)

Files

Files are a resource that must be opened and closed...

In [53]:
# the r refers to "read"
myfile = open("myfile.txt", "r")
full_contents = myfile.read()
myfile.close()
print(full_contents)

# to avoid forgetting to close
# (with will close the file once it exits
#  the code block)
with open("myfile.txt", "r") as myfile:
    full_contents = myfile.read()
print(full_contents)
hello there
this is the content of a file
1 2 3
:)

hello there
this is the content of a file
1 2 3
:)

There are multiple ways to get data out of a file...

In [54]:
# .read() gets the full file into a single string
# (note this will include new lines, \n!)
with open("myfile.txt", "r") as myfile:
    full_contents = myfile.read()
print(full_contents)

# .readline() reads the next line
# (note this will include new lines, \n!)
with open("myfile.txt", "r") as myfile:
    line1 = myfile.readline()
    line2 = myfile.readline()
print(line1)
print(line2)

# .readlines() reads the full file into
# a list of strings, where each line is an
# element in the list
with open("myfile.txt", "r") as myfile:
    all_lines = myfile.readlines()
print(all_lines)

# finally, you can simply loop through lines via for
with open("myfile.txt", "r") as myfile:
    for line in myfile:
        print(line)
hello there
this is the content of a file
1 2 3
:)

hello there

this is the content of a file

['hello there\n', 'this is the content of a file\n', '1 2 3\n', ':)\n']
hello there

this is the content of a file

1 2 3

:)

OOP

In [55]:
class MyClassName:
    
    # constructor
    # sets up initial field values
    # (in this case, some based upon
    # parameters to the constructor)
    def __init__(this, param1, param2):
        this.field1 = param1
        this.field2 = param2
        this.field3 = []
        
    def add_to_f3(this, x):
        this.field3.append(x)
    
    # called automatically via str(obj)
    # or print(obj)
    def __str__(this):
        return "field1={} field2={} field3={}".format(this.field1, this.field2, str(this.field3))

    ## called automatically via this == other
    ## return true if the two objects are the "same"
    def __eq__(this, other):
        return isinstance(other, MyClassName) and this.field2 == other.field2

# Makes new instances/objects
# (each calls the constructor)
obj1 = MyClassName('a', 'b')
obj2 = MyClassName('a', 'c')
obj3 = MyClassName('d', 'b')

obj1.add_to_f3('foo')
obj1.add_to_f3('bar')
obj1.add_to_f3('baz')

# calls __str__
print(obj1)

# calls __eq__
print(obj1 == obj2)
print(obj1 == obj3)
field1=a field2=b field3=['foo', 'bar', 'baz']
False
True