def execute(self, data={}): self.print() # Loop until we get the correct answer. while True: # If data does not contain a lesson state, create one if not "state" in data: data["state"] = dict() # To avoid corruption through user errors the user should not be given # direct access to the state. Hence, make a deep copy. dcp = deepcopy(data["state"]) # Get any values that the user generates, and pass them to # test_response. for value in self.get_response(data=dcp): if self.test_response(value, data=dcp): # Since test was passed, modify and return the data data["state"].update(value["added"]) data["state"].update(value["changed"]) for k in value["removed"]: del data["state"][k] return data else: try: colors.print_help(self.hint) except AttributeError: pass break
def get_response(self, data={}): # Parse the options and shuffle them, for variety. options = self.choices random.shuffle(options) # Loop until the user selects the correct answer. while True: # Begin by printing the menu with numerical identifiers. for i, option in enumerate(options): colors.print_option("%d: %s" % (i+1, option)) # Get the user's choice and try to return the relevant # answer, catching failures and restarting as appropriate. # Note that invalid input restarts the loop here, but an # incorrect answer will restart the loop outside of the # scope of the function. This allows for grading. # XXX: Try to match strings to choices, too. try: colors.print_inst("Select one of the numbered choices: ", end="") choice = int(input())-1 return options[choice] except (ValueError, IndexError): colors.print_help( "Please pick an integer between 1 and %d" % len(options)) continue
def execute(self, data={}): """Execute the question in the default way, by first printing itself, then asking for a response and testing it in a loop until it is correct.""" # XXX: Collect statistics here so that it can be used for # grading. # Print the output. self.print() # Loop until correct. while True: # Get the user's response. resp = self.get_response(data=data) # Test it. If correct (True), then break from this loop. If # not, print the hint, if it's present. testresult = self.test_response(resp, data=data) if testresult == True: break elif testresult == False: try: colors.print_help(self.hint) except AttributeError: pass else: # If the test is not a boolean, (i.e. None), then it was # not testable or relevant, for some reason. continue
def execute_lesson(self, identifier): """Executes a lesson based on a given identifier. This can be either an index (one-based) or a string matching a lesson name. If none can be found, it throws a NoSuchLessonException.""" # Load the lesson, if possible. lesson = self.load_lesson(identifier) # If the "data" directory is present, load it up and pass it # along in the lesson data. if os.path.isdir(os.path.join(self.rawdir, "data")): provided = Data(os.path.join(self.rawdir, "data")) else: provided = None # Execute it. data = lesson.execute( initial_data={ "coursedir": self.coursedir, "rawdir": self.rawdir, "provided": provided }) # Print a seperator to show it's complete. print() colors.print_help("Lesson complete!")
def execute_lesson(self, identifier): """Executes a lesson based on a given identifier. This can be either an index (one-based) or a string matching a lesson name. If none can be found, it throws a NoSuchLessonException.""" # Load the lesson, if possible. lesson = self.load_lesson(identifier) # If the "data" directory is present, load it up and pass it # along in the lesson data. if os.path.isdir(os.path.join(self.rawdir, "data")): provided = Data(os.path.join(self.rawdir, "data")) else: provided = None # Execute it. data = lesson.execute(initial_data={ "coursedir": self.coursedir, "rawdir": self.rawdir, "provided": provided }) # Print a seperator to show it's complete. print() colors.print_help("Lesson complete!")
def get_response(self, data={}): # Parse the options and shuffle them, for variety. options = self.choices random.shuffle(options) # Loop until the user selects the correct answer. while True: # Begin by printing the menu with numerical identifiers. for i, option in enumerate(options): colors.print_option("%d: %s" % (i + 1, option)) # Get the user's choice and try to return the relevant # answer, catching failures and restarting as appropriate. # Note that invalid input restarts the loop here, but an # incorrect answer will restart the loop outside of the # scope of the function. This allows for grading. # XXX: Try to match strings to choices, too. try: colors.print_inst("Select one of the numbered choices: ", end="") choice = int(input()) - 1 return options[choice] except (ValueError, IndexError): colors.print_help("Please pick an integer between 1 and %d" % len(options)) continue
def execute_lesson(self, identifier): """Executes a lesson based on a given identifier. This can be either an index (one-based) or a string matching a lesson name. If none can be found, it throws a NoSuchLessonException.""" # Load the lesson, if possible. lesson = self.load_lesson(identifier) # Execute it. data = lesson.execute(initial_data={"coursedir" : self.coursedir, "rawdir" : self.rawdir}) # Print a seperator to show it's complete. print() colors.print_help("Lesson complete!")
def execute_lesson(self, identifier): """Executes a lesson based on a given identifier. This can be either an index (one-based) or a string matching a lesson name. If none can be found, it throws a NoSuchLessonException.""" # Load the lesson, if possible. lesson = self.load_lesson(identifier) # Execute it. data = lesson.execute(initial_data={ "coursedir": self.coursedir, "rawdir": self.rawdir }) # Print a seperator to show it's complete. print() colors.print_help("Lesson complete!")
def execute(self, data={}): colors.print_help("Hello!")