import algolab
import sys
#sys.path.append('../exams/2017-09-04/solutions')
sys.path.append('past-exams/2017-09-04/solutions')
import nxpd
algolab.init()
There won't be any internet access. You will only be able to access:
Bonus point: One bonus point can be earned by writing stylish code. You got style if you:
avoid convoluted code like i.e.
if x > 5:
return True
else:
return False
when you could write just
return x > 5
%%HTML
<p class="algolab-warn">
WARNING: MAKE SURE ALL EXERCISE FILES AT LEAST COMPILE !!! <br/> 10 MINS BEFORE THE END
OF THE EXAM I WILL ASK YOU TO DO A FINAL CLEAN UP OF THE CODE
</p>
<p class="algolab-warn">
!!!!!!!!! WARNING !!!!!!!!!
<br/>
<br/>
!!!!!!!!! **ONLY** IMPLEMENTATIONS OF THE PROVIDED FUNCTION SIGNATURES WILL BE EVALUATED !!!!!!!!! <br/>
</p>
For example, if you are given to implement:
def f(x):
raise Exception("TODO implement me")
and you ship this code:
def my_f(x):
# a super fast, correct and stylish implementation
def f(x):
raise Exception("TODO implement me")
We will assess only the latter one f(x)
, and conclude it doesn't work at all :P !!!!!!!
Helper functions
Still, you are allowed to define any extra helper function you might need. If your f(x)
implementation calls some other function you defined like my_f
here, it is ok:
# Not called by f, will get ignored:
def my_g(x):
# bla
# Called by f, will be graded:
def my_f(y,z):
# bla
def f(x):
my_f(x,5)
To edit the files, you can use any editor of your choice:
%%HTML
<p class="algolab-important">
IMPORTANT: Pay close attention to the comments of the functions.
</p>
<p class="algolab-warn">
WARNING: <i>DON'T</i> modify function signatures! Just provide the implementation.
</p>
<p class="algolab-warn">
WARNING: <i>DON'T</i> change the existing test methods, just add new ones !!! You can add as many as you want.
</p>
<p class="algolab-warn">
WARNING: <i>DON'T</i> create other files. If you still do it, they won't be evaluated.
</p>
If you need to print some debugging information, you are allowed to put extra print
statements in the function bodies.
%%HTML
<p class="algolab-warn">
WARNING: even if <code>print</code> statements are allowed, be careful with prints that might
break your function!<br/><br/>
For example, avoid stuff like this:
<code>
x = 0
print 1/x
</code>
</p>
1) Download algolab-2017-09-04.zip and extract it on your desktop. Folder content should be like this:
algolab-2017-09-04
|- FIRSTNAME-LASTNAME-ID
|- exercise1.py
|- exercise2.py
|- exercise3.py
2) Rename FIRSTNAME-LASTNAME-ID
folder: put your name, lastname an id number, like john-doe-432432
From now on, you will be editing the files in that folder. At the end of the exam, that is what will be evaluated.
3) Edit the files following the instructions in this worksheet for each exercise. Every exercise should take max 25 mins. If it takes longer, leave it and try another exercise.
You are going to implement a class called MultiSet
, where you are only given the class skeleton, and you will need to determine which Python basic datastructures like list, set, dict (or combinations thereof) is best suited to actually hold the data.
In math a multiset (or bag) generalizes a set by allowing multiple instances of the multiset's elements.
The multiplicity of an element is the number of instances of the element in a specific multiset.
For example:
a, b
contains only elements a
and b
, each having multiplicity 1a, a, b
, a
has multiplicity 2 and b
has multiplicity 1a, a, a, b, b, b
, a
and b
both have multiplicity 3NOTE: order of insertion does not matter, so a, a, b
and a, b, a
are the same multiset,
where a
has multiplicity 2 and b
has multiplicity 1.
from exercise1_solution import *
EnvWorkingTest
¶Now open the file exercise1.py
and check your environment is working fine, by trying to run the test EnvWorkingTest
: it should always pass, if it doesn't, tell your instructor.
Notice that exercise1
is followed by a dot and test class name: .EnvWorkingTest
python -m unittest exercise1.EnvWorkingTest
algolab.run(EnvWorkingTest)
__init__
, add
and get
¶Now implement all of the following methods: __init__
, add
and get
:
def __init__(self):
""" Initializes the MultiSet as empty."""
raise Exception("TODO IMPLEMENT ME !!!")
def add(self, el):
""" Adds one instance of element el to the multiset
NOTE: MUST work in O(1)
"""
raise Exception("TODO IMPLEMENT ME !!!")
def get(self, el):
""" Returns the multiplicity of element el in the multiset.
If no instance of el is present, return 0.
NOTE: MUST work in O(1)
"""
raise Exception("TODO IMPLEMENT ME !!!")
Testing
Once done, running this will run only the tests in AddGetTest
class and hopefully they will pass.
Notice that exercise1
is followed by a dot and test class name .AddGetTest
:
python -m unittest exercise1.AddGetTest
algolab.run(AddGetTest)
removen
¶Implement the following removen
method:
def removen(self, el, n):
""" Removes n instances of element el from the multiset (that is, reduces el multiplicity by n)
If n is negative, raises ValueError.
If n represents a multiplicity bigger than the current multiplicity, raises LookupError
NOTE: multiset multiplicities are never negative
NOTE: MUST work in O(1)
"""
raise Exception("TODO IMPLEMENT ME !")
Testing: python -m unittest exercise1.RemovenTest
algolab.run(RemovenTest)
Start editing file exercise2.py
, which contains a simplified versioned of the UnorderedList
we saw in the labs.
from exercise2_solution import *
find_couple
¶Implement following find_couple
method.
def find_couple(self,a,b):
""" Search the list for the first two consecutive elements having data equal to
provided a and b, respectively. If such elements are found, the position
of the first one is returned, otherwise raises LookupError.
- MUST run in O(n), where n is the size of the list.
- Returned index start from 0 included
"""
raise Exception("TODO IMPLEMENT ME !")
Testing: python -m unittest exercise2.FindCoupleTest
algolab.run(FindCoupleTest)
swap
¶Implement the method swap
:
def swap (self, i, j):
"""
Swap the data of nodes at index i and j. Indeces start from 0 included.
If any of the indeces is out of bounds, rises IndexError.
NOTE: You MUST implement this function with a single scan of the list.
"""
raise Exception("TODO IMPLEMENT ME !")
Testing: python -m unittest exercise2.NorepTest
algolab.run(SwapTest)
Start editing file exercise3.py
, which contains a simplified versioned of the GenericTree
we saw in the labs.
from exercise3_solution import *
Implement the method mirror
:
def mirror(self):
""" Modifies this tree by mirroring it, that is, reverses the order
of all children of this node and of all its descendants
- MUST work in O(n) where n is the number of nodes
- MUST change the order of nodes, NOT the data (so don't touch the data !)
- DON'T create new nodes
- It is acceptable to use a recursive method.
Example:
a <- Becomes: a
|-b |-i
| |-c |-e
| \-d | |-h
|-e | |-g
| |-f | \-f
| |-g |-b
| \-h |-d
\-i \-c
"""
raise Exception("TODO IMPLEMENT ME !")
Testing: python -m unittest exercise3.MirrorTest
algolab.run(GenericTreeTest)
algolab.run(MirrorTest)
Implement the method clone
:
def clone(self):
""" Clones this tree, by returning an *entirely* new tree which is an
exact copy of this tree (so returned node and *all* its descendants must be new).
- MUST run in O(n) where n is the number of nodes
- a recursive method is acceptable.
"""
raise Exception("TODO IMPLEMENT ME !")
Testing: python -m unittest exercise3.CloneTest
algolab.run(CloneTest)