├── 01-Object-and-Data-Structure-Basics ├── dictionaries.py ├── exercises.txt ├── files.py ├── lists.py ├── numbers.py ├── print_formatting.py ├── sets_boolean.py ├── strings.py ├── test_file.txt └── tuples.py ├── 02-Comparison-Operators └── chained_comparison.py ├── 03-Python-Statements ├── for_loops.py ├── list_comprehensions.py ├── loop_else.py ├── range.py ├── statements_assessment.py └── while_loop.py ├── 04-Methods-and-Functions ├── Functions and Methods Homework.py ├── Nested Statements and Scope.py ├── functions.py ├── lambda.py └── methods.py ├── 05-Object-Oriented-Programming └── OOP.py ├── 06-Errors-And-Exception-Handling └── Errors_and_Expections.py ├── 07-Modules-And-Packages └── Modules_Packages.py ├── 08-Builtin-Functions ├── advanced functions test.py ├── all() and any().py ├── complex.py ├── enumerate.py ├── filter.py ├── map.py ├── reduce.py └── zip.py ├── 09-Decorators ├── dec-example-timer.py ├── decorator.py └── functions review.py ├── 10-Iterators-and-Generators ├── generator expressions.py ├── iterators and generators - homework.py └── iterators and generators.py ├── 11-Final-Capstone-Projects ├── coin flip simulation.py ├── dec_bin.py ├── distance between cities.py └── prime factorization.py ├── 12-Advanced-Modules ├── Collections-Module │ ├── counter-module.py │ ├── defaultdict-module.py │ ├── named-tuple.py │ └── ordered-dict-module.py ├── Regular-Expressions-Module │ ├── character-ranges.py │ ├── character-sets.py │ ├── escape-codes.py │ ├── exclusion.py │ ├── pattern-re-syntax.py │ └── regular-expressions.py ├── datetime-module.py ├── pdb-debugger.py ├── stringIO-module.py └── timeit-module.py ├── 13-Advanced-Object-and-Data-Structures ├── advanced-dictionaries.py ├── advanced-lists.py ├── advanced-numbers.py ├── advanced-sets.py └── advanced-strings.py ├── 14-Introducing-GUIs ├── .ipynb_checkpoints │ └── 1-interact-checkpoint.ipynb └── 1-interact.ipynb ├── MP2 - Test.py ├── Milestone Project 1 - TicTacToe Game.py ├── Milestone Project 2 - Blackjack 2.0.py └── Milestone Project 2 - Blackjack.py /01-Object-and-Data-Structure-Basics/dictionaries.py: -------------------------------------------------------------------------------- 1 | # DIctionaries are very flexable in what they can hold 2 | dict = {'key1': 1, 'key2': 4, 'key3': 'bacon', 'key4': ['item0', 'item1', 'item2']} 3 | print dict['key3'] 4 | print dict['key4'][0].upper() 5 | 6 | dict['key2'] -= 4 7 | print dict['key2'] 8 | 9 | dict2 = {} 10 | dict2['one'] = 'one' # creating a new key through assignment 11 | dict2['two'] = 2 12 | print dict2 13 | 14 | dict3 = {'key1': {'nestkey': {'subnestkey': 'value'}}} 15 | # NB: Keys are defined as strings, and should be called as such 16 | print dict3['key1']['nestkey']['subnestkey'] 17 | 18 | # Dictionary methods 19 | print dict.keys() # return a list of all keys 20 | print dict.values() # return all values 21 | print dict.items() # return tuples of all key-value pairs 22 | -------------------------------------------------------------------------------- /01-Object-and-Data-Structure-Basics/exercises.txt: -------------------------------------------------------------------------------- 1 | Before you begin your assessment, I wanted to point out some helpful links for practice: 2 | 3 | Basic Practice: 4 | http://codingbat.com/python 5 | 6 | More Mathematical (and Harder) Practice: 7 | https://projecteuler.net/archives 8 | 9 | List of Practice Problems: 10 | http://www.codeabbey.com/index/task_list 11 | 12 | A SubReddit Devoted to Daily Practice Problems: 13 | https://www.reddit.com/r/dailyprogrammer 14 | 15 | A very tricky website with very few hints and touch problems (Not for beginners but still interesting) 16 | http://www.pythonchallenge.com/ -------------------------------------------------------------------------------- /01-Object-and-Data-Structure-Basics/files.py: -------------------------------------------------------------------------------- 1 | # iPython: 2 | # %%writefile test.txt 3 | # Hello, this is text to a file 4 | 5 | my_file = open('test_file.txt', 'w+') # open (create) file for writing 6 | my_file.write('This is new data\n') # write data to file 7 | my_file.write('Some more data') 8 | 9 | my_file.seek(0) # reset cursor to start (seek to the start of file [index zero]) 10 | print my_file.readlines() # read data and store in memory 11 | 12 | my_file.seek(0) 13 | print my_file.read() # print data sequentially 14 | 15 | my_file.seek(0) 16 | for line in open('test_file.txt'): 17 | print line 18 | -------------------------------------------------------------------------------- /01-Object-and-Data-Structure-Basics/lists.py: -------------------------------------------------------------------------------- 1 | my_list = [1, 4, "b", "c", 5.3] 2 | print my_list[:2] 3 | print my_list[2:] 4 | 5 | my_list += ["e"] 6 | 7 | print my_list 8 | print my_list[5] + " " + my_list[2] + " " + my_list[3] 9 | 10 | print my_list * 2 11 | 12 | # Append method 13 | my_list.append("added") 14 | print my_list 15 | 16 | # Pop method - Pop off an item from the list 17 | my_list.pop(0) # pop off item at index zero 18 | my_list.pop() 19 | print my_list 20 | 21 | # Reverse method 22 | my_list.reverse() 23 | print my_list 24 | 25 | # Sort method - Alphabetical for charaters, ascending for numbers 26 | my_list.sort() 27 | print my_list 28 | -------------------------------------------------------------------------------- /01-Object-and-Data-Structure-Basics/numbers.py: -------------------------------------------------------------------------------- 1 | ''' 2 | PYTHON 2: Classic division (3/2=1) 3 | PYTHON 3: True division (3/2=1.5) 4 | 5 | Optional for PYTHON 2: 6 | from __future__ import division # imports true division from python 3 7 | 8 | ''' 9 | 10 | 11 | numbers = [3/2 , 3.0/2 , 3/2.0 , float(3)/2] 12 | print numbers 13 | 14 | # powers 15 | print 3**2 16 | 17 | # roots 18 | print 4**0.5 19 | 20 | # orders of operation followed by python 21 | print 2 + 10 * 10 + 3 22 | 23 | -------------------------------------------------------------------------------- /01-Object-and-Data-Structure-Basics/print_formatting.py: -------------------------------------------------------------------------------- 1 | # Floating point numbers 2 | # Format: %n1.n2f , where 3 | # n1 = total minimum number of digits the string should contain 4 | # n2 = how many digits to show past the decimal point 5 | 6 | print "Num: %1.2f" %(13.114) 7 | print "Num: %1.0f" %(13.114) 8 | print "Num: %1.5f" %(13.114) 9 | print "Num: %10.2f" %(13.114) 10 | print "Num: %25.2f" %(13.114) 11 | 12 | # Conversion format methods: 13 | # %s and %r actually convert any python object to a string using two seperate methods: str() and repr() 14 | print 'Here is a number: %s. Here is a string: %s' %(123.1,'hi') 15 | print 'Here is a number: %r. Here is a string: %r' %(123.1,'hi') 16 | 17 | # Multiple formatting 18 | print "First: %s, Second: %1.2f, Third: %r" %('hello', 1.342, 22) 19 | 20 | # .format() method 21 | print "This is a %s or a %s" %("bacon", "cat") 22 | print "This is a {a} or a {b}".format(a="bacon", b="cat") 23 | print "A {p} will allways be a {p} is this {p} world".format(p='dog') -------------------------------------------------------------------------------- /01-Object-and-Data-Structure-Basics/sets_boolean.py: -------------------------------------------------------------------------------- 1 | # sets are an unordered collection of unique elements 2 | x = set() 3 | x.add(1) 4 | print x 5 | 6 | x.add(2) 7 | x.add(1) # note that, since the value 1 is already in the set, the contents of x will remain unchanged 8 | print x 9 | 10 | l = [1, 2, 2, 3, 3, 4, 4, 4, 5, 6] 11 | print set(l) # notice that the duplicated are removed 12 | 13 | # Boolean: We can use the placeholder NONE for a variable we don't want to 14 | # asign yet 15 | test = True 16 | print test 17 | test2 = None # placeholder 18 | -------------------------------------------------------------------------------- /01-Object-and-Data-Structure-Basics/strings.py: -------------------------------------------------------------------------------- 1 | ''' 2 | PYTHON 2: print "print this info" -> statement 3 | PYTHON 3: print("print this info") -> function 4 | 5 | Option for PYTHON 2: 6 | from __future__ import print_function 7 | ''' 8 | 9 | 10 | # use single or double quotes 11 | str = "hello world" 12 | str2 = 'hello words' 13 | 14 | print str[0] # print the first letter 15 | print str[2:] # print from the third letter onwards 16 | print str[:3] # print up to the third letter 17 | print str[-1] # print the last letter 18 | print str[:-1] # print up to the last letter 19 | print str[::1] # print each letter, step sizes of one 20 | print str[::2] # print every second letter 21 | print str[::-1] # print the string in reverse 22 | 23 | # strings are immutable: str[2] = 'e' will produce an error 24 | 25 | str = str + ' bacon' 26 | print str 27 | 28 | print str * 5 29 | 30 | print len(str) 31 | print str.upper() # upper case 32 | print str.lower() # lower case 33 | print str.split() # split string by blank space (default) 34 | print str.split('w') # split string by element 35 | 36 | print "insert word here: {}".format("bacon") 37 | -------------------------------------------------------------------------------- /01-Object-and-Data-Structure-Basics/test_file.txt: -------------------------------------------------------------------------------- 1 | This is new data 2 | Some more data -------------------------------------------------------------------------------- /01-Object-and-Data-Structure-Basics/tuples.py: -------------------------------------------------------------------------------- 1 | # Tuples are similar to list, but immutable 2 | 3 | t = (1, 2, 3, 4, 5, 1, 2, 3) # t[0] = 5 would produce an error 4 | 5 | print len(t) 6 | print t 7 | print t[0] 8 | print t[-1] 9 | print t[::-1] 10 | 11 | # Tuples methods 12 | print t.index(2) # Return the index of a value 13 | print t.count(2) # Counts the number of times a value appears 14 | -------------------------------------------------------------------------------- /02-Comparison-Operators/chained_comparison.py: -------------------------------------------------------------------------------- 1 | a = 2 2 | b = 3 3 | c = 4 4 | 5 | print "a < b < c:", a < b < c 6 | print "a < b > c:", a < b > c 7 | print "a < b and b < c: ", a < b and b < c 8 | -------------------------------------------------------------------------------- /03-Python-Statements/for_loops.py: -------------------------------------------------------------------------------- 1 | # strings are sequences, so we can iterate over them 2 | str = 'this is a string' 3 | for letter in str: 4 | print letter 5 | 6 | # notice the special property of using tuples in a for loop 7 | t = ((1, 2), (3, 4), (5, 6)) 8 | 9 | for tup in t: 10 | print tup 11 | 12 | for (t1, t2) in t: # UNPACKING: here we can access individual elements of a tuple 13 | print t1 14 | 15 | d = {'key1': 1, 'key2': 2, 'key3': 3} 16 | 17 | for item in d: 18 | print item # notice: only the keys are printed 19 | 20 | # PYTHON 2: iteritems() 21 | 22 | for j, k in d.iteritems(): # d.iteritems() creates a generator 23 | print '{a} , {b}'.format(a=j, b=k) 24 | print '{0} , {1}'.format(j, k) 25 | print '%s , %d' % (j, k) 26 | 27 | """ 28 | # PYTHON 3: items() 29 | 30 | for j,k in d.items(): 31 | print ('{0} , {1}'.format(j,k)) 32 | """ 33 | -------------------------------------------------------------------------------- /03-Python-Statements/list_comprehensions.py: -------------------------------------------------------------------------------- 1 | # grab every letter in a string 2 | lst1 = [x for x in 'word'] 3 | print lst1 4 | 5 | # square numbers in range and turn into list 6 | lst2 = [x**2 for x in range(1, 6)] 7 | print lst2 8 | 9 | # add if statements 10 | lst3 = [x for x in range(11) if x % 2 == 0] 11 | print lst3 12 | 13 | # nested list comprehension 14 | lst4 = [x**2 for x in [x**2 for x in range(1, 6)]] 15 | print lst4 16 | 17 | # perform complicated arithmetic 18 | celsius = [0, 10, 20.1, 34.5] 19 | fahrenheit = [(32 + temp * (float(9) / 5)) for temp in celsius] 20 | print fahrenheit -------------------------------------------------------------------------------- /03-Python-Statements/loop_else.py: -------------------------------------------------------------------------------- 1 | test_val = 0 2 | 3 | # Loops support using else statements 4 | 5 | while test_val < 3: # the else statement is executed when the while condition becomes false 6 | print test_val 7 | test_val += 1 8 | else: 9 | print 'Finished' 10 | 11 | for k in range(1, 5): 12 | for i in (1, 2, 3): # the else statement is executed when the for loop has exhausted iterating the list 13 | if i == k: 14 | print '%d - True' % (k) 15 | break 16 | else: 17 | print '%d - False' % (k) -------------------------------------------------------------------------------- /03-Python-Statements/range.py: -------------------------------------------------------------------------------- 1 | x = range(0, 10) 2 | print type(x), x 3 | 4 | ''' 5 | notice that the range function stores the values in memory as a list 6 | 7 | when using for loops in python 2, the function xrange() should rather be used. xrange() creates a generator, only providing 8 | each value in the for loop as it is needed 9 | 10 | in python 3, the range() function serves as generator in a for loop 11 | ''' 12 | 13 | for i in xrange(0, 5): 14 | print i 15 | -------------------------------------------------------------------------------- /03-Python-Statements/statements_assessment.py: -------------------------------------------------------------------------------- 1 | st = 'Print only the words that start with s in this sentence' 2 | 3 | # Use for, split(), and if to create a Statement that will print out words that start with 's': 4 | st = st.split() 5 | for item in st: 6 | if item[0] == 's': 7 | print item 8 | 9 | # Use range() to print all the even numbers from 0 to 10. 10 | print [x for x in xrange(11) if x%2 == 0] 11 | print range(0,11,2) 12 | 13 | # Use List comprehension to create a list of all numbers between 1 and 50 that are divisble by 3. 14 | div3 = [x for x in xrange(1,51) if x%3==0] 15 | print div3 16 | 17 | # Go through the string below and if the length of a word is even print "even!" 18 | lst = [] 19 | st = 'Print every word in this sentence that has an even number of letters' 20 | st = st.split() 21 | for word in st: 22 | if len(word)%2==0: 23 | lst.append(word) 24 | print lst 25 | 26 | 27 | # Write a program that prints the integers from 1 to 100. But for multiples of three print "Fizz" instead of the number, 28 | # and for the multiples of five print "Buzz". For numbers which are multiples of both three and five print "FizzBuzz". 29 | lst2 = [] 30 | for num in xrange(1,101): 31 | if num%3 == 0 and num%5 == 0: 32 | lst2.append("FizzBuzz") 33 | elif num%3 == 0: 34 | lst2.append("Fizz") 35 | elif num%5 == 0: 36 | lst2.append("Buzz") 37 | else: 38 | lst2.append(num) 39 | print lst2 40 | 41 | # Use List Comprehension to create a list of the first letters of every word in the string below: 42 | st = 'Create a list of the first letters of every word in this string' 43 | lst3 = [x[0] for x in st.split()] 44 | print lst3 45 | 46 | -------------------------------------------------------------------------------- /03-Python-Statements/while_loop.py: -------------------------------------------------------------------------------- 1 | ''' 2 | break = breaks out of the closest enclosing loop 3 | continue = goes to the top of the closest enclosing loop 4 | pass = does nothing at all 5 | ''' 6 | 7 | test_val = 0 8 | 9 | while test_val < 10: 10 | if test_val in (1,2,3): 11 | test_val += 1 12 | continue # returns to the top of the while loop 13 | elif test_val == 7: 14 | break # ends/breaks the while loop 15 | print test_val 16 | test_val += 1 -------------------------------------------------------------------------------- /04-Methods-and-Functions/Functions and Methods Homework.py: -------------------------------------------------------------------------------- 1 | # Write a function that computes the volume of a sphere given its radius 2 | import math 3 | def vol(rad): 4 | return (4/3) * math.pi * (rad**3) 5 | print vol(5) 6 | 7 | 8 | # write a function that checks whether a number is in a given range (inclusive of high and low) 9 | def ran_check(num,low,high): 10 | if num in range(low,high+1): 11 | return True 12 | return False 13 | print ran_check(5,6,10) 14 | print ran_check(10,6,10) 15 | 16 | 17 | # write a python module that accepts a string and returns the number of upper case and lower case letters 18 | def up_low(s): 19 | count = {'upper':0, 'lower':0} 20 | for letter in s: 21 | if letter.islower(): 22 | count['lower'] += 1 23 | elif letter.isupper(): 24 | count['upper'] += 1 25 | print "Upper: ",count['upper'] 26 | print "Lower: ",count['lower'] 27 | up_low("This is B") 28 | 29 | 30 | # write a Python function that accepts a list and returns a new list with all the unique values 31 | l = [1,1,1,1,2,3,3,4,4,4,5] 32 | def unique_list(lst): 33 | temp = [] 34 | for num in set(lst): 35 | temp += [num] 36 | return temp 37 | print unique_list(l) 38 | 39 | def unique_list2(lst): 40 | return list(set(lst)) 41 | print unique_list2(l) 42 | 43 | 44 | # write a python function that multiplies all the numbers in a list 45 | def multiply(numbers): 46 | mult = numbers[0] 47 | for num in range(1,len(numbers)): 48 | mult *= numbers[num] 49 | return mult 50 | print multiply([1,2,3,4]) 51 | 52 | 53 | # write a Python function that checks whether a passed string is a pallendrome or not 54 | def palindrome(s): 55 | test = "" 56 | for word in s.split(): 57 | test += word 58 | if test == test[::-1]: 59 | return True 60 | else: 61 | return False 62 | print palindrome("Test Files case") 63 | print palindrome("nurses run") 64 | 65 | # suggested solution 66 | def palindrome_sug(s): 67 | s = s.replace(' ','') #replace all spaces with no space 68 | return s == s[::-1] #check through slicing 69 | print palindrome_sug('nurses run') 70 | 71 | # write a python function to check whether a passed string is a pangram or not (contains all letters of the alphabet) 72 | import string 73 | 74 | def is_pangram(s, alphabet=string.ascii_lowercase): 75 | alphaset = set(alphabet) 76 | alphaset.add(" ") 77 | return alphaset <= set(s.lower()) # determine if the string set contains each entry in the alphaset set 78 | print is_pangram('the quick brown fox jumps over the lazy 123456789') 79 | print is_pangram('the quick brown fox jumps over the lazy dog') 80 | print is_pangram('thequickbrownfoxjumpsoverthelazydog!') 81 | -------------------------------------------------------------------------------- /04-Methods-and-Functions/Nested Statements and Scope.py: -------------------------------------------------------------------------------- 1 | ''' 2 | The idea of scope can be described by 3 general rules: 3 | 1. Name assignments will create or change local names by default 4 | 2. Name references search (at most) four scopes, these are: 5 | - local 6 | - enclosing functions 7 | - global 8 | - built-in 9 | 3. Names declared in global and nonlocal statements map assigned names to enclosing module and function scopes 10 | ''' 11 | 12 | 13 | # Local - Names assigned in any way within a function (def or lambda), and not declared global in that function 14 | f = lambda x: x**2 15 | 16 | 17 | # Enclosing function locals - Name in scope of any and all enclosing functions (def and lambda), from inner to outer 18 | name = "this is a global name" 19 | 20 | def greet(): 21 | # enclosing function 22 | name = "sammy" 23 | 24 | def hello(): 25 | print 'Hello '+name 26 | hello() 27 | greet() 28 | 29 | 30 | # Global (module) - Name assigned at the top level of a module file, or declared global in a def within the file 31 | print name 32 | 33 | 34 | # Built-in (python) - Names preassigned in the built-in names module: open,range,SyntaxError,... 35 | print type(len) 36 | 37 | 38 | # Local variables 39 | x = 20 40 | def changeX(x): 41 | print "x is ",x 42 | x = 50 43 | print "changed x to ",x 44 | changeX(x) 45 | print "x is still ",x 46 | 47 | 48 | # Global statement 49 | x = 50 50 | def func(): 51 | global x 52 | print 'This function is now using the global x!' 53 | print 'Because of global x is: ', x 54 | x = 2 55 | print 'Ran func(), changed global x to', x 56 | 57 | print 'Before calling func(), x is: ', x 58 | func() 59 | print 'Value of x (outside of func()) is: ', x -------------------------------------------------------------------------------- /04-Methods-and-Functions/functions.py: -------------------------------------------------------------------------------- 1 | """ 2 | def name_of_function(arg1,arg2): 3 | ''' 4 | This is where the function's Document string (docstring) goes 5 | ''' 6 | # Do stuff here 7 | # Return desired result 8 | 9 | 10 | def function_name(parameters): 11 | '''docstring''' 12 | statement(s) 13 | """ 14 | 15 | import math 16 | 17 | def is_prime(num): 18 | ''' 19 | Naive method of checking for primes 20 | :param num: number to check for prime status 21 | :return: NONE 22 | ''' 23 | for n in xrange(2,num): 24 | if num % n == 0: 25 | print 'not prime' 26 | break 27 | else: # if never mod zero, then prime 28 | print 'prime' 29 | 30 | is_prime(16) 31 | 32 | def is_prime2(num): 33 | ''' 34 | Better method of checking for primes 35 | :param num: number to check for prime 36 | :return: prime status 37 | ''' 38 | if num % 2 == 0 and num > 2: 39 | return False 40 | for i in range(3, int(math.sqrt(num)) + 1, 2): 41 | if num % i == 0: 42 | return False 43 | return True 44 | 45 | print is_prime2(16) 46 | -------------------------------------------------------------------------------- /04-Methods-and-Functions/lambda.py: -------------------------------------------------------------------------------- 1 | ''' 2 | the lambda expression allows us to create "anonymous" functions 3 | 4 | lambda's body is a single expression, not a block of statements 5 | 6 | For a great breakdown of the lambda expression: 7 | https://pythonconquerstheuniverse.wordpress.com/2011/08/29/lambda_tutorial/ 8 | 9 | Form: lambda argument(s): return 10 | ''' 11 | 12 | # this is the form that the lambda expression intends to replicate 13 | def square(num): return num**2 14 | 15 | # Determine the square using a lambda function 16 | square = lambda num: num**2 17 | 18 | print type(square) # note that the variable square is assigned a function 19 | print square(2) 20 | 21 | # Determine if a number is even 22 | even = lambda x: x % 2 == 0 23 | print even(2), even(3) 24 | 25 | # Return the first letter of a string 26 | first = lambda s: s[0] 27 | print first("Hello") 28 | 29 | # Reverse a string 30 | rev = lambda s: s[::-1] 31 | print rev("Hello") 32 | 33 | # We can accept more than one function in the lambda expression 34 | adder = lambda x, y: x + y 35 | print adder(2, 4) 36 | 37 | # notice how lambda can be called anonymously (without asigning to a variable) 38 | new_list = [(lambda x: x*3)(num) for num in range(5)] 39 | print new 40 | -------------------------------------------------------------------------------- /04-Methods-and-Functions/methods.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Methods are essentially functions build into objects 3 | 4 | Methods are in the form: 5 | object.method(arg1,arg2,etc...) 6 | 7 | You'll later see that we can think of methods as having an argument 'self' referring to the object itself. 8 | You can't see this argument but we will be using it later on in the course during the OOP lectures. 9 | ''' 10 | 11 | l = [1, 2, 3, 4, 5] 12 | 13 | # append() allows us to add elements to the list 14 | l.append(6) 15 | print l 16 | 17 | # count() will count the number of occurrences of an element in the list 18 | print l.count(2) 19 | 20 | # extend list by appending items from an iterable 21 | l.extend(x for x in range(7, 11)) 22 | print l 23 | 24 | # insert object before index 25 | l.insert(2, 'insert') 26 | print l 27 | 28 | # remove and return item at index (default last item) 29 | print l.pop() 30 | print l.pop(2) 31 | print l 32 | 33 | # remove first occurance of a value (returns ValueError if value not present) 34 | l.remove(5) 35 | print l 36 | 37 | try: 38 | l.remove(5) 39 | except ValueError: 40 | print 'Value not present' 41 | 42 | # reverse in place 43 | l.reverse() 44 | print l 45 | 46 | # l.sort(cmp=None, key=None, reverse=False) 47 | l.sort() 48 | print l 49 | l.sort(reverse=True) 50 | print l 51 | -------------------------------------------------------------------------------- /05-Object-Oriented-Programming/OOP.py: -------------------------------------------------------------------------------- 1 | # CLASS 2 | # user defined object are created using the class keyword 3 | # from classes we create instances (specific object created from a particular class) 4 | 5 | class Sample(object): # by convention class names start with a capital letter 6 | pass 7 | 8 | # instance of sample 9 | x = Sample() 10 | 11 | print type(x) 12 | 13 | 14 | 15 | 16 | # ATTRIBUTES 17 | # attributes are charateristics of an object 18 | # syntax: self.attribute = something 19 | # special method used to initialize attributes: __init__() 20 | 21 | class Dog(object): 22 | species = 'mammal' # class object attribute (same for any instance of class) 23 | def __init__(self, breed, name): # called automatically after object has been created 24 | self.breed = breed # each attribute in a class defenition begins with a reference to the instance object (by convention named self) 25 | self.name = name 26 | 27 | sam = Dog(breed='Lab', name='Sam') 28 | print sam.breed # note no parentheses (attributes dont take arguments) 29 | print sam.name 30 | 31 | 32 | 33 | 34 | # METHODS 35 | # functions defined inside the body of a class 36 | # perform operations with the attributes of an object 37 | 38 | class Circle(object): 39 | pi = 3.14 40 | 41 | def __init__(self, radius=1): 42 | self.radius = radius 43 | 44 | def area(self): 45 | return (self.radius * self.radius * Circle.pi) 46 | 47 | def setRadius(self, radius): 48 | self.radius = radius 49 | 50 | def getRadius(self): 51 | return self.radius 52 | 53 | c = Circle() 54 | c.setRadius(2) 55 | print 'Radius is: ', c.getRadius() 56 | print 'Area is: ', c.area() 57 | 58 | 59 | 60 | 61 | # INHERITANCE 62 | # way to form new classes using classes that have already been defined 63 | # newly formed classes are called derived classes 64 | # derived classes (descendants) override or extend the functionality of base classes (ancestors) 65 | 66 | class Animal(object): 67 | def __init__(self): 68 | print "Animal created" 69 | 70 | def whoAmI(self): 71 | print "Animal" 72 | 73 | def eat(self): 74 | print "Eating" 75 | 76 | 77 | class Dog(Animal): 78 | def __init__(self): 79 | Animal.__init__(self) 80 | print "Dog created" 81 | 82 | def whoAmI(self): 83 | print "Dog" 84 | 85 | def bark(self): 86 | print "Woof!" 87 | 88 | dog = Dog() # note that the print statements of both the Animal and Dog classes are executed (functionality extended) 89 | dog.whoAmI() # overwrites functionality 90 | dog.bark() # extends functionality 91 | dog.eat() # inherits functionality 92 | 93 | 94 | 95 | 96 | # SPECIAL METHODS 97 | # these methods are not called directly but by Python specific language syntax 98 | 99 | class Book(object): 100 | def __init__(self, title, author, pages): 101 | print "A book is created" 102 | self.title = title 103 | self.author = author 104 | self.pages = pages 105 | 106 | def __str__(self): # called when print Book_instance is executed 107 | return "Title:%s , author:%s, pages:%s " %(self.title, self.author, self.pages) 108 | 109 | def __len__(self): # called when len(Book_instance) is executed 110 | return self.pages 111 | 112 | def __del__(self): # called when an instance of the Book class is destroyed 113 | print "A book is destroyed" 114 | 115 | book = Book("Python Rocks!", "Jose Portilla", 159) 116 | 117 | # Special Methods 118 | print book 119 | print len(book) 120 | del book 121 | -------------------------------------------------------------------------------- /06-Errors-And-Exception-Handling/Errors_and_Expections.py: -------------------------------------------------------------------------------- 1 | 2 | ''' SYNTAX: 3 | 4 | try: 5 | You do your operations here... 6 | except ExceptionI: 7 | If there is ExceptionI, then execute this block. 8 | except ExceptionII: 9 | If there is ExceptionII, then execute this block. 10 | else: 11 | If there is no exception then execute this block. 12 | finally: 13 | This code block would always be executed. 14 | ''' 15 | 16 | 17 | def askint(): 18 | while True: # notice the use of a while loop to keep prompting 19 | try: 20 | val = int(raw_input("Please enter an integer: ")) 21 | except: 22 | print "Looks like you did not enter an integer!" 23 | continue 24 | else: 25 | print 'Yep thats an integer!' 26 | break 27 | finally: 28 | print "Finally, I executed!" 29 | print val -------------------------------------------------------------------------------- /07-Modules-And-Packages/Modules_Packages.py: -------------------------------------------------------------------------------- 1 | ''' 2 | WRITING PACKAGES: 3 | 4 | Packages are name-spaces which contain multiple packages and modules themselves. They are simply directories, but with a twist. 5 | 6 | Each package in Python is a directory which MUST contain a special file called __init__.py. This file can be empty, and it indicates that the directory it contains is a Python package, so it can be imported the same way a module can be imported. 7 | 8 | If we create a directory called foo, which marks the package name, we can then create a module inside that package called bar. We also must not forget to add the __init__.py file inside the foo directory. 9 | 10 | The __init__.py file can also decide which modules the package exports as the API, while keeping other modules internal, by overriding the __all__ variable, like so: 11 | 12 | __init__.py: 13 | 14 | __all__ = ["bar"] 15 | ''' 16 | 17 | 18 | import math 19 | 20 | print dir(math) # can be used to print all functions available in module 21 | 22 | print help(math.ceil) # prints the documentation for a function within a module -------------------------------------------------------------------------------- /08-Builtin-Functions/advanced functions test.py: -------------------------------------------------------------------------------- 1 | ''' 2 | For this test, you should use the built-in functions to be able to write the requested functions in one line. 3 | ''' 4 | 5 | # PROBLEM 1: 6 | # Use map to create a function which finds the length of each word in the phrase (broken by spaces) and return 7 | # the values in a list.The function will have an input of a string, and output a list of integers. 8 | 9 | str = "This is bacon" 10 | len_words = map(lambda x: len(x),str.split()) 11 | print len_words 12 | len_words_solution = map(len,str.split()) 13 | print len_words_solution 14 | 15 | # PROBLEM 2: 16 | # Use reduce to take a list of digits and return the number that they correspond to. 17 | # Do not convert the integers to strings! 18 | 19 | num_list = [1,2,3,4,5] 20 | num = reduce(lambda x,y: x*10+y,num_list) 21 | print num 22 | 23 | # PROBLEM 3: 24 | # Use filter to return the words from a list of words which start with a target letter. 25 | 26 | words = ['this','cow','fat','chicken','seen','cat'] 27 | c_words = filter(lambda x: x[0] == 'c', words) 28 | print c_words 29 | 30 | # PROBLEM 4: 31 | # Use zip and list comprehension to return a list of the same length where each value is the two strings 32 | # from L1 and L2 concatenated together with connector between them. Look at the example output below: 33 | 34 | def concatenate(l1,l2,connector): 35 | return [x+connector+y for x,y in zip(l1,l2)] 36 | print concatenate(['get','you'],['mad','skank'],'-') 37 | 38 | # PROBLEM 5: 39 | # Use enumerate and other skills to return a dictionary which has the values of the list as keys and the index 40 | # as the value. You may assume that a value will only appear once in the given list. 41 | 42 | def swop_list(l): 43 | dout = {} 44 | for key,value in enumerate(l): 45 | dout[value] = key 46 | return dout 47 | print swop_list(['a','b','c']) 48 | 49 | lst = ['a','b','c'] 50 | dict_list = {key:value for value,key in enumerate(lst)} 51 | print dict_list 52 | 53 | # PROBLEM 6: 54 | # Use enumerate and other skills from above to return the count of the number of items in the list 55 | # whose value equals its index. 56 | 57 | lst = [0,1,3,4,5,5] 58 | eq_index = len(filter(lambda x: x[0]==x[1],enumerate(lst))) 59 | print eq_index 60 | eq_index_solution = len([num for count,num in enumerate(lst) if num == count]) 61 | print eq_index_solution 62 | 63 | -------------------------------------------------------------------------------- /08-Builtin-Functions/all() and any().py: -------------------------------------------------------------------------------- 1 | ''' 2 | all() and any() are built-in functions in Python that allow us to convienently check for boolean matching in an 3 | iterable. all() will return True if all elements in an iterable are True. It is the same as this function code: 4 | 5 | def all(iterable): 6 | for element in iterable: 7 | if not element: 8 | return False 9 | return True 10 | 11 | any() will return True if any of the elements in the iterable are True. It is equivalent to the following funciton code: 12 | 13 | def any(iterable): 14 | for element in iterable: 15 | if element: 16 | return True 17 | return False 18 | ''' 19 | 20 | 21 | lst = [True,True,False,True] 22 | print all(lst) 23 | print any(lst) -------------------------------------------------------------------------------- /08-Builtin-Functions/complex.py: -------------------------------------------------------------------------------- 1 | ''' 2 | complex() returns a complex number with the value real + imag*1j or converts a string or number to a complex number. 3 | 4 | If the first parameter is a string, it will be interpreted as a complex number and the function must be called 5 | without a second parameter. The second parameter can never be a string. Each argument may be any numeric type 6 | (including complex). If imag is omitted, it defaults to zero and the constructor serves as a numeric conversion 7 | like int and float. If both arguments are omitted, returns 0j. 8 | 9 | If you are doing math or engineering that requires complex numbers (such as dynamics,control systems, or 10 | impedence of a circuit) this is a useful tool to have in Python. 11 | ''' 12 | 13 | print complex(2,3) 14 | print complex('2+3j') -------------------------------------------------------------------------------- /08-Builtin-Functions/enumerate.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Enumerate allows you to keep a count as you iterate through an object. 3 | It does this by returning a tuple in the form (count,element). 4 | 5 | The function self is equivalent to: 6 | 7 | def enumerate(sequence, start=0): 8 | n = start 9 | for elem in sequence: 10 | yield n, elem 11 | n += 1 12 | ''' 13 | 14 | lst = ['a','b','c'] 15 | 16 | for number,item in enumerate(lst): 17 | print number,item 18 | 19 | for count,item in enumerate(lst): 20 | if count >= 2: 21 | break 22 | else: 23 | print item -------------------------------------------------------------------------------- /08-Builtin-Functions/filter.py: -------------------------------------------------------------------------------- 1 | ''' 2 | PYTHON 3: filter returns an iterable, not a list as in python 2. Use list() if required 3 | 4 | Syntax: filter(function,sequence) 5 | 6 | filter returns all elements in the sequence iterable for which the function returns True 7 | ''' 8 | 9 | # NOTE: filter(P, S) can almost always be written as [x for x in S if P(x)] -> lambda is slower than list comprehension 10 | 11 | lst = range(10) 12 | 13 | print filter(lambda x: x % 2 == 0, lst) # return all even numbers 14 | print filter(lambda x: x > 3, lst) # return all numbers greater than 3 -------------------------------------------------------------------------------- /08-Builtin-Functions/map.py: -------------------------------------------------------------------------------- 1 | ''' 2 | PYTHON 3: map returns an iterable, not a list as in python 2. Use list() if required 3 | 4 | Syntax: map(function,sequence) 5 | 6 | map subjects each element in the sequence to the specified function, and returns the results in the form of a list 7 | ''' 8 | 9 | # NOTE: map(F, S) can almost always be written as [F(x) for x in S] -> lambda is slower than list comprehension 10 | 11 | def farenheit(T): 12 | return (9.0/5)*T + 32 13 | 14 | temps = [0, 22.5, 40, 100] 15 | 16 | print map(farenheit, temps) # notice that the function is not passed with parentheses 17 | 18 | print map(lambda T: (9.0/5)*T + 32, temps) 19 | 20 | a = [1, 2, 3] 21 | b = [4, 5, 6] 22 | c = [7, 8, 9] 23 | 24 | print map(lambda x, y, z: x+y+z, a, b, c) # lambda function can use muliple arguments -------------------------------------------------------------------------------- /08-Builtin-Functions/reduce.py: -------------------------------------------------------------------------------- 1 | ''' 2 | PYTHON 3: reduce returns an iterable (use list() if required). import from functools 3 | 4 | Syntax: reduce(function,sequence) 5 | 6 | reduce the elements in the sequence to a single value by iteratively applying the specified function 7 | ''' 8 | 9 | list = [4, 56, 23, 453, 666, 23, 6789, 34] 10 | 11 | # find the maximum value in a list 12 | print reduce(lambda a, b: a if (a > b) else b, list) 13 | 14 | # funt the sum of the values in a list 15 | print reduce(lambda a, b: a+b, list) 16 | -------------------------------------------------------------------------------- /08-Builtin-Functions/zip.py: -------------------------------------------------------------------------------- 1 | # coding=utf-8 2 | ''' 3 | zip() makes an iterator that aggregates elements from each of the iterables. 4 | 5 | Returns an iterator of tuples, where the i-th tuple contains the i-th element from each of the argument 6 | sequences or iterables. The iterator stops when the shortest input iterable is exhausted. With a single 7 | iterable argument, it returns an iterator of 1-tuples. With no arguments, it returns an empty iterator. 8 | 9 | zip() is equivalent to: 10 | 11 | def zip(*iterables): 12 | # zip('ABCD', 'xy') --> Ax By 13 | sentinel = object() 14 | iterators = [iter(it) for it in iterables] 15 | while iterators: 16 | result = [] 17 | for it in iterators: 18 | elem = next(it, sentinel) 19 | if elem is sentinel: 20 | return 21 | result.append(elem) 22 | yield tuple(result) 23 | 24 | 25 | zip() should only be used with unequal length inputs when you don’t care about trailing, unmatched values 26 | from the longer iterables. 27 | ''' 28 | 29 | x = [1,2,3] 30 | y = [4,5,6] 31 | print zip(x,y) 32 | 33 | x = [1,2,3] 34 | y = [4,5,6,7,8] 35 | print zip(x,y) #zip stops when the shortest iterable is exhausted 36 | 37 | d1 = {'a':1,'b':2} 38 | d2 = {'c':4,'d':5} 39 | print zip(d1,d2) 40 | print zip(d1,d2.itervalues()) 41 | 42 | 43 | # switch the keys and values of two dictionaries 44 | def switch(d1,d2): 45 | dout = {} 46 | 47 | for d1key,d2value in zip(d1,d2.itervalues()): 48 | dout[d1key] = d2value 49 | 50 | return dout 51 | 52 | print switch(d1,d2) -------------------------------------------------------------------------------- /09-Decorators/dec-example-timer.py: -------------------------------------------------------------------------------- 1 | # usefull example of how to use decorator 2 | # decorator prints the execution time of the wrapped function 3 | 4 | import time 5 | 6 | 7 | def timerWrapper(func): 8 | def executionTime(str): 9 | t0 = time.time() 10 | func(str) 11 | t1 = time.time() 12 | print "Execution time: ", t0-t1 13 | return executionTime 14 | 15 | @timerWrapper 16 | def printText(str): 17 | print str 18 | 19 | printText('This is some random text to print') -------------------------------------------------------------------------------- /09-Decorators/decorator.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Decorators can be thought of as functions which modify the functionality of another function. 3 | They help to make your code shorter and mote "Pythonic". 4 | ''' 5 | 6 | def decorate_function(func): 7 | def wrap_func(): 8 | print "This goes before the function" 9 | func() 10 | print "This goes after the function" 11 | return wrap_func #NB: not returned with parentheses. function is not called, rather returned and assigned 12 | 13 | def basic_function(): 14 | print "BASIC FUNCTION EXECUTED" 15 | 16 | basic_function() 17 | 18 | basic_function = decorate_function(basic_function) 19 | basic_function() 20 | -------------------------------------------------------------------------------- /09-Decorators/functions review.py: -------------------------------------------------------------------------------- 1 | def func(): 2 | return 1 3 | print func() 4 | 5 | s = 'Global Variable' 6 | 7 | def func_locals(): 8 | print locals() 9 | 10 | # Local and global variables can be determined using the locals() and globals() functions 11 | 12 | print 'Global variable keys: ',globals().keys() 13 | print 'Value of global variable at key "s": ',globals()['s'] 14 | 15 | print func_locals() 16 | 17 | 18 | # Remember: EVERYTHING in Python is an object 19 | 20 | def hello(name='Nico'): 21 | print 'Hello '+name 22 | hello() 23 | greet = hello #notice no parentheses. the function hello is not called, rather just assigned to the greet variable 24 | print type(greet) #greet is now a function 25 | 26 | del hello 27 | greet() #the existance of the greet() function is not dependant on that of the hello() function 28 | 29 | # FUNCTIONS INSIDE FUNCTIONS: 30 | def new_hello(name='Nico'): 31 | print 'The hello() function has been executed' 32 | 33 | def greet(): 34 | return '\t This is inside the greet() function' 35 | 36 | def welcome(): 37 | return "\t This is inside the welcome() function" 38 | 39 | print greet() 40 | print welcome() 41 | print "Now we are back inside the hello() function" 42 | 43 | new_hello() 44 | 45 | # RETURNING FUNCTIONS 46 | def final_hello(name='Nico'): 47 | 48 | def greet(): 49 | return '\t This is inside the greet() function' 50 | 51 | def welcome(): 52 | return "\t This is inside the welcome() function" 53 | 54 | if name == 'Nico': 55 | return greet 56 | else: 57 | return welcome 58 | x = final_hello() 59 | y = final_hello('Bacon') 60 | 61 | print x() #assigned the greet() function 62 | print y() #assigned the welcome() function 63 | 64 | # FUNCTIONS AS ARGUMENTS 65 | def this_hello(): 66 | return 'Hi Nico!' 67 | 68 | def other(func): 69 | print 'Other code would go here' 70 | print func() 71 | 72 | print this_hello() 73 | print other(this_hello) -------------------------------------------------------------------------------- /10-Iterators-and-Generators/generator expressions.py: -------------------------------------------------------------------------------- 1 | # the following summation code will build a full list of squares in memory, iterate over those values, and, when 2 | # the reference is no longer needed, delete the list 3 | 4 | print sum([x*x for x in range(10)]) 5 | 6 | # Memory is conserved by using a generator expression instead: 7 | 8 | print sum(x*x for x in range(10)) -------------------------------------------------------------------------------- /10-Iterators-and-Generators/iterators and generators - homework.py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function 2 | 3 | # PROBLEM 1: 4 | # Create a generator that generates the squares of numbers up to some number N 5 | def gen_square(num): 6 | for n in range(num): 7 | yield n**2 8 | 9 | new = gen_square(5) 10 | for _ in range(5): 11 | print(next(new),end=' ') 12 | print('\n') 13 | 14 | 15 | 16 | # PROBLEM 2: 17 | # Create a generator that yields "n" random numbers between a low and high number (that are inputs). 18 | from random import randint 19 | 20 | def rand_nums(n,low,high): 21 | for num in range(n): 22 | yield randint(low,high) 23 | 24 | rand = rand_nums(5,2,9) 25 | for _ in range(5): 26 | print(next(rand),end=' ') 27 | print('\n') 28 | 29 | 30 | 31 | # PROBLEM 3: 32 | # Use the iter() function to convert the string below 33 | s = 'hello' 34 | s_gen = iter(s) 35 | for letter in s_gen: 36 | print(letter,end='') 37 | print('\n') 38 | 39 | 40 | 41 | # PROBLEM 4: 42 | # Explain a use case for a generator using a yield statement where you would not want to use a normal function with a return statement. 43 | 44 | # When iterating over a large range of numbers. Would require much less memory 45 | 46 | 47 | 48 | # PROBLEM 5 (Extra): 49 | # Can you explain what gencomp is in the code below? (Note: We never covered this in lecture!) 50 | my_list = [1,2,3,4,5] 51 | 52 | gencomp = (item for item in my_list if item > 3) 53 | 54 | for item in gencomp: 55 | print(item) 56 | 57 | # Generator expressions are high performance, memory efficient generalization fo list comprehensions and generators 58 | # see 'generator expressions.py' -------------------------------------------------------------------------------- /10-Iterators-and-Generators/iterators and generators.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Generator Functions: 3 | - Allows us to write a function that can send back a value and then later resume to pick up where it left off. 4 | - Syntax: yield statement 5 | - When compiled, generators become objects that support an iteration protocol 6 | - Automatically suspends and resumes their execution and state around the last point of value generation 7 | - Instead of having to compute an entire series of values upfront and the generator functions can be suspended 8 | - Known as state suspension 9 | ''' 10 | 11 | # Generator function for the cube of numbers (power of 3) 12 | def gencubes(num): 13 | for num in range(num): 14 | yield num**3 15 | 16 | for x in gencubes(10): 17 | print x 18 | 19 | # Generators are best for calculating large sets of results (particularly in calculations that involve loops 20 | # themselves) in cases where we don't want to allocate the memory for all of the results at the same time. 21 | 22 | print "\n" 23 | 24 | # next() and iter() built-in functions: 25 | def simple_gen(): 26 | for x in range(3): 27 | yield x 28 | 29 | g = simple_gen() 30 | print next(g) 31 | print next(g) 32 | print next(g) 33 | # print next(g) #error: StopIteration 34 | 35 | # Lets see how to use iter(). Remember that strings are iterables: 36 | s = 'hello' 37 | 38 | #Iterate over string 39 | for let in s: 40 | print let 41 | 42 | # That doesn't meen that the string itself is an iterator!! 43 | # next(s) #produces an error 44 | 45 | # the string object supports iterator, but is not itself an iterator. this is were iter() comes into play 46 | s_iter = iter(s) 47 | print next(s_iter) 48 | 49 | -------------------------------------------------------------------------------- /11-Final-Capstone-Projects/coin flip simulation.py: -------------------------------------------------------------------------------- 1 | from random import randint 2 | 3 | num_flips = 100 4 | result = [randint(0,1) for _ in range(num_flips)] 5 | print 'Heads: {0} ; Tails: {1}'.format(result.count(1),result.count(0)) -------------------------------------------------------------------------------- /11-Final-Capstone-Projects/dec_bin.py: -------------------------------------------------------------------------------- 1 | def dec_to_bin(num): 2 | if not num/2 == 0: 3 | return '{1}{0}'.format(str(num%2),dec_to_bin(num/2)) 4 | return str(num%2) 5 | 6 | def bin_to_dec(num): 7 | return sum(map(lambda x: 2**x[0] * int(x[1]),enumerate(num[::-1]))) 8 | 9 | 10 | binary = dec_to_bin(156) 11 | print binary 12 | dec = bin_to_dec(binary) 13 | print dec -------------------------------------------------------------------------------- /11-Final-Capstone-Projects/distance between cities.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Distance Between Two Cities - Calculates the distance between two cities and allows the user to specify a unit 3 | of distance. This program may require finding coordinates for the cities like latitude and longitude. 4 | ''' 5 | from geopy.geocoders import Nominatim 6 | from geopy.distance import vincenty 7 | 8 | def distance(city1,city2): 9 | geolocator = Nominatim() 10 | city1_data = geolocator.geocode(city1) 11 | city2_data = geolocator.geocode(city2) 12 | print vincenty((city1_data.latitude,city1_data.longitude),(city2_data.latitude,city2_data.longitude)).kilometers,'km' 13 | 14 | distance("Stellenbosch","Somerset West") 15 | -------------------------------------------------------------------------------- /11-Final-Capstone-Projects/prime factorization.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Prime Factorization - Have the user enter a number and find all Prime Factors (if there are any) and display them. 3 | ''' 4 | 5 | def prime_factor(num): 6 | for n in xrange(2,int(num**0.5)): 7 | if num % n == 0: 8 | return '{0} x {1}'.format(str(n),prime_factor(num/n)) 9 | return str(num) 10 | 11 | 12 | def is_prime(num): 13 | for n in range(2,int(num**0.5)): 14 | if num%n == 0: 15 | return False 16 | return True 17 | 18 | print prime_factor(104534534572) 19 | print is_prime(2011) -------------------------------------------------------------------------------- /12-Advanced-Modules/Collections-Module/counter-module.py: -------------------------------------------------------------------------------- 1 | ''' 2 | The collections module is a built-in module that implements specialized container datatypes providing alternatives to 3 | Python's general purpose built-in containers 4 | ''' 5 | 6 | # COUNTER 7 | # dict subclass which helps count hashable objects 8 | # elements are stored as dictionary keys and counts of the object are stored as the value 9 | 10 | from collections import Counter 11 | 12 | l = [1,2,2,2,2,3,3,3,1,2,1,12,3,2,32,1,21,1,223,1] 13 | print Counter(l) 14 | 15 | s = 'aaaabffkdlssjdoedfssd' 16 | print Counter(s) 17 | 18 | words = 'How many times does each word show up in this sentence word times each each word' 19 | print Counter(words.split()) 20 | 21 | print "" 22 | 23 | # Methods with counter: 24 | c = Counter(words.split()) 25 | print "Two most common words: ",c.most_common(2) 26 | print "Sum of all counts: ",sum(c.values()) 27 | print "List unique elements: ",list(c) 28 | print "Converts to a set: ",set(c) 29 | print "Converts to a regular dictionary: ",dict(c) 30 | print "Convert to a list of (elem,cnt) pairs: ",c.items() 31 | print "Convert from a list of (elem,cnt) pairs: Counter(dict(list_of_pairs)))" 32 | print "3 least common elements: ",c.most_common()[:-4:-1] 33 | print "Remove zero and negative counts: c+= Counter()" -------------------------------------------------------------------------------- /12-Advanced-Modules/Collections-Module/defaultdict-module.py: -------------------------------------------------------------------------------- 1 | ''' 2 | The collections module is a built-in module that implements specialized container datatypes providing alternatives to 3 | Python's general purpose built-in containers 4 | ''' 5 | 6 | # DEFAULTDICT: 7 | # dictionary like object which provides all methods provided by dictionary but takes first argument (default_factory) 8 | # as default datatype for the dictionary. Using defaultdict is faster than doing the same using dict.set_default method 9 | 10 | from collections import defaultdict 11 | 12 | d = {} 13 | #print d['one'] #KeyError 14 | 15 | # a defaultdict will never raise a KeyError 16 | # any key that does not exist gets the value returned by the default factory 17 | 18 | d = defaultdict(object) 19 | print d['one'] 20 | 21 | for item in d: 22 | print item 23 | 24 | # defaultdict can also initialize with default values 25 | d = defaultdict(lambda: 0) 26 | print d['one'] -------------------------------------------------------------------------------- /12-Advanced-Modules/Collections-Module/named-tuple.py: -------------------------------------------------------------------------------- 1 | ''' 2 | The collections module is a built-in module that implements specialized container datatypes providing alternatives to 3 | Python's general purpose built-in containers 4 | ''' 5 | 6 | # standard tuple uses numerical indices to access its members 7 | 8 | t = (12,13,14) 9 | print t[1] 10 | 11 | ''' 12 | For simple use cases, this is usually enough. On the other hand, remembering which index should be used for each 13 | value can lead to errors, especially if the tuple has a lot of fields and is constructed far from where it is used. 14 | A namedtuple assigns names, as well as the numerical index, to each member. 15 | 16 | Each kind of namedtuple is represented by its own class, created by using the namedtuple() factory function. 17 | The arguments are the name of the new class and a string containing the names of the elements. 18 | 19 | You can think of namedtuples as a very quick way of creating a new object/class type with some attribute fields. 20 | ''' 21 | 22 | from collections import namedtuple 23 | 24 | Dog = namedtuple('Dog','age breed name') 25 | sam = Dog(age = 2, breed = 'Lab', name='Sammy') 26 | frank = Dog(age = 2, breed = 'Shepard', name = 'Frankie') 27 | 28 | print "sam: ",sam 29 | print "sam.age: ",sam.age 30 | print "frank.breed: ",frank.breed 31 | print "sam[0]: ",sam[0] -------------------------------------------------------------------------------- /12-Advanced-Modules/Collections-Module/ordered-dict-module.py: -------------------------------------------------------------------------------- 1 | ''' 2 | The collections module is a built-in module that implements specialized container datatypes providing alternatives to 3 | Python's general purpose built-in containers 4 | ''' 5 | 6 | # ORDEREDDICT: 7 | # an OrderedDict is a dictionary subclass that remembers the order in which its contents were added 8 | 9 | from collections import OrderedDict 10 | 11 | print "Normal Dictionary:" 12 | 13 | d = {} 14 | 15 | d['a'] = 'A' 16 | d['b'] = 'B' 17 | d['c'] = 'C' 18 | 19 | for key,value in d.items(): 20 | print key, value 21 | 22 | print "" 23 | 24 | print "Ordered Dictionary:" 25 | 26 | d = OrderedDict() 27 | 28 | d['a'] = 'A' 29 | d['b'] = 'B' 30 | d['c'] = 'C' 31 | 32 | for key,value in d.items(): 33 | print key, value 34 | 35 | print "" 36 | 37 | # Equality with an ordered dictionary 38 | # a regular dict looks at its contents when testing for equality. an ordered dict also considers the order in which 39 | # the items were added 40 | 41 | print "Normal dictionaries are equal?" 42 | 43 | d1 = {} 44 | d1['a'] = 'A' 45 | d1['b'] = 'B' 46 | 47 | d2 = {} 48 | d2['b'] = 'B' 49 | d2['a'] = 'A' 50 | 51 | print d1 == d2 52 | 53 | print "" 54 | 55 | print "Orderd dictionaries are equal?" 56 | 57 | d1 = OrderedDict() 58 | d1['a'] = 'A' 59 | d1['b'] = 'B' 60 | 61 | d2 = OrderedDict() 62 | d2['b'] = 'B' 63 | d2['a'] = 'A' 64 | 65 | print d1 == d2 66 | 67 | -------------------------------------------------------------------------------- /12-Advanced-Modules/Regular-Expressions-Module/character-ranges.py: -------------------------------------------------------------------------------- 1 | ''' 2 | CHARACTER RANGES 3 | - define a character set to include all of the contiguous characters between a start and stop point 4 | - format: [start-end] 5 | - eg: [a-f] would return matches with any instance of letters between a and f 6 | ''' 7 | 8 | import re 9 | 10 | test_phrase = 'This is an example sentence. Lets see if we can find some letters.' 11 | 12 | test_patterns = ['[a-z]+', # sequences of lower case letters 13 | '[A-Z]+', # sequences of upper case letters 14 | '[a-zA-Z]+', # sequences of lower or upper case letters 15 | '[A-Z][a-z]+'] # one upper case letter followed by lower case letters 16 | 17 | for pattern in test_patterns: 18 | print re.findall(pattern,test_phrase) -------------------------------------------------------------------------------- /12-Advanced-Modules/Regular-Expressions-Module/character-sets.py: -------------------------------------------------------------------------------- 1 | ''' 2 | CHARACTER SETS 3 | - used to match any one of a group of characters at a point in the input 4 | - brackets are used to construct character set inputs 5 | - eg: the input [ab] searches for occurances of either a or b 6 | ''' 7 | 8 | import re 9 | 10 | test_phrase = 'sdsd..sssddd...sdddsddd...dsds...dsssss...sdddd' 11 | 12 | patterns = ['[sd]', # either s or d 13 | 's[sd]+'] # s followed by one or more s or d 14 | 15 | for pattern in patterns: 16 | print 'Searching phrase with re statement: '+pattern 17 | print re.findall(pattern,test_phrase) 18 | print '\n' -------------------------------------------------------------------------------- /12-Advanced-Modules/Regular-Expressions-Module/escape-codes.py: -------------------------------------------------------------------------------- 1 | ''' 2 | ESCAPE CODES 3 | - special escape codes to find specific types of patterns in your data 4 | - escapes are indicated by prefixing the characters with a backslash 5 | - backslash itself must be escaped in normal Python strings 6 | - using raw strings, created by prefixing the literal value with r, for creating regular expressions takes care of this problem 7 | 8 | \d - digit 9 | \D - non-digit 10 | \s - whitespace (tab, space, newline, ect) 11 | \S - non-whitespace 12 | \w - alphanumeric 13 | \W - non-alphanumeric 14 | 15 | ''' 16 | 17 | import re 18 | 19 | test_phrase = 'This is a string with some numbers 1233 and a symbol #hashtag' 20 | 21 | test_patterns = [r'\d+', # sequence of digits 22 | r'\D+', # sequence of non-digits 23 | r'\s+', # sequence of whitespace 24 | r'\S+', # sequence of non-whitespace 25 | r'\w+', # alphanumeric characters 26 | r'\W+', # non-alphanumeric 27 | ] 28 | 29 | for pattern in test_patterns: 30 | print re.findall(pattern,test_phrase) -------------------------------------------------------------------------------- /12-Advanced-Modules/Regular-Expressions-Module/exclusion.py: -------------------------------------------------------------------------------- 1 | ''' 2 | EXCLUSION 3 | - use ^ to exclude terms by incorporating it into the brackets syntax notation 4 | - eg: [^...] will match any single character not in the bracket notation 5 | ''' 6 | 7 | import re 8 | 9 | test_phrase = 'This is a string! But it has punctutation. How can we remove it?' 10 | 11 | print ' '.join(re.findall('[^!.? ]+',test_phrase)) 12 | print re.findall('[^!.? ]+',test_phrase) 13 | 14 | -------------------------------------------------------------------------------- /12-Advanced-Modules/Regular-Expressions-Module/pattern-re-syntax.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Use metacharacters along with re to find specific types of patterns 3 | 4 | Repetition Syntax: 5 | 1. A pattern followed by the metacharacter * is repeated zero or more times. 6 | 2. Replace the * with + and the pattern must appear at least once. 7 | 3. Using ? means the pattern appears zero or one time. 8 | 4. For a specific number of occurrences, use {m} after the pattern, where m is replaced with the number of times the pattern should repeat. 9 | 5. Use {m,n} where m is the minimum number of repetitions and n is the maximum. Leaving out n ({m,}) means the value appears at least m times, with no maximum. 10 | ''' 11 | 12 | import re 13 | 14 | def multi_re_find(patterns,phrase): 15 | ''' 16 | Takes in a list of regex patterns 17 | Prints a list of all matches 18 | ''' 19 | for pattern in patterns: 20 | print 'Searching the phrase using the re check: %r' %pattern 21 | print re.findall(pattern,phrase) 22 | print '\n' 23 | 24 | test_phrase = 'sdsd..sssddd...sdddsddd...dsds...dsssss...sdddd' 25 | 26 | test_patterns = ['sd*', # s followed by zero or more d's 27 | 'sd+', # s followed by one or more d's 28 | 'sd?', # s followed by zero or one d's 29 | 'sd{3}', # s followed by three d's 30 | 'sd{2,3}', # s followed by two to three d's 31 | ] 32 | 33 | multi_re_find(test_patterns,test_phrase) -------------------------------------------------------------------------------- /12-Advanced-Modules/Regular-Expressions-Module/regular-expressions.py: -------------------------------------------------------------------------------- 1 | ''' 2 | REGULAR EXPRESSIONS: 3 | - text matching patterns described with a formal syntax 4 | - 'regex' or 'regexp' 5 | - can include a variety of rules for finding repetition, text-matching, ect. 6 | - a lot of parsing problems can be solved with regular expressions 7 | ''' 8 | 9 | # SEARCHING FOR PATTERNS IN TEXT 10 | import re 11 | 12 | # List of patterns to search for 13 | patterns = [ 'term1', 'term2' ] 14 | 15 | # Text to parse 16 | text = 'This is a string with term1, but it does not have the other term.' 17 | 18 | for pattern in patterns: 19 | print 'Searching for "%s" in: \n"%s"' % (pattern, text), 20 | 21 | #Check for match 22 | if re.search(pattern, text): 23 | print '\n' 24 | print 'Match was found. \n' 25 | else: 26 | print '\n' 27 | print 'No Match was found.\n' 28 | 29 | # RETURN TYPE: Match object (None if no match was found) 30 | pattern = 'term1' 31 | text = 'This is a string with term1, but it does not have the other term.' 32 | match = re.search(pattern, text) 33 | print type(match) #returns a Match object 34 | 35 | # Match object returned by search() is more than just a Boolean or None 36 | print match.start() 37 | print match.end() 38 | 39 | 40 | 41 | # SPLIT WITH REGULAR EXPRESSIONS 42 | split_term = '@' 43 | phrase = 'What is the domain name of someone with the email: hello@gmail.com' 44 | print re.split(split_term, phrase) 45 | 46 | 47 | 48 | # FIND ALL INSTANCES OF A PATTERN 49 | print re.findall('match','test phrase match is in middle') -------------------------------------------------------------------------------- /12-Advanced-Modules/datetime-module.py: -------------------------------------------------------------------------------- 1 | ''' 2 | module: datetime 3 | 4 | - helps you deal with timestamps in your code 5 | - time values are represented with the time class 6 | - times have attributes for hours, minutes, seconds and microseconds 7 | - can also include timezone information 8 | - the arguments to initialize a time instance is optional (defaults to zero) 9 | 10 | ''' 11 | 12 | # TIME 13 | import datetime 14 | 15 | t = datetime.time(4, 20, 1) 16 | 17 | print t 18 | print 'hour: ',t.hour 19 | print 'minute: ',t.minute 20 | print 'second: ',t.second 21 | print 'microsecond: ',t.microsecond 22 | print 'time zone info: ',t.tzinfo 23 | 24 | # note: a time instance holds only the values of time, and not the date associated with that time 25 | 26 | # check the min and max values a time of day can have in the module 27 | print 'earliest: ',datetime.time.min 28 | print 'latest: ',datetime.time.max 29 | print 'resolution: ',datetime.time.resolution 30 | 31 | 32 | 33 | # DATES 34 | # - calendar date values are represented with the date class 35 | # - instances have attributes for year, month and day 36 | 37 | today = datetime.date.today() 38 | print today 39 | print 'ctime: ',today.ctime() 40 | print 'tuple: ',today.timetuple() 41 | print 'ordinal:', today.toordinal() 42 | print 'Year:', today.year 43 | print 'Mon :', today.month 44 | print 'Day :', today.day 45 | 46 | # check the min and max values a date can have in the module 47 | print 'earliest: ',datetime.date.min 48 | print 'latest: ',datetime.date.max 49 | print 'resolution: ',datetime.date.resolution 50 | 51 | # another way to create new date instances is to use the replace() method of an existing date 52 | d1 = datetime.date(2015,3,11) 53 | print 'd1: ',d1 54 | d2 = d1.replace(year=1990) 55 | print 'd2: ',d2 56 | 57 | 58 | 59 | # ARITHMETIC 60 | 61 | print 'd1-d2: ',d1-d2 -------------------------------------------------------------------------------- /12-Advanced-Modules/pdb-debugger.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Pyhon Debugger (pdb) 3 | 4 | - interactive debugging environment 5 | - pause you program, look at values, execute step-by-step 6 | 7 | ''' 8 | import pdb 9 | 10 | x = [1,3,4] 11 | y = 2 12 | z = 3 13 | 14 | result = x + z 15 | print result 16 | 17 | # set a trace using python debugger 18 | pdb.set_trace() 19 | 20 | result2 = y + x 21 | print result2 -------------------------------------------------------------------------------- /12-Advanced-Modules/stringIO-module.py: -------------------------------------------------------------------------------- 1 | ''' 2 | STRINGIO: 3 | - implements an in-memory file like object 4 | - this object can be used in input or output to most functions that would expect a standard file object 5 | - especially useful in web scraping cases where you want to read some string you scraped as a file 6 | ''' 7 | 8 | import StringIO 9 | 10 | message = 'This is just a normal string' 11 | f = StringIO.StringIO(message) # Use StringIO method to set as file object 12 | 13 | print f.read() 14 | 15 | f.write(' Second line written to file like object') 16 | f.seek(0) 17 | print f.read() -------------------------------------------------------------------------------- /12-Advanced-Modules/timeit-module.py: -------------------------------------------------------------------------------- 1 | ''' 2 | module: timeit 3 | ''' 4 | import timeit 5 | 6 | # for loop 7 | print 'For Loop: ',timeit.timeit('".".join(str(n) for n in range(100))',number=10000) 8 | 9 | # list comprehension 10 | print 'List Comprehension: ',timeit.timeit('"-".join([str(n) for n in range(100)])',number=10000) 11 | 12 | # map() 13 | print 'Map(): ',timeit.timeit('"-".join(map(str,range(100)))',number=10000) 14 | 15 | # NB: see iPython implementation of %timeit funtion -------------------------------------------------------------------------------- /13-Advanced-Object-and-Data-Structures/advanced-dictionaries.py: -------------------------------------------------------------------------------- 1 | d = {'k1': 1, 'k2': 2} 2 | 3 | # DICTIONARY COMPREHENSION 4 | print {x:x**2 for x in range(1,5)} 5 | 6 | 7 | # ITERATION OVER KEYS, VALUES AND ITEMS 8 | for key in d.iterkeys(): 9 | print key 10 | 11 | for value in d.itervalues(): 12 | print value 13 | 14 | for item in d.iteritems(): 15 | print item 16 | 17 | 18 | # VIEW KEYS, VALUES AND ITEMS 19 | print d.viewkeys() 20 | print d.viewvalues() 21 | print d.viewitems() -------------------------------------------------------------------------------- /13-Advanced-Object-and-Data-Structures/advanced-lists.py: -------------------------------------------------------------------------------- 1 | ls = [1, 2, 3] 2 | 3 | # COUNT 4 | # count() takes an element and returns the number of times it occurs in the list 5 | print ls.count(2) 6 | 7 | # APPEND 8 | # appends object to the end of list 9 | ls.append([1, 2]) 10 | print ls 11 | ls.pop() 12 | 13 | # EXTEND 14 | # extend list by appending elements from an iterable 15 | ls.extend([1, 2]) 16 | print ls 17 | 18 | # INDEX 19 | # return the index of whatever element is placed as an argument 20 | print ls.index(2) 21 | 22 | # INSERT - insert(index, object) 23 | # places object at the index supplied 24 | ls.insert(2, 'bacon') 25 | ls.insert(4, 'fish') 26 | print ls 27 | 28 | # POP 29 | ls.pop() # pops last value in list 30 | ls.pop(2) # pops value at index 2 31 | print ls 32 | 33 | # REMOVE 34 | # removes the first occurance of value 35 | ls.remove('fish') 36 | print ls 37 | 38 | # REVERSE 39 | # reverse list 40 | ls.reverse() 41 | print ls 42 | 43 | # SORT 44 | # sort in place 45 | ls.sort() 46 | print ls 47 | -------------------------------------------------------------------------------- /13-Advanced-Object-and-Data-Structures/advanced-numbers.py: -------------------------------------------------------------------------------- 1 | # HEXADECIMAL 2 | print hex(246) 3 | print hex(512) 4 | 5 | # BINARY 6 | print bin(1234) 7 | print bin(128) 8 | print bin(512) 9 | 10 | # POWER 11 | # with two arguments equivalent to x^y 12 | # with three argument equivalent to (x^y)%z, but may be more efficient (eg. for longs) 13 | print pow(2,4) 14 | print pow(3,2,5) 15 | 16 | # ABSOLUTE 17 | print abs(-3) 18 | print abs(3) 19 | 20 | # ROUND 21 | # round a number to a given precision in decimal digits (0 default) 22 | # always returns a floating point number 23 | print round(3) 24 | print round(3.1423453465,2) -------------------------------------------------------------------------------- /13-Advanced-Object-and-Data-Structures/advanced-sets.py: -------------------------------------------------------------------------------- 1 | s = set() 2 | 3 | # ADD 4 | s.add(1) 5 | s.add(2) 6 | print s 7 | 8 | # CLEAR 9 | s.clear() 10 | print s 11 | 12 | # COPY 13 | s = {1, 2, 3} 14 | sc = s.copy() 15 | print sc 16 | s.add(4) 17 | print sc # note changes to the original do not affect the copy 18 | print s 19 | 20 | # DIFFERENCE 21 | # syntax: set1.difference(set2) 22 | print s.difference(sc) 23 | 24 | # DIFFERENCE UPDATE 25 | # syntax: set1.difference_update(set2) 26 | # returns set1 after removing elements found in set2 27 | s1 = {1, 2, 3} 28 | s2 = {6, 2, 4} 29 | s1.difference_update(s2) 30 | print s1 31 | 32 | # DISCARD 33 | s.discard(2) 34 | print s 35 | 36 | # INTERSECTION and INTERSECTION_UPDATE 37 | # returns intersection of two or more sets as a new set 38 | s1 = {1, 2, 3} 39 | s2 = {2, 3, 4} 40 | print s1.intersection(s2) 41 | s1.intersection_update(s2) 42 | print s1 43 | 44 | # ISDISJOINT 45 | # returns True if two sets have a null intersection 46 | s1 = {1, 2} 47 | s2 = {1, 2, 4} 48 | s3 = {5} 49 | print s1.isdisjoint(s2) 50 | print s1.isdisjoint(s3) 51 | 52 | # ISSUBSET and ISSUPERSET 53 | print s1.issubset(s2) 54 | print s2.issubset(s1) 55 | print s1.issuperset(s2) 56 | print s2.issuperset(s1) 57 | 58 | # SYMMETRIC_DIFFERENCE and SYMMETRIC_UPDATE 59 | # return the symmetric difference of two sets as a new set (i.e. all elements that are in exactly one of the sets) 60 | print s1.symmetric_difference(s2) 61 | s2.symmetric_difference_update(s1) 62 | print s2 63 | 64 | # UNION 65 | print s1.union(s2) 66 | 67 | # UPDATE 68 | # update set with the union of itself and others 69 | s1.update(s2) 70 | print s1 71 | 72 | -------------------------------------------------------------------------------- /13-Advanced-Object-and-Data-Structures/advanced-strings.py: -------------------------------------------------------------------------------- 1 | s = 'hello world' 2 | 3 | # CHANGE CASE 4 | print s.capitalize() # capitalize the word in string 5 | print s.upper() 6 | print s.lower() 7 | 8 | 9 | # LOCATION AND COUNTING 10 | print s.count('o') 11 | print s.find('o') 12 | 13 | 14 | # FORMATTING 15 | print s.center(20,'-') 16 | print 'hello\thi'.expandtabs() 17 | 18 | 19 | t = 'hello' 20 | 21 | # IS CHECK METHODS 22 | print t.isalnum() # return True if all characters are alphanumeric 23 | print t.isalpha() # return True if all characters are alphabetic 24 | print t.islower() # return True if all cased characters are lowercase and there is at least one cased character 25 | print t.isupper() # return True if all cased characters are uppercase and there is at least one cased character 26 | print t.isspace() # return True if all character are whitespace 27 | print t.istitle() # return True if t is a Titlecased string (uppercase character follow uncased characters, lowercase characters only cased ones) 28 | print t.endswith('o') # boolean check on t[-1] 29 | 30 | 31 | # BUILT-IN REG EXPRESSIONS 32 | print s.split('e') 33 | print s.partition('e') # return tuple that includes separator (first occurence) 34 | 35 | -------------------------------------------------------------------------------- /14-Introducing-GUIs/.ipynb_checkpoints/1-interact-checkpoint.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 1, 6 | "metadata": { 7 | "collapsed": false 8 | }, 9 | "outputs": [], 10 | "source": [ 11 | "from ipywidgets import interact, interactive, fixed\n", 12 | "import ipywidgets as widget" 13 | ] 14 | }, 15 | { 16 | "cell_type": "code", 17 | "execution_count": 2, 18 | "metadata": { 19 | "collapsed": false 20 | }, 21 | "outputs": [], 22 | "source": [ 23 | "# very basic fucntion\n", 24 | "def f(x):\n", 25 | " return x" 26 | ] 27 | }, 28 | { 29 | "cell_type": "code", 30 | "execution_count": 3, 31 | "metadata": { 32 | "collapsed": false 33 | }, 34 | "outputs": [ 35 | { 36 | "data": { 37 | "text/plain": [ 38 | "17" 39 | ] 40 | }, 41 | "metadata": {}, 42 | "output_type": "display_data" 43 | } 44 | ], 45 | "source": [ 46 | "# generate slider to interact with\n", 47 | "interact(f, x=10,);" 48 | ] 49 | }, 50 | { 51 | "cell_type": "code", 52 | "execution_count": 4, 53 | "metadata": { 54 | "collapsed": false 55 | }, 56 | "outputs": [ 57 | { 58 | "data": { 59 | "text/plain": [ 60 | "True" 61 | ] 62 | }, 63 | "metadata": {}, 64 | "output_type": "display_data" 65 | } 66 | ], 67 | "source": [ 68 | "# booleans generate check boxes\n", 69 | "interact(f, x=True);" 70 | ] 71 | }, 72 | { 73 | "cell_type": "code", 74 | "execution_count": 6, 75 | "metadata": { 76 | "collapsed": false 77 | }, 78 | "outputs": [ 79 | { 80 | "data": { 81 | "text/plain": [ 82 | "'Hi there! you too'" 83 | ] 84 | }, 85 | "metadata": {}, 86 | "output_type": "display_data" 87 | } 88 | ], 89 | "source": [ 90 | "# strings generate text areas\n", 91 | "interact(f, x='Hi there!');" 92 | ] 93 | }, 94 | { 95 | "cell_type": "code", 96 | "execution_count": 7, 97 | "metadata": { 98 | "collapsed": false 99 | }, 100 | "outputs": [ 101 | { 102 | "data": { 103 | "text/plain": [ 104 | "(False, -0.7)" 105 | ] 106 | }, 107 | "metadata": {}, 108 | "output_type": "display_data" 109 | } 110 | ], 111 | "source": [ 112 | "# interact can also be used as a decorator\n", 113 | "@interact(x=True, y=1.0)\n", 114 | "def g(x, y):\n", 115 | " return (x, y)" 116 | ] 117 | }, 118 | { 119 | "cell_type": "code", 120 | "execution_count": 8, 121 | "metadata": { 122 | "collapsed": true 123 | }, 124 | "outputs": [], 125 | "source": [ 126 | "# again a simple function\n", 127 | "def h(p, q):\n", 128 | " return(p, q)" 129 | ] 130 | }, 131 | { 132 | "cell_type": "code", 133 | "execution_count": 10, 134 | "metadata": { 135 | "collapsed": false 136 | }, 137 | "outputs": [ 138 | { 139 | "data": { 140 | "text/plain": [ 141 | "(8, 20)" 142 | ] 143 | }, 144 | "metadata": {}, 145 | "output_type": "display_data" 146 | } 147 | ], 148 | "source": [ 149 | "# pass fixed(20) for q to hold it fixed at a value of 20\n", 150 | "interact(h, p=5, q=fixed(20));" 151 | ] 152 | }, 153 | { 154 | "cell_type": "code", 155 | "execution_count": null, 156 | "metadata": { 157 | "collapsed": true 158 | }, 159 | "outputs": [], 160 | "source": [] 161 | } 162 | ], 163 | "metadata": { 164 | "kernelspec": { 165 | "display_name": "Python 3", 166 | "language": "python", 167 | "name": "python3" 168 | }, 169 | "language_info": { 170 | "codemirror_mode": { 171 | "name": "ipython", 172 | "version": 3 173 | }, 174 | "file_extension": ".py", 175 | "mimetype": "text/x-python", 176 | "name": "python", 177 | "nbconvert_exporter": "python", 178 | "pygments_lexer": "ipython3", 179 | "version": "3.5.2" 180 | }, 181 | "widgets": { 182 | "state": { 183 | "30300b6c85c5437b9e6ccf9964ab0cb0": { 184 | "views": [] 185 | }, 186 | "31eb57b1af234cabb4250abba0d7a843": { 187 | "views": [] 188 | }, 189 | "3dbd7f1532db4c559a3a73ba1cac63e1": { 190 | "views": [] 191 | }, 192 | "424dc5b15791402b8c8847547c1a2834": { 193 | "views": [] 194 | }, 195 | "460ef3a91f2f47eabf7b3adb161d98aa": { 196 | "views": [ 197 | { 198 | "cell_index": 4 199 | } 200 | ] 201 | }, 202 | "4b90cf6b4d514ad49ecb5cd4665f0a45": { 203 | "views": [] 204 | }, 205 | "53e38a631b8a4f218027432d4d0d12e6": { 206 | "views": [ 207 | { 208 | "cell_index": 7 209 | } 210 | ] 211 | }, 212 | "5b91923ff65a4015bb21ff67c5c93730": { 213 | "views": [] 214 | }, 215 | "6052b7cff0c8453692273483dc45b910": { 216 | "views": [] 217 | }, 218 | "66f4b06a3cbc477db3787b3a06c04b1c": { 219 | "views": [] 220 | }, 221 | "6764ff0d016c44a281b5c595bed3cd4b": { 222 | "views": [] 223 | }, 224 | "7658bc43c5ff470ab37adc611e079139": { 225 | "views": [] 226 | }, 227 | "7bf71550878140acaee82065349c3bd6": { 228 | "views": [] 229 | }, 230 | "80317cf36bfc40bf8f8b09f6242a9006": { 231 | "views": [ 232 | { 233 | "cell_index": 5 234 | } 235 | ] 236 | }, 237 | "9063c343b1d24059b02e1832296b13e8": { 238 | "views": [] 239 | }, 240 | "92987b38f7f14ffda35bcc88c8b39b02": { 241 | "views": [] 242 | }, 243 | "935be0e992c94f0ca48a6ecdb26079c0": { 244 | "views": [] 245 | }, 246 | "9c5492a3830149dcbe8ec13b6a50f004": { 247 | "views": [] 248 | }, 249 | "a35c0b5881234f2cb82c8309ff31b576": { 250 | "views": [] 251 | }, 252 | "a4e5d1234e2c423b91f48af13268e342": { 253 | "views": [ 254 | { 255 | "cell_index": 2 256 | } 257 | ] 258 | }, 259 | "aa8780761e6b4bf981eed270209fe234": { 260 | "views": [] 261 | }, 262 | "aed9dabe5ee64034962b55f051c11734": { 263 | "views": [] 264 | }, 265 | "bb7100a0d9d94d09b26c5555d6b365b5": { 266 | "views": [] 267 | }, 268 | "c0536266c4a54f55a2ad557cc4ba298c": { 269 | "views": [ 270 | { 271 | "cell_index": 3 272 | } 273 | ] 274 | }, 275 | "c2d8ef7c3dfe4cc1b0b3774a43f33011": { 276 | "views": [] 277 | }, 278 | "c5fe6105d77940d29f1c221f8ccb5562": { 279 | "views": [] 280 | }, 281 | "c69b8f7e9fc54ec7803f456bf2f5b197": { 282 | "views": [] 283 | }, 284 | "ddf7989a901649ada37be8ba06475a7b": { 285 | "views": [] 286 | }, 287 | "e1a3460dce1446a8bc18f79be6e6e13d": { 288 | "views": [] 289 | }, 290 | "f4c2a1ec9ac4420193158374e2765800": { 291 | "views": [] 292 | } 293 | }, 294 | "version": "1.1.2" 295 | } 296 | }, 297 | "nbformat": 4, 298 | "nbformat_minor": 0 299 | } 300 | -------------------------------------------------------------------------------- /14-Introducing-GUIs/1-interact.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 1, 6 | "metadata": { 7 | "collapsed": false 8 | }, 9 | "outputs": [], 10 | "source": [ 11 | "from ipywidgets import interact, interactive, fixed\n", 12 | "import ipywidgets as widget" 13 | ] 14 | }, 15 | { 16 | "cell_type": "code", 17 | "execution_count": 2, 18 | "metadata": { 19 | "collapsed": false 20 | }, 21 | "outputs": [], 22 | "source": [ 23 | "# very basic fucntion\n", 24 | "def f(x):\n", 25 | " return x" 26 | ] 27 | }, 28 | { 29 | "cell_type": "code", 30 | "execution_count": 3, 31 | "metadata": { 32 | "collapsed": false 33 | }, 34 | "outputs": [ 35 | { 36 | "data": { 37 | "text/plain": [ 38 | "17" 39 | ] 40 | }, 41 | "metadata": {}, 42 | "output_type": "display_data" 43 | } 44 | ], 45 | "source": [ 46 | "# generate slider to interact with\n", 47 | "interact(f, x=10,);" 48 | ] 49 | }, 50 | { 51 | "cell_type": "code", 52 | "execution_count": 4, 53 | "metadata": { 54 | "collapsed": false 55 | }, 56 | "outputs": [ 57 | { 58 | "data": { 59 | "text/plain": [ 60 | "True" 61 | ] 62 | }, 63 | "metadata": {}, 64 | "output_type": "display_data" 65 | } 66 | ], 67 | "source": [ 68 | "# booleans generate check boxes\n", 69 | "interact(f, x=True);" 70 | ] 71 | }, 72 | { 73 | "cell_type": "code", 74 | "execution_count": 6, 75 | "metadata": { 76 | "collapsed": false 77 | }, 78 | "outputs": [ 79 | { 80 | "data": { 81 | "text/plain": [ 82 | "'Hi there! you too'" 83 | ] 84 | }, 85 | "metadata": {}, 86 | "output_type": "display_data" 87 | } 88 | ], 89 | "source": [ 90 | "# strings generate text areas\n", 91 | "interact(f, x='Hi there!');" 92 | ] 93 | }, 94 | { 95 | "cell_type": "code", 96 | "execution_count": 7, 97 | "metadata": { 98 | "collapsed": false 99 | }, 100 | "outputs": [ 101 | { 102 | "data": { 103 | "text/plain": [ 104 | "(False, -0.7)" 105 | ] 106 | }, 107 | "metadata": {}, 108 | "output_type": "display_data" 109 | } 110 | ], 111 | "source": [ 112 | "# interact can also be used as a decorator\n", 113 | "@interact(x=True, y=1.0)\n", 114 | "def g(x, y):\n", 115 | " return (x, y)" 116 | ] 117 | }, 118 | { 119 | "cell_type": "code", 120 | "execution_count": 8, 121 | "metadata": { 122 | "collapsed": true 123 | }, 124 | "outputs": [], 125 | "source": [ 126 | "# again a simple function\n", 127 | "def h(p, q):\n", 128 | " return(p, q)" 129 | ] 130 | }, 131 | { 132 | "cell_type": "code", 133 | "execution_count": 10, 134 | "metadata": { 135 | "collapsed": false 136 | }, 137 | "outputs": [ 138 | { 139 | "data": { 140 | "text/plain": [ 141 | "(8, 20)" 142 | ] 143 | }, 144 | "metadata": {}, 145 | "output_type": "display_data" 146 | } 147 | ], 148 | "source": [ 149 | "# pass fixed(20) for q to hold it fixed at a value of 20\n", 150 | "interact(h, p=5, q=fixed(20));" 151 | ] 152 | }, 153 | { 154 | "cell_type": "code", 155 | "execution_count": null, 156 | "metadata": { 157 | "collapsed": true 158 | }, 159 | "outputs": [], 160 | "source": [] 161 | } 162 | ], 163 | "metadata": { 164 | "kernelspec": { 165 | "display_name": "Python 3", 166 | "language": "python", 167 | "name": "python3" 168 | }, 169 | "language_info": { 170 | "codemirror_mode": { 171 | "name": "ipython", 172 | "version": 3 173 | }, 174 | "file_extension": ".py", 175 | "mimetype": "text/x-python", 176 | "name": "python", 177 | "nbconvert_exporter": "python", 178 | "pygments_lexer": "ipython3", 179 | "version": "3.5.2" 180 | }, 181 | "widgets": { 182 | "state": { 183 | "30300b6c85c5437b9e6ccf9964ab0cb0": { 184 | "views": [] 185 | }, 186 | "31eb57b1af234cabb4250abba0d7a843": { 187 | "views": [] 188 | }, 189 | "3dbd7f1532db4c559a3a73ba1cac63e1": { 190 | "views": [] 191 | }, 192 | "424dc5b15791402b8c8847547c1a2834": { 193 | "views": [] 194 | }, 195 | "460ef3a91f2f47eabf7b3adb161d98aa": { 196 | "views": [ 197 | { 198 | "cell_index": 4 199 | } 200 | ] 201 | }, 202 | "4b90cf6b4d514ad49ecb5cd4665f0a45": { 203 | "views": [] 204 | }, 205 | "53e38a631b8a4f218027432d4d0d12e6": { 206 | "views": [ 207 | { 208 | "cell_index": 7 209 | } 210 | ] 211 | }, 212 | "5b91923ff65a4015bb21ff67c5c93730": { 213 | "views": [] 214 | }, 215 | "6052b7cff0c8453692273483dc45b910": { 216 | "views": [] 217 | }, 218 | "66f4b06a3cbc477db3787b3a06c04b1c": { 219 | "views": [] 220 | }, 221 | "6764ff0d016c44a281b5c595bed3cd4b": { 222 | "views": [] 223 | }, 224 | "7658bc43c5ff470ab37adc611e079139": { 225 | "views": [] 226 | }, 227 | "7bf71550878140acaee82065349c3bd6": { 228 | "views": [] 229 | }, 230 | "80317cf36bfc40bf8f8b09f6242a9006": { 231 | "views": [ 232 | { 233 | "cell_index": 5 234 | } 235 | ] 236 | }, 237 | "9063c343b1d24059b02e1832296b13e8": { 238 | "views": [] 239 | }, 240 | "92987b38f7f14ffda35bcc88c8b39b02": { 241 | "views": [] 242 | }, 243 | "935be0e992c94f0ca48a6ecdb26079c0": { 244 | "views": [] 245 | }, 246 | "9c5492a3830149dcbe8ec13b6a50f004": { 247 | "views": [] 248 | }, 249 | "a35c0b5881234f2cb82c8309ff31b576": { 250 | "views": [] 251 | }, 252 | "a4e5d1234e2c423b91f48af13268e342": { 253 | "views": [ 254 | { 255 | "cell_index": 2 256 | } 257 | ] 258 | }, 259 | "aa8780761e6b4bf981eed270209fe234": { 260 | "views": [] 261 | }, 262 | "aed9dabe5ee64034962b55f051c11734": { 263 | "views": [] 264 | }, 265 | "bb7100a0d9d94d09b26c5555d6b365b5": { 266 | "views": [] 267 | }, 268 | "c0536266c4a54f55a2ad557cc4ba298c": { 269 | "views": [ 270 | { 271 | "cell_index": 3 272 | } 273 | ] 274 | }, 275 | "c2d8ef7c3dfe4cc1b0b3774a43f33011": { 276 | "views": [] 277 | }, 278 | "c5fe6105d77940d29f1c221f8ccb5562": { 279 | "views": [] 280 | }, 281 | "c69b8f7e9fc54ec7803f456bf2f5b197": { 282 | "views": [] 283 | }, 284 | "ddf7989a901649ada37be8ba06475a7b": { 285 | "views": [] 286 | }, 287 | "e1a3460dce1446a8bc18f79be6e6e13d": { 288 | "views": [] 289 | }, 290 | "f4c2a1ec9ac4420193158374e2765800": { 291 | "views": [] 292 | } 293 | }, 294 | "version": "1.1.2" 295 | } 296 | }, 297 | "nbformat": 4, 298 | "nbformat_minor": 0 299 | } 300 | -------------------------------------------------------------------------------- /MP2 - Test.py: -------------------------------------------------------------------------------- 1 | import itertools 2 | 3 | suits = ['Diamonds','Clubs','Hearts','Spades'] 4 | deck = list(itertools.product(range(1,11),suits)) + list(itertools.product(['Jack','Queen','King'],suits)) 5 | -------------------------------------------------------------------------------- /Milestone Project 1 - TicTacToe Game.py: -------------------------------------------------------------------------------- 1 | board = [[' ',' ',' '],[' ',' ',' '],[' ',' ',' ']] 2 | assign = {'x': 'Player 1 ', 'o': 'Player 2 '} 3 | 4 | 5 | def game(): 6 | player_move = True 7 | while True: 8 | print_board() 9 | while True: 10 | user_entry = raw_input("Please enter your move (row, column): ") 11 | move = valid_entry(user_entry,player_move) 12 | if not move: 13 | continue 14 | break 15 | player_move = not player_move 16 | board[move[1]-1][move[2]-1] = move[0] 17 | get = result() 18 | if not get: 19 | continue 20 | print_board() 21 | print get 22 | break 23 | 24 | 25 | def valid_entry(user_entry,player_move): 26 | try: 27 | entry = user_entry.split(',') 28 | if len(entry) == 2: 29 | entry[0] = int(entry[0]) 30 | entry[1] = int(entry[1]) 31 | if isinstance(entry[0],int) and isinstance(entry[1],int): 32 | if entry[0] in [1,2,3] and entry[1] in [1,2,3]: 33 | try: 34 | if board[entry[0]-1][entry[1]-1] == ' ': 35 | if player_move: 36 | return ['x',entry[0],entry[1]] 37 | else: 38 | return ['o',entry[0],entry[1]] 39 | except ValueError: 40 | pass 41 | print "Please enter index to a free block" 42 | return False 43 | except ValueError: 44 | pass 45 | print "Please enter a valid index" 46 | return False 47 | 48 | def result(): 49 | for num in (0,1,2): 50 | if (len(set(board[num][:])) <= 1) and (board[num][0] != ' '): 51 | return assign[board[num][0]]+'wins' 52 | if len(set([x[num] for x in board])) <= 1 and (board[num][0] != ' '): 53 | return assign[board[0][num]]+'wins' 54 | if (board[0][0] == board[1][1] == board[2][2]) and (board[0][0] != ' '): 55 | return assign[board[0][0]]+'wins' 56 | if (board[2][0] == board[1][1] == board[0][2]) and (board[2][0] != ' '): 57 | return assign[board[2][0]]+'wins' 58 | 59 | for line in board: 60 | for num in line: 61 | if num == ' ': 62 | return False 63 | return "Tie game" 64 | 65 | 66 | def print_board(): 67 | print board[0][:] 68 | print board[1][:] 69 | print board[2][:] 70 | 71 | if __name__ == '__main__': 72 | game() -------------------------------------------------------------------------------- /Milestone Project 2 - Blackjack 2.0.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Text based blackjack game. Should still implement double down and split 3 | ''' 4 | 5 | from __future__ import print_function 6 | import itertools,random 7 | 8 | class Player(object): 9 | def __init__(self,money): 10 | self.money = money 11 | 12 | def bet(self,amount): 13 | self.money -= amount 14 | 15 | def winnings(self,amount): 16 | self.money += amount 17 | 18 | 19 | class Deck(object): 20 | def __init__(self): 21 | self.suits = ['Diamonds','Clubs','Hearts','Spades'] 22 | self.deck = list(itertools.product(range(2,11)+['Jack','Queen','King','Ace'],self.suits)) 23 | 24 | def shuffle(self): 25 | print('Dealer is shuffling the cards...') 26 | random.shuffle(self.deck) 27 | 28 | def deal_card(self): 29 | return self.deck.pop() 30 | 31 | class Hand(object): 32 | def __init__(self,name): 33 | self.cards = [] 34 | self.name = name 35 | 36 | def show_hand(self,dealer): 37 | if not dealer: 38 | print("{} hand:".format(self.name),self.cards,'which adds up to',self.score()) 39 | else: 40 | print("{} hand:".format(self.name),self.cards[0]) 41 | 42 | def score(self): 43 | sum = 0 44 | ace_count = 0 45 | for card in self.cards: 46 | if isinstance(card[0],int): 47 | sum += int(card[0]) 48 | elif card[0] in ['Jack','Queen','King']: 49 | sum += 10 50 | else: 51 | ace_count += 1 52 | sum += 11 53 | while sum > 21: 54 | if ace_count > 0: 55 | sum -= 10 56 | ace_count -= 1 57 | continue 58 | break 59 | return sum 60 | 61 | def draw_card(self,card): 62 | self.cards += card 63 | 64 | def dealer_score(self): 65 | if self.score() >= 17: 66 | return True 67 | else: 68 | return False 69 | 70 | 71 | def game(): 72 | player = Player(400) 73 | 74 | while True: 75 | bet_amount = 0 76 | print('You have',player.money) 77 | while True: 78 | bet_amount = raw_input('How much would you like to bet? ') 79 | try: 80 | bet_amount = int(bet_amount) 81 | break 82 | except: 83 | print('Please enter a numerical value') 84 | player.bet(bet_amount) 85 | 86 | game_result = None 87 | 88 | new_deck = Deck() 89 | new_deck.shuffle() 90 | 91 | player_hand = Hand('Player') 92 | dealer_hand = Hand('Dealer') 93 | 94 | print('Cards are dealt...') 95 | for i in (1,2): 96 | player_hand.draw_card([new_deck.deck.pop()]) 97 | dealer_hand.draw_card([new_deck.deck.pop()]) 98 | 99 | player_hand.show_hand(False) 100 | dealer_hand.show_hand(True) 101 | 102 | while True: 103 | add_card = raw_input("Would you like another card? (y/n) ") 104 | 105 | if add_card == 'y': 106 | player_hand.draw_card([new_deck.deck.pop()]) 107 | player_hand.show_hand(False) 108 | dealer_hand.show_hand(True) 109 | if player_hand.score() > 21: 110 | print('You are bust! Dealer wins') 111 | game_result = -1 112 | break 113 | elif len(player_hand.cards) >= 5: 114 | print('Monkey! You win') 115 | game_result = 1 116 | break 117 | elif add_card == 'n': 118 | break 119 | else: 120 | print('Not a valid entry') 121 | 122 | if game_result != -1: 123 | while not dealer_hand.dealer_score(): 124 | dealer_hand.draw_card([new_deck.deck.pop()]) 125 | 126 | game_result = results(player_hand,dealer_hand,bet_amount) 127 | 128 | if game_result == 1: 129 | player.winnings(2*bet_amount) 130 | if game_result == 0: 131 | player.winnings(bet_amount) 132 | 133 | print('You have',player.money,end='\n\n') 134 | 135 | 136 | new_game = raw_input('Would you like to play another game? (y/n)' ) 137 | if new_game == 'y': 138 | continue 139 | else: 140 | print('You ended up with',player.money) 141 | break 142 | 143 | 144 | def results(player_hand,dealer_hand,bet_amount): 145 | print('') 146 | print('Your score:',player_hand.score()) 147 | print('Dealer score:',dealer_hand.score()) 148 | if (dealer_hand.score() > 21): 149 | print('Dealer is bust. You win',2*bet_amount) 150 | return 1 151 | elif (player_hand.score() > dealer_hand.score()): 152 | print('You win',2*bet_amount) 153 | return 1 154 | elif (player_hand.score() < dealer_hand.score()): 155 | print('You lose') 156 | return -1 157 | else: 158 | print('Tie game') 159 | return 0 160 | 161 | if __name__ == '__main__': 162 | game() -------------------------------------------------------------------------------- /Milestone Project 2 - Blackjack.py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function 2 | import itertools,random 3 | 4 | class Player(object): 5 | def __init__(self,money): 6 | self.money = money 7 | 8 | def bet(self,amount): 9 | self.money -= amount 10 | 11 | def winnings(self,amount): 12 | self.money += amount 13 | 14 | 15 | class Deck(object): 16 | def __init__(self): 17 | self.suits = ['Diamonds','Clubs','Hearts','Spades'] 18 | self.deck = list(itertools.product(range(2,11)+['Jack','Queen','King','Ace'],self.suits)) 19 | 20 | def shuffle(self): 21 | print('Dealer is shuffling the cards...') 22 | random.shuffle(self.deck) 23 | 24 | def deal_card(self): 25 | return self.deck.pop() 26 | 27 | class Hand(object): 28 | def __init__(self): 29 | self.cards = [] 30 | 31 | def score(self): 32 | sum = 0 33 | ace_count = 0 34 | for card in self.cards: 35 | if isinstance(card[0],int): 36 | sum += int(card[0]) 37 | elif card[0] in ['Jack','Queen','King']: 38 | sum += 10 39 | else: 40 | ace_count += 1 41 | sum += 11 42 | while sum > 21: 43 | if ace_count > 0: 44 | sum -= 10 45 | ace_count -= 1 46 | continue 47 | break 48 | return sum 49 | 50 | def draw_card(self,card): 51 | self.cards += card 52 | 53 | def dealer_score(self): 54 | if self.score() >= 17: 55 | return True 56 | else: 57 | return False 58 | 59 | def game(): 60 | player = Player(400) 61 | 62 | while True: 63 | bet_amount = 0 64 | print('You have',player.money) 65 | while True: 66 | bet_amount = raw_input('How much would you like to bet? ') 67 | try: 68 | bet_amount = int(bet_amount) 69 | break 70 | except: 71 | print('Please enter a numerical value') 72 | player.bet(bet_amount) 73 | 74 | game_result = None 75 | 76 | new_deck = Deck() 77 | new_deck.shuffle() 78 | 79 | player_hand = Hand() 80 | dealer_hand = Hand() 81 | 82 | print('Cards are dealt...') 83 | for i in (1,2): 84 | player_hand.draw_card([new_deck.deck.pop()]) 85 | dealer_hand.draw_card([new_deck.deck.pop()]) 86 | 87 | show_hands(player_hand,dealer_hand) 88 | 89 | while True: 90 | add_card = raw_input("Would you like another card? (y/n) ") 91 | 92 | if add_card == 'y': 93 | player_hand.draw_card([new_deck.deck.pop()]) 94 | show_hands(player_hand,dealer_hand) 95 | if player_hand.score() > 21: 96 | print('You are bust! Dealer wins') 97 | game_result = -1 98 | break 99 | elif len(player_hand.cards) >= 5: 100 | print('Monkey! You win') 101 | game_result = 1 102 | break 103 | elif add_card == 'n': 104 | break 105 | else: 106 | print('Not a valid entry') 107 | 108 | if game_result != -1: 109 | while not dealer_hand.dealer_score(): 110 | dealer_hand.draw_card([new_deck.deck.pop()]) 111 | 112 | game_result = results(player_hand,dealer_hand,bet_amount) 113 | 114 | if game_result == 1: 115 | player.winnings(2*bet_amount) 116 | if game_result == 0: 117 | player.winnings(bet_amount) 118 | 119 | print('You have',player.money,end='\n\n') 120 | 121 | 122 | new_game = raw_input('Would you like to play another game? (y/n)' ) 123 | if new_game == 'y': 124 | continue 125 | else: 126 | print('You ended up with',player.money) 127 | break 128 | 129 | 130 | def results(player_hand,dealer_hand,bet_amount): 131 | print('') 132 | print('Your score:',player_hand.score()) 133 | print('Dealer score:',dealer_hand.score()) 134 | if (dealer_hand.score() > 21): 135 | print('Dealer is bust. You win',2*bet_amount) 136 | return 1 137 | elif (player_hand.score() > dealer_hand.score()): 138 | print('You win',2*bet_amount) 139 | return 1 140 | elif (player_hand.score() < dealer_hand.score()): 141 | print('You lose') 142 | return -1 143 | else: 144 | print('Tie game') 145 | return 0 146 | 147 | 148 | def show_hands(player_hand,dealer_hand): 149 | print('') 150 | print('You have: ',player_hand.cards,'which adds up to',player_hand.score()) 151 | print('The dealer has: ',dealer_hand.cards[0]) 152 | 153 | if __name__ == '__main__': 154 | game() --------------------------------------------------------------------------------