# Learn Python: Classe - bonus challenge

I have tried to implement the bonus challenges, but I am really struggeling with the get.average:

At the bottom I added some Grades to the self.grades list in the Student class. I now tried to create a for loop which iterates over every value in the list and adds it to my total, which I then can divide by the length of my list in order to get the average. But I cant figure out what exactly to add to my total count, as I get a TypeError "unsupported operand for int and grade

``````
class Student():

def __init__(self, name, year):
self.name = name
self.year = year

total_count = 0
def get_average(self):
**self.total_count += ?**

print(calculate_average)

minimum_passing = 65

def __init__(self, score):
self.score = score

def is_passing(self):
if self.score > self.minimum_passing:
else:
print("Sorry, score is not high enough")

roger = Student("Roger van der Weyden", 10)
sandro = Student("Sandro Botticelli", 12)
pieter = Student("Pieter Bruegel the Elder", 8)

``````

Simplest would be to use the built in, `sum(list)` function.

This will only be zero with each new Student instance, but will not be zeroed out on subsequent calls to `get_average()`. The method needs to be self-contained (pun not intended).

The `sum` function works like so,

``````sum(list_object)
``````

The method can be written as a single return statementâ€¦

``return sum(self.grades) / len(self.grades)``

Hi @cloud6474260085 and welcome to the Codecademy Forums.

Within the Forums, it is useful to provide a link to an exercise when it is to serve as the focus of a discussion.

Link to exercise: Learn Python 3: Classes: Review

Here, we need to access the numerical value that is stored within each `Grade` instance:

``````      **self.total_count += ?**
``````

Based on the loop header, that would be `grade.score`.

However, as we design systems in which we define types, such as classes, we need to plan what information each instance of those types should store and how those instances are to behave.

In some respects, a `Grade` should behave as a number. We ought to be able to use the `+` operator to add two `Grade` instances together. It would be even nicer if, as @mtf suggests, we could use the `sum` function to total up a `list` of `Grade` instances.

See the following example, where we define a `SummableThing` class. Then try to use it as a model for adapting the `Grade` class, so that we can use the `+` operator and the `sum` function as desired:

``````class SummableThing:
# Simple model for things that can be added up
def __init__(self, val):
self.val = val
def __repr__(self):
return str(self.val)
# Enable us to use the + operator on SummableThing objects
return SummableThing(self.val + other.val)
# Enable us to use the sum function on list of SummableThing objects
if other == 0:
return self
else:
n0 = SummableThing(99)
n1 = SummableThing(7)
n2 = SummableThing(8)
n3 = SummableThing(5)

print(sum([n0, n1, n2, n3]))
``````

Output:

``````119
``````

You can do a search for information on `__add__` and `__radd__` for additional insights.

donâ€™t need radd for sum unless there are other types in there

â€¦ oh, sum uses `0 :: int` as default identity, would have to specify a different identity value
â€¦ Iâ€™d kind of want sum to use the first value when present, or possibly even put the identity value on the right side â€¦ doesnâ€™t quite add up, whatever, I guess what `sum` â€śwantsâ€ť here is `numbers.Number` instances (but it still allows other things for some reason â€¦ legacy presumably but one would think it would have gotten tidied up in python 3)

oh and if 65 is minimum passing then 65 should pass

Bit of an off-topic thought: What problems is the code supposed to solve?

Because if itâ€™s computing an average, then one small function is enough for that.
The one other thing that seems like it could be useful is grouping up the attributes of a student.
So then, does this fulfill the requirements?

``````from collections import namedtuple

def average(xs):
return sum(xs) / len(xs)

Student = namedtuple('Student', ['name', 'year', 'grades'])
roger = Student("Roger van der Weyden", 10, [])
sandro = Student("Sandro Botticelli", 12, [])
pieter = Student("Pieter Bruegel the Elder", 8, [100, 80, 50])
``````

What does the rest of the code provide?
I think itâ€™s healthy to have some hard limits to lean on.

1 Like

FYI, we know this will not work directly since we need to resolve each score from the Grade objects in `self.grades`.

``````return sum(self.grades) / len(self.grades)
``````

A simple list comprehension will aid in the processâ€¦

``return sum([x.score for x in self.grades]) / len(self.grades)``
1 Like

The exercise is open ended in that step 9 invites the user to add some features to the program â€¦

From here you could:

• Write a `Grade` method `.is_passing()`
• â€¦

So a user could think about what math operations weâ€™d often perform on grades, and implement those via operators, other methods, or external functions. These might include:

• averaging a series of grades
• performing a weighted average of a series of grades
• multiplying a grade by a number
• converting a numerical score to a letter grade
• converting a letter grade to a numerical score

We could think about how grades are like numbers as well as how they differ from numbers. For instance, it makes sense to provide a means of averaging grades or multiplying a grade by a number. But it doesnâ€™t make sense to offer a means of multiplying a grade by a grade.

Yeah, itâ€™s not a very good example of encapsulation, our having to deal with the quirks of the internal workings of the `sum` function.

Hereâ€™s a peek into what the `sum` function does with a `list`:

``````class SummableThing:
# Simple model for things that can be added up
def __init__(self, val):
self.val = val
def __repr__(self):
return "SummableThing({})".format(self.val)
# Enable us to use the + operator on SummableThing
return SummableThing(self.val + other.val)
# Enable us to use the sum function on list of SummableThing
if other == 0:
return self
else:
st4 = SummableThing(4)
st5 = SummableThing(5)
st6 = SummableThing(6)
st7 = SummableThing(7)

print("result: {}".format(sum([st4, st5, st6, st7])))
``````

Output:

``````__radd__: SummableThing(4) 0
It initializes the result to `0`. Then it iterates though the `list`, performing `+` operations, with each encountered item as the left operand, and the current accumulated result as the right operand.