See More

from pythonwhat.parsing import ObjectAssignmentParser from pythonwhat.Test import DefinedProcessTest, InstanceProcessTest, DefinedCollProcessTest, EqualValueProcessTest from pythonwhat.Reporter import Reporter from pythonwhat.Feedback import Feedback from pythonwhat.tasks import isDefinedInProcess, isInstanceInProcess, getValueInProcess, isDefinedCollInProcess, ReprFail from pythonwhat.check_funcs import part_to_child, has_equal_value MSG_PREPEND = "FMT:Check the variable `{index}`. " MSG_UNDEFINED = "FMT:Are you sure you defined the {typestr}, `{index}`?" MSG_INCORRECT_VAL = """FMT: Have you specified the correct value for "{key}" inside `{parent[sol_part][name]}`?""" MSG_KEY_MISSING = "__JINJA__:There is no {{ 'column' if 'DataFrame' in parent.typestr else 'key' }} inside {{parent.index}}." def check_object(index, missing_msg=MSG_UNDEFINED, expand_msg=MSG_PREPEND, state=None, typestr="variable"): rep = Reporter.active_reporter if not isDefinedInProcess(index, state.solution_process): raise NameError("%r not in solution environment " % index) append_message = {'msg': expand_msg, 'kwargs': {'index': index, 'typestr': typestr}} # create child state, using either parser output, or create part from name fallback = lambda: ObjectAssignmentParser.get_part(index) stu_part = state.student_object_assignments.get(index, fallback()) sol_part = state.solution_object_assignments.get(index, fallback()) # test object exists _msg = state.build_message(missing_msg, append_message['kwargs']) rep.do_test(DefinedProcessTest(index, state.student_process, Feedback(_msg))) child = part_to_child(stu_part, sol_part, append_message, state) return child def is_instance(inst, not_instance_msg="FMT:Is it a {inst.__name__}?", name=None, state=None): rep = Reporter.active_reporter sol_name = name or state.solution_parts.get('name') stu_name = name or state.student_parts.get('name') if not isInstanceInProcess(sol_name, inst, state.solution_process): raise ValueError("%r is not a %s in the solution environment" % (sol_name, type(inst))) _msg = state.build_message(not_instance_msg, {'inst': inst}) feedback = Feedback(_msg, state.highlight) rep.do_test(InstanceProcessTest(stu_name, inst, state.student_process, feedback)) return state def has_key(key, key_missing_msg=MSG_KEY_MISSING, name = None, state=None): rep = Reporter.active_reporter sol_name = name or state.solution_parts.get('name') stu_name = name or state.student_parts.get('name') if not isDefinedCollInProcess(sol_name, key, state.solution_process): raise NameError("Not all keys you specified are actually keys in %s in the solution process" % sol_name) # check if key available _msg = state.build_message(key_missing_msg, {'key': key}) rep.do_test(DefinedCollProcessTest(stu_name, key, state.student_process, Feedback(_msg, state.highlight))) return state def has_equal_key(key, incorrect_value_msg=MSG_INCORRECT_VAL, key_missing_msg=MSG_KEY_MISSING, name=None, state=None): rep = Reporter.active_reporter sol_name = name or state.solution_parts.get('name') stu_name = name or state.student_parts.get('name') has_key(key, key_missing_msg, state=state) sol_value, sol_str = getValueInProcess(sol_name, key, state.solution_process) if isinstance(sol_value, ReprFail): raise NameError("Value from %r can't be fetched from the solution process: %s" % c(sol_name, sol_value.info)) # check if value ok _msg = state.build_message(incorrect_value_msg, {'key': key}) rep.do_test(EqualValueProcessTest(stu_name, key, state.student_process, sol_value, Feedback(_msg, state.highlight))) return state