def add_message(self, message, raw=False): if not raw: # We assume raw messages, formatted for HTML, are printed separately if self.mute: util.unmute_print() print '*** ' + message if self.mute: util.mute_print() message = cgi.escape(message) self.messages[self.current_question].append(message)
def grade(self, grading_module, exception_map={}, bonus_pic=False): """ Grades each question grading_module: the module with all the grading functions (pass in with sys.modules[__name__]) """ completed_questions = set([]) for q in self.questions: print('\nQuestion %s' % q) print('=' * (9 + len(q))) print() self.current_question = q incompleted = self.prereqs[q].difference(completed_questions) if len(incompleted) > 0: prereq = incompleted.pop() print( """*** NOTE: Make sure to complete Question %s before working on Question %s, *** because Question %s builds upon your answer for Question %s. """ % (prereq, q, q, prereq)) continue if self.mute: util.mute_print() try: util.TimeoutFunction(getattr(grading_module, q), 1800)( self) # Call the question's function #TimeoutFunction(getattr(grading_module, q),1200)(self) # Call the question's function except Exception as inst: self.add_exception_message(q, inst, traceback) self.add_error_hints(exception_map, inst, q[1]) except: self.fail('FAIL: Terminated with a string exception.') finally: if self.mute: util.unmute_print() if self.points[q] >= self.maxes[q]: completed_questions.add(q) print('\n### Question %s: %d/%d ###\n' % (q, self.points[q], self.maxes[q])) print('\nFinished at %d:%02d:%02d' % time.localtime()[3:6]) print("\nProvisional grades\n==================") for q in self.questions: print('Question %s: %d/%d' % (q, self.points[q], self.maxes[q])) print('------------------') print('Total: %d/%d' % (self.points.total_count(), sum(self.maxes.values()))) if bonus_pic and self.points.total_count() == 25: print(""" ALL HAIL GRANDPAC. LONG LIVE THE GHOSTBUSTING KING. --- ---- --- | \ / + \ / | | + \--/ \--/ + | | + + | | + + + | @@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ \ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ \ / @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ V \ @@@@@@@@@@@@@@@@@@@@@@@@@@@@ \ / @@@@@@@@@@@@@@@@@@@@@@@@@@ V @@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@ /\ @@@@@@@@@@@@@@@@@@@@@@ / \ @@@@@@@@@@@@@@@@@@@@@@@@@ /\ / @@@@@@@@@@@@@@@@@@@@@@@@@@@ / \ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ / @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@ """) print(""" Your grades are NOT yet registered. To register your grades, make sure to follow your instructor's guidelines to receive credit on your project. """) if self.edx_output: self.produce_output() if self.gs_output: self.produce_grade_scope_output()
def grade(self, grading_module, exception_map={}, bonus_pic=False): """ Grades each question grading_module: the module with all the grading functions (pass in with sys.modules[__name__]) """ completed_questions = set([]) for q in self.questions: print '\nQuestion %s' % q print '=' * (9 + len(q)) print self.current_question = q incompleted = self.prereqs[q].difference(completed_questions) if len(incompleted) > 0: prereq = incompleted.pop() print \ """*** NOTE: Make sure to complete Question %s before working on Question %s, *** because Question %s builds upon your answer for Question %s. """ % (prereq, q, q, prereq) continue if self.mute: util.mute_print() try: util.TimeoutFunction(getattr(grading_module, q), 1800)( self) # Call the question's function # TimeoutFunction(getattr(grading_module, q),1200)(self) # Call # the question's function except Exception as inst: self.add_exception_message(q, inst, traceback) self.add_error_hints(exception_map, inst, q[1]) except BaseException: self.fail('FAIL: Terminated with a string exception.') finally: if self.mute: util.unmute_print() if self.points[q] >= self.maxes[q]: completed_questions.add(q) print '\n### Question %s: %d/%d ###\n' % (q, self.points[q], self.maxes[q]) print '\nFinished at %d:%02d:%02d' % time.localtime()[3:6] print "\nProvisional grades\n==================" for q in self.questions: print 'Question %s: %d/%d' % (q, self.points[q], self.maxes[q]) print '------------------' print 'Total: %d/%d' % (self.points.total_count(), sum(self.maxes.values())) if bonus_pic and self.points.total_count() == 25: print """ ALL HAIL GRANDPAC. LONG LIVE THE GHOSTBUSTING KING. --- ---- --- | \ / + \ / | | + \--/ \--/ + | | + + | | + + + | @@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ \ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ \ / @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ V \ @@@@@@@@@@@@@@@@@@@@@@@@@@@@ \ / @@@@@@@@@@@@@@@@@@@@@@@@@@ V @@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@ /\ @@@@@@@@@@@@@@@@@@@@@@ / \ @@@@@@@@@@@@@@@@@@@@@@@@@ /\ / @@@@@@@@@@@@@@@@@@@@@@@@@@@ / \ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ / @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@ """ print """ Your grades are NOT yet registered. To register your grades, make sure\n\n (a) You have PROPER HEADER AND AUTHENTICITY STATEMENT on all source files you are submitting, \n (b) Create a single zip file containing just the files you were instructed to modify, and\n (c) Upload your zip file to canvas. """ if self.edx_output: self.produce_output() if self.gs_output: self.produce_grade_scope_output()
*** because Question %s builds upon your answer for Question %s. """ % (prereq, q, q, prereq) continue if self.mute: util.mute_print() try: util.TimeoutFunction(getattr(grading_module, q), 300)(self) # Call the question's function #TimeoutFunction(getattr(grading_module, q),1200)(self) # Call the question's function except Exception, inst: self.add_exception_message(q, inst, traceback) self.add_error_hints(exception_map, inst, q[1]) except: self.fail('FAIL: Terminated with a string exception.') finally: if self.mute: util.unmute_print() if self.points[q] >= self.maxes[q]: completed_questions.add(q) print '\n### Question %s: %d/%d ###\n' % (q, self.points[q], self.maxes[q]) print '\nFinished at %d:%02d:%02d' % time.localtime()[3:6] print "\nProvisional grades\n==================" for q in self.questions: print 'Question %s: %d/%d' % (q, self.points[q], self.maxes[q]) print '------------------' print 'Total: %d/%d' % (self.points.total_count(), sum(self.maxes.values()))
continue if self.mute: util.mute_print() try: util.TimeoutFunction(getattr(grading_module, q), 300)(self) # Call the question's function #TimeoutFunction(getattr(grading_module, q),1200)(self) # Call the question's function except Exception, inst: self.add_exception_message(q, inst, traceback) self.add_error_hints(exception_map, inst, q[1]) except: self.fail('FAIL: Terminated with a string exception.') finally: if self.mute: util.unmute_print() if self.points[q] >= self.maxes[q]: completed_questions.add(q) print '\n### Question %s: %d/%d ###\n' % (q, self.points[q], self.maxes[q]) print '\nFinished at %d:%02d:%02d' % time.localtime()[3:6] print "\nProvisional grades\n==================" for q in self.questions: print 'Question %s: %d/%d' % (q, self.points[q], self.maxes[q]) print '------------------' print 'Total: %d/%d' % (self.points.total_count(), sum(self.maxes.values()))
def grade(self, grading_module, exception_map={}, bonus_pic=False): """Grade each question. Args: grading_module: the module with all the grading functions (pass in with sys.modules[__name__]) """ completed_questions = set([]) for q in self.questions: print('\nQuestion %s' % q) print('=' * (9 + len(q))) print() self.current_question = q incompleted = self.prereqs[q].difference(completed_questions) if len(incompleted) > 0: prereq = incompleted.pop() print("*** NOTE: Make sure to complete Question %s before \ working on Question %s,\n\ *** because Question %s builds upon your answer for Question %s." % (prereq, q, q, prereq)) continue if self.mute: util.mute_print() try: # Call the question's function util.TimeoutFunction(getattr(grading_module, q), 300)(self) except Exception as inst: self.add_exception_message(q, inst, traceback) self.add_error_hints(exception_map, inst, q[1]) finally: if self.mute: util.unmute_print() if self.points[q] >= self.maxes[q]: completed_questions.add(q) print('\n### Question %s: %d/%d ###\n' % (q, self.points[q], self.maxes[q])) # if self.student_code comes in then we lint if self.student_code is not None: try: from flake8.api import legacy as flake8 # noqa on the following since just importing to test installed import pep8ext_naming # noqa import flake8_docstrings # noqa print("\nLinting Code...\n" + "=" * 15) self.current_question = "linting" style_guide = flake8.get_style_guide() report = style_guide.check_files(self.student_code.split(",")) self.maxes["linting"] = self.linting_value self.points["linting"] = self.linting_value if report.total_errors > 0: self.fail("FAIL: You should fix all linting errors " + "before submission in order to receive full " + "credit!") self.add_message("") for module in self.student_code.split(","): self.check_header(module) if (("project_test_classes" in dir(grading_module) and "extra_lint" in dir(grading_module.project_test_classes) )): grading_module.project_test_classes.extra_lint(self) if self.points["linting"] == self.linting_value: self.add_message("PASS: no linting errors.") print('\n### Linter: %d/%d ###\n' % (self.points['linting'], self.maxes['linting'])) except ImportError: print(""" ### WARNING: Unable to import flake8 and/or extensions, so cannot \ properly lint your code. ### Please install flake8, pep8-naming, and flake8-docstrings to auto-check \ whether you are adhering to proper style and docstring conventions. To install, run: pip install flake8 pep8-naming flake8-docstrings """) print('\nFinished at %d:%02d:%02d' % time.localtime()[3:6]) print("\nProvisional grades\n==================") for q in self.questions: print('Question %s: %d/%d' % (q, self.points[q], self.maxes[q])) if "linting" in self.maxes: print('Linter: %d/%d' % (self.points["linting"], self.maxes["linting"])) print('------------------') print('Total: %d/%d' % (self.points.total_count(), sum(self.maxes.values()))) if bonus_pic and self.points.total_count() == 25: print(""" ALL HAIL GRANDPAC. LONG LIVE THE GHOSTBUSTING KING. --- ---- --- | \ / + \ / | | + \--/ \--/ + | | + + | | + + + | @@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ \ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ \ / @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ V \ @@@@@@@@@@@@@@@@@@@@@@@@@@@@ \ / @@@@@@@@@@@@@@@@@@@@@@@@@@ V @@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@ /\ @@@@@@@@@@@@@@@@@@@@@@ / \ @@@@@@@@@@@@@@@@@@@@@@@@@ /\ / @@@@@@@@@@@@@@@@@@@@@@@@@@@ / \ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ / @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@ """) print(""" Your grades are NOT yet registered. To register your grades, make sure (a) You have PROPER HEADER AND AUTHENTICITY STATEMENT on all source files \ you are submitting, (b) Create a single zip file containing just the files you were instructed to \ modify, and (c) Upload your zip file to canvas. """) if self.edx_output: self.produce_edx_output() if self.gs_output: self.produce_grade_scope_output()