Introduction to Computer Programming: Lab 11

Inheritance and Recursion


Instructions


Exercises

  1. Download and expand the starter archive folder. Examine the contents of each file. Review and experiment with the three example files based on what we have covered in lecture over the past week: counters.py, nim.py, and recursion.py.


    For this next set of problems, work in account.py and test your code using bank_repl.py. Experiment with running bank_repl() (in bank_repl.py). It is a simple REPL that allows the user to create checking and savings accounts. Out of the box, you should be able to create checking accounts, deposit funds into them, and transfer funds between them.

  2. Add a withdraw(self, amount) method from the Checking class so that a user can withdraw money. (The REPL indicates how this should work.)

  3. Write a Savings class that inherits from the base Account class. Overwrite the constructor by adding an __init__(self, id, initial_deposit, interest_rate) method. Both initial_deposit and interest_rate can be assumed to be positive float values. The latter should be expected as a percentage (so that 2% interest would be expressed as 2.0 but recorded in the object as 0.02). The constructor should allow you to create a savings account via the REPL.

  4. Add a __str__ method to Savings that is similar to that of Checking but indicates it is a savings account and includes the interest rate in what it displays. You can test this via the list menu option of the REPL.

  5. Add a compound method to Savings that increases the account's balance according to its interest rate. Example: if the balance is 5.0 and the interest rate is 2.0 (stored as 0.02) then the interest on that is 0.02 * 5.00 which is 0.1; that should be added to the balance, so the resulting new balance becomes 5.1.


    For this next set of problems, work in fractal.py. Examine the lab11_graphics module - it is nearly identical to the square_graphics modules we have been using in class, recent labs and the final programming project; but it allows us to choose the size of the underlying squares.

  6. Complete the function draw_perfect_square(color, r, c, n) where r and c are row-column coordinates on the screen's grid and n is assumed to be a power of 2. The function should be recursive and use the paint function in the base case. It should draw a large square of size n whose upper-left corner is at row-column coordinate (r, c). The strategy is best illustrated by an example. Suppose we wanted to draw an 8x8 square, somewhat like this:

    AAAABBBB
    AAAABBBB
    AAAABBBB
    AAAABBBB
    CCCCDDDD
    CCCCDDDD
    CCCCDDDD
    CCCCDDDD

    The 8x8 square can be though of as four 4x4 squares (the As, Bs, Cs and Ds). But each of those can be thought of as four 2x2 squares. For example the As might be:

    EEFF
    EEFF
    GGHH
    GGHH

    And, again, each 2x2 square can be thought of as four 1x1 squares:

    IJ
    KL

    You can test your code using test_square().

  7. Complete draw_rect(color, r, c, h, w) so that it is just like draw_perfect_square but the height (h) and width (w) of the large rectangle need not be same, nor do they have to be powers of 2. The idea is the same as before: each larger rectangle can be thought of as four (nearly) identical smaller rectangles. The only catch is that without the dimension being a power of 2 we need to be a little more careful about splitting the problem into subproblems. For example if the height is 7, then the subrectangles drawn should be two of height 3 and two of height 4. But the process can, as with the previous problem, continue recursively down until the base case is reached where the dimensions are 1. (You may find it helpful to have two base cases: one where both dimensions are 1 so that a paint operation can be used; the other if either dimension is zero then no action should occur.)

  8. Finally, use draw_rect to draw the Sierpinski Carpet fractal. This is where using smaller square sizes can pay off (with the cells we have been using for other projects, you cannot fit much of the carpet on the screen; but if you pick nice small cells - like 3 pixels per side - you can pack quite a few in). The carpet is itself recursive: each time we split a square into nine smaller squares.