425
425
def __repr__(self):
426
426
return "<%s %s in %s>" % (type(self).__name__, self.exercise.name,
427
427
self.worksheet.name)
429
class ExerciseSave(Storm):
431
Represents a potential solution to an exercise that a user has submitted
432
to the server for storage.
433
A basic ExerciseSave is just the current saved text for this exercise for
434
this user (doesn't count towards their attempts).
435
ExerciseSave may be extended with additional semantics (such as
438
__storm_table__ = "problem_save"
439
__storm_primary__ = "exercise_id", "user_id", "date"
441
exercise_id = Int(name="problemid")
442
exercise = Reference(exercise_id, Exercise.id)
443
user_id = Int(name="loginid")
444
user = Reference(user_id, User.id)
448
__init__ = _kwarg_init
451
return "<%s %s by %s at %s>" % (type(self).__name__,
452
self.exercise.name, self.user.login, self.date.strftime("%c"))
454
class ExerciseAttempt(ExerciseSave):
456
An ExerciseAttempt is a special case of an ExerciseSave. Like an
457
ExerciseSave, it constitutes exercise solution data that the user has
458
submitted to the server for storage.
459
In addition, it contains additional information about the submission.
460
complete - True if this submission was successful, rendering this exercise
461
complete for this user.
462
active - True if this submission is "active" (usually true). Submissions
463
may be de-activated by privileged users for special reasons, and then
464
they won't count (either as a penalty or success), but will still be
467
__storm_table__ = "problem_attempt"
468
__storm_primary__ = "exercise_id", "user_id", "date"
470
# The "text" field is the same but has a different name in the DB table
472
text = Unicode(name="attempt")