Intro to Classes: Bonus - Attendance problems

Hi All,

I am a pretty new student to python and was working my way through the “intro to Classes” review: https://www.codecademy.com/courses/learn-python-3/lessons/data-types/exercises/review

I have had a tough time with understanding this lesson in general, but largely worked through most of the challenges, save the last one relating to recording attendance: " Add an instance variable to Student that is a dictionary called .attendance , with dates as keys and booleans as values that indicate whether the student attended school that day."

Looking through the forums I found a couple interpretations of this question. I built mine with the understanding that I would enter a dictionary of key : value pairs, corresponding to the date : Boolean recording if the student had attended that day. Those values would then get appended into the instance variable as an overall record of attendance. My code is listed below, all sections from other questions in the exercise were removed. The error I receive is:
TypeError: attendance() missing 1 required positional argument: ‘prescence’

class Student: def __init__(self, name, year): self.name = name self.year = year self.grades = [] self.attendance_days = {} def attendance(self, date, prescence): for day in self.date: self.attendance_days.append(day[0]) return self.attendance_days pieter = Student("Pieter Bruegel the Elder", 8) print(pieter.attendance({"06/20/2021": True, "06/21/2021": False}))

I know I am missing something(s) basic, but just cant seem to figure out what.

1 Like

Hello, @method3046985979, and welcome to the forums.

The error is saying that your method takes one more argument than you are providing. If we look at your method call, we see that only one argument (a dictionary with 2 elements) is passed:

Consider what your method takes as parameters. It appears you want a date and a boolean value.

Your method won’t work as expected either. Dictionaries don’t have the same attributes as lists. Specifically, dictionaries don’t have an append attribute.

1 Like

Thank you for the help. In light of what you said, I guess I dont understand how I would pass a dictionary into a method as opposed to several discrete strings/ints/etc. Also, how would I indicate that the method should iterate through the different elements of the dictionary?

My understanding of the instructions was to write a method for adding a single date along with the boolean value indicating whether or not the student was in attendance at a time though you certainly could write a method that accepts a dictionary argument made up of several elements as you’ve attempted. I like that idea better, and since you’re inclined to go that route, let’s explore it.

You want to pass a dictionary with one or more key: value pairs, so when you write your method signature, rather than including two parameters (in addition to self), you’d only want one, a dictionary. That’s the first step. What’s next? Do you recall how to iterate through a dictionary?

Edit:
Actually, you wouldn’t need to iterate through the dictionary passed. Look into the update() method. You could iterate through the dictionary, and add each key: value pair individually if you’d rather.

1 Like

Thank you for pointing me in the right direction. I fixed the for statement to properly reference the dictionary, and replaced the append with the update method. IM guessing there is a more efficient way to accomplish this based on your comment, but I dont think I see it. Can this be condensed into a comprehension?

Code is below:

class Student: def __init__(self, name, year): self.name = name self.year = year self.grades = [] self.attendance_days = {} def attendance(self, date_rec): for d, v in date_rec.items(): # print(d, v) self.attendance_days.update({d: v}) return self.attendance_days pieter = Student("Pieter Bruegel the Elder", 8) print(pieter.attendance({"06/20/2021": True, "06/21/2021": False}))
1 Like

No need. If you already had a few elements in the attendance_days dictionary, and you were adding more, a comprehension wouldn’t be beneficial.

Consider this example:

my_dict = {1: 'a', 2: 'b', 3: 'c'} print(my_dict) new_values = {4: 'd', 5: 'e', 6: 'f'} my_dict.update(new_values) print(my_dict) overwrite_values = {1: 'z', 2: 'y', 3: 'x'} my_dict.update(overwrite_values) print(my_dict) add_new_and_overwrite = {1: 'a', 2: 'b', 3: 'c', 7: 'g', 8: 'h', 9: 'i'} my_dict.update(add_new_and_overwrite) print(my_dict)

Hi! May I ask someone to check my code?

  • should I add Attendance class?
  • should I check in add_attendance method, whether passed attributes belongs to Attendance class? How to do that? In add_grade method there is “if type(grade) is Grade”, but I don’t know how to do that if I have 2 attributes in my class.
class Student():
  def __init__(self, name, year):
    self.name = name
    self.year = year
    self.attendance= {}
  
  def add_attendance(self, date, attend):
    self.date = date
    self.attend = attend
    self.attendance[self.date] = self.attend

  def get_attendance(self):
    presence  = []
    absence = []
    for i in self.attendance.values():
        if i == True:
            presence.append(i)
        elif i == False:
            absence.append(i)
    attendance = int(len(presence) / (len(presence) + len(absence)) * 100)
    return print(f"{self.name.split()[0]} has got {attendance} percent of attendance")

class Attendance():
    def __init__(self, date, attend):
        self.date = date
        self.attend = attend

Hi, I have followed the instructions word for word. Users won’t be able to add all the attendance in one go. They would need to do entries one by one for each date. As for now, I am not supporting bulk attendance import. Check out the code here,

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

  def add_attendance(self,date,attendance_value):
    self.attendance[date]=attendance_value

    

  def add_grade(self,grade):
    if type(grade) is Grade:
      self.grades.append(grade)
  
  def get_average(self):
    total = 0
    
    for grade in self.grades:
      # going into grade class's attribute
      # print(grade.score)
      total+=grade.score
    # print(len(self.grades))
    return total/len(self.grades)


class Grade:
  minimum_passing = 65

  def __init__(self,score):
    self.score=score
  def is_passing(self):
    if self.score>=self.minimum_passing:
      return True
    return False

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

# adds the new grade to student: pieter
new_grade = Grade(100)
pieter.add_grade(new_grade)

new_grade = Grade(60)
pieter.add_grade(new_grade)

# checks the passing grade of student:pieter
print(new_grade.is_passing())
# result: False

# pieter's average of grades
print(pieter.get_average())
# result : 80.0

# adds the pieter's attandence
pieter.add_attendance('20/07/1995',True)
pieter.add_attendance('21/07/1995',False)
pieter.add_attendance('22/07/1995',True)
pieter.add_attendance('23/07/1995',True)
pieter.add_attendance('24/07/1995',True)

# prints the pieter's attendance
print(pieter.attendance)

# result : {'20/07/1995': True, '21/07/1995': False, '22/07/1995': True, '23/07/1995': True, '24/07/1995': True}