Starting from:
$35

$29

Lab#2 Solution

learning goals

In this lab you will:

    • Practice designing and implementing subclasses. Resources here include lecture materials from week 2 and 3, and How to think like a computer scientist.

    • You'll also re-visit some things you've already done:

{ Get more practice designing classes

{ Continue using the design recipe for functions (which also works ne for methods).

{ Continue using good programming style by consulting pep 8 and CSC108 style guidelines.

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 ask your TA questions, or ask on Piazza.

The second hour of your tutorial/lab will require that you are able to log in to MarkUs. Be sure you are able to do this well before Thursday. You need to carefully follow this link, and once it says you have

successfully changed your teach.cs password, you need to wait 25 minutes before you can log in to teach.cs machines, or MarkUs.

where we’re headed

You will design and implement GradeEntry, LetterGradeEntry, and NumericGradeEntry below, so that you can create and run a le test lab2.py with code very similar to:


if __name__ == ’__main__’:

grades = [NumericGradeEntry(’csc148’, 87, 0.5), NumericGradeEntry(’mat137’, 76, 1.0), LetterGradeEntry(’his450’, ’B+’, 0.5)]

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.SOMETHING * g.SOMETHINGELSE # methods or attributes of g

for g in grades])    # using each g in grades

# sum up the credits

total_weight = sum([g.SOMETHING for g in grades])

print("GPA = {}".format(total / total_weight))

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.SOMETHING * g.SOMETHINGELSE for g in grades]

Check out list comprehensions if needed.




1
setup

We assume that you either remember some of the setup techniques from last week, look for them in the lab#1 handout or consult your TA and other students. You'll need to:

    • Start up Pycharm or another IDE for Python programs, and navigate to csc148/Labs/lab2, or create this directory if it's not there.

    • Download the le specs.txt from among the lab#2 materials, and save it under your own lab2 subdi-rectory. Open specs.txt in Pycharm (or some other IDE), and read through it.

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 you will be creating subclasses of GradeEntry through inheritance. Here's what you need to do:

    1. Create and open a new le with your editor called grade.py in the subdirectory lab2.

    2. Perform an object-oriented analysis of the specications 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, list them in the class docstring

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.


    • use the CSC108 function design recipe








2
design NumericGradeEntry

The procedure for designing a subclass is similar to design of class GradeEntry, with a few important di
er-ences:

    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 re-

design 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 instance of GradeEntry without knowing that it is a LetterGradeEntry should experience results that are consistent with the public interface of GradeEntry.2

design LetterGradeEntry

This will be very similar to the procedure for designing attention to the method(s) that were not implemented in in LetterGradeEntry.

NumericGradeEntry. Once again, devote special GradeEntry, as well as the attributes that are new

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 GradeEntrythat 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





init  :
design. Here is how you would implement the extended












    1. The 
rst statement in your implementation should be

GradeEntry.__init__(self, ???)

. . . where the question marks indicate possible values GradeEntry's initializer needs.


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

2. after the rst 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.

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.

Remember, during the second hour of your lab/tutorial you will submit some work online from BA3175.


















































4

More products