Question
Introduction Serpent City is an island resort that is implementing an automated system to track revenues and taxes due for three types of businesses: restaurants,
Introduction
Serpent City is an island resort that is implementing an automated system to track revenues and taxes due for three types of businesses: restaurants, hotels, and convenience stores. You are to write a set of Python classes that track the revenues and taxes based on the specifications below.
Details
You need to write a set of four Python classes. The structures for these Python classes are described here:
A parent class of businesses (Business) o This is an abstract class, so this class will have no concrete instance. o All instance variables must be private (that is, they must start with an underscore character).
This class needs to keep track of at least four (4) pieces of information: account number an integer (int) business name a string (str) the primary income a floating point value (float)
the secondary income a floating point value (float)o This class must have the following API:
The following are instance methods
-
Business (accountNumber, name) # this is the constructor, it creates and
registers a business
-
getAccountNumber () # return the account number of the business
-
setAccountNumber (accountNumber) # set the account number of the
business
-
getName () # return the name of the business
-
setName (name) # set the name of the business
-
getPrimaryIncome () # return the accumulated primary income
-
getSecondaryIncome () # return the accumulated secondary income
-
addPrimaryIncome (amount) # add the amount to the accumulated primary income
-
addSecondaryIncome (amount) # add the amount to the accumulated secondary income
-
getTaxDue () # abstract method for calculating tax (this method needs to be abstract since every type of business has a different tax calculating scheme)
-
report () # return a string that lists the income and tax due (see below for details)
The following are class methods
-
registerBusinesses (business) # register the given business so it can be
found later
-
clearBusinesses () # clear all registered businesses
-
getRegisteredBusinesses () # return a list of (registered) businesses, return
an empty list if no business has been registered yet
-
findBusiness (accountNumber) # find (registered) business by account
number, return None if none found
o Each type of businesses will have two types of incomes primary income and secondary
income. Each of the primary income and secondary income are defined based on the type of
business. o The report () method must return a string that looks like the following (see example
output files provided):
-
The first line shows the account number and name of business
-
The second line reports the type of this business
-
The third and the fourth lines display the primary and secondary income, respectively
-
The fifth line displays the total income
-
The sixth line shows the calculated tax due.
-
All floating-point values (incomes and taxes due) should be output with two (2) digits
after the decimal points.
Three subclasses, one each for restaurants, hotels, and convenience stores. o These subclasses cannot have instance variables, not even private instance variables class
variables that are constants are acceptable. o These subclasses should have a constructor that takes an account number and a name. o ThesesubclassesshouldalsoimplementthegetTaxDue()andthereport()methods
to make the subclasses concrete. o These subclasses should NOT implement these methods: getAccountNumber,
setAccountNumber, getName, setName, getPrimaryIncome, getSecondaryIncome,addPrimaryIncome, and addSecondaryIncome. These methods should be implemented in the parent Business and inherited into the subclasses unmodified.
The tax due for a restaurant is calculated as follow: o Primary income is the (non-alcoholic) food income and will be charged a tax of 6%. o Secondary income is the alcoholic income and will be charged a tax of 12%. o Ifthesecondaryincomeisgreaterthanprimaryincome,asurtaxof5%willbecharged.This
surtax is calculated on the total income. The tax due for a hotel is calculated as follow:
o Primary income is for room income. o Secondary income is for suite income. o The larger of the two types of income will be charged a tax of 15%, while the smaller one
will be charged a tax of 12%.
The tax due for a convenience store is calculated as follow: o Primary income is income for everything except newspaper and will be charged a tax of 7%.o Secondary income is income for newspaper and will not be charged of any tax.
-
Except for those defined in the API described above, all other methods must be private.
-
There cannot be any import statement in your file.
The following diagram shows the class hierarchy of the four Business classes along with the class diagrams. Note that we are following standard UML specification: abstract items are shown in italics, static items (including constructors) are shown underlined, and the "+" symbol represents a public item.
Business |
+Business (accountNumber, name) +getAccountNumber () +setAccountNumber (accountNumber) +getName () +setName (name) +getPrimaryIncome () +addPrimaryIncome (amount) +getSecondaryIncome () +addSecondaryIncome (amount) +getTaxDue () +report () +registerBusiness (business) +clearBusinesses () +findBusiness (accountNumber) +getRegisteredBusinesses () |
ConvenienceStore |
+ConvenienceStore (accountNumber, name) +getTaxDue () +report () |
Hotel |
+Hotel (accountNumber, name) +getTaxDue () +report () |
Restaurant |
+Restaurant (accountNumber, name) +getTaxDue () +report () |
Testing
A tester class (BusinessTester.py) and a set of three (3) data files (data-small.txt, data- medium.txt, and data-large.txt) are provided for you to test your classes. The tester assumes that your implementation is named Business.py and is placed in the same folder.
The tester will do the following:
-
Create five (5) different valid businesses.
-
Read from the data file and add receipts to the businesses. The receipts in the data file is
arranged in unpredictable order. All receipts in the file are guaranteed to be valid so no checking
is necessary.
-
Calculate and print out the tax due for each registered business.
The corresponding outputs for these data files are also provided in separated files (result-small.txt,result-medium.txt, and result-large.txt). Your implementation (when run with the provided tester) should produce the identical output1.
Please note that the tester is compatible to Python 3.x. This is the version of Python I will test your code with, so your code also needs to be compatible to at least Python 3.x.
BusinessTester
def loadClasses (module, path): global Business, Restaurant, Hotel, ConvenienceStore import sys sys.path.insert (0, path) try: module = __import__ (module) Business = getattr (module, 'Business') Restaurant = getattr (module, 'Restaurant') Hotel = getattr (module, 'Hotel') ConvenienceStore = getattr (module, 'ConvenienceStore') finally: sys.path.pop (0)
def setupBusiness (): Business.clearBusinesses () # the Business class will keep track all created businesses, no need to do so here. Restaurant (101, "Moe's") Restaurant (102, "Joe's") Hotel (201, 'Ritz') Hotel (202, 'Notel Motel') ConvenienceStore (612, 'Six Twelve')
def process (filename): f = open (filename) for line in f: fields = line.split () accountNumber = int (fields [0]) primary = fields [1] == '1' amount = float (fields [2]) business = Business.findBusiness (accountNumber) if not business is None: if primary: business.addPrimaryIncome (amount) else: business.addSecondaryIncome (amount) f.close ()
def report (filename): f = open (filename, 'w') for business in Business.getRegisteredBusinesses (): f.write (business.report () + ' ') f.close ()
def compare (file1, file2): f1 = open (file1) f2 = open (file2) return f1.read () == f2.read ()
def test (module = 'Business', path = '.', record = print): try: loadClasses (module, path) except: record ('File loading error - testing not executed.') return 0 score = 0 for file in ('small', 'medium', 'large'): setupBusiness () infile = 'data-' + file + '.txt' outfile = 'my-result-' + file + '.txt' reffile = 'result-' + file + '.txt' try: process (infile) report (outfile) if (compare (outfile, reffile)): record ('Processing %s: passed.' % infile) score = score + 3 else: record ('Processing %s: failed, please compare the files %s and %s' % (infile, outfile, reffile)) except Exception as err: t = type (err).__name__ record ('Exception caught when processing %s.' % infile) record ('Exception type: %s' % t) record ('Exception message: %s' % err) return score
if __name__ == '__main__': test ()
**The data files make the question too large, but they are just data to run through the tester**
Step by Step Solution
There are 3 Steps involved in it
Step: 1
Get Instant Access to Expert-Tailored Solutions
See step-by-step solutions with expert insights and AI powered tools for academic success
Step: 2
Step: 3
Ace Your Homework with AI
Get the answers you need in no time with our AI-driven, step-by-step assistance
Get Started