# Introduction to Computer Programming: Lab 11

## Inheritance and Recursion

#### Instructions

• Work on this lab with your partner (or on your own if you have not been assigned one).

• Download the starter archive. It is a compressed folder consisting of several files. Expand the folder. Your work should take place in just two files: `account.py` and `fractal.py`; however, you should examine the contents of each file.

• You are welcome to try runnable solutions (included in the archive): `account_x.py` and `fractals_x.py`. (To try the former, modify `bank_repl.py` so that imports `account_x` instead of `account`.)

• Unlike most other labs this semester, this is intended to be relatively short. However, if you do not have time to complete the exercises during the scheduled time then you should finish them on your own.

#### 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 `l`ist 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 `A`s, `B`s, `C`s and `D`s). But each of those can be thought of as four 2x2 squares. For example the `A`s 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.