Python Classes Review - Further Practice Discussion

Edit 2: I added a line of code to return a different message for a student with perfect attendance.

Edit 1: I figured out how to do what I was wanting which was to keep count of the number of absences. I converted the boolean values to integers then counted the number of ‘False’ values.

I figured out how to manipulate the different data the way I want to, I think. However, can someone please help me figure out how get my absence counter to work? It works for Pieter because he only has 1 absence, but it also says that Roger has 1 absence when he has 2. I’m sure it’s simple, but my brain is FRIED! I will edit later after I’ve worked on it some more. I think I need to review the options I have for working with the list of values in a dictionary. And I might have just answered my own question…be back soon!

``````class Student:
def __init__(self, name, year):
self.name = name
self.year = year
self.attendance = {}

def get_avg(self):
minimum_passing = 65
if average >= minimum_passing:
return "My grade average is: {:1f}\nI am passing! :)".format(average)
else:
return "My grade average is: {:1f}\nI am failing! :(".format(average)

self.attendance[date] = record

def get_attendance(self):
attendance = []
for x in self.attendance.values():
attendance.append(int(x))
for x in attendance:
if sum(attendance) == len(self.attendance):
return "I have perfect attendance!"
else:
return "I have {} absence/s recorded.".format(attendance.count(0))

def __repr__(self):
return "My name is {} and I am in year {}.\nThese are my grades: {}\n{}\nAttendance Record: {}\n{}\n".format(self.name, self.year, self.grades, self.get_avg(), self.attendance, self.get_attendance())

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

minimum_passing = 65
return "This is a passing score!"
else:
return "You are failing!"

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

sandro_grades = [90, 80, 95, 75, 65, 50, 45, 40, 35]
roger_grades = [95, 66, 78, 89, 98]

pieter_attendance = [('2/6/2021', True), ('2/5/2021', False), ('2/7/2021', True)]
sandro_attendance = [('2/6/2021', True), ('2/5/2021', True), ('2/7/2021', True)]
roger_attendance = [('2/6/2021', False), ('2/5/2021', False), ('2/7/2021', True)]

for x in list(pieter_attendance):
date = x[0]
record = x[1]

for x in list(sandro_attendance):
date = x[0]
record = x[1]

for x in list(roger_attendance):
date = x[0]
record = x[1]

#print(pieter)
#print(sandro)
#print(roger)
``````
2 Likes

This is my code but I don’t know why system annouced that it’s an error in my def attendance even I found it’s kind similar to you and I don’t know why. This is the error it is showed:

``````Traceback (most recent call last):
File "script.py", line 46, in <module>
pieter.attendance(date, status)
File "script.py", line 18, in attendance
self.attendance[date] = status
TypeError: 'method' object does not support item assignment
``````
``````class Student:

def __init__(self, name, year):

self.name = name

self.year = year

def get_average(self):

s = 0

s += student.score

def attendance(self, date, status):

self.attendance[date] = status

#################################

minimum_passing = 65

def __init__(self, score):

self.score = score

self.passed = str(self.score >= self.minimum_passing)

def is_passing(self, score):

if self.score >= minimum_passing:

return True

else:

return False

def __repr__(self):

return self.passed

######################################

roger = Student("Roger van der Weyden", 10)

sandro = Student("Sandro Botticelli", 12)

pieter = Student("Pieter Bruegel the Elder", 8)

pieter_attendance = [('2/6/2021', True)]

for i in list(pieter_attendance):

date = i[0]

status = i[1]

pieter.attendance(date, status)

print(score)
``````

Take a look at the following method.

You’re trying to assign a key `self.attendance` with a value. However, because you didn’t instantiate `self.attendance = {}` at the beginning of your class, what happens is that it tries to assign the method itself, because it’s also named `attendance`, which doesn’t work. That’s where you get the `TypeError: 'method' object does not support item assignment`.

Thank you for your answering, I added the instantiate at the beginning and I fixed the first problem but there is still other error called:

``````Traceback (most recent call last):
File "script.py", line 47, in <module>
pieter.attendance(date, status)
TypeError: 'dict' object is not callable
``````
``````class Student:

def __init__(self, name, year):

self.name = name

self.year = year

self.attendance = {}

def get_average(self):

s = 0

s += student.score

def attendance(self, date, status):

self.attendance[date] = status

#################################

minimum_passing = 65

def __init__(self, score):

self.score = score

self.passed = str(self.score >= self.minimum_passing)

def is_passing(self, score):

if self.score >= minimum_passing:

return True

else:

return False

def __repr__(self):

return self.passed

######################################

roger = Student("Roger van der Weyden", 10)

sandro = Student("Sandro Botticelli", 12)

pieter = Student("Pieter Bruegel the Elder", 8)

pieter_attendance = [('2/6/2021', True)]

for i in list(pieter_attendance):

date = i[0]

status = i[1]

pieter.attendance(date, status)

print(score)
``````

the error says:

``````TypeError: 'dict' object is not callable
``````

which means you try to call the dictionary as if it where a function. How do we add a key value pair to the dictionary?

1 Like

a quick question:

``````class Grade:
minimum_passing = 65 # atribute
def __init__(self, score):
self.score = score #is it like saying set this class score to be the
#score passed in?
``````

`self.score` is the instance variable, which we can then access in other methods

`score` is the parameter of the init method

why does python has too many self? I’m kind of a beginner in c# and I keep thinking why python has too many self isn’t supposed to be easier ? OOP in c# seems to be less complicated…

Is it normal to think that? Maybe since I’m starting, and I’m not accustomed to the language

`self` is just a way of addressing object context. Unlike JavaScript, objects in Python do not have a fixed variable (`this`) so every method must have a formal parameter so it can see the scope above. What we call it is unimportant.

Witness:

``````>>> class foo():
def __init__(self, a):
self.a = a
def __repr__(self):
return str(dir(self))

>>> b = foo('a')
>>> print (b)
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'a']
>>>
``````

And now,

``````>>> class foo():
def __init__(this, a):
this.a = a
def __repr__(this):
return str(dir(this))

>>> b = foo('a')
>>> print (b)
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'a']
>>>
``````
2 Likes

I can’t figure out why my code is producing the following:

<bound method Student.get_average of <main.Student object at 0x7fcd59914ef0>>

For starters, `print(pieter.get_average)`. When we examine the class definition, `get_average` is a method, not an attribute that carries a value. Fix this, and return if more issues persist. We did spot another suspicious bit of code but will wait until this fix is in.

1 Like

Thank you for the tip. I fixed it and I changed:

I realized that grade was being received by the method as an object and not an int. So the method was adding the objects to the list - which makes sense why get_average wasn’t working properly either.

2 Likes

yes, finally i can see it. if i tried adding a score, just as int not as class Grade, it wouldn’t work and it makes sense.

syntax is really complicated and not intuitively obvious though. i think i’ll start calling my objects whatever_obj, just so it’s immediately obvious for me, that when i pass it as an argument of a function of some other class, that it is indeed an object (with it’s own properties).

yes, finally i can see it. if i tried adding a score, just as int not as class Grade, it wouldn’t work and it makes sense.

syntax is really complicated and not intuitively obvious though. i think i’ll start calling my objects whatever_obj, just so it’s immediately obvious for me, that when i pass it as an argument of a function of some other class, that it is indeed an object (with it’s own properties).

Hello, this is my full code, hope it helps someone out.

PS. If you’re looking for inspiration or you’re having a hard time coding:

This is my second time trying to get through CS101: Introduction to Programming. The first time i didn’t even bother coding the bonuses (in all CS101) because i thought i couldn’t do it. I kept looking at the forums wondering how people came up with the solutions for the bonuses and thinking if i would ever do that or i was just wasting my time trying to learn programming. Just keep trying, it gets easier

``````class Student:
def __init__(self, name, year):
self.name = name
self.year = year

def get_average(self):
num = 0
num += i.score

def __repr__(self):
return self.name

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

minimum_passing = 65

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

def is_passing(self):
if self.score > self.minimum_passing:
return "This is a passing grade"
else:
return "This is not a passing grade"

#print(pieter.get_average())

pieter.attendance = {"monday": True, "tuesday": False}
roger.attendance = {"monday": False, "tuesday": True}

def get_attendance(student):
for date, value in student.attendance.items():
if value:
print("{student} did attend on {date}".format(student=student, date=date))
else:
print("{student} didn't attend on {date}".format(student=student, date=date))

#get_attendance(pieter)
#get_attendance(roger)
``````
2 Likes

this is how I did the get_average method

Thank you for your codes, it does really help seeing how other people think through different problems @laviedfleur Your words are encouraging

1 Like

class Student:
def init(self, name, year):
self.name=name
self.year=year
self.aattendance={}
def get_average(self):
sum=0

def attendance(self, date, attendance):
self.date=date
self.attendance=attendance
self.aattendance[self.date]= self.attendance
return self.aattendance
roger=Student(‘Roger van der Weyden’,10)
sandro=Student(‘Sandro Botticelli’,12)
pieter=Student(‘Pieter Bruegel the Elder’,8)
minimum_passing =65
def init(self, score):
self.score=score
def is_passing(self):
if self.score>self.minimum_passing:
return True
return False

print(a.is_passing())
print(pieter.get_average())

p=pieter.attendance(‘26.07.’, ‘present’)
print(p)
pieter.attendance(‘25.07.’, ‘present’)

Output:
[100, 50, 75]
True
75.0
{‘26.07.’: ‘present’}
Traceback (most recent call last):
File “script.py”, line 44, in
pieter.attendance(‘25.07.’, ‘present’)
TypeError: ‘str’ object is not callable

You seem to have a method (function) named `attendance` and a parameter `attendance` and a `self.attendance`
These may interfere with each other or overwrite each other in some cases.

Thanks, it was in self.date and self.attendance I just removed object self and it worked.