I was getting bored with the simplistic challenges posed in my programming logic class. So when last week  this exercise was given to us as homework;

Automobile Costs

Design a modular program that asks the user to enter the monthly costs for the following expenses incurred from operating his or her automobile: loan payment, insurance, gas, oil, tires and maintenance. The program should then display the total monthly cost of these expenses, and the total annual cost of these expenses.

I decided to take some liberties interpreting the scope of the exercise. Sure, they expect the the user to be prompted for the six expense items and then to simply add  up the amounts and multiply them by twelve. However I see the opportunity for some looping, if I instead read ‘monthly costs’ and ‘total annual cost’ to mean that we should cycle through the months. Of course some of the items, loan and insurance for instance, will be repeating amounts, so I will need to build that in as well. Otherwise the user would be forced to enter 72 numbers. Here is what I came up with:

#! /usr/bin/python
# Program to gather and compile the monthly
# and yearly costs of operating a vehicle

# initialize arrays
def months_array():
        jan = ['Jan']
        feb = ['Feb']
        mar = ['Mar']
        apr = ['Apr']
        may = ['May']
        jun = ['Jun']
        jul = ['Jul']
        aug = ['Aug']
        sep = ['Sep']
        oct = ['oct']
        nov = ['Nov']
        dec = ['Dec']
        months = [jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec]
        for x in range(len(months)):
                each_month(x, months[x][0], months);
        return months

        # initialize each month array
def each_month(monNum, monName, months):
        items = ['loan', 'insurance','fuel', 'oil', 'tires', 'maintanence']
        for e in range(len(items)):
                months[monNum].append(get_expense(monName, items[e]))
        return months

# Ask user for expense
def get_expense(monName, expense) :
        if repeatDict[expense].isdigit():
                return repeatDict[expense];
        else :
                input = raw_input('Enter the amount of the ' + expense + ' expense for '+ monName + ' $');
                while check_numeric(input) :
                        input = raw_input('Enter the amount of the ' + expense + ' expense for '+ monName + ' $');
                does_it_repeat(expense, input);
                return input

# Calculates monthly total
def month_total(thisMonth) :
        subtotal = 0
        #we have to skip the first item it is a name string - not numeric
        for x in range(len(thisMonth)-1) :
                subtotal = subtotal + int(thisMonth[x+1])
        return subtotal

#calculate yearly totals
def make_yearly(months) :
        yearly =['Yrly']
        itemTotal = 0
        for i in range(len(months[0]) - 1) :            #number of items
                for m in range(len(months)) :               #number of months
                        itemTotal = itemTotal + int(months[m][i + 1])
                itemTotal = 0
        return yearly

# check for non-numeric input
def check_numeric(numeric):
    if numeric.strip() == "" :
        print 'This field cannot be left blank. '
        return True;
    elif not numeric.isdigit() :
        print 'This field is numeric only. '
        return True
    else :
        return False

# create output in table form
def make_output(months):
        items = ['', 'loan', 'insur','fuel', 'oil', 'tires', ' maintnc', 'Monthly']
        line = '';
        for i in range(len(months[0])) :                #number of items
                line = pad(items[i]);
                for m in range(len(months)) :           #number of months
                        line = line + pad(str(months[m][i]))
                print line

# pad output for table formating
def pad(item_str):
        padding = 8 - len(item_str)
        for p in range(padding) :
                item_str = ' ' + item_str;
        return item_str;

# if charge is a repeating one, record the value
def does_it_repeat(item, amount):
        if repeatDict[item] == 'Null' :
                val = raw_input('Is this a monthly repeating charge? (yes/no)')
                if val.lower()[:1] == 'y' :
                        repeatDict[item] = amount;
                else : repeatDict[item] = 'No'

repeatDict = {'loan': 'Null', 'insurance': 'Null','fuel': 'Null', 'oil': 'Null', 'tires': 'Null', 'maintanence': 'Null'}
months = months_array()

I asked the instructor a question about loops in the flow chart and he replied we aren’t using any loops.
I said ‘Well my program has them’, and he asked where.
I said ‘To cycle through the months and through the expenses’.
He said ‘You were supposed to multiply by twelve’.
He started looking at my code and said ‘some of these expenses obviously repeat.’
I replied that I built that functionality into the program, pointing it out.

He then said ‘Well when I get to yours I will probably just go “information overload” and write something like “Brilliant!” and give you an “A” without actually reading it.”
I replied “The code is there, it works.”

So now I know how to get an automatic ‘A’, cause the instructor to have a buffer overflow error and insert a “100%” into the GPU (grade processing unit). Actually, since then I have gone back to strictly doing the exercises as expected, reflecting only the concepts from the accompanying chapter. Its a lot less work, although it is also a lot less fun.


Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s