Lab_1
-
Overview: installation of python3 (IDLE under windows), variables, string and list operations (slicing + concatination), booleans
-
Remember:
-
Indentation: instead of using {} to identify the range of a block as in C/C++/Java, python uses indentation
-
Slicing: index starts from 0; last index not included; "-" sign is the reverse index with "-1" means the last element
-
Concatination: When using "+" for concatination, it creats a third object, when using List.append() method, it change the list itself, in this sense, list is mutable and string is not mutable
-
-
Solution:
- Review Questions:
In [1]:
print(5 * 2 ** 3)
In [2]:test = "mystring" print(test[:-1])
In [3]:X = "extraordinary" print(X[:5], X[1] + X[3:5] + X[-1])
In [4]:mystring = "abcdefghijklmnop" print(mystring[-1::-2])
In [5]:X = [1, 2, 3, 4, 5, 6, 7] print(X[-1:len(X) // 2 - 1:-1]) # for python2, 5/2 = 2, for python3, 5/2 = 2.5, but 5//2 = 2
- Review Questions:
Lab_2
-
Overview: how to define a function, concept of variable scope, for loops and while loops, Tutorial 2 functions
-
Recommendation: using IpythonNotebook on Wakari --- A cloud based python environment, it saves you the efforts of configurating python environment and packages by yourself.
-
Creat an account on Wakari
-
After a few seconds, the default python2.7 environment will be loaded and you can experience the interactive ipython notebook, don't forget to change Env to np18py33-1.9, as we are using python3.3.2
-
You can create a new notebook and save the result as .ipynb file, try it
-
-
Common mistakes:
-
forget to return the value
-
be careful of where to put the return statement (take care of indentation), especially in a for loop, if everytime the function returns after processing the first element of a list or string, it may be this mistake
-
when iterating a list, either
-
for item in list:
print(item)
or
for i in range(len(list)):
print(list[i])
don't mix them together
- Solution:
- Review Questions:
In [1]:
def even(num): ''' takes as input an integer and returns True if that integer is even and False otherwise. ''' if num % 2: return False return True print(even(1), even(2), even(3), even(12))
In [2]:def absolute(num): ''' takes as input a number and returns its absolute value. ''' if num < 0: return -num return num print(absolute(1), absolute(0), absolute(-1))
In [3]:def firstword(sentence): ''' takes as input a string representing a sentence and returns the first word in that sentence ''' fstWord = '' i = 0 while sentence[i] != ' ': fstWord = fstWord + sentence[i] i += 1 return fstWord firstword('hello world')
Out[3]:In [4]:def harmonic(n): ''' sum 1 + 1/2 + 1/3 + ... + 1/n ''' sum = 0 for i in range(1,n+1): sum += 1/i return sum harmonic(5)
Out[4]:In [5]:def palindrome(string): ''' takes a string as input and returns True if it is a palindrome and False otherwise ''' strLen = len(string) for i in range(strLen // 2): if string[i] != string[strLen - 1 - i]: return False return True print(palindrome('abcd'), palindrome('abc'), palindrome('abba'), palindrome('abcba'), palindrome([1,2,3,2,1]))
In [6]:def supercount(lol, query): ''' takes as input a list of lists and an item and returns a count of how many times that item appears in the lists''' count = 0 for l in lol: for item in l: if item == query: count += 1 return count print(supercount([ [9, 9, 2], [3, 9], [5, 9, 9] ], 9))
In [7]:def harmonic(n): ''' takes as input a number n and returns the sum 1/1+ 1/2 + 1/3 + ... + 1/n, the "nth harmonic number" ''' sum = 0 i = 1 while i <= n: sum += 1/i i += 1 return sum def reach(val): ''' takes a number k as input and returns the first value of n such that 1/1 + 1/2 + 1/3 + ... + 1/n is at least k''' k = 1 while harmonic(k) < val: k += 1 return k print(harmonic(5), reach(10)) # reach(10) may take a few seconds
In [8]:def unique(lst): ''' take as input a list of numbers, with some numbers possibly repeated, and return a new list in which each number in the original list appears exactly once''' uniLst = [] for l in lst: if l not in uniLst: uniLst.append(l) return uniLst unique([1,2,1,3,4,3])
Out[8]:In [9]:# using while def unique(lst): uniLst = [] i = 0 while i < len(lst): if lst[i] not in uniLst: uniLst.append(lst[i]) i += 1 return uniLst unique([1,3,4,5,3,2,8,5,3,4])
Out[9]: - Exercise - Scrabble Word/Letter Score:
In [1]:
# A list of lists storing the Scrabble # scores of all of the 26 letters values = [ ["a", 1], ["b", 3], ["c", 3], ["d", 2], ["e", 1], \ ["f", 4], ["g", 2], ["h", 4], ["i", 1], ["j", 8], ["k", 5], \ ["l", 1], ["m", 3], ["n", 1], ["o", 1], ["p", 3], ["q", 10], \ ["r", 1], ["s", 1], ["t", 1], ["u", 1], ["v", 4], ["w", 4], \ ["x", 8], ["y", 4], ["z", 10] ]
In [2]:def letterScore(letter): """ This function takes a single letter as input and returns the score for that letter. """ # Use a loop to find the letter for value in values: # "for i in range(len(values))" is not recommended if letter == value[0]: return value[1] print(letter, "'s value is not defined, return 0 instead! \n") return 0 #
In [3]:# Test letterScore function print(letterScore("m"), letterScore("z")) print(letterScore("@"))
In [4]:def scrabbleScore(word): """ This function takes a single word as input and returns the total score of all of the letters in the word. """ # Inititalize the total score to be 0 totalScore = 0 for letter in word: totalScore += letterScore(letter) # Return the total score return totalScore
In [5]:# Test scrabbleScore function print(scrabbleScore('cat'), scrabbleScore('apple'), scrabbleScore('python'), scrabbleScore('quetzal'), scrabbleScore('jonquil'), scrabbleScore('syzygy'))
- Review Questions:
Lab_3
-
Overview: arrays, print, clear screen and delay
-
Remember:
-
list is mutable inside a function, if you want the function to return a new list without changing the original list passed into the function, you need to create an empty list
res = []
, then append elements inside withres.append()
method. -
everything in python is reference,
listB = listA
only make listB points to the same object which listA is pointing to, it does not create a new object for listB, so when change listB, it also change listA. If you want a real copy, check these ways. -
in the GameOfLife exercise, some still make mistakes like
-
for rows in currentGen[minRow:row+2]:
for cell in rows[minCol:column+2]:
if rows[cell] == 1:
count += 1
in neighbors() function, be clear about the meaning of cell here, it's not an index!
- Solution:
- Review Questions:
In [1]:
def neighbors(input, row, col): ''' takes a 2D array named input, a row index, and a column index as input and returns the number of neighbors of array[row][col] that are 1's ''' sum = 0 for i in range(max(0, row - 1), min(len(input), row + 2)): for j in range(max(0, col - 1), min(len(input[0]), col + 2)): # print(i, j, input[i][j], sum) if (i != row or j != col) and input[i][j] == 1: sum += 1 return sum bigArray = [ [0, 1, 1, 1, 1, 0, 0, 0], [1, 0, 0, 0, 0, 1, 0, 1], [0, 0, 1, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 1, 1, 0, 1, 1], [0, 0, 0, 0, 0, 1, 0, 1], [1, 1, 1, 0, 0, 0, 1, 0], [1, 0, 1, 0, 0, 0, 0, 1] ] print(neighbors(bigArray, 3, 3), neighbors(bigArray, 5, 6), neighbors(bigArray, 4, 1), neighbors(bigArray, 7, 1))
In [2]:def nextgen(input): ''' takes as input a list which is a 2D array of the current generation of creatures and returns a new list which is a 2D array of the same size representing the next generation of the array, according to the rules of Life.''' output = [] rows = len(input) cols = len(input[0]) for i in range(0, rows): newrow = [] for j in range(0, cols): if input[i][j] == 1: if neighbors(input, i, j) == 2 or neighbors(input, i, j) == 3: newrow.append(1) else: newrow.append(0) else: if neighbors(input, i, j) == 3: newrow.append(1) else: newrow.append(0) output.append(newrow) return output start = [[1, 0, 0, 1], [0, 0, 0, 1], [1, 0, 0, 0], [1, 1, 1, 1]] firstGen = nextgen(start) print(firstGen) print(start) secondGen = nextgen(firstGen) print(secondGen) thirdGen = nextgen(secondGen) print(thirdGen) fourthGen = nextgen(thirdGen) print(fourthGen) fifthGen = nextgen(fourthGen) print(fifthGen)
- Exercise - Game of Life:
In [1]:
import time from IPython.display import clear_output import sys def neighbors(currentGen, row, column): """ This function takes a 2D array and the row number and the column number of the target cell and returns the number of neighbor cells that are 1. """ count = 0 if row - 1 < 0: minRow = 0 else: minRow = row - 1 if column - 1 < 0: minCol = 0 else: minCol = column - 1 for rows in currentGen[minRow:row+2]: for cell in rows[minCol:column+2]: if cell == 1: count += 1 if currentGen[row][column] == 1: count -= 1 return count def nextgen(currentGen): """ This function takes a 2D array and returns the next generation according to the rules of Conway's Game of Life. This function uses neighbors() shown above. """ output = [] for row in range(len(currentGen)): newRow = [] for col in range(len(currentGen[row])): nbs = neighbors(currentGen, row, col) if currentGen[row][col] == 0: if nbs == 3: newRow.append(1) else: newRow.append(0) else: if nbs == 2 or nbs == 3: newRow.append(1) else: newRow.append(0) output.append(newRow) return output def print_life(currentGen): """ This function prints the input 2D array. Every cell that is 1 is printed as a '#' and every cell that is 0 is printed as an empty space. """ output = "" for row in currentGen: for cell in row: if cell == 0: output = output + " " else: output = output + "#" output = output + "\n" output = output + "\n" print(output) def life(currentGen, generation): """ This function implements Conway's Game of Life. """ clear_output() print("Initial generation:") print_life(currentGen) sys.stdout.flush() # flush output so it can be printed immediately time.sleep(1) newGen = currentGen for i in range(generation): newGen = nextgen(newGen) clear_output() print("Generation " + str(i+1) + ":") print_life(newGen) sys.stdout.flush() time.sleep(1/8)
In [2]:start = [ [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 1, 1, 1, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0] ] life(start, 3)
In [3]:tumbler = [ [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0], [0,0,0,0,1,0,1,0,0,0,1,0,1,0,0,0,0,0], [0,0,0,0,1,0,0,1,0,1,0,0,1,0,0,0,0,0], [0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0], [0,0,0,0,0,0,1,1,0,1,1,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] ] life(tumbler, 30)
In [4]:face = [ [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,1,1,0,0,0,0,0,0,1,1,0,0,0,0,0,0], [0,0,0,1,0,0,1,0,0,0,0,1,0,0,1,0,0,0,0,0], [0,0,0,1,0,0,1,0,0,0,0,1,0,0,1,0,0,0,0,0], [0,0,0,1,0,0,1,0,0,0,0,1,0,0,1,0,0,0,0,0], [0,0,0,0,1,1,0,0,0,0,0,0,1,1,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,1,0,0,1,0,1,1,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,1,1,0,0,1,1,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0], [0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0], [0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,1,0,0,0,0], [0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0], [0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] ] life(face, 60)
In [5]:glider_gun = [ [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\ 0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\ 0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,\ 0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0], [0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,\ 0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0], [0,1,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,\ 0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,1,1,0,0,0,0,0,0,0,0,1,0,0,0,1,0,1,1,\ 0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,\ 0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,\ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,\ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] ] life(glider_gun, 100)
In [6]:glider_gun.extend([[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]] * 15) life(glider_gun,500)
- Review Questions:
Lab_4
-
Overview: user input, dealing with errors using "try-except-else", files I/O
-
Solution:
- Review Questions:
In [1]:
def morse(str): ''' takes as input a string and returns the Morse code version of that string, assume that all the letters in the input are in lower case''' morsecode = {'a':".-", 'b':"-...", 'c':"-.-.", 'd':"-..", \ 'e':".", 'f':"..-.", 'g':"--.", 'h':"....", 'i':"..", \ 'j':".---", 'k':"-.-", 'l':".-..", 'm':"--", \ 'n':"-.", 'o':"---", 'p':".--.", 'q':"--.-", \ 'r':".-.", 's':"...", 't':"-", 'u':"..-", 'v':"...-", \ 'w':".--", 'x':"-..-", 'y':"-.--", 'z':"--.." } res = '' for i in range(len(str)): if str[i] == ' ': res += ' ' else: res += morsecode[str[i]] if i != len(str) - 1: res += ' ' return res print(morse('e'), '\n' + morse('a boy'), '\n' + morse('python code'))
In [2]:def piglatin(): ''' takes no inputs. It asks the user to enter a string (a single word) and then prints the word in Pig Latin ''' while True: try: word = input('Enter a word: ') if word[0] not in ['a', 'e', 'i', 'o', 'u']: word += word[0] + 'ay' word = word[1:] else: word += 'way' except IndexError: print("You may enter an empty string, please try again!") else: print(word) piglatin()
- Exercise - Text Database Utilitites:
In [1]:
""" The three functions in this file are used as database utilities. The database is used as a phone book. """ def DBcreate(): """ Create a new database with some data """ # Ask the user for the file name of the database filename = input('Enter the name of the file to write: ') # Open the file for writing dbFile = open(filename, 'w') # Ask the user for the name of the new contact name = input('Enter a name: ') # Now we will use a while loop to repeatedly ask for new # contacts. # The while loop ends when the entered name is "done". while name != 'done': # 1. Ask the user for the phone number phone = input('Enter a phone number: ') # 2. Write the new contact to the database file dbFile.write(name + '\n' + phone + '\n') # 3. Ask the user for the name of the new contact name = input('Enter a name: ') # Say "Goodbye!" print('Goodbye!') # Close the database file dbFile.close() # This function, DBappend(), is already completed for you. # This is given to you. You do not need to change it. def DBappend(): """ Append new data to an existing database """ # Keep trying until we have a valid file name while True: try: # Ask the user for the file name of the database fileName = input( \ "Enter the name of the file to write: " \ ) # Try reading the file with the given name dbFile = open(fileName, "r") except IOError: # If the file does not exist print("There is no file by that name. Try again...") else: # No problem opening the file # Close it dbFile.close() # Open the file again to append new contact data dbFile = open(fileName, "a") # Exit the infinite while loop break # Ask the user for the name of the new contact name = input("Enter a name: ") # Now we will use a while loop to repeatedly ask for new # contacts. # The while loop ends when the entered name is "done". while name != "done": # Ask the user for the phone number of the new contact number = input("Enter a phone number: ") # Write the new contact to the database file dbFile.write(name + "\n") dbFile.write(number + "\n") # Ask the user for the name of the new contact name = input("Enter a name: ") # Say "Goodbye!" print("Goodbye!") # Close the database file dbFile.close() def DBquery(): """ Retrieve contact data from the database """ # Keep trying until we successfully read # an existing database file while True: try: # Ask the user for the file name of the database filename = input('Enter the name of the file to read: ') # Try reading the file with the given name dbFile = open(filename, 'r') except IOError: # If the file does not exist print("There is no file by that name. Try again...") else: # No problem opening the file # Read all the lines from the file records = dbFile.readlines() # Close the file dbFile.close() break # Create the phone book, an empty dictionary phoneBook = {} # Remove all the '\n' from the data loaded from the file for i in range(len(records)): records[i] = records[i][0:-1] # Now we will use a for loop to go through all the lines # of the data loaded from the file (already done above), # two lines at once. The first line is the contact name # and the second line is the phone number. # Complete this inside the for loop: # Add new contact into the dictionary for i in range(0, len(records), 2): phoneBook[records[i]] = records[i + 1] # Ask the user for the name to be searched for name = input('Enter a name: ') # Now we will use a while loop to repeatedly ask for names # to be searched for. # The while loop ends when the entered name is "done". while name != 'done': # Complete this inside the while loop: # 1. Check if the contact name can be found in # the phone book # 1.1. If yes, then show the phone number # 1.2. If no, then show an error message if name in phoneBook: print(phoneBook[name]) else: print('Sorry, there is no number for that name.') # 2. Ask the user for the name to be searched for name = input("Enter a name: ") # Say "Goodbye!" print("Goodbye!")
In [2]:DBcreate()
In [3]:DBappend()
In [4]:DBquery()
- Review Questions:
Lab_5
-
Overview: recursion, turtle graphics module, class
-
Solution:
- Review Questions:
In [1]:
def pow(x,y): ''' takes two numbers x and y as input and computes xy.''' if not (isinstance(y, int) and y >= 0): print('y should be non-negative integer') return if y == 0: return 1 else: return x * pow(x, y-1) pow(2, 5)
Out[1]:In [2]:def member(item, L): '''returns True if item is an element of list L and returns False otherwise. ''' # print(L) if not len(L): return False else: if item == L[0]: return True else: return member(item, L[1:]) print(member(3, [1, 2, 3, 4]), member(3, [2, 4, 6, 8]))
In [3]:from turtle import * def pattern(number, length): ''' draws number squares, each with the given side length. ''' speed(10) tiltAngle = 360 / number pointing = 0 while pointing < 360: for i in range(4): forward(length) left(90) left(tiltAngle) pointing += tiltAngle reset() pattern(6,100) reset() pattern(20, 100) reset() pattern(16, 100)
In [4]:def triangle(length, level): ''' draw Sierpinski triangle ''' speed(10) if level == 1: forward(length) left(120) forward(length) left(120) forward(length) left(120) else: triangle(length / 2, level - 1) forward(length / 2) triangle(length / 2, level - 1) left(120) forward(length / 2) right(120) triangle(length / 2, level -1) right(120) forward(length / 2) left(120) reset() triangle(320, 5)
- Exercise - Recursion Tree
In [1]:
from turtle import * # Turn left for 90 degrees left(90) def tree(trunkLength, currentDepth, maximumDepth): """ Draw a tree with turtle graphics recursively. """ speed(10) # Draw a trunk forward(trunkLength) if currentDepth < maximumDepth: # Turn left for 'angle' degrees left(30) # Recursively draw a smaller tree tree(trunkLength / 2, currentDepth + 1, maximumDepth) # Turn right for 2 * 'angle' degrees right(60) # Recursively draw another smaller tree tree(trunkLength / 2, currentDepth + 1, maximumDepth) # Turn left for 'angle' degrees, so that the # turtle faces its original starting direction left(30) # Return to the original starting position left(180) forward(trunkLength) left(180) reset() left(90) tree(100, 0, 5)
- Review Questions:
Supporting Materials
Basis:
Wiki: Python Syntax and Semantics
Gain Experience of Using Many Packages:
Scikit-learn for Machine Learning
Collection of Python Web Frameworks (Django, Flask, Bottle, Tornado, CherryPy, web2py, Pylons ...)
Feel the Power of Python:
Ipython Notebooks for Everything
Collection of Python Related Videos