I want to do the following kind of test :
I ask students to write a class for Vector2D with 2 methods : one to add another vector and another one to multiply with a number (plus a constructor and a __str__ method).
So the good answer must be :
class Vecteur2D: def __init__(self,x,y): self.x = x self.y = y def __str__(self): return "[" + str(self.x) + "," + str(self.y) + "]" def multScalaire(self,s): self.x = self.x * s self.y = self.y * s def addVecteur(self,v): self.x = self.x + v.x self.y = self.y + v.yI want to give some points to students who manage to write the __init__ and __str__ methods, even if they can't write the multScalaire and addVecteur methods.
So, I configure my question like this :
and the same for 3 more tests :
the second one with only the multScalaire method
v1 = Vecteur2D(7,3)
the third one with the addVecteur method and the last one with all the methods.
When I test this question, if I answer with all but the multScalaire method, the first AND the third one should be OK but I get this :
Why does the second test (with multScalaire method) block the execution of the third test (which should be OK and add some points to the student)?
That's an interesting question.
CodeRunner is intended primarily for use with All or nothing grading - see my rant on How programming quizzes should work. In that context, it's generally appropriate to abort all testing when a runtime error occurs. Runtime errors are usually a drastic failure of the submitted code, including such things as indexing out of range, timeout errors and, in Python, the use of undefined variables and methods. The same error most commonly occurs in all tests and displaying a test result table with the same error in each row, when the student is going to get zero anyway, just adds insult to injury. In the case of timeout errors, it also wastes time. Note, too, that many of the runtime errors in Python, including the example you quote, would be compile errors in a statically typed language so the student wouldn't get any marks anyway in such a language.
I believe that mostly the same considerations apply even when you're not using all-or-nothing grading - a table with every row displaying the same runtime error looks silly regardless. In your particular case I accept that it would seem appropriate to continue testing, but I'm not sure that it's a compelling enough example to warrant changing the strategy. I think your question would actually be better cast as two or three different questions, e.g.
- Write a class Vecteur that has an initialiser and a __str__ method.
- Add to your Vecteur class a multScalaire method
However, if your heart is set on using partial grading, you could resolve the problem you have simply by recasting your test in the form
v1 = Vecteur2D(7, 3) if hasattr(v1, multScalaire): v1.multScalaire(8) print(v1) else: print('multScalaire unimplemented')
Hope that helps.
Thank you for your reply and explanations.
The solution you suggest works perfectly, you just need to write multScalaire like a String in the hasattr test :
if hasattr(v1, 'multScalaire'):instead of
if hasattr(v1, multScalaire):