Reputation: 1
I am trying to write a program that calculates one's grade for a class. The way I have it structured is that the user can add exams, projects, labs, or whatever and each has a certain weight. For now I am just trying to get it to work only with exams. The problem is that my final grade is stuck at 0, because it records the grade as the default value, zero. How can I make it record the new value OR even better is there a way to just take the values of a certain column in tkinter?
def ShowFinalGrade(self):
Label(self, text= "Final Grade").grid(row=10, column=0, columnspan=3)
Label(self, text= self.Calculate()).grid(row=10, column=4)
finalpercent=87
fp = finalpercent
grading_scale = self.CreateGradeScale()
self.class_score = Button(self, text="Calculate Grade", command=self.Calculate)
self.class_score.grid(row=10, column=5, padx=50)
if fp>= grading_scale[0]:
self.finalgrade= "A"
elif fp>= grading_scale[1]:
self.finalgrade= "A-"
elif fp>= grading_scale[2]:
self.finalgrade= "B+"
elif fp>= grading_scale[3]:
self.finalgrade= "B"
elif fp>= grading_scale[4]:
self.finalgrade= "B-"
elif fp>= grading_scale[5]:
self.finalgrade= "C+"
elif fp>= grading_scale[6]:
self.finalgrade= "C"
elif fp>= grading_scale[7]:
self.finalgrade= "C-"
elif fp>= grading_scale[8]:
self.finalgrade= "D+"
elif fp>= grading_scale[9]:
self.finalgrade= "D"
else:
self.finalgrade= "F"
Label(self, text = self.finalgrade).grid(row=10, column=3, columnspan=3)
def AddExam(self):
examnumber = self.examnumber
examname = Entry(self)
examname.grid(row=examnumber+1, column=0)
examname.insert(0, "Exam "+str(examnumber))
examgrade = Entry(self)
examgrade.grid(row=examnumber+1, column=1)
examgrade.insert(0,0)
# self.examtotal += float(examgrade.get())
self.examscores.append(float(examgrade.get()))
print(examgrade) # Troubleshooting
self.examnumber+=1
def Calculate(self):
examsum = 0
if len(self.examscores)!=0:
for i in range(len(self.examscores)):
examsum+= self.examscores[i]
examavg = examsum / len(self.examscores)
else:
examavg = 0
return examavg
Upvotes: 0
Views: 482
Reputation: 1557
When you set the label to text=self.Calculate(), Python merely executes the function Calculate at that point and uses its returned result as the label text.
If you want tkinter to automatically update the label every time a new calculation is performed, then the cleanest way to do it is to use a StringVar:
self.examAverage = tk.StringVar()
Label(self, textvariable=self.examAverage).grid(row=10, column=4)
and then in Calculate, instead of
return examavg
do
self.eaxmAverage.set(examavg)
May I also propose a more Pythonic way of mapping the mark fp to a grade - your approach, though valid, does not use the Python idiom. For example, you may try:
def getGrade(self, fp):
#example grading scale
gradeBoundaries = [(95, 'A'), (85, 'A-'), (75, 'B+'),
(65, 'B'), (60, 'B-'), (55, 'C+'),
(50, 'C'), (45, 'C-'), (40, 'D+'),
(35, 'D'), (0, 'F')]
return next((grade for mark,grade in gradeBoundaries if fp>=mark),'Error')
Or, if you wish to keep the grading scale separate from the grades (since it may change from exam to exam), you may try:
def getGrade(self, fp, grading_scale):
grades = 'A A- B+ B B- C+ C C- D+ D F'.split(' ')
return next((grade for mark, grade in zip(grading_scale, grades) if fp >= mark), 'Error')
and then supply the grading scale either as an instance variable, or as an argument:
getGrade(70,[95,85,75,65,60,55,50,45,40,35,0])
Upvotes: 1