CS 1110 Final Solutions May 2017

Similar documents
CS 1110 Final, May 2017

Time: 9am-11:30am, Thursday May 17 th Location: Barton Hall: the central and east portions of the track/gym floor.

CS 1110 Final Exam Solutions May 15th, 2014

CS 1110 Final, December 8th, Question Points Score Total: 100

CS 1110 Final, December 8th, Question Points Score Total: 100

CS 1110: Introduction to Computing Using Python Loop Invariants

CS 1110 Prelim 2 November 14th, 2013

CS 1110 Final Exam, May 2018

CS 1110 Prelim 2 Solutions April 2018

Last Name: First: Netid: Section. CS 1110 Final, December 17th, 2014

CS 1110 Final, December 17th, Question Points Score Total: 100

CS 1110 Final Exam Solutions May 2018

CS1110. Lecture 22: Prelim 2 Review Session. Announcements. Processed prelim regrade requests: on the front table.

CS 1110: WORKED EXAMPLES REGARDING LOOPS AND INVARIANTS

CS 1110 Prelim 1 October 4th, 2012

CS 1110 Prelim 2 November 10th, 2016

Lecture 26: Sorting CS 1110 Introduction to Computing Using Python

Lecture 17: Classes (Chapter 15)

Acct. balance Acct. balance 50 25

CS 1110 Final, December 16th, 2013

CS Lecture 19: Loop invariants

Last Name: First Name: Cornell NetID, all caps: CS 1110 Regular Prelim 1 Solutions March 2018

CS 1110, LAB 13: SEQUENCE ALGORITHMS

CS 1110 Regular Prelim 1, March 14th, 2017

Text Input and Conditionals

CS Prelim 2 Review Fall 2018

STREAMS AND REVIEW 12

CS 1110 Final Exam May 9th, 2013 SOLUTIONS

CS Prelim 2 Review Fall 2017

CS 1110 Prelim 2 November 13th, 2014

isinstance and While Loops

ASYMPTOTIC COMPLEXITY

CS 1110: Introduction to Computing Using Python Lists and Sequences

CS 1110 Prelim 2 April 22, 2014

CS Prelim 2 Review Fall 2015

CS Prelim 2 Review Fall 2014

CS 1110 Prelim 1 October 17th, 2013

CS 1110 Final, December 16th, 2013

CS 1110 Prelim 2 November 6th, 2012

CS Prelim 2 Review Fall 2012

Abstract Data Types Chapter 1

Lecture 24: Loop Invariants

Lecture 17: Classes (Chapter 15)

PREPARING FOR PRELIM 1

CSC148 Recipe for Designing Classes

CS 1110 Final, December 9th, Question Points Score Total: 100

PREPARING FOR THE FINAL EXAM

CS 1110, LAB 12: SEQUENCE ALGORITHMS First Name: Last Name: NetID:

Python review. 1 Python basics. References. CS 234 Naomi Nishimura

Lecture 18: Using Classes Effectively (Chapter 16)

Last Name: UTION First Name: SOL Cornell NetID: CS1110. Solution: CS 1110 Prelim 2 April 26, 2016

CS Lecture 18: Card Tricks. Announcements. Slides by D. Gries, L. Lee, S. Marschner, W. White

Sorting and Searching

Short Answer Questions (40 points)

Abstract Data Types. CS 234, Fall Types, Data Types Abstraction Abstract Data Types Preconditions, Postconditions ADT Examples

INSTITUTE OF AERONAUTICAL ENGINEERING

ASYMPTOTIC COMPLEXITY

Lecture 10: Lists and Sequences

Review 2. Classes and Subclasses

Math 15 - Spring Homework 5.2 Solutions

CS1110 Lab 6 (Mar 17-18, 2015)

Prelim 2, CS2110. SOLUTION

CSCI 150: Exam 3 Practice Problems

CS 115 Exam 3, Spring 2014

CS 1110, Spring 2018: Prelim 1 study guide Prepared Tuesday March 6, 2018

Hanoi, Counting and Sierpinski s triangle Infinite complexity in finite area

CS 1110 Prelim 2 April 26th, 2016

Total Score /15 /20 /30 /10 /5 /20 Grader

CS 115 Lecture 8. Selection: the if statement. Neil Moore


CS 1110 Prelim 2 November 12th, 2015

CMSC 201 Fall 2016 Lab 09 Advanced Debugging

CS 3 Midterm 1 Review

CS 1110 Prelim 1 October 15th, 2015

Lab 10: OCaml sequences, comparators, stable sorting 12:00 PM, Nov 12, 2017

CS 1110 Prelim 1, March 2018

x[2] x[2] = "d" x.append("d") x.insert(0, "d") x[3:5] x.s ort()

CS 1110 Prelim 2 November 12th, 2015

Lecture 18. Classes and Types

Total Score /15 /20 /30 /10 /5 /20 Grader

SEARCHING AND SORTING HINT AT ASYMPTOTIC COMPLEXITY

Question 1. tmp = Stack() # Transfer every item from stk onto tmp. while not stk.is_empty(): tmp.push(stk.pop())

def F a c t o r i a l ( n ) : i f n == 1 : return 1 else : return n F a c t o r i a l ( n 1) def main ( ) : print ( F a c t o r i a l ( 4 ) )

Prelim 1. CS2110, October 2, 2014, 5:30 PM Extra Total Question TrueFalse Multiple Object Oriented

Prelim 2, CS :30 PM, 25 April Total Question Name Short Search/ Collections Trees Graphs

CS 1110 Prelim 2 April 21, 2015 GRADING GUIDE

Review 1. Call Frames; Diagramming Objects

Flow Control: Branches and loops

CS 1110 Prelim 2 April 21, 2015

Assignment 7: Due Wednesday May 11 at 6pm UPDATES on Monday May 9

CMSC 201 Spring 2019 Lab 06 Lists

6.149 Checkoff 2. What to complete. Recall: Creating a file and running a program in IDLE.

Clicker Question What will this print? def blah(x): return x+1 def main(): z = blah(3) print(z) main() A) 3 B) 4 C) 5 D) It causes an error

Working with recursion. From definition to template. Readings: HtDP, sections 11, 12, 13 (Intermezzo 2).

Working with recursion

A Second Look At ML. Chapter Seven Modern Programming Languages, 2nd ed. 1

QUIZ. 0] Define arrays 1] Define records 2] How are arrays and records: (a) similar? (b) different?

Prelim 2 Solution. CS 2110, November 19, 2015, 7:30 PM Total. Sorting Invariants Max Score Grader

Control, Quick Overview. Selection. Selection 7/6/2017. Chapter 2. Control

Programming Languages ML Programming Project Due 9/28/2001, 5:00 p.m.

Transcription:

Last Name: First Name: Cornell NetID, all caps: CS 1110 Final Solutions May 2017 1. [11 points] Implement the following function according to its specification. def putsidebyside(two_line_strings): """Returns: a string with two lines. The first line of the return string should contain, in order, the first line of each string in two_line_strings, separated by a space. The second line of the return string should contain, in order, the second line of each string in two_line_strings, separated by a space. Input: two_line_strings, which is a non-empty list of two-line strings. Each string has exactly this form: xx\nxx, where x is a character in [a..z or A..Z or 0..9]. There will always be exactly two characters before and after the new line character \n. Remember that \n is a SINGLE special character indicating a new line (which causes the string to print over multiple lines). For example: putsidebyside(["ab\ncd", "EF\nGH"]) should return "AB EF\nCD GH". This corresponds to arranging strings that print as: AB CD and: EF GH into the following: AB EF CD GH Note: should NOT add a space before the first string or after the last string. This would be wrong because there is a space before the first AB\nCD: AB EF CD GH Another example: putsidebyside(["ab\ncd", "EF\nGH", "IJ\nKL"]) returns "AB EF IJ\nCD GH KL". """ Implement this function on the next page.

# Put your code for function putsidebyside below. Here are several alternatives. Solution LL1: def solll1(two_line_strings): top = "" bottom ="" for tls in two_line_strings: nindex = tls.find("\n") front = tls[:nindex] back = tls[nindex+1:] top += (front + " ") bottom += ( back + " ") return top.strip() + "\n" + bottom.strip() Solution AP1: def solap1(two_line_strings): top_str = '' bottom_str = '' for x in two_line_strings: top_str += x[0:2] + ' ' Solution EA: """ # BEGIN REMOVE line1 = "" line2 = "" first = True for a_string in two_line_strings: parts = a_string.split("\n") if first: first = False else: line1 += " " line2 += " " line1 += parts[0] Solution AP2: def solap2(two_line_strings): top_str = two_line_strings[0][0:2] Page 2

bottom_str = two_line_strings[0][3:5] for x in two_line_strings[1:]: top_str += ' ' + x[0:2] Solution AP3: def solap3(two_line_strings): # ima hacky haxor solution. Uses [::], which wasn't discussed in class twolist = '\n'.join(two_line_strings).split('\n') first = twolist[::2] #crazy python nonsense Alternate: Solution LL2 def solll2(two_line_strings): converted = map(splitem, two_line_strings) # top is output[0], bottom is output[1] output = [converted[0][0], converted[0][1]] for i innon range(1, len(converted)): for j in range(2): output[j] += (" " + converted[i][j]) return output[0] + "\n" + output[1] # helper for solll2; to allow use of map def splitem(tls): """Version of split() that takes the string to split as an argument""" Page 3

2. [21 points] Consider the following code to solve the Towers of Hanoi problem. We guarantee there are no errors. 1 class Tower(object): 2 def init (self, name, disks): 3 self.disks = disks 4 self.name = name 5 6 def topdisk(self): 7 if self.disks == []: 8 return None 9 else: 10 return self.disks[len(self.disks) - 1] 11 12 def poptopdisk(self): 13 return self.disks.pop(len(self.disks) - 1) 14 15 def move(self, to): 16 if self.topdisk() is not None: 17 isempty = to.topdisk() is None 18 19 if isempty or to.topdisk() > self.topdisk(): 20 to.disks.append(self.poptopdisk()) 21 22 def plan(source, target, other, num_disks): 23 if num_disks == 1: 24 source.move(target) 25 else: 26 plan(source, other, target, num_disks-1) 27 print "move disk" 28 source.move(target) 29 plan(other, target, source, num_disks-1) 30 31 left = Tower("left", [2, 1]) 32 middle = Tower("middle", []) 33 right = Tower("right", []) 34 plan(left, right, middle, len(left.disks)) Draw the requested items here: #BEGIN REMOVE # Erik Andersen # END REMOVE class Tower(object): def init (self, name, disks): self.disks = disks self.name = name def topdisk(self): if self.disks == []: return None else: return self.disks[len(self.disks) - 1] def poptopdisk(self): return self.disks.pop(len(self.disks) - 1) def move(self, to): if self.topdisk() is not None: isempty = to.topdisk() is None # BEGIN REMOVE # This looks like it shouldn't work when on isvalid = to.topdisk() > self.topdisk() # END REMOVE if isempty or to.topdisk() > self.topdisk() to.disks.append(self.poptopdisk()) def plan(source, target, other, num_disks): if num_disks == 1: source.move(target) else: In the space above, draw the function call frames for plan, global variables, and object folders that result by running this code. Do NOT draw class folders or folders for functions. You do NOT need to draw function call frames for any function other than plan. Remember that lists are objects. Page 4

It is OK to include line 25 (for the line else:) in the 1st call frame Page 5

3. For debugging purposes, Professor Andersen wants to count how many moves it takes to complete the Towers of Hanoi puzzle in the previous example. He added a print statement on line 27 to print move disk whenever a disk is moved. This may have been a poor choice. (a) [1 point] How many times will move disk get printed when the code is run? 1 (b) [1 point] How many moves were actually made (i.e., line 20 was actually executed)? 3 (c) [3 points] Suggest how Prof. Andersen can change the code so that move disk is printed each time a move is made. Refer to specific line numbers on which print statements should be inserted or deleted, and also be clear about the level of indentation of any added prints. Delete print at 27; add print at 21, indented under the second if. OR: Add a print on Line 24 OR: Delete print at 27; add print at line 16 OR: Delete print at 27; add print at line 13 before return 4. Consider the following subclass Loutcome of class Outcome. It has almost the same class invariant as Outcome. The differences are shown in orange below, so you should be to just skim the orange parts. class Loutcome(Outcome): """ An instance is a loser-annotated outcome in a tournament tree. Attributes: winner [nonempty str]: name of the winner in this Loutcome Must be the same as the name of *exactly one* of attributes input1 or input2, defined next. loser [nonempty str]: name of the loser in this Loutcome input1 [Loutcome or nonempty string]: If a nonempty string, the name of a competitor in the tournament, and we say that the name of input1 is that string. If a Loutcome, then the name of input1 is its winner attribute. input2 [Loutcome or nonempty string]: If a nonempty string, the name of a competitor in the tournament, and we say that the name of input2 is that string If a Loutcome, then the name of input2 is its winner attribute. Note that the constraints (invariants) on winner imply that the names of input1 and input2 must be different. """ Page 6

(a) [12 points] Implement the init method of Loutcome below. def init (self, in1, in2, one_won=true): """Same as for the init for Outcome, except that: If one_won is True, loser is the name of in2's winner (if in2 is an Loutcome) or in2 itself (if in2 is a string) Otherwise, loser is in1's winner (if in1 is an Loutcome) or in1 itself (if in1 is a string) Preconditions: same as for the init for Outcome, except substitute the word "Loutcome" for "Outcome" """ ### You MUST effectively call the init method of Outcome. ### Its header is: def init (self, in1, in2, one_won=true) ### You are allowed to use _extract_name (see below for specification). We can use extract name on Loutcomes because Loutcomes are Outcomes (since Loutcome is a subclass of Outcome). Outcome. init (self, in1, in2, one_won) # CAN'T say "one_won=true" if one_won: # "if one_won == True" OK self.loser = _extract_name(in2) else: self.loser = _extract_name(in1) Specification for extract name(). It is not a method of Outcome. def _extract_name(x): """Returns: string that is the name of x, defined as follows: If x is an Outcome, then the name is x's winner; otherwise, the name is x itself. Precondition: x is either a non-empty string or an Outcome.""" Page 7

(b) [17 points] Implement the following method of Loutcome according to its specification. def winsandlosses(self, team): """Returns: a two-item list where the item at index 0 is the number of games that team won, and the item at index 1 is the number of games that team lost. Precondition: team [str] is a team that played in this Loutcome. Example: for the Loutcome below: Here's the desired output for various teams: D beat B D beat A A beat B "A" --> [1,1] A "B" --> [1,2] B "C" --> [0,2] D beat C "D" --> [3,0] C D B beat C B C """ ### Hint: We are dealing with Loutcomes, so you don't need _extract_name. # BEGIN REMOVE if team == self.winner: output = [1, 0] elif team == self.loser: output = [0, 1] else: output = [0,0] for sub in [self.input1, self.input2]: if isinstance(sub, Loutcome): suboutput = sub.winsandlosses(team) output[0] += suboutput[0] output[1] += suboutput[1] Page 8

5. [12 points] Implement the following function according to its specification. def merge_records(d1, d2): """Input: d1 and d2 are (possibly empty) dictionaries representing win-loss records: Each key is a non-empty string representing a team name. The value for each key is a two-item list of ints, where the first is the number of wins and the second is the number of losses for that team in some tournament/outcome tree. This function adds the win-loss records of d2 into d1. WARNINGS: It does NOT return anything; it changes d1 but not d2. And, the values in the altered d1 should be different list objects than the list objects that are values in d2, even if they have the same numbers in them. For example: if d1 is and d2 is then d1 becomes {"Cornell": [10,1], {"Cornell": [2,0], {"Cornell":[12,1], "Harvard": [4,3]} "Stanford": [0,3]} "Harvard": [4,3], "Stanford": [0,3]} where the new d1's "Stanford" list [0,3] is a DIFFERENT list object than d2's "Stanford" list object """ ### HINT: for a list mylist, list(mylist) or mylist[:] returns a copy of mylist. for team in d2: if team in d1: d1[team][0] += d2[team][0] d1[team][1] += d2[team][1] else: d1[team] = list(d2[team]) # d2[team][:] also OK Alternate solution: for team in d2: if team not in d1: # "if not team in d1" also OK # make it so team *is* in d1 d1[team] = [0,0] d1[team][0] += d2[team][0] d1[team][1] += d2[team][1] Page 9

Alternate solution with more loops than necessary: for team in d1: if team in d2: d1[team][0] += d2[team][0] d1[team][1] += d2[team][1] for team in d2: if team not in d1: d1[team] = list(d2[team]) Page 10

6. A progression is a sequence of integers that are separated by the same distance; for instance, 5, 10, 15, 20 is a progression with 3 steps of step-size 5, and -15, -12, -9 is a progression with 2 steps of step-size 3. We would like to use a while-loop to write a function has_progression(x, step, n) that returns the starting index start in list of ints x for a progression of step-size step that has at least n steps. (It should return -1 if there is no such start, and we require that n>=1). For example, suppose that x is [1, 2, 14, 16, 18, 20, 22]. Then, has_progression(x, 2, 3) --> 2 b/c x[2]==14, x[3]==16, x[4]==18, x[5]==20 has_progression(x, 2, 4) --> 2 b/c the step-2 progression 14,16,18,20,22 starts at x[2] and has 4 steps. has_progression(x, 2, 5) --> -1 has_progression(x, 1, 1) --> 0 We give you the following invariant, documenting variables start, m, and i. start i x the progression can t start here progression of m steps??? In words, x[start..i-1] forms a progression with m steps; x[..start-1] does not contain an n-step progression, and if start-1 is a valid index, then x[start-1]!= x[start] - step. (a) [4 points] We initialize i to be 1, because there is necessarily a progression in x[0..0], albeit one with 0 steps. What should we then initialize m and start to be, according to the invariant? m = 0, start = 0 (b) [3 points] Is the following a correct while-loop condition according to the invariant? If yes, write the word YES below it; otherwise, cross it out and write a correct while-loop condition below it. while m < n and i < len(x) - 1: It should be while m < n and i < len(x):, or loop ends too early. (c) [5 points] Suppose the invariant is true, and m is much less than n and i is much less than the length of x. Now, suppose we find out that x[i] == x[i-1]+step. According to the invariant......should m and/or i be updated? If so, give Python code making the update(s); if not, write No changes. m += 1 or m = m+1. i += 1 or i = i+1. Luckily, here, the order of i and ms update doesn t matter. Page 11

...and, should start be updated? If so, give Python code making the update; if not, write No change to start. No change to start Helper function for question on next page. def swap(b,h,k): """ Swaps element h and k in list b """ tmp = b[h] b[h] = b[k] b[k] = tmp Page 12

7. [15 points] Implement string list sort according to its specification. def string_list_sort(b,h,k): """Swaps items in the PORTION of list b from index h up to and including index k so that strings are in front and lists are in back. Returns: index i such that b[h..i] are strings and b[i+1..k] are lists. Example: if b = [['Prospero', 'and', 'Ariel'], 'how', ['are', 'you']] string_list_sort(b,0,2) returns 0, and could change b to : ['how', ['are', 'you'], ['Prospero', 'and', 'Ariel']] or ['how', ['Prospero', 'and', 'Ariel'], ['are', 'you']] Your solution MUST use a while loop, MUST NOT create a copy of the list, and MUST satisfy the invariants set out in the code below. Precondition: b is a nonempty list containing only lists and strings; h and k are integers that are valid indices in list b""" # INVARIANT: b[h..i] are strings, b[t..k] are lists # PRECONDITION: no strings or lists yet identified (b[h..i] and b[t..k] both empty) # FIRST, FIX THESE INITIALIZATIONS i = None t = None # Hint: you may use the swap function from the previous page i = h - 1 t = k + 1 while t!= i+1: # i < t-1 also OK if type(b[i+1]) == str: i = i + 1 else: # type(b[i+1]) == list swap(b,i+1,t-1) t = t - 1 Alternate solution: i = h - 1 t = k + 1 while t!= i+1: # i < t-1, t >= i also OK if type(b[t-1]) == list: #isinstance also good here Page 13

t = t - 1 else: # type(b[t-1]) == str swap(b,i+1,t-1) #may also use python b[i+1],b[t-1] = b[t-1],b[j-1] i = i + 1 return i return i #POSTCONDITION: b[h..i] are strings, b[i+1..k] are lists Page 14

8. (a) [3 points] Consider the following class definition: 1 class Bird(object): 2 def init (self, n): 3 self.name = n 4 def tweet(self, punc): 5 output = self.name + " says tweet" 6 return output + str(punc) Write a Python assignment statement that stores in variable x the ID of a new Bird object whose name is the string Caliban. x = Bird("Caliban") (b) [8 points] Consider the following objects and global variables: Draw the call frame that results from the call b2.tweet(? ), stopping execution just before line 6 is executed. Include any crossed-off variable contents or line numbers. 9. [1 point] Fill in your last name, first name, and Cornell NetID at the top of each page. Page 15

Always do this! It prevents disaster in cases where a staple fails. Page 16