Hope Rouselle <hrouse...@jevedi.com> writes: > Hope Rouselle <hrouse...@jevedi.com> writes: > > [...] > >> Of course, you want to see the code. I need to work on producing a >> small example. Perhaps I will even answer my own question when I do. > > [...] > > Here's a small-enough case. We have two students here. One is called > student.py and the other is called other.py. They both get question 1 > wrong, but they --- by definition --- get question 2 right. Each > question is worth 10 points, so they both should get losses = 10. > > (*) Student student.py > > def question1(t): # right answer is t[2] > return t[1] # lack of attention, wrong answer > > > (*) Student other.py > > def question1(t): # right answer is t[2] > return t[0] # also lack of attention, wrong answer > > > (*) Grading > > All is good on first run. > > Python 3.5.2 [...] on win32 > [...] >>>> reproducible_problem() > student.py, total losses 10 > other.py, total losses 10 > > The the problem: > >>>> reproducible_problem() > student.py, total losses 0 > other.py, total losses 0 > > They lose nothing because both modules are now permanently modified. > > (*) The code of grading.py > > # -*- mode: python; python-indent-offset: 2 -*- > def key_question1(t): > # Pretty simple. Student must just return index 2 of a tuple. > return t[2] > > def reproducible_problem(): # grade all students > okay, m = get_student_module("student.py") > r = grade_student(m) > print("student.py, total losses", r) # should be 10 > okay, m = get_student_module("other.py") > r = grade_student(m) > print("other.py, total losses", r) # should be 10 > > def grade_student(m): # grades a single student > losses = question1_verifier(m) > losses += question2_verifier(m) > return losses > > def question1_verifier(m): > losses = 0 > if m.question1( (0, 1, 2, 3) ) != 2: # wrong answer > losses = 10 > return losses > > def question2_verifier(m): > m.question1 = key_question1 > # To grade question 2, we overwrite the student's module by giving > # it the key_question1 procedure. This way we are able to let the > # student get question 2 even if s/he got question 1 incorrect. > losses = 0 > return losses
My solution is to painfully save each original procedure from student in a variable, replace them with the key's, then restore them at the end. I couldn't overwrite m.__dict__ because it is readonly. (Didn't find a neater's way out.) def question2_verifier(m): question1_original = m.question1 m.question1 = key_question1 # apply verifications... m.question1 = question1_original return losses -- https://mail.python.org/mailman/listinfo/python-list