Не понятно почему не работает реализация метода

Есть метод average_value в классе Student. он должен считать среднее значение оценок, которые есть в self.grades и помещать их в self.avg.
Но у меня почему-то выдает все равно 0. Объясните почему.

class Student:
"""
All students which can give marks Lecturers
"""

def __init__(self, name, surname, gender):
    self.name = name
    self.surname = surname
    self.gender = gender
    self.finished_courses = []
    self.courses_in_progress = []
    self.grades = {}
    self.avg = 0

def grade_s(self, lecturer, course, grade):
    if isinstance(lecturer, Lecturer) and course in self.finished_courses and course in lecturer.courses_attached:
        if course in lecturer.grades_f_s:
            lecturer.grades_f_s[course] += [grade]
        else:
            lecturer.grades_f_s[course] = [grade]
    else:
        return 'Ошибка'


def average_value(self, name, course):
    if isinstance(name, Student) and course in self.finished_courses and course in self.courses_in_progress:
      avg = sum(self.grades.values()) / len(self.grades.values())
      self.avg += avg


def __str__(self):
    text = f'Имя: {self.name} \nФамилия: {self.surname} \nСредняя оценказа ДЗ: \nКурсы в процессе изучения: {self.courses_in_progress}' \
           f'\nЗавершенные курсы: {self.finished_courses}'

    return text

class Mentor:
""""
ALL mentors
"""

def __init__(self, name, surname):
    self.name = name
    self.surname = surname
    self.courses_attached = []


class Revewier(Mentor):
'''
Reviewier checking homeworks and give marks
'''

def __init__(self, name, surname):
    super().__init__(name, surname)

def rate_hw(self, student, course, grade):
    if isinstance(student, Student) and course in self.courses_attached and course in student.courses_in_progress:
        if course in student.grades:
            student.grades[course] += [grade]
        else:
            student.grades[course] = [grade]
    else:
        return 'Ошибка'

def __str__(self):
    text = f'Имя: {self.name} \nФамилия: {self.surname}'
    return text

st = Student('Roy', 'Jhons', 'male')
st.courses_in_progress += ['Python']
st.finished_courses += ['C++']
re = Revewier('Alek', 'Bolduin')
re.courses_attached += ['Python']
re.rate_hw(st, 'Python', 9)
re.rate_hw(st, 'Python', 7)
re.rate_hw(st, 'Python', 4)
st.average_value('Python', [9, 7, 4])
print(st.avg) ----- Вывод 0 (Как будто не посчитало среднее)

Ответы (2 шт):

Автор решения: S. Nick

У вас в методе average_value() неверно прописаны условия и обратите внимание на объект self.grades

class Student:
    """
    All students which can give marks Lecturers
    """

    def __init__(self, name, surname, gender):
        self.name = name
        self.surname = surname
        self.gender = gender
        self.finished_courses = []
        self.courses_in_progress = []
        self.grades = {}
        self.avg = 0

    def grade_s(self, lecturer, course, grade):
        if isinstance(lecturer, Lecturer) and course in self.finished_courses and course in lecturer.courses_attached:
            if course in lecturer.grades_f_s:
                lecturer.grades_f_s[course] += [grade]
            else:
                lecturer.grades_f_s[course] = [grade]
        else:
            return 'Ошибка'

#  !!! ??? vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
    def average_value(self, name, course):
        print(f'{name}    -- {isinstance(name, Student)}')                                       # ???
        print(f'{course} -- {course in self.finished_courses} -- {self.finished_courses}')       # ???
        print(f'{course} -- {course in self.courses_in_progress} -- {self.courses_in_progress}') # ???
        
# ???        if isinstance(name, Student) and \
# ???           course in self.finished_courses and \
# ???           course in self.courses_in_progress:

        print(f'\nself.grades --- {self.grades}\n') 

#        avg = sum(self.grades.values()) / len(self.grades.values())
        avg = sum(self.grades[name]) / len(self.grades[name])                                  # !!! +++
        
        self.avg += avg
# +++ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

    def __str__(self):
        text = f'Имя: {self.name} \nФамилия: {self.surname} \nСредняя оценказа ДЗ: \nКурсы в процессе изучения: {self.courses_in_progress}' \
               f'\nЗавершенные курсы: {self.finished_courses}'
        return text


class Mentor:
    """"
    ALL mentors
    """

    def __init__(self, name, surname):
        self.name = name
        self.surname = surname
        self.courses_attached = []


class Revewier(Mentor):
    '''
    Reviewier checking homeworks and give marks
    '''

    def __init__(self, name, surname):
        super().__init__(name, surname)
        
    def __str__(self):
        text = f'Имя: {self.name} \nФамилия: {self.surname}'
        return text

    def rate_hw(self, student, course, grade):
        if isinstance(student, Student) and \
           course in self.courses_attached and \
           course in student.courses_in_progress:
            if course in student.grades:
                student.grades[course] += [grade]
            else:
                student.grades[course] = [grade]
        else:
            return 'Ошибка'


st = Student('Roy', 'Jhons', 'male')
st.courses_in_progress += ['Python']
st.finished_courses += ['C++']

re = Revewier('Alek', 'Bolduin')
re.courses_attached += ['Python']
re.rate_hw(st, 'Python', 9)
re.rate_hw(st, 'Python', 7)
re.rate_hw(st, 'Python', 4)

st.average_value('Python', [9, 7, 4])
print(f"среднее значение оценок ({st.grades['Python']}): {st.avg}")  

введите сюда описание изображения

→ Ссылка
Автор решения: Daniil Loban

Первое на что следует обратить внимание параметры метода name, course (self в данном случае нет смысла рассматривать)

Вы передаете 'Python', [9, 7, 4]

т.е.:

  • name = 'Python'
  • course = [9, 7, 4]

Мне не очень понятно ваше именование в таком случае, но допустим оно верное В таком случае следующее на что стоит посмотреть на условие if

  • if isinstance(name, Student)

будет False так как строка не инстанс класса Student

  • and course in self.finished_courses

будет False так как [9, 7, 4] не строка и не содержится в списке: ['C++']

  • and course in self.courses_in_progress:

будет False по той же причине, но список будет иным: ['Python']

Думаю, что последнюю часть условия нет смысла добавлять через and так как к примеру строка с названием курса не может быть одновременно в законченных курсах и прикрепленных, поэтому вероятно имелось в виду or, хотя возможно и тут я ошибаюсь.

В любом случае ваше условие не выполняется по этой причине вы получаете 0.

Если вы уберете на время условие ваш код все равно не заработает. Причина в том что dict.values() вернет список списков а списки друг с другом нельзя суммировать sum таким образом нужно как минимум извлечь первый список и уже его суммировать:

    avg = sum(list(self.grades.values())[0])  / len(list(self.grades.values())[0])
    self.avg += avg

Этот код вызывает много вопросов у меня, как и например почему вы передаете оценки хотя считаете внутреннее поле self.grades, но в любом случае, надеюсь я помог Вам увидеть те ошибки которые были допущены и Вы сможете их исправить уже самостоятельно, подкорректировав логику программы там, где необходимо.

→ Ссылка