Problem Set 5 - Due Tuesday March 10

Reading

  1. Slides and notebooks from Lec 08 (Sequences and Loops), Lec 09 (Iteration, Part 1), and Lec 10 (Lists, Memory Diagrams, and Mutable vs. Immutable Sequences).
  2. Problems and solutions from Lab 05: Loops and Lab 06: Lists
  3. Think Python, Ch. 8: Strings
  4. Think Python, Ch. 7: Iteration
  5. Think Python, Ch. 9: Lists

About this Problem Set

This problem set will give you practice with sequences (strings and lists), operations on sequences, loops on sequences, loops with graphics, and list memory diagrams.

Other notes:

All code for this assignment is available in the ps05 folder in the cs111/download directory within your cs server account.


Task 0: Scrambled Solutions

This is an individual problem which you must complete on your own, although you can ask for help from the CS111 staff.

This time we have three puzzles for you to solve to review the problem set 4 solutions: One puzzle for each task. Go to:

CS 111 Puzzles

and select each of the options under Problem Set 4. These puzzles will only be made available after ps04 is due.

As before, please download and submit your solution files, and email pmawhort@wellesley.edu if you run into trouble.


Task 1: Word Play

In this problem, having a partner is optional, but is strongly recommended. If you want to find a partner, use this Piazza post.

The task 1 rubric shows how this task will be graded, and can be used as a checklist to make sure you are done with the task.

In this task you will flesh out the definitions of various word-related functions in the provided file wordplay.py.

Subtask 1a: Scrabble Score

In the game Scrabble, players compete to score points by building words out of individual letter tiles. Each letter is associated with a number of points based on how frequently it appears in different words (so, e.g., 'Q' and 'Z' are worth lots of points because it's harder to make words containing them). The Scrabble value of an entire word is just the sum of the values of each of its letters. In this subtask, you will determine word point values by adding the points assigned by Scrabble to each letter, which are shown in the following table:

Points Letters
1 A, E, I, L, N, O, R, S, T, U
2 D, G
3 B, C, M, P
4 F, H, V, W, Y
5 K
8 J, X
10 Q, Z

You must define the following two functions in wordplay.py:

def scrabblePoints(letter):
    """
    Returns the Scrabble score of a particular letter (a single-character
    string), as determined by the table in the PS05 Task 1a description.
    Case of the letter does not matter. Returns 0 for non-letter
    characters.
    """
    # Flesh out the body of this function

def scrabbleScore(word):
    """
    Returns total number of Scrabble points that whole word is worth, as
    determined by the table in the PS05 Task 1a description. This
    function must call scrabblePoints.
    """
    # Flesh out the body of this function

Examples

In []: scrabblePoints('s')
Out[]: 1

In []: scrabblePoints('E')
Out[]: 1

In []: scrabblePoints('c')
Out[]: 3

In []: scrabblePoints('Q')
Out[]: 10

In []: scrabblePoints('5')
Out[]: 0

In []: scrabblePoints('?')
Out[]: 0

In []: scrabblePoints(' ')
Out[]: 0

In []: scrabbleScore('cat')
Out[]: 5

In []: scrabbleScore('QUIZ')
Out[]: 22

In []: scrabbleScore('juxtapose')
Out[]: 25

In []: scrabbleScore('Wellesley')
Out[]: 15

In []: scrabbleScore("I'm 3LI73!") # Nonletter characters have score 0
Out[]: 6

Notes

Testing

Subtask 1b: Word Properties

We are interested in some fun properties of written words.

  1. Does the word use only the top row of keys (i.e., 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p') on a standard keyboard layout? Examples are typewriter and pretty.
  2. Does a word contain at least three vowels in a row? Examples are beautiful and delicious.
  3. Does a word contain exactly one occurrence of each of the five English vowels? Examples are precarious, education and tambourine.

Your task is to flesh out the definitions of these three functions in wordplay.py:

def isTopRow(word):
    """
    This predicate determines if word can be spelled using only letters in      
    the top row of the  keyboard: q, w, e, r, t, y, u, i, o, p.                    
    Returns a boolean.
    """
    # Flesh out the body of this function

def isBeauteous(word):
    """
    Call a word "beauteous" if it contains at least three consecutive
    vowels. 'beauteous' itself is beauteous (both 'eau' and 'eou'), but
    so are. 'delicous' (iou) and 'sequoia' ('uoia'). In contrast,
    'aardvark', and 'nation' are not.
    This predicate returns True if word is beauteous and False otherwise.
    """
    # Flesh out the body of this function

def isPrecarious(word):
    """Call a word "precarious" if it contains exactly one of each of 
    the five vowels (aeiou), not necessarily in order. Examples of such 
    words are 'precarious', 'education', 'facetious' (has them in order!)
    'tambourine', 'authorize', and 'sequoia'. In contrast, 
    'auction' (no 'e'), 'precautionary' (two 'a's), and 'insidious' 
    (five vowels, but three are 'i's) are not precarious. 
    This predicate returns True if word is precarious and False otherwise.
    """
    # Flesh out the body of this function

Examples:

As shown below, your Your functions should not be sensitive to capitalization.

In [2]: isTopRow('typewriter') # topRow words use only top row keys
Out[2]: True

In [3]: isTopRow('Pretty')
Out[3]: True

In [3]: isTopRow('QUIP')
Out[3]: True

In [4]: isTopRow('bunny')
Out[4]: False

In [5]: isTopRow('sequoia')
Out[5]: False

In [6]: isBeauteous('delicious') # Beauteous words have at least 
Out[6]: True                     # three consecutive vowels

In [7]: isBeauteous('sequoia') 
Out[7]: True

In [8]: isBeauteous('education') 
Out[8]: False

In [9]: isBeauteous('amnesia') 
Out[9]: False

In [10]: isPrecarious('education') # Precarious words have 
Out[10]: True                      # exactly one of each vowel

In [11]: isPrecarious('sequoia') # 'sequoia' is both beauteous *and* precarious!
Out[11]: True

In [12]: isPrecarious('auction') # No 'e'
Out[12]: False

In [13]: isPrecarious('precautionary') # Six total vowels covering all five, but with two 'a's
Out[13]: False

In [14]: isPrecarious('insidious') # Five vowels, but no 'a' or 'e'
Out[14]: False

Notes

Testing

Subtask 1c: Counting Words

If you're ever asked to write a "300-word abstract" or a "1000-word paper" you may have used a word count tool to make sure that what you submit meets the requirements. For this task, you will build your own word count tool: the function countWords, when given a string, should return an integer that represents the number of separate words in that string. Here are some examples of how this function should work:

In [0]: countWords("a simple example")
Out [0]: 3

In [1]: countWords("Once you consider punctuation, things get harder.")
Out [1]: 7

In [2]: countWords("A word may occur at the end of a string")
Out [2]: 10

In [3]: countWords("   counting   the   spaces   will   not   help    you   ")
Out [3]: 7

In [4]: countWords("Don't forget that contractions count as one word!")
Out [4]: 8

In [5]: countWords("Hyphenated-words are still counted separately though.")
Out [5]: 7

In [6]: countWords("Numbers count as words 2.")
Out [6]: 5

In [7]: countWords("3.1415926 is as delicious as 1,000 cakes.")
Out [7]: 7

In [8]: countWords("Without:spaces:or:hyphens:new:words:aren't:counted.")
Out [8]: 1

In [9]: countWords("192.168.0.1 and 1.5,2.5 are each 1 word, but 1.5, 2.5 is 2.")
Out [9]: 12

In [10]: countWords("More complex cases: 1:23 a.m., 12°33'4\", and Ph.D.")
Out [10]: 8

In [11]: countWords("Punctuation marks alone are not (!) words.")
Out [11]: 6

In [12]: countWords("""
Spaces aren't the only kind of white-space character,
and counting words in a paragraph should work just
fine.
""")
Out [12]: 19

Note that any character which is a letter of the alphabet or a number counts as "part of a word," while any white-space character or hyphen is "in between words." A "word" is therefore a sequence of characters that contains at least one letter or number, which is separated from other such sequences by at least one white-space character or hyphen. Although punctuation marks by themselves are not words, they may be part of a word (like 'Ph.D.' or `'Don't``) without breaking it into smaller words.

Your Task

Finish the function countWords in wordlplay.py so that it works as indicated by the examples above. For full credit, use only a single for loop.

Notes

Testing


Task 2: Concentric Circles

This is an individual problem which you must complete on your own, though you may ask for help from the CS111 staff.

The task 2 rubric shows how this task will be graded, and can be used as a checklist to make sure you are done with the task.

In this task, you will create a Python file named circles.py and define two functions in it:

Your file should begin with this header, which you should fill out:

# Your name:
# Your username:
# CS111 PS05 Task 2
# circles.py
# Submission date:

You will probably want to import turtle and turtleBeads by putting the following lines at the beginning of your code:

from turtle import *
from turtleBeads import *

Subtask 2a: concentricCircles

In this subtask, your goal is to generate pictures like the following:

reset()
noTrace()
concentricCircles(200, 5, 'LightSalmon2', 'Khaki1')
color("black")
showPicture()
reset()
noTrace()
concentricCircles(400, 8, 'Gold', 'DeepSkyBlue')
color("black")
showPicture()
reset()
noTrace()
concentricCircles(500, 2, 'RoyalBlue1', 'SeaGreen1')
color("black")
showPicture()
reset()
noTrace()
concentricCircles(500, 15, 'Aquamarine', 'AntiqueWhite')
color("black")
showPicture()


In circles.py, define the function concentricCircles that fulfills the following contract:

def concentricCircles(diameter, numCircles, innerColor, outerColor):
    """
    Draws a pattern of concentric circles, where the diameter of the
    largest is the given diameter and there are the given number of
    circles. The innerColor is used for the innermost circle and every
    other circle outwards to the edge, while the outerColor is used for
    the alternating circles between those colored with the innerColor.

    Leaves the turtle in the same position and orientation as it started
    in.
    """

Notes

Testing

Subtask 2b: circleRow

In this task, your goal is to generate pictures like the following:

reset()
noTrace()
circleRow(1,500,7,'orange','yellow')
color("black")
showPicture()
reset()
noTrace()
rt(45)
circleRow(3,600,10,'HotPink','LightSkyBlue1')
color("black")
showPicture()
reset()
noTrace()
lt(90)
leap(150)
rt(90)
circleRow(5,480,8,'aquamarine','antiquewhite')
color("black")
showPicture()
reset()
noTrace()
circleRow(10,600,9,'black','white')
color("black")
showPicture()

In your circles.py file, define a function circleRow that fulfills the following contract:

def circleRow(numCirclesInRow, totalLength, numCircles, innerColor, outerColor):
    """
    Draws numCirclesInRow bulls-eye patterns, each of which is a series of
    numCircles concentric circles using the two given colors. The total
    length of all of the circles from edge to edge is the given totalLength.

    The row of circles is centered at the turtle's starting position, and
    the row is angled according to the turtle's starting angle; the
    turtle is returned to its starting position and angle after the row
    is completed. Each circle in the row touches the next one exactly on
    the edge, so the diameter of each circle is equal to the distance
    between their centers.
    """

Notes

Testing

You can test circleRow by adding test cases like the following to the if __name__ == "__main__": conditional block:

reset()
noTrace()
rt(45)
circleRow(3,600,10,'HotPink','LightSkyBlue1')
color("black")
showPicture()

Notice how this test case rotates before drawing the row, and the result is a row that's oriented diagonally.



Task 3: Memory Diagrams

This is an individual problem that you must complete on your own, though you may ask for help from the CS111 staff.

The task 3 rubric shows how this task will be graded, and can be used as a checklist to make sure you are done with the task.

This problem involves memory diagrams. You should review the notation and conventions for memory diagrams explained in Lec 10 before starting this problem.

Subtask 3a: Matching Code to Memory Diagrams

In this subtask you are given these ten code snippets and six memory diagrams (the code snippets are named CODE0 through CODE9 and the memory diagrams are labeled 'A' through 'F'). Your goal is to match each code snippet with the corresponding memory diagram. (A single diagram might be generated by multiple snippets.)

Each snippet attempts to generate the following memory diagram A:

Some of the snippets may successfully create diagram A, but others create other memory diagrams.

You will express your answers in the provided file memDiagram.py by assigning the given variables CODE0 through CODE9 (initially defined to be the value None) to be one of the strings 'A' through 'F' (to indicate that it creates the diagram named by that string).

If your file has a syntax error, you comment out the variable assignments, or you assign values other than the 1-character strings 'A', 'B', 'C', 'D', 'E', or 'F', you will not get credit for any malformed answers. Part of this subtask is understanding how to supply these answers, so if you are confused about this, please ask for clarification.

Subtask 3b: Modifying Memory Diagram A

Assume that the value of variable x is the list with memory diagram A:

In this subtask, you will flesh out the body of the function A_to_K in memDiagram.py that takes as its single parameter a list named L, and modifies it in such a way that after calling A_to_K(x), the structure of x has been changed to that of memory diagram K:

In the body of A_to_K, your code should satisfy the following restrictions:

Subtask 3c: Drawing a Modified Memory Diagram

Assume that the value of variable x is the list with memory diagram A:

In this subtask, you will draw the final memory diagram that shows the structure of the list x after executing the following sequence of statements:

x[3] = [x[1], x[0], x[2][0]]
x[1].insert(0, x[2])
x[0].append(56)
x[2][0] = x[2][1] + x[1][1] + x[3][0][0][0] 

You must draw your memory diagram on the following template page.

You will need to upload it electronically to GradeScope in order to submit it.

Notes



Feedback: Time Spent File

As in the previous psets, your time spent submission for this pset will involve entering values for the variables in the timeSpent.py file.


How to turn in this Problem Set

Note: If you are not going to be able to get everything done before the deadline, you may take a 24-hour extension, no questions asked. To do so, however, you must fill out this extension form before the deadline has passed. If it is close to the deadline and you don't know if you'll make it in time, fill out the extension form now, and then turn in your work. The extension applies to both the GradeScope and file transfer submission deadlines.

GradeScope submission

You must submit the solution page of subtask 3c via GradeScope by 11:59 pm on the DUE DATE = Tuesday, March 10, 2020. You must draw the memory diagram on the following template page.

Electronic submission