CSC148 Lab #02

$35.00

Category: You will Instantly receive a download link for .zip solution file upon Payment || To Order Original Work Click Custom Order?

Description

5/5 - (5 votes)

goals
In this lab you will:
You’ll re-visit some things you’ve already done:
– Get more practice with the class design recipe.
– Continue using the design recipe for functions (which also works fine for methods).
– Continue using good programming style by consulting CSC108 style guidelines and pep 8.
You are encouraged to start working on this lab as soon as it is posted. If you feel shaky on the lab, be sure
to come in and work through it with your TA. There will be a quiz during the last 15 minutes of the lab
which you are likely to ace if you have worked through the lab. Also make sure, you have a good
understanding of list comprehensions before you start.
notes
 You are required to work in teams of 2.
 It’s a requirement that your teammate be different than your teammates in any other labs or
assignments.
 You are required to use the machines in the lab as well as your cdf account.
where we’re headed
You will design and implement GradeEntry, LetterGradeEntry, and NumericGradeEntry below, so that
you can create and run a file test_lab02.py with code very similar to:
if __name__ == ’__main__’:
grades = [NumericGradeEntry(’csc148’, 87, 1.0),
NumericGradeEntry(’bio150’, 76, 2.0),
LetterGradeEntry(’his450’, ’B+’,1.0)]
for g in grades:
# Use appropriate ??? methods or attributes of g in format
print(“Weight: {}, grade: {}, points: {}”.format(g.?, g.??, g.???))
# Use methods or attributes of g to compute weight times points
total = sum( # sum of the list of…
[g.? * g.?? # ? and ?? are methods or attributes of g
for g in grades]) # using each g in grades
# sum up the credits
total_weight = sum([g.? for g in grades])
print(“GPA = {}”.format(total / total_weight))
2
Important: Notice that the code above never checks whether a particular g is a LetterGradeEntry versus
a NumericGradeEntry. You design the classes below so that it just does the right thing! Also notice the list
comprehension:
[g.? * g.?? for g in grades]
Check out list comprehensions if needed.
setup
We assume that you either remember some of the setup techniques from lab01, look for them in the
lab#1 handout or consult your TA and other students. You’ll need to:
 Log into your cdf account, start up Pycharm, and navigate to csc148/Labs/lab02
 Start the browser and navigate to the lab02 (this document) page on the
CSC148H1 web site.
 Download the file specs.txt, and save it under your own lab02 subdirectory. Open specs.txt
in Pycharm, and read through it.
Show your work to your TA before moving on, to reassure yourself that you’re on the right track.
design GradeEntry
Begin by designing the public interface of class GradeEntry, using the instructions below. You are not
intended to be able to create instances of class GradeEntry, rather through inheritance you will be
creating subclasses of GradeEntry. Here’s what you need to do:
1. Create and open a new file with your editor called grade.py in the subdirectory lab02.
2. Perform an object-oriented analysis of the specifications in specs.txt, following the same recipe we
used in class for Point, Shape, Rational, etc.:
(a) choose a class name (GradeEntry) and write a brief description in the class docstring.
(b) write some examples of client code that uses your class
(c) decide what services your class should provide as public methods, for each method declare an
API1
(examples, header, type contract, description)
(d) decide which attributes your class should provide without calling a method—that means decide
which attributes are public—list them in the class docstring
3. Using your CDF username and password, log on to MarkUs at the following URL:
https://markus.cdf.toronto.edu/csc148-2016-05/

1 use the function design recipe
3
Find the Lab 02 submission page, and submit your file grade.py. Get help from other students or
your TA if you’re not sure how to do this or if you run into any problems!
Show your work to a TA before proceeding, in order to be reassured you are on the right track.
implement GradeEntry
The design is where the hard thinking should take place, so now it’s time to implement GradeEntry.
Remember that there is at least one method in GradeEntry that should only be implemented in its
subclasses. In that case (or cases) the implementation for the method is an easy one-liner:
raise NotImplementedError(’Subclass needed’)
Here’s what you need to do:
1. write the body of special methods __init__, __eq__, and __str__
2. write the body of other methods
Notice that there is no practical way to try out instances of GradeEntry until you have created one or more
subclasses. There will be one or more methods that generate those annoying NotImplementedErrors.
design NumericGradeEntry
The procedure for designing a subclass is similar to design of class GradeEntry, with a few important
differences:
1. Rather than class NumericGradeEntry:, your declaration will be
class NumericGradeEntry(GradeEntry):
This tells Python (and human readers) that this class inherits attributes and methods from
GradeEntry
2. Attributes and methods that you will use unchanged from GradeEntry (we say you inherit these)
need not be mentioned in the class docstring. New attributes of NumericGradeEntry should be
documented in the class docstring, as usual.
3. If you have new attributes for NumericGradeEntry that were not in GradeEntry, you will need to
redesign the __init__ method. This will include writing a new docstring for the method that says
that NumericGradeEntry’s initializer extends the initializer of GradeEntry, gives a (probably) new
header and type contract, a new example of a call to the initializer, and says what the initializer
does to the new attributes.
4. You will have (at least) one method that could not be implemented in class GradeEntry, but can
now be implemented in NumericGradeEntry. Your docstring should say that the method in
NumericGradeEntry (which should have the same name as in GradeEntry) overrides the
corresponding method in GradeEntry. You should be careful that the type contract for the method
in NumericGradeEntryEntry is consistent with the type contract for the corresponding function in
GradeEntry. A good mental exercise is to convince yourself that any client code that uses an
4
instance of GradeEntry without knowing that it is a LetterGradeEntry should experience results
that are consistent with the public interface of GradeEntry.
1
Show your work to a TA before moving on.
design LetterGradeEntry
This will be very similar to the procedure for designing NumericGradeEntry. Once again, devote special
attention to the method(s) that were not implemented in GradeEntry, as well as the attributes that are
new in LetterGradeEntry.
implement both NumericGradeEntry and LetterGradeEntry
Here is where we experience the labour-saving features of declaring subclasses. If we designed
GradeEntry carefully, there should be a lot of code that was written in GradeEntry that does not have to
be re-written in NumericGradeEntry and LetterGradeEntry—the code is already there, through
inheritance. Avoiding duplicate code also avoids many errors. For the attributes and methods of
GradeEntry that will be used unchanged in these subclasses your implementation consists of…nothing.
You did the work in GradeEntry. If you don’t initialize any new attributes in a subclasses, you don’t need
to have additional documentation.
We have already discussed how to document an __init__ method that extends the one from
GradeEntry under design. Here is how you would implement the extended __init__:
1. The first statement in your implementation should be
GradeEntry.__init__(self, ???)
…where the question marks indicate possible values GradeEntry’s initializer needs.
2. after the first line, add code to initialize your new attributes that aren’t inherited from GradeEntry.
You should have some method(s) that are not inherited from GradeEntry. You should implement these
as usual, even if they share a name with the corresponding method in GradeEntry.
Show your work to your TA one last time. Congratulations: you’re done with this lab!
additional exercises
As well as the various grade entries, here are some additional exercises in designing and implementing
classes with inheritance. We set up each one so that one appropriate solution involves class Roster
together with one of its subclasses.
We certainly don’t expect you to do this many exercises in the lab, but they are here for additional
practice. We’ll have a brief quiz in the last 15 minutes of the lab, which will involve an exercise similar to
one of the additional exercises.

1 This subtle, yet very important, idea is a consequence of the Liskov Substitution Principle, and is worth taking the time to think through.