Homework 9

Due Tuesday 25-Mar, at 9:00pm


To start

  1. Create a folder named ‘hw9’
  2. Create a new file hw9.py in that folder
  3. Edit hw9.py and add the functions and some testcases as required
  4. When you have completed and fully tested hw8, submit hw9.py to Gradescope. For this hw, you may submit up to 15 times, but only your last submission counts.

Some important notes

  1. This homework is solo. You may not collaborate or discuss it with anyone outside of the course, and your options for discussing with other students currently taking the course are limited. See the academic honesty policy for more details.
  2. After you submit to Gradescope, make sure you check your score. If you aren’t sure how to do this, then ask a CA or Professor.
  3. There is no partial credit on Gradescope testcases. Your Gradescope score is your Gradescope score.
  4. Read the last bullet point again. Seriously, we won’t go back later and increase your Gradescope score for any reason. Even if you worked really hard and it was only a minor error…
  5. Do not hardcode the test cases in your solutions.
  6. Remember the course’s academic integrity policy. Solving the homework yourself is your best preparation for exams and quizzes; cheating or short-cutting your learning process in order to improve your homework score will actually hurt your course grade long-term.

Limitations

Do not use sets, dictionaries, try/except, classes, or recursion this week. The autograder (or a manual CA review later) will reject your submission entirely if you do.

A Note About Style Grading

Like in the previous assignment, we will be grading your code based on whether it follows the 15-112 style guide. We may deduct up to 10 points from your overall grade for style errors. We highly recommend that you try to write clean code with good style all along, rather than fixing your style issues at the end. Good style helps you code faster and with fewer bugs. It is totally worth it. In any case, style grading already started, so please use good style from now on!

Problems

  1. Marble, ConstantMarble, and DarkeningMarble classes [100 pts]
    Write the Marble, ConstantMarble, and DarkeningMarble classes so that the following test code passes (and without hardcoding any cases, so any similar code would also pass). Also, you must use OOP properly (we may check this manually, after the autograder gives you a preliminary score).

    def getLocalMethods(clss): import types # This is a helper function for the test function below. # It returns a sorted list of the names of the methods # defined in a class. It's okay if you don't fully understand it! result = [ ] for var in clss.__dict__: val = clss.__dict__[var] if (isinstance(val, types.FunctionType)): result.append(var) return sorted(result) def testMarbleClasses(): print("Testing Marble classes...", end="") # A Marble takes a string (not a list) of comma-separated color names m1 = Marble('Pink,Cyan') assert(m1.colorCount() == 2) # pink and cyan assert(Marble.getMarbleCount() == 1) # we have created 1 marble so far # When converted to a string, the Marble includes the color names, # each separated by a comma and a space, and all lower-case, and listed # in alphabetical order: assert(str(m1) == '<Marble with colors: cyan, pink>') m2 = Marble('Red,Orange,yellow,GREEN') assert(str(m2) == '<Marble with colors: green, orange, red, yellow>') assert(m2.colorCount() == 4) assert(Marble.getMarbleCount() == 2) # we have created 2 marbles so far # This also works in a list: assert(str([m1]) == '[<Marble with colors: cyan, pink>]') # Equality works as expected: m3 = Marble('red,blue') m4 = Marble('BLUE,RED') m5 = Marble('red,green,blue') assert((m3 == m4) and (m3 != m5) and (m3 != "Don't crash here!")) assert(Marble.getMarbleCount() == 5) # we have created 5 marbles so far # You can add colors, which only change the marble if they are not present: assert(m3.addColor('Red') == False) # False means the color was not added, # because it was already there # and no changes here: assert(m3.colorCount() == 2) assert(str(m3) == '<Marble with colors: blue, red>') assert((m3 == m4) and (m3 != m5)) # Once more, but with a new color: assert(m3.addColor('green') == True) # True means the color was added! # and so these all change: assert(m3.colorCount() == 3) assert(str(m3) == '<Marble with colors: blue, green, red>') assert((m3 != m4) and (m3 == m5)) # A ConstantMarble is a marble that never changes its color: m6 = ConstantMarble('red,blue') assert(isinstance(m6, Marble)) assert(str(m6) == '<Marble with colors: blue, red>') assert(m6.addColor('green') == False) # constant marbles never change! assert(str(m6) == '<Marble with colors: blue, red>') assert(Marble.getMarbleCount() == 6) # we have created 6 marbles so far assert(getLocalMethods(ConstantMarble) == ['addColor']) # A DarkeningMarble is a marble that prefixes 'dark' to any colors # that are added after it is first created. # Note: for full credit, you must use super() properly here! m7 = DarkeningMarble('red,blue') assert(isinstance(m7, Marble)) assert(str(m7) == '<Marble with colors: blue, red>') # not darkened assert(m7.addColor('green') == True) # but green will become darkgreen assert(str(m7) == '<Marble with colors: blue, darkgreen, red>') assert(Marble.getMarbleCount() == 7) # we have created 7 marbles so far assert(getLocalMethods(DarkeningMarble) == ['__init__', 'addColor']) print("Passed!")