Pale Machine CSE101, Groups 1-4
Objectives
What we will evaluate today: Everything!
Setup: Before you start
Launch Spyder (from the Applications/Programming menu). If you see a “Spyder update” message, just click OK and ignore it.
Before you start: create a new
project, called PracticalExam_1
(using “New
Project” from the “Projects” menu). This will ensure that files from
last week (and future weeks) do not get mixed up together. Download
files dict1.txt
and dict2.txt
from Moodle and
put them in the project folder.
Now create a new file named
wordgame.py
. This is the file in which you will be writing
your code today.
Introduction
In this exam you will implement the following word game. The game
starts with a fixed relatively long word, for example,
mathematics
. Then, at each step, the player tries to come
up with a word which can be constructed using the letters from the
original word in any order. Note that each letter can appear in
a new word at most as many times as it appears in the original word. For
mathematics
, possible words include tea
,
cat
, cast
, ham
, etc. For each
word, the player gets the number of points equal to the length of the
word. Once the player gives up, the total score is counted.
Exercises
Exercise 1: Is this a word?
We start with a function which checks if a given word is “allowed” by
looking this word up in a provided dictionary (represented as a list of
words). We define a function is_in_dictionary
which takes
two arguments:
word
is a word to look up;dictionary
is a list of “allowed” words.
The function should return True
if the word
appears in the dictionary
and False
otherwise.
The comparison is assumed to be case-sensive, that is, cat
is not the same as CaT
.
Copy the following function stub into your file and complete it:
def is_in_dictionary(word, dictionary):
"""checks if the word appears in the dictionary
"""
pass # remove this line and replace with your own code
Testing
Test your function is_in_dictionary()
in the
console, for example as follows:
In [1]: is_in_dictionary("cat", ["dog", "cat", "cow"])
Out[1]: True
In [2]: is_in_dictionary("cat", ["dog", "catastrophy", "cow"])
Out[2]: False
In [3]: is_in_dictionary("COW", ["dog", "catastrophy", "cow"])
Out[3]: False
Note: It is important to test your function in the console as there is no grader feedback.
Exercise 2: Reading dictionary from file
Of course, it is not interesting to play with a dictionary like
["dog", "cat", "cow"]
, and it is definitely tedious to type
an actual dictionary by hand. The goal of the exercise is to create a
function read_dictionary(filename)
reading a dictionary
from file filename
. The file filename
is
assumed to have at most one word per line (with possibly starting and
trailing empty spaces) as well as empty lines. The words are guaranteed
to be distinct. The function should return a list containing all the
words. Here is the starter code:
def read_dictionary(filename):
"""Reads a dictionary from file.
"""
pass # remove this line and replace with your own code
Testing
When you have finished your function, test it in the console. You should see the following behavior:
In [4]: read_dictionary("dict1.txt")
Out[4]: ['dog', 'cat', 'cow']
In [5]: read_dictionary("dict2.txt")[:5]
Out[5]: ['people', 'history', 'way', 'art', 'world']
Exercise 3: Checking if a word is constructable
Now we would like to check if a given word can be constructed using
the letters of our original word. This will be done by a function
is_constructable(target, source)
, where target
and source
are words. The function should return
True
if target
can be constructed using the
letters of source
and False
otherwise. Here is
the starter code:
def is_constructable(target, source):
"""Checks if the word target can be constructed from the letters of
the word source.
"""
pass # remove this line and replace with your own code
Hint
You may want to use the count
method which may be
familiar from TD2 (try "mama".count('m')
and
"abaca".count('c')
).
Testing
When you have finished your function is_constructable
,
test it in the console. You should be able to reproduce
the following behavior:
In [6]: is_constructable("cat", "mathematics")
Out[6]: True
In [7]: is_constructable("catch", "mathematics")
Out[7]: False
In [8]: is_constructable("mamama", "mathematics")
Out[8]: False
In [9]: is_constructable("ratio", "algorithm")
Out[9]: True
Exercise 4: Playing one round
Now we will write a function one_round()
for playing one
round of the game which takes 3 parameters:
mainword
is a word from which the other words should be constructed;found
is a list of words (already found by the player);dictionary
is a dictionary.
The function should prompt the player
Please construct a new word from the letters of the word _mainword_:
.
Once the player types the word, one of the following should happen:
- if the player types
!
(meaning he/she wants to stop the game), the function should return-1
; - if the player types a word equal to
mainword
, the function should printLet's try something more interesting!
and return0
; - if the player types a word which is not present in the dictionary,
the function should print
I do not know this word!
and return0
; - if the player types a word already present in
found
, the function should printYou have already found this word!
and return0
; - if the player types a word which cannot be constructed from the
letters of the
mainword
, the function should printNot enough letters!
and return0
; - if the player types a word which can be constructed, is present in
the dictionary, and had not been found before, the function should print
Good job, you have earned # points
, where#
is the length of the word; the function should return the length of the found word in this case.
Do not forget to update the found
list!
def one_round(mainword, found, dictionary):
"""plays one round of the game
"""
pass # remove this line and replace with your own code
Testing
Now, test your function one_round()
in the
console, for example as follows.
In [10]: dictionary = read_dictionary("dict2.txt")
In [11]: found = []
In [12]: one_round("mathematics", found, dictionary)
Please construct a new word from the letters of the word mathematics:cat
Good job, you have earned 3 points
Out[12]: 3
In [13]: one_round("mathematics", found, dictionary)
Please construct a new word from the letters of the word mathematics:cat
You have already found this word!
Out[13]: 0
In [14]: one_round("mathematics", found, dictionary)
Please construct a new word from the letters of the word mathematics:math
Good job, you have earned 4 points
Out[14]: 4
In [15]: one_round("mathematics", found, dictionary)
Please construct a new word from the letters of the word mathematics:abracadabra
I do not know this word!
Out[15]: 0
In [16]: found = []
In [17]: one_round("algorithm", found, dictionary)
Please construct a new word from the letters of the word algorithm:algorithm
Let's try something more interesting!
Out[17]: 0
In [18]: one_round("algorithm", found, dictionary)
Please construct a new word from the letters of the word algorithm:!
Out[18]: -1
Exercise 5: Playing the game!
Now we use the one_round()
function to write a
play_game()
function which takes mainword
and
dictionary
as arguments. It should ask the player for a new
word until the player types !
thus choosing to stop. Once
the game is stopped, the function should print:
You have constructed:
followed by a comma-separated list of
constructed words and Total score:
followed by the total
score.
def play_game(mainword, dictionary):
pass # remove this line and replace with your own code
Testing
When you have finished your function play_game
,
test it in the console. You should be able to reproduce
the following behavior:
In [19]: dictionary = read_dictionary("dict2.txt")
In [20]: play_game("mathematics", dictionary)
Please construct a new word from the letters of the word mathematics:math
Good job, you have earned 4 points
Please construct a new word from the letters of the word mathematics:cat
Good job, you have earned 3 points
Please construct a new word from the letters of the word mathematics:hat
Good job, you have earned 3 points
Please construct a new word from the letters of the word mathematics:!
You have constructed: math,cat,hat
Total score: 10
In [21]: play_game("algorithm", dictionary)
Please construct a new word from the letters of the word algorithm:math
Good job, you have earned 4 points
Please construct a new word from the letters of the word algorithm:math
You have already found this word!
Please construct a new word from the letters of the word algorithm:algo
I do not know this word!
Please construct a new word from the letters of the word algorithm:girl
Good job, you have earned 4 points
Please construct a new word from the letters of the word algorithm:algorithm
Let's try something more interesting!
Please construct a new word from the letters of the word algorithm:tom
I do not know this word!
Please construct a new word from the letters of the word algorithm:atom
I do not know this word!
Please construct a new word from the letters of the word algorithm:log
Good job, you have earned 3 points
Please construct a new word from the letters of the word algorithm:!
You have constructed: math,girl,log
Total score: 11
Exercise 6: Writing a super-player
You may think like
if I was a machine, I could just go over the whole dictionary...
.
Well, you do have a machine at your disposal! Write a function
superplayer()
taking as arguments mainword
and
dictionary
. The function should return a list of all the
words in the dictionary which could be constructed from the
mainword
(not counting the mainword
!) and the
corresponding score.
def superplayer(mainword, dictionary):
"""finds all the words which can be constructed using the letters of `mainword`.
returns the list of these words and the total number of letters in them.
"""
pass # remove this line and replace with your own code
Testing
Test your function superplayer()
in the
console; for example, you should have the following
behavior:
In [22]: dictionary = read_dictionary("dict2.txt")
In [23]: superplayer("mathematics", dictionary)
Out[23]: (['meat', 'math', 'tea', 'chest', 'hat', 'time', 'heat', 'state',
'test', 'site', 'case', 'cash', 'act', 'item', 'ice', 'taste',
'sea', 'seat', 'team', 'match', 'east', 'shame', 'cat', 'mate',
'she', 'set', 'teach', 'hit', 'eat', 'tie', 'hate'], 119)
In [24]: superplayer("algorithm", dictionary)
Out[24]: (['art', 'goal', 'math', 'hair', 'ratio', 'girl', 'hat', 'air',
'light', 'oil', 'log', 'arm', 'mail', 'harm', 'might', 'hit'], 60)
In [25]: superplayer("algorithm", [])
Out[25]: ([], 0)
In [26]: superplayer("ALGORITHM", dictionary)
Out[26]: ([], 0)
In [27]: superplayer("abracadabra", dictionary)
Out[27]: (['card', 'bad', 'car', 'bar'], 13)
Exercise 7: Constructing explicitly
Our function is_constructable
can define if the
target
word can be constructed from the letters of the
source
word, but even if the output is True
is
not always so easy to see. In this exercise, we will create a more
“visual” version of this function. Write a function
is_constructable2
which takes as input words
target
and source
(both are assumed to contain
only lower case letters) and does the following:
- if
target
cannot be constructed from the letters ofsource
, returnNone
- otherwise, return
source
where letters oftarget
are transfromed to the uppercase. For example, fortarget
andsource
beingcat
andmathematics
, one possible output ismaThemAtiCs
(the othera
and othert
could be uppercased instead).
def is_constructable2(target, source):
"""if target cannot be construtced using the letters of source, returns None.
otherwise, returns a copy of source with the letters used
to construct target being in the upper case
"""
pass # remove this line and replace with your own code
Testing
Test your function is_constructable2()
in the
console; for example, you should have the following
behavior:
In [28]: is_constructable2("cat", "mathematics")
Out[28]: 'mAThematiCs'
In [29]: is_constructable2("elephant", "mathematics")
In [30]: is_constructable2("card", "abracadabra")
Out[30]: 'AbRaCaDabra'
In [31]: is_constructable2("hair", "algorithm")
Out[31]: 'AlgoRItHm'