Problem Set 7 - Due Friday, April 17, 2020
- Slides and notebooks from Lec 13 (Nested Loops). For the second challenge problem, slides and notebooks from Lec 15 (Sorting).
- Problems and solutions from Lab 09 (Nested Loops and Sorting).
- Think Python, Ch. 7: Iteration and Think Python, Ch. 10: Lists
About this Problem Set
This problem set will give you practice with nested lists and loops in the context of turtle graphics. There is a challenge problem if you want to practice sorting.
There is no task 0 for this pset. However, if you wish to review the solutions from the previous problem set, puzzles will be available at the CS 111 Puzzles page as usual.
In Task 1 (Partner task) you will write code that draws square tiles made up of colored sections, and then code that draws multiple tiles to form a floor pattern. Finally, you will create your own custom tile pattern.
As a challenge task, Challenge 1 invites you to extend your tile drawing code to draw fancier tiles.
- Challenge 2 is an opportunity to get some practice with sorting, if you wish.
Both challenges are entirely optional; there is only one normal task for this problem set.
If you want to find a partner to work with (on any or all parts of the pset), you can use this Piazza post.
Remember that you are encouraged to talk with other people (not just your partner) about high-level problem-solving strategies.
The CS111 Problem Set Guide gives an overview of psets, and includes some new hints on how to work together remotely.
Follow the style guidelines in the CS 111 Code Style Guide
Everything is new this year, so we don't know how long it will take, but we hope that if you just do task 1 and not the challenge tasks, it should take a few hours at most, especially if you have done the lab and/or reference the lab solutions and videos. The challenge task 1 can take as long as you want it to, and the challenge task 2 should also hopefully take just a couple of hours at most.
- When you're done with the 1 task, fill out your time spent form and follow the submission instructions to submit your pset.
All code for this assignment is available in the
ps07 folder in the
cs111/download directory within your
cs server account.
Task 1: Drawing Tiles
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 (but remember that all we require now is an honest attempt).
For this task, you will write turtle drawing code using nested loops that can create pictures like these:
These pictures are drawn using rectangular arrangements of square tiles, like the four tiles shown in this image:
First you will write code to draw a single tile, then to draw a floor pattern made of many tiles. In both cases, a nested list (a list which contains other lists) will specify the pattern to be drawn.
Subtask 1a: Drawing One Tile
For this subtask, your goal is to fill out the definition of the
drawTile function in
tiles.py so that it draws a single tile. The
function is given two parameters to work with: a
tilePattern, which is
a nested list specifying the colors for the tile to be drawn, and a
tileHeight, which specifies how large the entire tile should be. You
may assume that all tiles are square, but they may not all have the same
number of rows and columns. A
tilePattern is a list of lists of colors,
and looks like this:
exampleTile = [ [ "blue", "blue", "navy" ], [ "blue", "navy", "blue" ], [ "navy", "blue", "blue" ] ]
That tile pattern when drawn by
drawTile would look like this:
Notice how the turtle (indicated by the arrow) is at the north-west
corner of the square and is facing east: that is both the starting and
ending position of the turtle when
drawTile is called.
drawTile function should work for any square tile pattern and any
positive tile height specified.
The docstring for the
drawTile function describes in detail how it
works, all you have to do is implement it so that is behaves as described
here and in that docstring.
You will need to use a nested for loop, and in particular to keep track of the turtle's movements across rows and down columns to make sure that it ends up back where it started, and that things are drawn in the right place. Also make sure that the total height and width of the tile drawn is equal to the
It is recommended that you do not use the
drawRectangle, because since they are drawn from the center of the square instead of from its upper-left corner, using them will make your code more complicated. Using a series of four forward/turn pairs to draw a square is simpler in this case.
- The testing code at the bottom of the file should draw the four tiles
shown in the picture above. You may wish to comment out the floor
pattern tests and
inputstatements while working on
drawTileso that it just draws the tiles and finishes immediately.
Subtask 1b: Drawing a Floor Pattern
Once you get your tile drawing function working, the second part of this
task is to fill out the
drawFloor function. It is quite similar to
drawTile, with a few differences:
Instead of starting from (and ending at) the north-west corner, it starts from the (vertical) center of the west edge of the floor.
Although tiles are always square, floor patterns may be rectangular (the brick wall pattern above is 6x4, for example). You may still assume that each row of the floor pattern contains the same number of entries (no mismatched rows).
- Instead of each entry in the rows of the pattern being a color string,
each entry will be an entire tile pattern. Your
drawFloorfunction must call your
drawTilefunction to draw the tiles.
The docstring for
drawFloor describes its behavior in detail. Go ahead
and implement it according to the behavior described there and here. When
you're done the testing code should draw the brick wall and basket weave
patterns shown above.
tileHeightfor each tile is determined by the
floorHeightof the entire floor and the number of rows in the floor pattern. Tiles are always square, so the width of each tile is equal to its height.
- Because the turtle starts at the center of the west edge of the floor, the first thing that your code should do is move up from the starting position to the top of the floor pattern so that a for loop can draw the entire floor starting from the north-west, and the last thing in your code should be movement back to the center of the west edge of the pattern from wherever the turtle ends up naturally. You do not have to move east or west at the start of the function to "get to" the left edge of the floor. Instead, the turtle's position when the function is called determines where that left edge will appear.
testPatternfunction draws floors patterns centered horizontally by first measuring the width of the pattern and moving west to compensate for that. It can be used to test your
drawFloorcode, and indeed several tests are included in the starter file, which should produce the first two images shown at start of this task (the brick wall and the basket weave). The third test runs your
myFloorPatternfunction and draws the resulting pattern, which will draw just a blue square until you customize that function.
Subtask 2c: Create Your Own Floor
Now that you've gotten the
drawFloor functions done, it's time for some fun: fill out the code for
myFloorPattern so that it returns a floor pattern, which uses one or more custom tiles that it also defines (the starter code defines one tile which is just a blue square, and a pattern that's just one of those tiles).
myFloorPattern function is returning a custom floor pattern,
the last piece of testing code should show you what this pattern looks
like. Your function can simply return a list structure that you carefully
craft by hand and enter into your Python file, or it can use code (even
for loops) to create some kind of complex pattern if you
like (what about a rainbow, for example?).
The final picture shown above is a custom floor pattern created from two diagonal tiles that are selected at random to fill in the floor, creating a randomized maze structure. The inspiration for that pattern is a 1-line BASIC program from the 1980's.
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
How to turn in this problem set
- Each partner must save their pair's
tiles.pyfile in their
- Save your filled out
- Note: It is critical that the name of the folder you submit is
timeSpent.py. In other words, do not rename the folder that you downloaded, do all of your work within the existing files, and do not delete or rename any of the existing files in this folder. We have automated scripts to check your electronic submission: an improperly named folder or a folder with improperly named files will not count as a valid submission. For the challenge tasks you may create extra files as needed.
- Drop your entire
ps07folder in your
dropfolder on the
csserver using Cyberduck by 11:59pm on the DUE DATE = Friday April 17, 2020.
- Under current conditions, you only need to submit an attempt for this problem set, but please do submit your attempt on time.
- If you need an extension, you may take an automatic 24-hour extension by filling out the late submission form, but for circumstances that warrant a longer extension, please reach out to one of the instructors directly via email.
Challenge Problems (optional & ungraded)
Challenge 1: Advanced Tiles
This is an open-ended challenge: extend your tile and floor drawing code
in some way to create new possibilities for drawing tiles, and then
create a new custom floor that makes use of these. Make sure that you do
this in another file (e.g.,
fancyTiles.py) so that your task 1 code is
Examples of ways you could extend the code:
- Write a function to swap out the colors in a tile so that you can more easily create versions of the same pattern which use different colors.
- Allow None to appear in tile definitions, so that some regions of the tile are not drawn, allowing whatever is drawn underneath to show through.
- Allow tiles to be rectangular, instead of requiring that they be square.
- Allow floor pattern specifications to include orientation information, so that the same tile can be drawn in different rotations.
- Allow floor pattern specifications to contain multiple tile patterns in each position that can be drawn on top of each other (works well with rotation and/or transparent regions of tiles).
Here are some example images that are possible with a few of the above extensions:
Challenge 2: Word Patterns and Distant Reading
In literature, especially "classic" literature, authors' perspectives shape the possibilities of the narrative world in ways that don't fully reflect the real world we live in. Actions that an author deems important or realistic occur, other actions do not.
One group of techniques that can help us examine how the world of a novel is constructed is called "distant reading," and these techniques involve reading a text not in the linear manner that was intended but instead picking out words or phrases based on some other principle and examining the patterns that result. Interpreting these patterns can be tricky, but they can also reveal interesting information.
For this challenge, you will apply a very simple distant reading technique to several classic novels to examine how often different classic novels discuss men vs. women.
distantReading.py file there is a
pronounUsage variable which
contains data extracted from a few "classic" novels about how many times
different gendered pronouns are used (unfortunately, this technique is
not easy to extend to examine representation of characters beyond a
gender binary, which is one of its limitations). In this challenge
exercise, you'll fill in the various sorting functions in
distantReading.py which sort the data in different ways, and finally
create a report function that sorts the data according to the ratio
between female and male pronouns and then prints information about each
novel in sorted order, including the "gender ratio" for that novel.
You will write three sorting functions, each with an associated helper function act as the sort key:
sortByYearsorts the data by year of publication.
sortByTotalPronounssorts the data by the total number of pronouns used, across all variants in each category.
sortByGenderRatiosorts the data by the ratio between the sum of all three female pronouns and the sum of all three male pronouns (the "gender ratio"). Of course this is only a crude measure, because for example, places where male or female characters are referred to by name are not included.
Finally, you will write a
reportGenderRatios function which uses
sortByGenderRatio to sort the data, and then prints the title, author,
year of publication, and gender ratio for each novel in the sorted
Click on "show results" below to show the correct results, but only after you've written the sorting functions yourself and think that they're correct.
Show resultsThe full output of the program when all functions have been implemented should be:
By year: Don Quixote Emma Frankenstein Alice's Adventures in Wonderland Dracula Anne of Green Gables By total pronouns: Don Quixote Emma Dracula Anne of Green Gables Frankenstein Alice's Adventures in Wonderland By gender ratio: Anne of Green Gables Alice's Adventures in Wonderland Emma Frankenstein Dracula Don Quixote Gender ratio report: "Anne of Green Gables" by Lucy Maud Montgomery, 1908: 3.298 "Alice's Adventures in Wonderland" by Lewis Carroll, 1865: 3.066 "Emma" by Jane Austen, 1815: 1.298 "Frankenstein" by Mary Shelley, 1818: 0.464 "Dracula" by Bram Stoker, 1897: 0.377 "Don Quixote" by Cervantes, 1605: 0.235
Although this kind of word-counting is a fairly trivial example of distant reading, we will get to a more interesting example next week when we are learning about dictionaries.