user2757442
user2757442

Reputation: 175

How to access a dictionary in a function that is defined in another function in the same class

I have created a class with two functions inside of it. These functions run forever in a loop at the bottom of the code. However, the first function creates a dictionary and the user adds values to this dictionary. The second function is meant to import the dictionary and add 10 to each value. However, when I run this code, I get an error stating that 'Materials is not defined'. How am I supposed to properly use the dictionary in both functions?

Here is my code:

class materialsClass:
    def materialsChange(self):
        while True: 
            q1 = raw_input("Type 'edit' to add or change a material, or 'continue' to continue: ")
            if q1 == 'edit':
                while True:
                    q2 = raw_input("Type 'add' to add a new material, 'edit' to edit amount of a material: ")
                    if q2 == 'add': 
                        x = str(raw_input("Enter the Material: "))
                        y = int(0)
                        Materials = {x:y}
                        break
                    elif q2 == 'edit': 
                        x = str(raw_input("Enter your Material: "))
                        y = int(raw_input("Enter your Change: "))
                        Materials[x] += y
                        break
                    else:
                        print "Please Type an Option"
            elif q1 == 'continue': break           
            else:
                print "Type an Option!"

        print Materials


    def materialCounter(self):
        for k in Materials: Materials[k] += 10
        print Materials

while True:
    obj=materialsClass()
    obj.materialsChange()
    obj.materialCounter()

Upvotes: 3

Views: 4533

Answers (3)

Selcuk
Selcuk

Reputation: 59228

You cannot use a variable local to a method within another method. You need to define the variable in the class scope and make it an instance variable. For example:

class materialsClass:
    def __init__(self):
        self.Materials = dict()

    def materialsChange(self):
        ...
        self.Materials[x] = y
        (in place of Materials = {x:y})

    def materialCounter(self):
        for k in self.Materials: 
            self.Materials[k] += 10
        print self.Materials

Also note that when the interpreter runs the line

Materials = {x:y}

it replaces the Materials dictionary with a new one and you are not actually adding a new material in the dictionary. That's why you should write:

self.Materials[x] = y

instead. This will add a new material to the dictionary.

Upvotes: 4

Christopher John
Christopher John

Reputation: 4490

To build on some of the other answers. You have to create a dictionary under the class and the way you were adding items to the dictionary was incorrect so I have changed that. You also have to create a class in the proper way for it to work. I have checked this code and it works for me anyway. I hope this helps.

class materialsClass(object):
    def __init__(self): # create a new class
        self.materials = {} # create a new dictionary under this class
    def materialsChange(self):
        while True: 
            q1 = raw_input("Type 'edit' to add or change a material, or 'continue' to continue: ")
            if q1 == 'edit':
                while True:
                    q2 = raw_input("Type 'add' to add a new material, 'edit' to edit amount of a material: ")
                    if q2 == 'add': 
                        x = str(raw_input("Enter the Material: "))
                        y = int(0) 
                        self.materials[x] = y # this is how to add items to dictionaries sequentially
                        print self.materials
                        break
                    elif q2 == 'edit': 
                        x = str(raw_input("Enter your Material: "))
                        y = int(raw_input("Enter your Change: "))
                        self.materials[x] = y
                        print self.materials
                        break
                    else:
                        print "Please Type an Option"
            elif q1 == 'continue': break           
            else:
                print "Type an Option!"

        print self.materials


    def materialCounter(self):
        for k in self.materials:
            self.materials[k] = self.materials[k] + 10
        print self.materials


obj=materialsClass() # you do not need to create the class again and again, just once is fine

while True:
    obj.materialsChange()
    obj.materialCounter()

Upvotes: 1

Kasravnd
Kasravnd

Reputation: 107297

Variables inside the functions are in local namespace so you can not use Materials inside the second function as it has been defined in first one ! you can initial Materials in the enclosing class scope instead :

But note that you need to initial your variable inside the __init__ function:

class materialsClass:
    def __init__(self):
        self.Materials=dict()
    def materialsChange(self):
        while True: 
            q1 = raw_input("Type 'edit' to add or change a material, or 'continue' to continue: ")
            if q1 == 'edit':
                while True:
                    q2 = raw_input("Type 'add' to add a new material, 'edit' to edit amount of a material: ")
                    if q2 == 'add': 
                        x = str(raw_input("Enter the Material: "))
                        y = int(0)
                        self.Materials = {x:y}
                        break
                    elif q2 == 'edit': 
                        x = str(raw_input("Enter your Material: "))
                        y = int(raw_input("Enter your Change: "))
                        self.Materials[x] += y
                        break
                    else:
                        print "Please Type an Option"
            elif q1 == 'continue': break           
            else:
                print "Type an Option!"

        print self.Materials


    def materialCounter(self):
        for k in self.Materials: self.Materials[k] += 10
        print self.Materials

Upvotes: 2

Related Questions