Will
Will

Reputation: 651

multiple argument values error

I'm just starting out in OOP for python (so please excuse me if this is a stupid question). I am working with a model which uses a function to simulate the decay of a CO2 emission within the atmosphere. For each timestep, the c_size property of the class Emission should decrease using the decay function

I've simplified the code to a single run, but I keep getting the error:

Traceback (most recent call last):
File "<co2>", line 20, in <module>
x.decay(year=1) 
TypeError: decay() got multiple values for argument 'year'

I can't see where any multiple values could be coming from. I'm only passing a single int value to the code.

The code is:

import numpy as np

class Emission:
    def __init__(self,e_year=0, e_size=0.0):
        self.e_year=e_year #emission year
        self.e_size=e_size #emission size
        self.c_size=[e_size] #current size

    def decay(year):
        #returns a % decay based on the year since emission 0 = 100% 1 = 93%
        # etc. from AR5 WG1 Chapter 8 supplementary material equation 8.SM.10
        # using coefficients from table 8.SM.10
        term1 = 0.2173
        term2 = 0.224*np.exp(-year/394.4)
        term3 = 0.2824*np.exp(-year/36.54)
        term4 = 0.2763*np.exp(-year/4.304)
        out = (term1+term2+term3+term4)*self.e_size
        self.c_size.append(out)
        print(self.c_size)

x = Emission(e_year=1,e_size=10.0)
x.decay(year=1)

Upvotes: 1

Views: 83

Answers (2)

MSeifert
MSeifert

Reputation: 152647

You forgot the self in the method signature for decay so Python tried to insert the instance as first argument (which is year) and you also passed in year explicitly - resulting in the conflict of arguments.

So just change the method definition to:

def decay(self, year):

It's important to realize that the name self for the first argument of methods is just a convention. It also works if you name it year (although you have to find a different name for the second argument), or this or the_instance. The important thing is that the instance is implicitly passed as first argument to the method when you call the method.

So this would work as well:

def decay(blabla, year):
    term1 = 0.2173
    term2 = 0.224*np.exp(-year/394.4)
    term3 = 0.2824*np.exp(-year/36.54)
    term4 = 0.2763*np.exp(-year/4.304)
    out = (term1+term2+term3+term4)*blabla.e_size
    blabla.c_size.append(out)
    print(blabla.c_size)

But that's against the common Python convention and I had to change all the selfs in the method with blabla.


Further comments:

In case you're exclusively dealing with scalars as year you probably should use math.exp instead of numpy.exp, because it's much faster. But math.exp only works on scalars, so if you want to use lists or arrays for year you have to use numpy.exp.

Upvotes: 6

fievel
fievel

Reputation: 480

The first argument of class methods should be self.

class Emission:
    def __init__(self,e_year=0, e_size=0.0):
        self.e_year=e_year #emission year
        self.e_size=e_size #emission size
        self.c_size=[e_size] #current size

    def decay(self, year):
        #returns a % decay based on the year since emission 0 = 100% 1 = 93% etc. from AR5 WG1 Chapter 8 supplementary material equation 8.SM.10 using coefficients from table 8.SM.10
        term1 = 0.2173
        term2 = 0.224*np.exp(-year/394.4)
        term3 = 0.2824*np.exp(-year/36.54)
        term4 = 0.2763*np.exp(-year/4.304)
        out = (term1+term2+term3+term4)*self.e_size
        self.c_size.append(out)
        print(self.c_size)

Upvotes: 2

Related Questions