Chapter 16: Object-Oriented Software Development

Example 16.1, Page Number 831

In [1]:
class set:                                 #*class set*#
    
    def __init__(self):                    #constructor
        self.__arr = []
        
    def insert(self,s):                    #insert the element in the array
        self.__arr.append(s)

    def begin(self):                       #return the first index position
        return 0
    
    def end(self):                         #return the last index position
        return len(self.__arr)
    
    def empty(self):                       #check set is empty or not
        if len(self.__arr)==0:
            return True
        else:
            return False
        
    def erase(self,s):                     #erase a particualr item from the set
        self.__arr.remove(s)
        
    def op1(self,n):                       #function to return array element
        return self.__arr[n]
    
    
class vector:                               #*class vector*#
    
    def __init__(self):                     #constructor
        self.__arr = []
        
    def push_back(self,s):                  #insert the element in the array
        self.__arr.append(s)

    def begin(self):                       #return the first index position
        return 0
    
    def end(self):                         #return the last index position
        return len(self.__arr)
    
    def empty(self):                       #check vector is empty or not
        if len(self.__arr)==0:
            return True
        else:
            return False
        
    def size(self):                         #return the size of vector
        return len(self.__arr)
        
    def erase(self,s):                      #erase a particualr item from the vector
        self.__arr.remove(s)
        
    def op1(self,n):                     #function to return array element
        return self.__arr[n]   
    
    def sort(self,a,b):                  #sort the elements of vector by date
        for k in range(1,b,1):
            j=k-1
            
            c = compareDates()
            while c.cmpdat(self.__arr[k],self.__arr[j]) and j>=0:
                self.__arr[j+1] = self.__arr[j]
                j -= 1
                
            self.__arr[j+1] = self.__arr[k]
            
            
                                    #get line of text
def getaLine(inStr):            
    inStr = raw_input()
    return inStr


def getaChar():                     #get a character
    ch = raw_input()
    return ch



class tenant:                                  #---class tenant---#
    
    def __init__(self,n,aNo):
        self.__name = n                        #tenant's name
        self.__aptNumber = aNo                 #tenant's apartment number
        
    def __del__(self):
        pass
    
    def getAptNumber(self):
        return self.__aptNumber
    
    
#friend functions

def ten_lt(t1,t2):                                 #overloaded less than function
    return t1._tenant__name < t2._tenant__name

def ten_eq(t1,t2):                                 #overloaded equal function
    return t1._tenant__name == t2._tenant__name

def ten_out(t):                                    #for output
    print t._tenant__aptNumber,'\t',t._tenant__name
    

    
class compareTenants:                                  #---class compareTenants---#
    
    def cmpTen(self,ptrT1,ptrT2):           #compares tenants
        return ten_lt(ptrT1,ptrT2)
    

    
class tenantList:                                  #---class tenantList---#
    __setPtrsTens = set()                          #set object
    
    def __del__(self):                             #destructor
        
        while not (self.__setPtrsTens.empty()):    
            
            j = self.__setPtrsTens.begin()
            self.__setPtrsTens.erase(self.__setPtrsTens.op1(j))       #erase all tenants
            
            
    def insertTenant(self,ptrT):                #insert tenants into set
        self.__setPtrsTens.insert(ptrT)
        
        
    def getAptNo(self,tName):                   #return apartment number
        
        dummy = tenant(tName,0)
        iter = self.__setPtrsTens.begin()
        
        while iter != self.__setPtrsTens.end():
            aptNo = self.__setPtrsTens.op1(iter).getAptNumber()         #look for tenant on the list?
            
            if ten_eq(dummy,self.__setPtrsTens.op1(iter)):             #yes
                return aptNo
            
            iter += 1
            
        return -1                                                      #no
    
    
    def display(self):                                                 #display tenant list
        print '\nApt#\tTenant name\n----------------------\n',
        
        if self.__setPtrsTens.empty():
            print '*****No tenants*****'
            
        else:
            iter = self.__setPtrsTens.begin()
        
            while iter != self.__setPtrsTens.end():
                ten_out(self.__setPtrsTens.op1(iter))
                iter += 1
                

                
class tenantInputScreen:                                  #---class tenantInputScreen---#
    __ptrTenantList = tenantList()
    
    def __init__(self,ptrTL=None):
        self.__ptrTenantList = ptrTL
        self.__tName = ""
        self.__aptNo = 0
            
    def getTenant(self):                                   #get tenant info
        print "Enter tenant's name (George Smith): ",
        self.__tName = getaLine(self.__tName)
        
        self.__aptNo =  input("Enter tenant's apartment number (10): ")
        
        ptrTenant = tenant(self.__tName,self.__aptNo)
        self.__ptrTenantList.insertTenant(ptrTenant)        #send to tenant list
        
        
        
class rentRow:                                            #---class rentRow---#
    
    def __init__(self,an):                            #one-arg constructor
        self.__aptNo = an
        self.__rent = [0 for j in range(12)]
        
    def setRent(self,m,am):                           #return rent for one month
        self.__rent[m] = am
        
    def getSumOfRow(self):                            #return sum of rent  in row
        c = 0
        for j in range(12):
            c += self.__rent[j]
            
        return j
    
    
def rent_lt(t1,t2):                                   #overloaded less than function
    return t1._rentRow__aptNo < t2._rentRow__aptNo

def rent_eq(t1,t2):                                   #overloaded equal function
    return t1._rentRow__aptNo == t2._rentRow__aptNo

def rent_out(an):                                     #for output
    print an._rentRow__aptNo,'\t',                    #print apartment number
    
    for j in range(12):                               #print 12 rents
        if (an._rentRow__rent[j] == 0):
            print '  0 ',
            
        else:
            print an._rentRow__rent[j],' ',
            
    print ''
            
            
            
class compareRows:                                      #---class compareRows---#
    
    def cmpRow(self,ptrR1,ptrR2):                       #compare apartment number
        return rent_lt(ptrR1,ptrR2)
    
    
    
class rentRecord:                                       #---class rentRecord---#
    __setPtrsRR = set()
    
    def __del__(self):                                  #destructor
        while not (self.__setPtrsRR.empty()):
            
            j = self.__setPtrsRR.begin()
            self.__setPtrsRR.erase(self.__setPtrsRR.op1(j))         #delete rent rows, remove ptrs from set
            
            
    def insertRent(self,aptNo,month,amount):
        
        searchRow = rentRow(aptNo)                                  #temp row with same aptNo
        
        iter = self.__setPtrsRR.begin()                             #searchsetPtrsRR
        
        b=0
        while iter != self.__setPtrsRR.end():                       #rent row found?
            
            if rent_eq(searchRow,self.__setPtrsRR.op1(iter)):       #yes,
                self.__setPtrsRR.op1(iter).setRent(month,amount)    #put rent in row
                b=1
                break
            else:                                                   #didn't find it
                iter += 1
                
        if(b==0):        
            ptrRow = rentRow(aptNo)                     #make new row
            ptrRow.setRent(month,amount)                #put rent in row
        
            self.__setPtrsRR.insert(ptrRow)             #put row in set
                
                
    def display(self):
        print "\nAptNo\tJan  Feb  Mar  Apr  May  Jun  Jul  Aug  Sep  Oct  Nov  Dec\n-----------------------------------------------------",
        print "---------------"
        
        if self.__setPtrsRR.empty():
            print "*****No Rents*****"
            
        else:
            iter = self.__setPtrsRR.begin()
        
            while iter != self.__setPtrsRR.end():
                rent_out(self.__setPtrsRR.op1(iter))
                iter += 1
                
                
    def getSumOfRents(self):                #returns sum of all rents
        sumRents = 0.0
        
        iter = self.__setPtrsRR.begin()
        
        while iter != self.__setPtrsRR.end():
            sumRents += self.__setPtrsRR.op1(iter).getSumOfRow()
            iter += 1
            
        return sumRents
    
    

class rentInputScreen:                                       #---class rentInputScreen---#
    __ptrTenantList = tenantList()
    __ptrRentRecord = rentRecord()
    
    def __init__(self,ptrTL=None,ptrRR=None):
        self.__ptrTenantList = ptrTL
        self.__ptrRentRecord = ptrRR
        
        self.__renterName = None
        self.__rentPaid = 0.0
        self.__month = 0
        self.__aptNo = 0
        
        
    def getRent(self):                                  #rent for one tenant and one month
        
        print "Enter tenant's name: ",
        self.__renterName = getaLine(self.__renterName)
        
        self.__aptNo = self.__ptrTenantList.getAptNo(self.__renterName)
        
        if self.__aptNo>0:                                                    #if name found,
                                                                              #get rent amount
            self.__rentPaid =  input("Enter amount paid (345.67): ")
            self.__month = input("Enter month rent is for(1-12): ")
            
            self.__month -= 1                                                 #internal is 0-11
            
            self.__ptrRentRecord.insertRent(self.__aptNo,self.__month,self.__rentPaid)
            
        else:
            print 'No tenant with that name.'
            
            
class expense:                                                   #---class expense---#
    
    def __init__(self,m=0,d=0,c="",p="",a=0.0):                  #constructor
        self.__month = m
        self.__day = d
        self.__category = c
        self.__payee = p
        self.__amount = a
        
        
def exp_lt(e1,e2):                                   #overloaded less than function
    if e1._expense__month == e2._expense__month:
        return e1._expense__day < e2._expense__day

def exp_eq(e1,e2):                                   #overloaded equal function
    return e1._expense__month == e2._expense__month and e1._expense__day == e2._expense__day

def exp_out(exp):                                    #for output
    print exp._expense__month,'/',exp._expense__day,'\t',exp._expense__payee,'\t',exp._expense__amount,'\t',exp._expense__category
    
  
    
class compareDates:                                                   #---class compareDates---#
    
    def cmpdat(self,ptrE1,ptrE2):                                     #compare expenses according to dates
        return exp_lt(ptrE1,ptrE2)
    
    
    
class compareCategories:                                              #---class compareCategories---#
    
    def cmpcat(self,ptrE1,ptrE2):                                     #compare expenses according to category
        return ptrE1._expense__category < ptrE2._expense__category
    
    
    
class expenseRecord:                                                   #---class expenseRecord---#
    __vectPtrsExpenses = vector()
    
    def __del__(self):                                                 #destructor
        
        while not (self.__vectPtrsExpenses.empty()):
            
            j = self.__vectPtrsExpenses.begin()
            self.__vectPtrsExpenses.erase(self.__vectPtrsExpenses.op1(j))           #delete expense objects, remove ptrs from vector
            
    def insertExp(self,ptrExp):
        self.__vectPtrsExpenses.push_back(ptrExp)
        
    def display(self):
        print "\nDate\tPayee\t\tAmount\tCategory\n--------------------------------------------"
        
        if self.__vectPtrsExpenses.size() == 0:
            print "*****No Expenses*****"
            
        else:
            self.__vectPtrsExpenses.sort(self.__vectPtrsExpenses.begin(),self.__vectPtrsExpenses.end())     #sort by date
             
            iter = self.__vectPtrsExpenses.begin()
        
            while iter != self.__vectPtrsExpenses.end():
                exp_out(self.__vectPtrsExpenses.op1(iter))
                iter += 1
                
    def displaySummary(self):                                 #used by annualReport
        
        totalExpenses = 0.0                                   #total, all category
        
        if self.__vectPtrsExpenses.size() == 0:
            print "\tAll categories\t0"
            return 0.0
        
        self.__vectPtrsExpenses.sort(self.__vectPtrsExpenses.begin(),self.__vectPtrsExpenses.end())        #sort by category
        
        #for each category, sum the enries
        
        iter = self.__vectPtrsExpenses.begin()
        tempCat = self.__vectPtrsExpenses.op1(iter)._expense__category
        sumCat = 0.0
        
        while iter != self.__vectPtrsExpenses.end():
            
            if tempCat == self.__vectPtrsExpenses.op1(iter)._expense__category:
                sumCat += self.__vectPtrsExpenses.op1(iter)._expense__amount           #same category
                
            else:
                                                                #different category
                print '\t',tempCat,'\t',sumCat
                totalExpenses += sumCat                         #add previous category
                
                tempCat = self.__vectPtrsExpenses.op1(iter)._expense__category
                sumCat = self.__vectPtrsExpenses.op1(iter)._expense__amount           #add final amount
                
            iter += 1
            
        totalExpenses += sumCat                            #add fianl category
        print '\t',tempCat,'\t',sumCat
        
        return totalExpenses
    

class expenseInputScreen:                                           #---class expenseInputScreen---#
    __ptrExpenseRecord = expenseRecord()
    
    def __init__(self,per=None):                                    #constructor
        self.__ptrExpenseRecord = per
        
        
    def getExpense(self):
        
        month = input("Enter month (1-12): ")
        day = input("Enter day (1-31): ")
        
        category = ""
        print "Enter expense category (Repairing, Utilities): ",
        category = getaLine(category)
        
        payee = ""
        print "Enter payee (Bob's Hardware, Big Electric Co): ",
        payee = getaLine(payee)
        
        amount = input("Enter amount (39.95): ")
        
        ptrExpense = expense(month,day,category,payee,amount)
        
        self.__ptrExpenseRecord.insertExp(ptrExpense)
        
        
        
class annualReport:                                           #---class annualReport---#
    
    __ptrRR = rentRecord()
    __ptrER = expenseRecord()
    
    def __init__(self,pRR=None,pER=None):                     #constructor
        self.__ptrRR = pRR
        self.__ptrER = pER
        self.__expenses = 0.0
        self.__rents = 0.0
        
    def display(self):                                        #display annual report
        print "Annual Summary\n-----------------------------\nIncome\n\tRent\t\t",
        self.__rents = self.__ptrRR.getSumOfRents()
        print self.__rents
        print "Expenses"
        self.__expenses = self.__ptrER.displaySummary()
        print "\nbalance\t\t\t",self.__rents-self.__expenses
        
        
class userInterface:                                           #---class userInterface---#
    
    __ptrTenantList = tenantList()
    __ptrTenantInputScreen = tenantInputScreen()
    __ptrRentRecord = rentRecord()
    __ptrrentInputScreen = rentInputScreen()
    __ptrExpenseRecord = expenseRecord()
    __ptrExpenseInputScreen = expenseInputScreen()
    __ptrAnnualReport = annualReport()
    
    def __init__(self):                                        #constructor
        
        #three reports exist for the life of the program
        self.__ptrTenantList = tenantList()
        self.__ptrRentRecord = rentRecord()
        self.__ptrExpenseRecord = expenseRecord()
        
    def __del__(self):                                         #destructor
        del self.__ptrTenantList
        del self.__ptrRentRecord
        del self.__ptrExpenseRecord
        
    
    
    def interact(self):
        
        while True:
            
            print "\nEnter 'i' to input data, "
            print "      'd' to display a report,"
            print "      'q' to quit program: ",
            
            ch = getaChar()
            
            if ch=='i':                                  #enter data
                
                print "Enter 't' to add tenant,"
                print "      'r' to record rent payment"
                print "      'e' to record expense: ",
                
                ch = getaChar()
                print '\n'
                
                if ch=='t':
                    self.__ptrTenantInputScreen = tenantInputScreen(self.__ptrTenantList)
                    self.__ptrTenantInputScreen.getTenant()
                    
                elif ch=='r':
                    self.__ptrRentInputScreen = rentInputScreen(self.__ptrTenantList,self.__ptrRentRecord)
                    self.__ptrRentInputScreen.getRent()
                    
                elif ch=='e':
                    self.__ptrExpenseInputScreen = expenseInputScreen(self.__ptrExpenseRecord)
                    self.__ptrExpenseInputScreen.getExpense()
                    
                else:
                    print "Unknown input option"
                
                
            elif ch=='d':                                 #display data
                
                print "Enter 't' to display tenants,"
                print "      'r' to display rents"
                print "      'e' to display expense,"
                print "      'a' to display annual report: ",
                
                ch = getaChar()
                print '\n'
                
                if ch=='t':
                    self.__ptrTenantList.display()
                    
                elif ch=='r':
                    self.__ptrRentRecord.display()
                    
                elif ch=='e':
                    self.__ptrExpenseRecord.display()
                    
                elif ch=='a':
                    self.__ptrAnnualReport = annualReport(self.__ptrRentRecord,self.__ptrExpenseRecord)
                    self.__ptrAnnualReport.display()
                    del self.__ptrAnnualReport
                    
                else:
                    print "Unknown display option"
                
                    
            elif ch=='q':
                break                        #quit
                
            else:
                print "Unknown option. Enter only 'i', 'd' or 'q'"
                
            
                
theUserInterface = userInterface()

theUserInterface.interact()
Enter 'i' to input data, 
      'd' to display a report,
      'q' to quit program: i
 Enter 't' to add tenant,
      'r' to record rent payment
      'e' to record expense: t
 

Enter tenant's name (George Smith): Harry Ellis
Enter tenant's apartment number (10): 101
 
Enter 'i' to input data, 
      'd' to display a report,
      'q' to quit program: i
 Enter 't' to add tenant,
      'r' to record rent payment
      'e' to record expense: t
 

Enter tenant's name (George Smith): Wanda Brown
Enter tenant's apartment number (10): 102
 
Enter 'i' to input data, 
      'd' to display a report,
      'q' to quit program: d
 Enter 't' to display tenants,
      'r' to display rents
      'e' to display expense,
      'a' to display annual report: t
 


Apt#	Tenant name
----------------------
101 	Harry Ellis
102 	Wanda Brown

Enter 'i' to input data, 
      'd' to display a report,
      'q' to quit program: i
 Enter 't' to add tenant,
      'r' to record rent payment
      'e' to record expense: r
 

Enter tenant's name: Harry Ellis
Enter amount paid (345.67): 695
Enter month rent is for(1-12): 1
 
Enter 'i' to input data, 
      'd' to display a report,
      'q' to quit program: i
 Enter 't' to add tenant,
      'r' to record rent payment
      'e' to record expense: r
 

Enter tenant's name: Harry Ellis
Enter amount paid (345.67): 695
Enter month rent is for(1-12): 2
 
Enter 'i' to input data, 
      'd' to display a report,
      'q' to quit program: i
 Enter 't' to add tenant,
      'r' to record rent payment
      'e' to record expense: r
 

Enter tenant's name: Wanda Brown
Enter amount paid (345.67): 595
Enter month rent is for(1-12): 1
 
Enter 'i' to input data, 
      'd' to display a report,
      'q' to quit program: Wanda Brown
 Unknown option. Enter only 'i', 'd' or 'q'

Enter 'i' to input data, 
      'd' to display a report,
      'q' to quit program: i
 Enter 't' to add tenant,
      'r' to record rent payment
      'e' to record expense: r
 

Enter tenant's name: Wanda Brown
Enter amount paid (345.67): 595
Enter month rent is for(1-12): 2
 
Enter 'i' to input data, 
      'd' to display a report,
      'q' to quit program: d
 Enter 't' to display tenants,
      'r' to display rents
      'e' to display expense,
      'a' to display annual report: r
 


AptNo	Jan  Feb  Mar  Apr  May  Jun  Jul  Aug  Sep  Oct  Nov  Dec
----------------------------------------------------- ---------------
101 	695   695     0    0    0    0    0    0    0    0    0    0  
102 	595   595     0    0    0    0    0    0    0    0    0    0  

Enter 'i' to input data, 
      'd' to display a report,
      'q' to quit program: i
 Enter 't' to add tenant,
      'r' to record rent payment
      'e' to record expense: e
 

Enter month (1-12): 1
Enter day (1-31): 3
Enter expense category (Repairing, Utilities): Mortgage
 Enter payee (Bob's Hardware, Big Electric Co): First megaBank
Enter amount (39.95): 5187.30
 
Enter 'i' to input data, 
      'd' to display a report,
      'q' to quit program: i
 Enter 't' to add tenant,
      'r' to record rent payment
      'e' to record expense: e
 

Enter month (1-12): 1
Enter day (1-31): 8
Enter expense category (Repairing, Utilities): Utilities
 Enter payee (Bob's Hardware, Big Electric Co): City Water
Enter amount (39.95): 963.10
 
Enter 'i' to input data, 
      'd' to display a report,
      'q' to quit program: i
 Enter 't' to add tenant,
      'r' to record rent payment
      'e' to record expense: e
 

Enter month (1-12): 1
Enter day (1-31): 9
Enter expense category (Repairing, Utilities): Insurance
 Enter payee (Bob's Hardware, Big Electric Co): Steady State
Enter amount (39.95): 4840.00
 
Enter 'i' to input data, 
      'd' to display a report,
      'q' to quit program: d
 Enter 't' to display tenants,
      'r' to display rents
      'e' to display expense,
      'a' to display annual report: e
 


Date	Payee		Amount	Category
--------------------------------------------
1 / 3 	First megaBank 	5187.3 	Mortgage
1 / 8 	City Water 	963.1 	Utilities
1 / 9 	Steady State 	4840.0 	Insurance

Enter 'i' to input data, 
      'd' to display a report,
      'q' to quit program: d
 Enter 't' to display tenants,
      'r' to display rents
      'e' to display expense,
      'a' to display annual report: a
 

Annual Summary
-----------------------------
Income
	Rent		22.0
Expenses
	Mortgage 	5187.3
	Utilities 	963.1
	Insurance 	4840.0

balance			-10968.4

Enter 'i' to input data, 
      'd' to display a report,
      'q' to quit program: q

In [ ]: