Problem Set 6 - Due Thu, Mar 16 at 23:59 EST
Reading material and Resources
The external resources are not required reading, but they might be helpful to provide context and details.
- Think Python, Ch. 11: Dictionaries
- Slides and notebooks from Lec 10, Lec 11
- Lab on Dictionaries and Data Visualization
- Python documentation on dictionary operations
- Lab notes on "How to make a pie chart"
- Lab plotting examples
- matplotlib gallery
- matplotlib plotting commands
- matplotlib examples
About this Problem Set
This problem set will give you practice with dictionaries, especially creating dictionaries and accumulating with dictionaries; preparing data for visualization using list comprehension; and data visualization.
- In Task 1, you will write a program to find anagrams using dictionaries.
- In Task 2 (a partner task), you will perform data analysis and plotting on a dataset about passengers on the Titanic. Use this shared Google Doc to find a pair programming partner. Remember that you can work with the same partner a maximum of TWICE this semester. We will deduct 2 points per day for any students who have not recorded their names on the pair programming google doc by Sunday, Mar 12 at 11:59pm.
- The CS111 Problem Set Guide gives an overview of psets, including a detailed description of individual and partner tasks.
- In Fall 2016, students spent an average of 2.96 hours on Task 1 (min 1 hour, max 9 hours), and 4.4 hours on Task 2 (min 3 hours, max 12 hours).
All code for this assignment is available in the ps06
folder in
the cs111/download
directory within your cs
server account.
This assignment also uses the Otter Inspector program
to help you do a final check for Task 1, Task 2,
and your Honor Code form before you submit.
Task 1: Unjumble
This is an individual problem which you must complete on your own, though you may ask for help from the CS111 staff.
Word Jumble is a popular game that appears in many newspapers and online.
The game involves "unjumbling" English words whose letters have been reordered.
For instance, the jumbled word ytikt
can be unjumbled to kitty
.
Here is one version of the game online.

You will create a Python program in unjumble.py
that is able to successfully unjumble jumbled words.
Here is how to produce candidate words from a jumbled word:
-
For each word in English, convert that word to an "unjumble key" by sorting the lowercase versions of the characters of the word in alphabetical order. For instance, the unjumble key for
regal
would beaeglr
. -
Then create a dictionary that associates each such unjumble key with a set of all words that have the same unjumble key. For example, the unjumble dictionary will associate the unjumble key
aeglr
with the set of words{'glare', 'lager', 'large', 'regal'}
. - To unjumble a string, simply convert it to its unjumble key,
and look that up in the unjumble dictionary.
For example, to unjumble
rgael
, you convert it to its keyaeglr
, and look it up in the unjumble dictionary to find that it unjumbles to any of the words in the set{'glare', 'lager', 'large', 'regal'}
.
We have provided three lists of English words of different sizes.
Fill in the functions as described in the subtasks below.
All your code should be in your unjumble.py
file in the ps06
folder
from the download
directory.
Subtask a
The unjumbleKey
function takes a single argument, a string,
and returns a string that is the unjumble key of its input
-- i.e., a string consisting of the lowercase versions
of all characters of the string in alphabetical order.
For example:
In [1]: unjumbleKey('argle')
Out[1]: 'aeglr'
In [2]: unjumbleKey('regal')
Out[2]: 'aeglr'
In [3]: unjumbleKey('Star')
Out[3]: 'arst'
In [4]: unjumbleKey('HISTRIONICS')
Out[4]: 'chiiinorsst'
Notes
- When applied to a string, the
sorted
function returns a list of the characters in sorted order (which in the case of letters, is alphabetical order).
In [1]: sorted('abracadabra')
Out[1]: ['a','a','a','a','a','b','b','c','d','r','r']
- The join method can be used to glue a list of strings together, using a string which is applied as a separator.
In [2]: ':'.join(['bunny','cat','dog'])
Out[2]: 'bunny:cat:dog'
In [3]: ' '.join(['bunny','cat','dog'])
Out[3]: 'bunny cat dog'
In [4]: ''.join(['bunny','cat','dog'])
Out[4]: 'bunnycatdog'
Subtask b
The makeUnjumbleDictionary
function takes a single argument,
a list of words,
and returns a dictionary that associates the unjumble key
of every word in the word-list with the set of all words with that unjumble key.
All words in the same set will be anagrams
-- i.e., words that all have exactly the same letters (including repeated ones),
but in different orders.
unjumble.py
imports three word-lists: tinyWordList
(33 words),
mediumWordList
(45,425), and largeWordList
(438,712 words).
Test makeUnjumbleDictionary
on these lists.
In [1]: tinyDict = makeUnjumbleDictionary(tinyWordList)
In [2]: tinyDict
Out[2]:
{'acerst': {'caster', 'caters', 'crates', 'reacts', 'recast', 'traces'},
'aegilnrt': {'alerting', 'altering', 'integral', 'relating', 'triangle'},
'aeglr': {'glare', 'lager', 'large', 'regal'},
'aeinrrst': {'restrain', 'retains', 'strainer', 'terrains', 'trainers'},
'arst': {'arts', 'rats', 'star', 'tars', 'tsar'},
'chiiinorsst': {'histrionics', 'trichinosis'},
'opst': {'opts', 'post', 'pots', 'spot', 'stop', 'tops'}}
In [3]: mediumDict = makeUnjumbleDictionary(mediumWordList)
In [4]: print "len of mediumDict:", len(mediumDict)
len of mediumDict: 42273
In [5]: largeDict = makeUnjumbleDictionary(largeWordList)
In [6]: print "len of largeDct:", len(largeDict)
len of largeDict: 386268
Notes
-
Remember to not use the method
keys
in the for loop. -
If you
print tinyDict
(instead of simply typing it on the interactive pane), the result you'll see is different from above: the order is different, and you'll see the word set in front of each value. -
This function creates a dictionary of sets. The closest example to this that you've seen in our notes is Exercise 5 in the Lecture 10 Dictionaries notebook, Reverse Lookup, that creates a dictionary of lists. Start by studying that example, but keep in mind these things: The parameter for your function is a list, not a dictionary as in Reverse Lookup. Additionally, the solution for the exercise is not the only possible solution: one can avoid an else clause, by flipping the conditional expression.
-
This function contains a double-use of the accumulation pattern: you are accumulating when creating the dictionary, but also when creating the sets that are values in this dictionary. The generic accumulation pattern has at least these two steps: a) initialize an empty accumulator; b) update the accumulator within a loop. However, different data structures we have seen are updated in different ways. Lists use
append
, sets useadd
(see example below), while dictionaries use assignment statements to create or update key:value items. The methodupdate
of a dictionary shouldn't be used during accumulation, because it replaces, instead of updating a previous key:value pair. - Empty sets are initalized by invoking
set()
.
In [1]: example = set()
In [2]: example
Out[2]: set()
Do not initialize a set by using empty curly braces, because Python uses them for initializing an empty dict. However, if you need to create a set with one element, you can write:
In [3]: one = {5}
In [4]: one
Out[4]: {5}
In [5]: type(one)
Out[5]: set
- To update a set you can use the method
add
:
In [6]: example.add('a')
In [7]: example
Out[7]: {'a'}
In [8]: example.add('b')
In [9]: example
Out[9]: {'a', 'b'}
-
We suggest that when you're testing your function, you only check the lengths of the two dictionaries returned by
makeUnjumbleDictionary(mediumWordList)
andmakeUnjumbleDictionary(largeWordList)
rather than their contents, because they are huge. - For those who are comfortable with the method
get
, it can be used as well, but keep in mind that methods likeappend
andadd
don't return a value, they only have a side-effect by mutation, thus, usingget
might be a bit different from the examples we have seen. That said, we encourage you to give it a try :)
Subtask c
The unjumble
function takes an unjumble dictionary
(of the type created by makeUnjumbleDictionary
) and a string (that doesn't need to be a meaningful word),
and returns a set of all words in the dictionary to which the input string unjumbles.
If there are no such words, it returns the empty set. For example,
In [1]: tinyDict = makeUnjumbleDictionary(tinyWordList)
In [2]: unjumble(tinyDict, 'esrat')
Out[2]: set()
In [3]: print unjumble(tinyDict, 'esrat')
Out[3]: set([])
In [4]: mediumDict = makeUnjumbleDictionary(mediumWordList)
In [5]: unjumble(mediumDict, 'esrat')
Out[5]: {'aster', 'rates', 'stare', 'tears'}
In [6]: print unjumble(mediumDict, 'esrat')
Out[6]: set(['stare', 'rates', 'tears', 'aster'])
In [7]: largeDict = makeUnjumbleDictionary(largeWordList)
In [8]: unjumble(largeDict, 'esrat')
Out[8]: {'arest', 'arets', 'aster', 'astre', 'earst', 'rates', 'reast', 'resat',
'serta', 'stare', 'stear', 'strae', 'tares', 'tarse', 'taser', 'tears', 'teras'}
For fun, use your unjumble
function as an assistant in playing the online jumble game
Notes
-
This function uses the helper function
unjumbleKey
. -
Again, remember that the function output is displayed differently when printed with
print
. Notice the difference betweenOut[2]
andOut[3]
orOut[4]
andOut[5]
, despite having to do with the same function call in both cases. -
IMPORTANT: In order to check if a key
k
is in a dictionaryd
, use the expressionk in d
rather thank in d.keys()
. The latter expression creates a new list of keys every time it is evaluated, and searches each member of the list to check that it is equal tok
. This can be extremely slow for large word lists. Checking for membership of a key in a dictionary is very fast, no matter how large the dictionary is. - This function has a particularly succinct solution composed of a single statement, which involves
the method
get
.
Subtask d
Which words have the most anagrams?
Define a function named mostAnagrams
that takes an unjumble dictionary
(of the type created by makeUnjumbleDictionary
)
and returns the largest set of anagrams in that dictionary.
In [1]: tinyDict = makeUnjumbleDictionary(tinyWordList)
In [2]: mostAnagrams(tinyDict)
Out[2]: {'opts', 'post', 'pots', 'spot', 'stop', 'tops'}
In [3]: mediumDict = makeUnjumbleDictionary(mediumWordList)
In [4]: mostAnagrams(mediumDict)
Out[4]: {'pares', 'parse', 'pears', 'rapes', 'reaps', 'spare', 'spear'}
In [5]: mostAnagrams(largeDict)
Out[5]: {'arest',
'arets',
'aster',
'astre',
'earst',
'rates',
'reast',
'resat',
'serta',
'stare',
'stear',
'strae',
'tares',
'tarse',
'taser',
'tears',
'teras'}
Notes
- IMPORTANT UPDATE for mostAnagrams (6:30pm Mar 15):
There may be more than one valid set for a given size in
mostAnagrams
. Note that there is currently a bug in Otter Inspect that causes it to accept only one of the multiple valid sets. Consider amostAnagrams
result correct if it returns a valid set of anagrams containing the same number of words as the set that otter inspect expects, even if Otter Inspect indicates an incorrect result. - The two solutions provided for the function
bestScrabbleWord
in PS05 are good starting points to think about how to solve this subtask. - When printing the results of the function from the test cases in the
if __name__ == '__main__':
block, what you'll see looks different from the outputs above:
set(['pots', 'spot', 'stop', 'post', 'tops', 'opts'])
set(['pares', 'spear', 'pears', 'parse', 'spare', 'rapes', 'reaps'])
set(['earst', 'reast', 'arest', 'taser', 'tares', 'resat', 'aster', 'stear', 'tarse', 'teras', 'tears', 'arets', 'serta', 'rates', 'astre', 'strae', 'stare'])
Task 2: Titanic Analysis
This task is a partner problem in which you are required to work with a partner as part of a two-person team.
In this task, you will analyze data about passengers from the Titanic, a large ship that tragically sank in the waters of the North Atlantic Ocean in 1912.
Passenger data can be found in the titanicdata.txt
file provided in the ps06
folder.
Study the structure of the data in titanicdata.txt
.
Then, study the code in the readtitanic.py
file,
which reads the contents of titanicdata.txt
and transforms it into a list of dictionaries,
where every list element is a passenger represented by a dictionary.
Because the information for the passengers is incomplete,
not all passenger dictionaries have the same keys.
Try the examples below in your interactive console after running readtitanic.py
.
Notice how passenger 2168 has six keys in the dictionary, but passenger 2203 has only four keys.
In [25]: len(passengerList)
Out[25]: 2208
In[26]: passengerList[2168]
Out[26]:
{'age': '31.0',
'class': '1st Class',
'group': 'Servant',
'job': 'Personal Maid',
'name': 'Miss Helen Alice Wilson',
'status': 'survivor'}
In[27]: passsengerList[2203]
Out[27]:
{'age': '22.0',
'class': '3rd Class',
'name': 'Mr Mapriededer Zakarian',
'status': 'victim'}
There is even a passenger who has only three keys in the dictionary. UNGRADED CHALLENGE: Can you find this passenger using a single line list comprehension statement? UNGRADED EXTRA CHALLENGE: Can you find both this passenger and his index in the list with one line of code?
Open up titanic.py
in your ps06
folder.
This file imports the passengerList
variable from readtitanic.py
.
You will define the functions described in the subtasks below in titanic.py
.
Subtask a
Write a function that takes a list of passenger dictionaries
(such as passengerList
) and creates a dictionary that keeps track of the
number of survivors and victims in every cabin class,
as well as the calculated survival rate by cabin class.
Below is the contract of the function you'll need to write.
(The header is already in titanic.py
).
def createSurvivalDictionary(passengers):
"""Given a list of passenger dictionaries, return a dictionary
whose keys are all the cabin classes that appear in passengers.
The value associated with each cabin class name should
itself be another dictionary that has three key/value pairs:
(1) The key "survivors" maps to the number of survivors in
the cabin class;
(2) The key "victims" maps to the number of victims in the
cabin class;
(3) The key "survivalRate" maps to the survival rate in the
cabin class (a floating point number rounded to 3 decimal digits)
"""
Testing:
In[30]: createSurvivalDictionary(passengerList)
Out[30]:
{'1st Class': {'survivalRate': 0.62, 'survivors': 201, 'victims': 123},
'2nd Class': {'survivalRate': 0.418, 'survivors': 119, 'victims': 166},
'3rd Class': {'survivalRate': 0.254, 'survivors': 180, 'victims': 528},
'A la Carte': {'survivalRate': 0.043, 'survivors': 3, 'victims': 66},
'Deck': {'survivalRate': 0.652, 'survivors': 43, 'victims': 23},
'Engine': {'survivalRate': 0.222, 'survivors': 72, 'victims': 253},
'Victualling': {'survivalRate': 0.218, 'survivors': 94, 'victims': 337}}
Notes
-
This problem is another variation of the accumulation pattern. In this case, it's the inner dictionaries that are accumulating values for survivors and victims as one loops over the list of passenger dictionaries.
- The built-in function
set
can convert a list with duplicate elements into a set of unique elements. For example:
In [50]: fruitList = ['apple', 'orange', 'apple', 'orange', 'lemon']
In [51]: set(fruitList)
Out[51]: {'apple', 'lemon', 'orange'}
In [52]: print set(fruitList)
set(['orange', 'lemon', 'apple'])
-
The recommended algorithm for solving this task is as follows. (If you find an easier approach, feel free to pursue it instead.)
- find all the cabin classes (using the function
set
). Hint, accumulate all the cabin classes, then applyset
. NOTE: if you feel comfortable with list comprehension, it's a great place to use it here. - make a dictionary that associates each cabin class
with the mini-dictionary,
{'survivors': 0, 'victims': 0}
. DO NOT hard-code the keys by looking up what the cabin classes are. Imagine that we give you another data set like this, for example about the sinking of SS Hong Mo, where the cabin names are different. Also, DO NOT create a single mini-dictionaryminiDct = {'survivors': 0, 'victims': 0}
, and then use the variableminiDict
to map it to every key. It's aliasing! All your keys will be pointing to the same dictionary value. Instead, within the for loop assign the value{'survivors': 0, 'victims': 0}
directly to each cabin class (from the set you generated in step 1.) - iterate through the passenger list updating the mini-dictionary for the cabin class of each passenger.
- once all the passengers have been processed, the correct
survivalRate
value can be assigned to each mini-dictionary based on the number of survivors and victims (adding a new key:value item to the existing mini-dicts).
- find all the cabin classes (using the function
-
In Python, the name
class
is a special keyword (which we'll see in a few weeks), so don't use it as a variable name. - Remember that the division of two integer values in Python is also an integer [useful for calculating the survivalRatio.]
Subtask b: Plotting
Bar Chart of Survival Rates by Class
Define the function barChartOfSurvivalRates
which will display a horizontal bar chart showing
the percentage of survivors by cabin class, in decreasing order by survival rate.
We have provided a statement, plt.savefig('survival.png')
at the end of the function body that will save the plot in a file
named "survival.png" in your ps06
folder. This is useful because the Otter Inspect
displays it in the test results.
def barChartOfSurvivalRates(passengers):
"""Given a list of passenger dictionaries, displays a horizontal
bar chart of the sorted percentage of survival rates for each
cabin class. A percentage value is a floating point number
between 0 and 1.0.
"""
# flesh this out here
plt.savefig('survival.png') # saves plot in file
plt.clf() # clear plot so future plots will start fresh
Our solution for barChartOfSurvivalRates(passengerList)
generates the bar chart below.
You are free to use different styling to display the information,
as long as you fulfill the major requirements.
The color of the bars is "indian red" (the name of an iron oxide pigment, click here to read more).

Notes:
-
You must invoke
createSurvivalDictionary
from Subtask a as a helper function in the definition ofbarChartOfSurvivalRates
, to get the data you need for the chart. -
To create this chart, you'll be using the
plot
functionbarh
which you used for the Ironman visualizations in Lab 7. -
In the lab task, the data was already sorted for you from the smallest values to the largest. In this task, you'll need to sort the data yourself. To do that, you'll use the built-in function
sorted
. Here are some examples.This section was expanded on March 15 to include many more examples of the
sorted
function and how to sort with tuples..By default,
sorted
returns a new list in which elements are sorted in ascending order according to their "natural" order. For example, numbers are sorted in numerical order and strings are sorted in dictionary order:In [1]: sorted([23, 42, 251, 17, 5, 230, 111]) Out[1]: [5, 17, 23, 42, 111, 230, 251] In [2]: cities = ['New York', 'Los Angeles', 'Boston', 'Chicago', 'Providence', 'Atlanta'] In [3]: sorted(cities) Out[3]: ['Atlanta', 'Boston', 'Chicago', 'Los Angeles', 'New York', 'Providence']
Tuples are first sorted in ascending order by their 0th slots. If the 0th slots are equal, the 1st slot is a tiebreaker. If the 0th and 1st slots are equal, the 2nd slot is a tiebreaker; and so on. In the following example, all
'Doe'
s come before all'Jones'
s, which come before'Smith'
, but the tuples beginning with last name'Doe'
are sorted in ascending order by first name:In [4]: sorted([('Jones', 'Bob'), ('Doe', 'Mary'), ('Smith', 'Mark'), ('Doe', 'George'), ('Jones', 'Ann'), ('Doe', 'John')]) Out[4][('Doe', 'George'), ('Doe', 'John'), ('Doe', 'Mary'), ('Jones', 'Ann'), ('Jones', 'Bob'), ('Smith', 'Mark')]
If we want descending order instead, we simply add the keyword argument
reverse=True
:In [5]: sorted([23, 42, 251, 17, 5, 230, 111], reverse=True) Out[5]: [251, 230, 111, 42, 23, 17, 5] In [6]: sorted(cities, reverse=True) Out[6]: ['Providence', 'New York', 'Los Angeles', 'Chicago', 'Boston', 'Atlanta'] In [7]: sorted([('Jones', 'Bob'), ('Doe', 'Mary'), ('Smith', 'Mark'), ('Doe', 'George'), ('Jones', 'Ann'), ('Doe', 'John')], reverse=True) Out[7]: [('Smith', 'Mark'), ('Jones', 'Bob'), ('Jones', 'Ann'), ('Doe', 'Mary'), ('Doe', 'John'), ('Doe', 'George')]
But what if we want some other ordering. E.g., suppose we want to sort cities by the length of their names (as strings)? We can leverage the way tuples are sorted to do this! We make a list of pairs (2-tuples) whose 0th element is the length of the city name, and whose 1st element is the city name itself:
In [8]: cityLengths = [(len(city), city) for city in cities] In [9]: cityLengths Out[9]: [(8, 'New York'), (11, 'Los Angeles'), (6, 'Boston'), (7, 'Chicago'), (10, 'Providence'), (7, 'Atlanta')]
Now if we sort these tuples, they'll be sorted first by length of name, and then alphabetically for two names with the same length:
In [10]: sorted(cityLengths) Out[10]:[(6, 'Boston'), (7, 'Atlanta'), (7, 'Chicago'), (8, 'New York'), (10, 'Providence'), (11, 'Los Angeles')]
And what if we want only the city names ordered by their length, without the tuples with the additional length information? We use a list comprehension to extract the 1st slot of each tuple:
In [11]: [city for (length, city) in sorted(cityLengths)] Out[11]: ['Boston', 'Atlanta', 'Chicago', 'New York', 'Providence', 'Los Angeles'] In [12]: [pair[1] for pair in sorted(cityLengths)] # Alternative approach Out[12}: ['Boston', 'Atlanta', 'Chicago', 'New York', 'Providence', 'Los Angeles']
- The difficulty of this task lies in creating the list of tuples containing the pairs of
survival rates and cabin classes together, so that you can do the sorting. Once you have
sorted the pairs, you can unpair them as shown above or in the lab Solution.
(There is another unpairing trick using
zip
shown in slide 10-30 of the Dictionary lecture slides.)
Pie Chart of Victims' Cabin Classes
Implement the function pieChartOfVictimsCabinClasses
which will create a pie chart showing the relative number of Titanic victims
from each cabin class.
We have provided a statement, plt.savefig('cabinclasses.png')
at the end of the function body that will save the plot in a file
named "cabinclasses.png" in your ps06
folder.
def pieChartOfVictimsCabinClasses(passengers):
"""Given a list of passenger dictionaries, displays a pie chart
showing the relative number of victims from each cabin class.
Pie slices should be labeled with the cabin names, and ordered
clockwise from smallest pie slice to largest pie slice
starting at 12 o'clock.
"""
# flesh this out here
plt.savefig('cabinclasses.png') # saves plot in file
plt.clf() # clear plot so future plots will start fresh
The following chart is the one generated by our solution when
pieChartOfVictimsCabinClasses(passengerList)
.
See notes for details how this was created.

You can test your plots in two ways:
-
Invoke
barChartOfSurvivalRates(passengerList)
orpieChartOfVictimsCabinClasses(passengerList)
in the Interactive Console (or within anif __name__=='__main'
block in your file). These invocations will create the plots and save them to image files named "survival.png" and "cabinclasses.png" in yourps06
folder respectively. Open these files to check the result. - Run
otterInspect.py
which displays your plots and the expected plots on the output webpage.
Notes:
-
You must invoke
createSurvivalDictionary
from Subtask a as a helper function in the definition ofpieChartOfVictimsCabinClasses
. -
Just like in Task 2b, the most challenging part is to create list of tuples, sort them while together, and then unpair them to use for plotting. You'll notice a similarity in this process of pairing and unpairing tuples and you might want to capture this pattern in a helper function (once you've solved the tasks).
-
Use the statement
plt.figure(figsize=(6,6), facecolor='white')
before the call to pie in order to get a circular pie instead of an oval pie. -
We have used the parameter
startangle
to control the ordering of slices. -
We have used the parameter
autopct
to display the percentage values within the pie slices. - We have used a colormap to generate a new list of colors for chart.
This list is passed to pie with the named parameter colors.
If you are interested in the names of color maps in
matplotlib
, consult this page. Below is our code -- feel free to use a different colormap.
colormap = plt.cm.Set2 # Set2 is the name of the colormap
colors = colormap(np.linspace(0., 1., NRofSLICES)))
# NRofSLICES needs to be replaced with an expression.
- The lab notes for How to make a pie chart will be very useful too.
Task 3: Honor Code Form and Final Checks
As in the previous problem sets, your honor code submission for this pset will involve
defining entering values for the variables in the honorcode.py
file.
This is a Python file, so your values must be valid Python code (strings or numbers).
If you wrote any function invocations or print statements in your Python files to test your code,
please remove them, comment them out before you submit, or wrap them in a if __name__=='__main__'
block.
Points will be deducted for isolated function invocations or superfluous print statements.
Your titanic.py
program and functions should not pop open any plots when run.
If you used plt.show()
during testing to see the plots, please delete that line or comment it out.
Remember to run otterInspect.py
one final time before you submit
to check that your unjumble.py
and titanic.py
programs work as intended, and
that your honor code form is complete.
While running your code through otterInspect is not required,
it is highly recommended since it may catch errors that you haven't noticed.
If you have issues running otterInspect.py
,
first check for the following common issues.
- Your code is written in the provided program files in the
ps06
folder, and you haven't deleted or moved any of the existing files, or created new files. - You have selected "Keep directory synced to editor" when running
otterInspect.py
in Canopy - You have followed the specifications here of how your code should be organized into functions.
- If
otterInspect
says you have failed test cases, read the problem set directions carefully to verify exactly what your functions are supposed to do. In particular, be careful about the distinction between print and return, and check that the returned values are of the appropriate types. Precision is important in CS! Points will be deducted for such mistakes.
If you are unable to resolve this issue after going through this checklist, seek help from any of the course staff.
How to turn in this Problem Set
- Save your final
unjumble.py
file in yourps06
folder. - Each team member should save their
titanic.py
file in theirps06
folder. - Save your filled-up
honorcode.py
file inps06
folder as well. - Note: It is critical that the name of the folder you submit is
ps06
, and your submitted files areunjumble.py
,titanic.py
, andhonorcode.py
. In other words, do not rename the folder that you downloaded, do not create new files or folders, and do not delete or re-name any of the existing files in this folder. Improperly named files or functions will incur penalties. - Drop your entire
ps06
folder in yourdrop
folder on thecs
server using Cyberduck by 11:59pm on Thu, Mar 16th, 2017. - Failure to submit your code before the deadline will result in zero credit for the code portion of PS06.