# 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()
# Use input(string) to request a string from the keyboard
result_string = input("prompt: ")
print(result_string)
# 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))
# 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))
# 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)]))
See https://docs.python.org/3/reference/expressions.html#operator-precedence for Python "PEMDAS"
# Adding works for many types
print(1 + 2)
print(1 + 2.5)
print("a" + "b")
print("A" + str("1"))
print([1, 2] + [3, 4])
# 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)
# 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)
# 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)
# 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'])
# 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])
# 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
Note: strings are immutable, meaning they cannot be changed (but you can create a new string based upon the contents of an old one)
# 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
# Use len(string) to find out how many characters are in the string
print(len("abcd"))
# 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('.'))
# Use string.join(list) to create a string by joining each list element with the string
print("-".join(['nameA', 'nameB', 'nameC']))
# 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))
# Use string.upper()/lower() to change case
print("Howdy".upper())
print("Howdy".lower())
# Use string.strip() to remove whitespace at the beginning/end of a string
print("<" + " Howdy ".strip() + ">")
Note: lists are mutable, meaning they can be changed
# You can create an empty list a couple ways...
print([])
print(list())
# 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)
# 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)
# 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)
# 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]))
# 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
# 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)
# 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])
Dictionaries are unordered collections of key-value pairs, where keys are unique and immutable
# 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)
# 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)
# 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))
# 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)
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))
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))
# And yes, there are dictionary comprehensions
print({x:x**2 for x in range(11) if x % 2 == 0})
Used to execute one or more lines only if a condition holds
# 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...")
# 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!")
# 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!")
Fancy word for doing things over and over
# 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)
# 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)
# Use enumerate(list) to get both the list index and value
for index, value in enumerate(['a', 'b', 'c']):
print("list[{}] = {}".format(index, value))
# 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))
# 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!")
# 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))
# Functions can be supplied as parameters
def myfunc2(value, func):
return func(value)
print(myfunc2("hello", len))
# 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))
# 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))
# 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)
# 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)
# 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)
# 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]
# 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()
Files are a resource that must be opened and closed...
# 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)
There are multiple ways to get data out of a file...
# .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)
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)