Introduction to Computer Science II

Homework 3

Due by 11:50am on Tuesday, January 25

Reading

Read chapter 8 and the week 3 lecture notes.

Problems

Solve the following by implementing the corresponding classes in homework3.py. When done, submit that file through D2L.


1.    [Lab]    Implement class SavingsAccount as a subclass of the class BankAccount you developed in Homework 2. Your implementation should override the inherited construct method __init__() and add an additional method addInterest() using the following specs:
Usage:
>>> s = SavingsAccount(3, 100)
>>> s.balance()
100
>>> s.addInterest()
>>> s.balance()
103.0
>>> s = SavingsAccount(3)
>>> s.deposit(1000)
>>> s.addInterest()
>>> s.balance()
1030.0


2.    [Lab]  There are some problems with the implementation of the class BankAccount from Homework 2, and they are illustrated here:
>>> x = BankAccount(-700)
>>> x.balance()
-700
>>> x.withdraw(70)
>>> x.balance()
-770
>>> x.deposit(-7)
>>> x.balance()
Balance: -777
The problems are: (1) a bank account with a negative balance can be created, (2) the withdrawal amount is greater than the balance, and (3) the deposit amount is negative. Modify the code for the BankAccount class so that a ValueError exception is thrown for any of these violations, together with an appropriate message: 'Illegal balance', 'Overdraft', or 'Negative deposit'. For example:
Usage:
>>> x = BankAccount2(-700)
Traceback (most recent call last):
...
ValueError: Negative balance
>>> x = BankAccount2(700)
>>> x.withdraw(800)
Traceback (most recent call last):
...
ValueError: Overdraft
>>> x.deposit(-100)
Traceback (most recent call last):
...
ValueError: Negative deposit



3.    [Lab]    In problem 2, a generic ValueError exception is raised if any of the three violations occur. It would be more useful if a more specific, user-defined exception is raised instead. Define new exception classes NegativeBalanceError, OverdraftError, and DepositError that would be raised instead. In addition, the informal string representation of the exception object should contain the balance that would result from the negative balance account creation, the overdraft, or the negative deposit. For example, when trying to create a bank account with a negative balance, the error message should include the balance that would result if the bank account creation was allowed:
>>> x = BankAccount3(-5)
Traceback (most recent call last):
...
NegativeBalanceError: Account created with negative balance -5
When a withdrawal results in a negative balance, the error message should also include the balance that would result if the withdrawal was allowed:
>>> x = BankAccount3(5)
>>> x.withdraw(7)
Traceback (most recent call last):
...
OverdraftError: Operation would result in negative balance -2
If a negative deposit is attempted, the negative deposit amount should be included in the error message:
>>> x.deposit(-3)
Traceback (most recent call last):
...
DepositError: Negative deposit -3
Finally, reimplement the class BankAccount to use these new exception classes instead of ValueError.


4.     Develop a class Textfile that provides methods to analyze a text file. The class Textfile will support a constructor that takes as input a file name (as a string) and instantiates a Textfile object associated with the corresponding text file.  The Textfile class should support methods nchars(), nwords(), and nlines() that return the number of characters, words, and lines, respectively, in the associated text file. The class should also support methods read() and readlines() that return the content of the text file as a string or as a list of lines, respectively, just as we would expect for file objects. Finally, the class should support method grep() that takes a target string as input and searches for lines in the text file that contain the target string. The method returns the lines in the file containing the target string; in addition, the method should print the line number, where line numbering starts with 0.

Test your implementation using the test file raven.txt.
Usage:
>>> t = Textfile('raven.txt')
>>> t.nchars()
6299
>>> t.nwords()
1125
>>> t.nlines()
126
>>> print(t.read())
Once upon a midnight dreary, while I pondered weak and weary, ... Shall be lifted - nevermore!
>>> t.grep('nevermore')
75: Of `Never-nevermore.`
89: She shall press, ah, nevermore!
124: Shall be lifted - nevermore!


5.    Add method words() to class Textfile. It takes no input and returns a list, without duplicates, of words in the file.
Usage:
>>> t = Textfile('raven.txt')
>>> t.words()
['Ah', 'Aidenn', 'And', 'As', 'Back', 'Be', 'Bird', 'But', 'By', 'Caught', 'Clasp', 'Darkness',
...
'wondering', 'word', 'wore', 'wrought', 'yet', 'yore', 'you', 'your']



6.    Add method occurrences() to class Textfile. It takes no input and returns a dictionary mapping each word in the file (the key) to the number of times it occurs in the file (the value).
Usage:
>>> t = Textfile('raven.txt')
>>> t.occurences()
{'Once': 1, 'upon': 4, 'a': 15, 'midnight': 1, 'dreary': 1, 'while': 1, 'I': 32, 'pondered': 1,
...
 'streaming': 1, 'throws': 1, 'shadow': 2, 'lies': 1, 'floating': 1, 'Shall': 1, 'lifted': 1}