def function_node(func, tree): function_name = t.get_code_bit(func.__name__) return only( node for node in tree.body if isinstance(node, ast.FunctionDef) if node.name == function_name )
def clean_program(program, cls): if callable(program) and not cls.auto_translate_program: program = inspect.getsource(program).splitlines()[1:] if not callable(program): program = clean_spaces(program) if not is_valid_syntax(program): cls.auto_translate_program = False cls.show_solution_program = program = t.translate_program(cls, program) return program func = program source = t.translate_program(cls, inspect.getsource(program)) globs = func.__globals__ # noqa exec(source, globs) func = globs[t.get_code_bit(func.__name__)] func = MethodType(func, "") lines = source.splitlines() cls.is_function_exercise = lines[-1].strip().startswith("return ") if cls.is_function_exercise: func = func() assert lines[0] == f"def {t.get_code_bit('solution')}(self):" assert lines[-1] == f" return {func.__name__}" source = clean_spaces(lines[1:-1]) source = program = clean_solution_function(func, source) tree = ast.parse(source) if not any( isinstance(node, ast.Return) for node in ast.walk(tree) ) and not getattr(cls, "no_returns_stdout", False): func = returns_stdout(func) func = add_stdin_input_arg(func) func = NoMethodWrapper(func) cls.solution = func func_node = function_node(func, tree) if cls.is_function_exercise: cls.show_solution_program = ast.get_source_segment(source, func_node) else: lines = lines[func_node.body[0].lineno - 1 :] cls.show_solution_program = program = clean_spaces(lines) if hasattr(cls, "test_values"): [[inputs, _result]] = itertools.islice(cls.test_values(), 1) cls.stdin_input = inputs.pop("stdin_input", []) if inputs: inputs = inputs_string(inputs) program = inputs + "\n" + program compile(program, "<program>", "exec") # check validity return program
def check(self): return t.get_code_bit(hello_world_repr) in self.result
def Hello(): return ast.literal_eval(t.get_code_bit("'Hello'"))
def word(): return t.get_code_bit('word')
Similarly, `'sunshine'` is `'sunshine'`, but what's `__program__` without quotes? """ program = "sunshine" predicted_output_choices = [ "sunshine", "'sunshine'", "Hello", "'Hello'" ] correct_output = "Error" final_text = """ The answer is that `sunshine` looks like a variable, so Python tries to look up its value, but since we never defined a variable with that name we get an error. """ your_name = t.get_code_bit("your_name") class UsingVariables(Page): title = "Using Variables and `print()`" class name_assign(Step): """ Previously we made a variable called `word` with the value `'Hello'` with this code: word = 'Hello' Now make a variable called `your_name` whose value is another string. (The character `_` in `your_name` is called an *underscore*. Use it to separate words when you want a variable name containing multiple words. You can type it on most keyboards by pressing Shift and hyphen/dash/minus (`-`).) """