2

I am trying to place a method in a class that will replace null values with running average of non null values. Please refer to the code below:

class ElNinoData(object):
    # Your implementation here 
    add = 0
    counter = 0
    average = 0

    # methods
    def __init__(self , object):
        self.object = object

    def get_humidity(self):
        if not math.isnan(self.object['humidity']):  
            global add 
            global counter
            global average

            add += self.object['humidity']
            counter += 1
            average = add/counter
        else:
            self.object['humidity'] = average
        return self.object['humidity']

While executing this class in a method, I am getting the following error:

<ipython-input-40-c52c3ac6484b> in get_humidity(self)
     19             global average
     20 
---> 21             add += self.object['humidity']
     22             counter += 1
     23             average = add/counter

NameError: name 'add' is not defined

Could anyone please explain the error,I am relatively new to python?

Suel Ahmed
  • 63
  • 5

4 Answers4

3
class ElNinoData(object):
    add = 0

The add here is not a global variable,

            global add

therefore this does not give access to it, but instead looks for that actual global.

            add += self.object['humidity']

+= requires the variable to exist already (so that the old value can be added to), and you don't have a global add, nor a local one - you have a class attribute.

To access it directly, you can use ElNinoData.add, just as you would from code outside the class. Similarly for the other class attributes.

Looking up the class attribute via the instance - self.add - also succeeds. However, modifying the value then attaches a separate attribute to the instance, and leaves the class attribute unaffected.

Karl Knechtel
  • 62,466
  • 11
  • 102
  • 153
2

If you want the members to be specific to an object, change it to this

class ElNinoData(object):
    # Nothing here

    # methods
    def __init__(self , object):
        self.add = 0
        self.counter = 0
        self.average = 0
        self.object = object

and continue to refer to them with self..

If you want them to be class-wide, leave them where they are, but refer to them via ElNinoData..

In any case, you shouldn't use global here.

Ami Tavory
  • 74,578
  • 11
  • 141
  • 185
1

I think the problem is that your values add, counter and average are not global.

In order to set these values on your class instance, you have to use self instead. Something like this:

def get_humidity(self):
    if not math.isnan(self.object['humidity']):  
        self.add += self.object['humidity']
        self.counter += 1
        self.average = add/counter
    else:
        self.object['humidity'] = average
    return self.object['humidity']
Pavel Botsman
  • 773
  • 1
  • 11
  • 25
1

What you are missing here is that you have initialized the variables but not given them any values and then you are adding the values using +=, due to which python is throwing you this error. Refer to the below code:-

class ElNinoData(object):
# Your implementation here 
    add = 0
    counter = 0
    average = 0

    # methods
    def __init__(self , object):
        self.object = object

    def get_humidity(self):
        if not math.isnan(self.object['humidity']):  
            global add 
            global counter
            global average
            add = 0
            counter = 1
            add += self.object['humidity']
            counter += 1
            average = add/counter
        else:
            self.object['humidity'] = average
        return self.object['humidity']
t = {'humidity' : 10}
a =ElNinoData(t)
a.get_humidity()