######################################################## # FUNCTIONS: ######################################################## # main idea -> to modulate (organize) code into segments/blocks. # We do this to make our code easier to read and # maintain/debug. When I make a logical flaw/make a # "bug" in my code, I use functions to quickly locate # where in my code that I am making a mistake. # ex: lets say apple wants to make the new iphone 6 (not again...), # the CEO needs to have a meeting with the head of # the engineering department, the publicity department, the marketing # department, etc and tell them the main goal and # that they each need to do their part to make this overall goal # achievable. Each department is like a program. # the CEO is like the purpose of all your lines of code. # You need each of those departments to do their own # individual things in order to make this iphone 6 happen. # To take it a little further, inside each department # may be sub-departments that will help achieve the overall # goal set by, lets say, the marketing department. # this idea is called top-down design or, in other words, # functions calling functions. # Writing Functions: # 1) functions with no parameters def doSomething(): print "im in a function!" doSomething() doSomething() def f(x, y, z): print "hi" a = 5 f(1, 2, a) # FORMAL ARGUMENT LIST: (x, y, z) # ARGUEMNT LIST: (1, 2, a) # 2) functions with one parameter def printSquare(x): print x, "^2 =", (x*x) printSquare(2) printSquare(3) # 3) functions with multiple parameters def printSum(x,y): print x, "+", y, "=", x+y printSum(2,3) printSum(3,4) # 4) Functions that return a value def square(x): return x*x print square(3) print square(4) x = square(3) + square(4) print x # MEMO example # 5) Functions calling other functions def square(x): return x*x def printSquare(x): print x, "**2 =", square(x) printSquare(3) printSquare(4) # Another example: def square(x): return x**2 def squareRoot(x): return x**0.5 def hypotenuse(a, b): return squareRoot(square(a) + square(b)) a = 3 b = 4 c = hypotenuse(a, b) print "hypotenuse =", c # random tricks: def f(x = 1, y = 2): print 'x = ', x print 'y = ', y f() f(3, 4) f(y = 1, x = 2) f(2) f(y = 1) # local and global scopes: def t(x): print x t(x) x = 5 def f(): y = 5 g(x) def g(x): f = x f -= 1 print f print x ######################################################## # STACK - BASICS: ######################################################## # 1) First in last out!!!! # 2) putting down -> push # 3) picking up -> pop # 4) CAN ONLY WORK AT THE TOP -> peek() -> maintain order!!!! # the function we wrote in recitation to represent a stack: # stack() - uses strings to represent a stack. adds strings by # console input from left to right where the far left # represents the bottom of the stack and the string # at the far right is the top of the stack. Type 'pop' # to remove an element from the stack and 'quit' when you # done. def stack(): stack = '' while (True): x = raw_input("enter something: ") if (x == 'pop'): flag = True index = len(stack) - 2 # bec of space at end length = index # store index for end of loop count = 0 while (flag): if (index <= 0): break elif (stack[index] == ' '): flag = False else: index -= 1 count += 1 stack = stack[0 : length - count] elif (x == "quit"): break else: stack += (x + ' ') print "stack: ", stack ######################################################## # STRINGS: ######################################################## # STRINGS EVERYWHERE!!! print "abcdef" print "abcdefgh"[0] print "abcdefgh"[1] print "abcdefgh"[2] print "---------------" print "abcdefgh"[-1] print "abcdefgh"[-2] print "---------------" print "abcdefgh"[0:3] print "abcdefgh"[1:3] print "abcdefgh"[2:3] print "abcdefgh"[3:3] print "abcdefgh"[3:] print "abcdefgh"[:3] print "---------------" print "abcdefgh"[len("abcdefgh")-1] # print "abcdefgh"[len("abcdefgh")] # INDEX ERROR # print "abcdefgh"[22] # INDEX ERROR! # Escape Sequences print "Double-quote: \"" print "Backslash: \\" print "Newline (in brackets): [\n]" print "Tab (in brackets): [\t]" print "These items are tab-delimited, 3-per-line:" print "abc\tdef\tg\nhi\tj\\\tk\n---" a = "REALLLLLLLLLY!!!!! LOOOOOOONG!!!!! \ STRING!!!!!!!!!!!! \ THAT JUST KEEPS GOING!!!!\ DONE...." print a # prints all in one line!!! because of the '\' # loop with indexes s = "abcd" index = 0 while (index != len(s)): print index, s[index] index += 1 # loop without indexes s = "abcd" for c in s: print c # You cannot change strings! They are immutable. s = "abcde" # s[2] = "z" # error! # string formatting: s = "The %s have won %d Super Bowls" % ("Steelers", 6) print s # prints: The Steelers have won 6 Super Bowls s = "The square root of %d is about %0.2f, give or take" % (5, 5**0.5) print s # prints: The square root of 5 is about 2.24, give or take ############### # hasThreeWords ############### # hasThreeWords # Write the function hasThreeWords that takes a string (which you may assume # only contains letters or spaces) and returns true if the string contains # exactly three words, with no leading spaces, and with each word separated # by exactly one space. def hasThreeWords(s): index = 0 count = 0 while index != len(s): if (index == 0) and (s[0] == ' '): return False elif (s[-1] == ' '): return False elif (s[index] == ' '): if (index + 1 < len(s)) and (s[index + 1] != ' '): count += 1 else: return False index += 1 if (count == 2): return True else: return False def testHasThreeWords(): print "Testing hasThreeWords()...", assert(hasThreeWords("a b c") == True) assert(hasThreeWords("this should work") == True) assert(hasThreeWords("this should work ") == False) assert(hasThreeWords("but this should fail") == False) assert(hasThreeWords("this too") == False) assert(hasThreeWords("likewise") == False) assert(hasThreeWords(" leading space fails") == False) assert(hasThreeWords("no double spaces") == False) print "Passed!" testHasThreeWords() ######################################################## # EXCEPTIONS: ######################################################## def isFactor(factor, n): return (n % factor == 0) #1) Simplest form try: if isFactor(0, 2): print "0 is a factor of 2" if isFactor(2, 0): print "2 is a factor of 0" except: print "We just caught an error" #2) With Exception information try: if isFactor(0, 2): print "0 is a factor of 2" if isFactor(2, 0): print "2 is a factor of 0" except Exception as error: print "We just caught this error:", error #3) Catching specific exception types try: prompt = "Enter a number to invert: " n = float(raw_input(prompt)) # non-float ==> ValueError inverse = 1/n # n==0 ==> ZeroDivisionError if (n == 42): ruhRoh() # no such function! print "The inverse of", n, "is", inverse except ZeroDivisionError: print "Cannot divide by 0." except ValueError: print "You did not enter a number!" except Exception as error: print "Unknown error:", error print " Error type:", type(error) ######################################################## # 1-D LISTS: ######################################################## # 1) Creating Lists: # Empty List a = [ ] b = list() # also creates an empty list # List with One Element a = [ "hello" ] # List with Multiple Elements a = [ 2, 3, 5, 7 ] a = range(2, 8) # same thing as above list! # range is inclusive of the first number # AND exclusive of the last number! because of len()! # List with Multiple Elements of Different Types a = [ 2, "dog", False, 3.14 ] # List with Duplicate Elements a = [ "wow" ] * 5 print a # prints ['wow', 'wow', 'wow', 'wow', 'wow'] # List from Another Sequence Type a = list("abcd") print a # prints ['a', 'b', 'c', 'd'] # 2) List Properties (len, min, max, sum): a = [ 2, 3, 5, 2 ] print "a = ", a print "len =", len(a) print "min =", min(a) print "max =", max(a) print "sum =", sum(a) # 3) Accessing Elements: # Create a list a = [2, 3, 5, 7, 11, 13] print "a =", a # Access non-negative indexes print "a[0] =", a[0] print "a[2] =", a[2] # Access negative indexes print "a[-1] =", a[-1] print "a[-3] =", a[-3] # Access slices a[start:end:step] print "a[0:2] =", a[0:2] print "a[1:4] =", a[1:4] print "a[1:6:2] =", a[1:6:2] # 4) List Aliases: # Create a list a = [ 2, 3, 5, 7 ] # Create an alias to the list b = a # We now have two references (aliases) to the SAME list a[0] = 42 b[1] = 99 print a print b # Function parameters are aliases, too! def f(a): a[0] = 42 a = [2, 3, 5, 7] f(a) print a # *** another example *** # Create a list a = [ 2, 3, 5, 7 ] # Create an alias to the list b = a # Create a different list with the same elements c = [ 2, 3, 5, 7 ] # a and b are references (aliases) to the SAME list # c is a reference to a different but EQUAL list print "initially:" print " a==b :", a==b print " a==c :", a==c print " a is b:", a is b print " a is c:", a is c # Now changes to a also change b (the SAME list) but not c (a different list) a[0] = 42 print "After changing a[0] to 42" print " a=",a print " b=",b print " c=",c print " a==b :", a==b print " a==c :", a==c print " a is b:", a is b print " a is c:", a is c ######### # insert ######### # Write the function insert(a, x, i) that non-destructively # inserts x into the ith position of a. So if a = [5,3,1,9], # insert(a, 4, 2) would return [5,3,4,1,9], but a would still be [5,3,1,9]. def insert(a, x, i): length = len(a) b = range(0, length+1) # (length + 1) because we are adding an element!! # get a copy of 'a' that is NON-ALIASED!! for k in range(0, length): temp = a[k] b[k] = temp # slice the part of list that will be added after inserted element f = b[i:length] # slice the part of list that will be before inserted element b = b[0:i+1] # reassign 'b' because we are going to add the new element # add the new element at index 'i' b[i] = x # add the chopped off part to the end b += f return b def testInsert(): print "testing insert()..." a = range(0, 6) # inclusive on left and exclusive on right! assert(insert(a, 0, 0) == [0, 0, 1, 2, 3, 4, 5]) assert(insert(a, "poop", 3) == [0, 1, 2, "poop", 3, 4, 5]) assert(insert(a, ("HOT", "DAMN"), 5) == [0, 1, 2, 3, 4, ("HOT", "DAMN"), 5]) assert(insert(a, range(0, 6), 0) == [[0, 1, 2, 3, 4, 5], 0, 1, 2, 3, 4, 5]) print "all tests passed!" testInsert() ######################################################## # SETS: ######################################################## engineers = set(['John', 'Jane', 'Jack', 'Janice']) programmers = set(['Jack', 'Sam', 'Susan', 'Janice']) managers = set(['Jane', 'Jack', 'Susan', 'Zack']) print "engineers: ", engineers print "programmers: ", programmers print "managers: ", managers employees = engineers | programmers | managers # union print "employees (engineers | programmers | managers) : ", employees engineering_management = engineers & managers # intersection print "engineering_management (engineers & managers) : ", engineering_management fulltime_management = managers - engineers - programmers # difference print "fulltime_management (managers - engineers - programmers) : ", fulltime_management