George
George

Reputation: 5691

'list' object has no attribute 'method'

I have a list with measurements, like:

[[Measurements(100, 0.3)],
[Measurements(33, 0.5)]]

Then , I have a list with some criteria which contains list of measurements:

 [Criteria(999, [[Measurements(100, 0.3)],
                        [Measurements(33, 0.5)]])],

 [Criteria(999, [[Measurements(150, 0.3)],
                        [Measurements(35, 0.5)]])]

Finally, I want to supply the above list as input and execute the code:

class Measurements():
    def __init__(self, value, other):
        self.value = value
        self.other = other


class Criteria():
    def __init__(self, new_value, measurements):
        self.new_value = new_value
        self.measurements = measurements

    def method(self):

        # Here, I am iterating through all measurements
        # and replace the value according to criteria
        for idx, x in enumerate(self.measurements):
            if (self.measurements[idx].value > 20 and
                    self.measurements[idx].value < 110):

                self.measurements[idx].value = self.new_value
        return self.measurements


class Evaluate():
    def __init__(self, criteria):
        self.criteria = criteria

    def execute(self):
        criteria = self.criteria

        # Here, I am iterating through all criteria
        # and call the method from criteria
        for i, c in enumerate(criteria):
            c.method()
            return c.measurements


def main():

    criteria = [
        [Criteria(999, [[Measurements(100, 0.3)],
                        [Measurements(33, 0.5)]])],

        [Criteria(999, [[Measurements(150, 0.3)],
                        [Measurements(35, 0.5)]])]
    ]

    obs = (Evaluate(criteria).execute())


if __name__ == "__main__":
    main()

and I am receiving c.method() AttributeError: 'list' object has no attribute 'method'

I want my results to be the new corrected Measurements, so :

[[Measurements(999, 0.3)],
[Measurements(999, 0.5)]],
[Measurements(150, 0.3)],
[Measurements(999, 0.5)]]

Upvotes: 0

Views: 2307

Answers (1)

Martijn Pieters
Martijn Pieters

Reputation: 1124758

All your Criteria() and Measurement() objects each are stored in a one-element list, which in turn are stored in a larger list. Either account for this, or don't use one-element nested lists.

I don't see any reason for those one-element lists; the following definition should make your code work:

criteria = [
    Criteria(999, [Measurements(100, 0.3), Measurements(33, 0.5)]),
    Criteria(999, [Measurements(150, 0.3), Measurements(35, 0.5)]),
]

You'll otherwise will have to either extract that one element each time, or use nested loops:

def execute(self):
    for c in self.criteria:
        c[0].method()

or

def execute(self):
    for c_list in self.criteria:
        for c in c_list:
            c.method()

You should also not use return in a for loop, at least not if you want to get the measurements for all criteria. Collect the measurements in a list, then return that list.

You also are using self way too many times in the Criteria.method() loop. There is no need for enumerate(), you don't need indices to alter mutable objects.

Corrected code:

class Measurements():
    def __init__(self, value, other):
        self.value = value
        self.other = other


class Criteria():
    def __init__(self, new_value, measurements):
        self.new_value = new_value
        self.measurements = measurements

    def method(self):
        for measurement in self.measurements:
            if 20 < measurement.value < 110:
                measurement.value = self.new_value
        return self.measurements

class Evaluate():
    def __init__(self, criteria):
        self.criteria = criteria

    def execute(self):
        results = []
        for c in self.criteria:
            measurements = c.method()
            results.extend(measurements)
        return results

def main():
    criteria = [
        Criteria(999, [Measurements(100, 0.3), Measurements(33, 0.5)]),
        Criteria(999, [Measurements(150, 0.3), Measurements(35, 0.5)]),
    ]

    obs = Evaluate(criteria).execute()

Upvotes: 3

Related Questions