Cant find a variable in a list
Question:
I wrote this code as a part of a course I am taking right now, and even though I asked some friends to debug it we didn’t manage to find the problem in the code. It throws an error that the variable I am looking for cannot be found in the list, even though I can find it when I debug and the functions I use are supposed to find it. Can anyone help me fix it?
class Grade:
def __init__(self, grade_val, grade_weight):
if grade_weight > 4 or grade_weight < 1 or grade_val > 100 or grade_val < 0:
print("Grade weight should be a number between 1 and 4 and Grade value should be between 0 and 100")
else:
self.grade_value = grade_val
self.grade_weight = grade_weight
def get_val(self):
return self.grade_value
def get_weight(self):
return self.grade_weight
class Subject:
def __init__(self, subject_name):
self.name = subject_name
self.grades = []
def add_grade(self, grade):
if not isinstance(grade, Grade):
return "Wrong input"
self.grades.append(grade)
def avg(self):
counter = 0
grade_sum = 0
for grade in self.grades:
grade_sum += grade.get_val() * grade.get_weight()
counter += grade.get_weight()
return grade_sum / counter
def __str__(self):
grades_str = ""
for grade in self.grades:
grades_str += f"Val: {grade.get_val()} Weight: {grade.get_weight()}. "
return grades_str
def __len__(self):
return len(self.grades)
def __lt__(self, other):
if not isinstance(other, Subject):
return "Wrong input"
if self.avg() > other.avg():
return "Self avg is bigger"
if self.avg() < other.avg():
return "Other avg is bigger"
return "Avgs are equal"
def __gt__(self, other):
self.__lt__(other)
class Student:
def __init__(self, name, s_id):
self.name = name
self.id = s_id
self.subjects = []
def add_sub(self, subject):
if not isinstance(subject, Subject):
return "Wrong input"
self.subjects.append(subject)
def add_grade(self, subject, grade):
if not isinstance(grade, Grade):
return "Wrong input"
for subj in self.subjects:
if subj.name == subject:
subj.add_grade(grade)
# self.subjects[self.subjects.index(subject)].add_grade(grade)
def get_subs(self):
return self.subjects
def sub_avg(self, subject):
return self.subjects[self.subjects.index(subject)].avg()
def student_avg(self):
summ = 0
for subject in self.subjects:
summ += subject.avg()
return summ / self.subjects.len()
std = Student("Ofek", 42069)
std.add_sub(Subject("Math"))
# subs = std.get_subs()
# for sub in subs:
# print(sub.name)
# print(std.subjects[0].name)
std.add_grade("Math", Grade(98, 4))
std.add_grade("Math", Grade(92, 2))
std.add_sub(Subject("English"))
std.add_grade("English", Grade(85, 3))
print(std.sub_avg("Math"))
print(std.student_avg())
Traceback (most recent call last):
File "C:Usersbar_mDesktopDevOpsPythonCodegrade_exe.py", line 99, in <module>
print(std.sub_avg("Math"))
^^^^^^^^^^^^^^^^^^^
File "C:Usersbar_mDesktopDevOpsPythonCodegrade_exe.py", line 80, in sub_avg
return self.subjects[self.subjects.index(subject)].avg()
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
ValueError: 'Math' is not in list
Thx for the support in advance <3
Answers:
In sub_avg()
, subject
is a string that names a subject, but self.subjects
is a list of Subject
instances, not strings. You need to loop through the list looking for the one with that name.
def sub_avg(self, subject):
for sub in self.subjects:
if sub.name == subject:
return sub.avg()
raise KeyError(f"Subject {subject} not found in {self}")
I wrote this code as a part of a course I am taking right now, and even though I asked some friends to debug it we didn’t manage to find the problem in the code. It throws an error that the variable I am looking for cannot be found in the list, even though I can find it when I debug and the functions I use are supposed to find it. Can anyone help me fix it?
class Grade:
def __init__(self, grade_val, grade_weight):
if grade_weight > 4 or grade_weight < 1 or grade_val > 100 or grade_val < 0:
print("Grade weight should be a number between 1 and 4 and Grade value should be between 0 and 100")
else:
self.grade_value = grade_val
self.grade_weight = grade_weight
def get_val(self):
return self.grade_value
def get_weight(self):
return self.grade_weight
class Subject:
def __init__(self, subject_name):
self.name = subject_name
self.grades = []
def add_grade(self, grade):
if not isinstance(grade, Grade):
return "Wrong input"
self.grades.append(grade)
def avg(self):
counter = 0
grade_sum = 0
for grade in self.grades:
grade_sum += grade.get_val() * grade.get_weight()
counter += grade.get_weight()
return grade_sum / counter
def __str__(self):
grades_str = ""
for grade in self.grades:
grades_str += f"Val: {grade.get_val()} Weight: {grade.get_weight()}. "
return grades_str
def __len__(self):
return len(self.grades)
def __lt__(self, other):
if not isinstance(other, Subject):
return "Wrong input"
if self.avg() > other.avg():
return "Self avg is bigger"
if self.avg() < other.avg():
return "Other avg is bigger"
return "Avgs are equal"
def __gt__(self, other):
self.__lt__(other)
class Student:
def __init__(self, name, s_id):
self.name = name
self.id = s_id
self.subjects = []
def add_sub(self, subject):
if not isinstance(subject, Subject):
return "Wrong input"
self.subjects.append(subject)
def add_grade(self, subject, grade):
if not isinstance(grade, Grade):
return "Wrong input"
for subj in self.subjects:
if subj.name == subject:
subj.add_grade(grade)
# self.subjects[self.subjects.index(subject)].add_grade(grade)
def get_subs(self):
return self.subjects
def sub_avg(self, subject):
return self.subjects[self.subjects.index(subject)].avg()
def student_avg(self):
summ = 0
for subject in self.subjects:
summ += subject.avg()
return summ / self.subjects.len()
std = Student("Ofek", 42069)
std.add_sub(Subject("Math"))
# subs = std.get_subs()
# for sub in subs:
# print(sub.name)
# print(std.subjects[0].name)
std.add_grade("Math", Grade(98, 4))
std.add_grade("Math", Grade(92, 2))
std.add_sub(Subject("English"))
std.add_grade("English", Grade(85, 3))
print(std.sub_avg("Math"))
print(std.student_avg())
Traceback (most recent call last):
File "C:Usersbar_mDesktopDevOpsPythonCodegrade_exe.py", line 99, in <module>
print(std.sub_avg("Math"))
^^^^^^^^^^^^^^^^^^^
File "C:Usersbar_mDesktopDevOpsPythonCodegrade_exe.py", line 80, in sub_avg
return self.subjects[self.subjects.index(subject)].avg()
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
ValueError: 'Math' is not in list
Thx for the support in advance <3
In sub_avg()
, subject
is a string that names a subject, but self.subjects
is a list of Subject
instances, not strings. You need to loop through the list looking for the one with that name.
def sub_avg(self, subject):
for sub in self.subjects:
if sub.name == subject:
return sub.avg()
raise KeyError(f"Subject {subject} not found in {self}")