2

I'm trying to write an object-oriented program that allows me to enter and store monthly income and bills, and view all data as needed. I can successfully store an object, but when I try to use my view_all function, I get this error:

in view_all print(item.get_month()) AttributeError: 'str' object has no attribute 'get_month'

If you could help me track down this problem I'd be grateful!

# Create a month class

class Month:

    # Use __init__ method to initialize the attributes

    def __init__(self, month, income, tds, pnm, zia, water):
        self.__month = month
        self.__income = income
        self.__tds = tds
        self.__pnm = pnm
        self.__zia = zia
        self.__water = water


    # The set methods accept arguments:

    def set_month(self, month):
        self.__month = month

    def set_income(self, income):
        self.__income = income

    def set_tds(self, tds):
        self.__tds = tds

    def set_pnm(self, pnm):
        self.__pnm = pnm

    def set_zia(self, zia):
        self.__zia = zia

    def set_water(self, water):
        self.__water = water

    # The get methods return the data:

    def get_month(self):
        return self.__month

    def get_income(self):
        return self.__income

    def get_tds(self):
        return self.__tds

    def get_pnm(self):
        return self.__pnm

    def get_zia(self):
        return self.__zia

    def get_water(self):
        return self.__water

    # The __str__ method return's the object's state as a string

    def __str__(self):
        return "Month: " + self.__month + \
               "\nIncome: " + self.__income + \
               "\nTDS: " + self.__tds + \
               "\nPNM: " + self.__PNM + \
               "\nZia: " + self.__zia + \
               "\nWater: " + self.__water

And the main program:

import Month_Class
import pickle

ADD_MONTH = 1
VIEW_ALL = 2
QUIT = 3

FILENAME = 'ruidoso.dat'

def main():
    months = load_months()
    choice = 0
    while choice != QUIT:
        choice = get_menu_choice()

        if choice == ADD_MONTH:
            add_month(months)
        elif choice == VIEW_ALL:
            view_all(months)

    save_months(months)


def load_months():
    try:
        input_file = open(FILENAME, 'rb')
        months_dct = pickle.load(input_file)
        input_file.close
    except IOError:
        month_dct = {}
    return month_dct

def get_menu_choice():
    print()
    print('Menu')
    print('------------------')
    print("1. Add data for a new month")
    print("2. View data for all months")
    print('Any other number saves and quits the program!')
    print()

    choice = int(input('Enter your choice: '))
    while choice < ADD_MONTH or choice > QUIT:
             choice = int(input('Enter a valid choice: '))
    return choice

def add_month(months):
    month = input('Enter the name of the month: ')
    income = input('Total income for this month: ')
    tds = input('TDS Broadband bill total: ')
    pnm = input('PNM bill total: ')
    zia = input('Zia Natural Gas bill total: ')
    water = input('City of Ruidoso bill total: ')

    entry = Month_Class.Month(month, income, tds, pnm, zia, water)

    if month not in months:
        months[month] = entry
        print('The entry has been added')
    else:
        print('That month already exists!')

def save_months(months):
    output_file = open(FILENAME, 'wb')
    pickle.dump(months, output_file)
    output_file.close()


def view_all(months):
    for item in months:
        print(item.get_month())
        print(item.get_income())
        print(item.get_tds())
        print(item.get_pnm())
        print(item.get_zia())
        print(item.get_water())

main()        
Python guy
  • 99
  • 2
  • 3
  • 9
  • FYI: Using getters and setters in Python is highly unusual. – Matthias May 10 '16 at 07:36
  • @Matthias This was part of our textbook. Is it really not used often? – Python guy May 14 '16 at 03:23
  • No, it is not. What advantage do you get in Python when you use getters and setters? Just use the instance attribute itself. If there is some more logic than just setting the value the usage of the `@property` decorator is advised. Check out [this question](http://stackoverflow.com/questions/2627002/whats-the-pythonic-way-to-use-getters-and-setters). – Matthias May 16 '16 at 16:50

2 Answers2

2

You need to iterate over the dictionary differently

for month, item in months.items():
    print(item.get_month())
    ... 
OneCricketeer
  • 179,855
  • 19
  • 132
  • 245
  • Awesome. This has been bothering me for a while, thanks for your help. – Python guy May 10 '16 at 03:39
  • one other small issue is appearing after the .dat file is created. UnboundLocalError: local variable 'month_dct' referenced before assignment. There seems to be a problem loading the data from the .dat file into the months_dct dictionary, specifically the line "return month_dct". – Python guy May 10 '16 at 03:54
0

In the view_all method, you must to iterate over dictionary:

for key, item in months.iteritems():
    print(item.get_month())

and you got other error in __str__ method of Month class:

"\nPNM: " + self.__PNM + \

the correct is:

"\nPNM: " + self.__pnm + \
mrcaste
  • 23
  • 8