def test_template(template):
    """Tests if the creation of a template ends up with a valid template. Returns 1/0 for success/failure."""
    got_trough_test = 0  # 1 if template got through test, and 0 if not.
    # Make numbers, check condition, check calculations
    random_domain = template.random_domain
    # Efficiency note: it might be faster to pass the domain list, instead of getting them from template every time.
    answer = template.answer
    question = template.question_text
    solution = template.solution
    conditions = template.conditions
    conditions = remove_unnecessary(conditions)

    variable_dict = generate_valid_numbers(question, random_domain, "", False)
    inserted_conditions = string_replace(conditions, variable_dict)
    if len(conditions) > 1:
        conditions_pass = sympify(latex_to_sympy(inserted_conditions))
    else:
        conditions_pass = True
    if conditions_pass:
        answer = string_replace(answer, variable_dict)
        solution = string_replace(solution, variable_dict)

        try:
            answer = parse_answer(answer, random_domain)
            parse_solution(solution, random_domain)  # Checks if solution can be parsed
            got_trough_test = 1
        except Exception:
            pass
        if answer == 'error':
            got_trough_test = 0
    return got_trough_test
def cheat_check(user_answer, disallowed, variables):
    """Checks whether the user has used symbols/functions that are not allowed"""
    standard_disallowed = ['int', 'test', "'", '@', '?']
    for x in disallowed:
        replaced_x = replace_variables_from_array(variables, x)
        standard_disallowed.append(parse_solution(replaced_x, ''))

    for s in standard_disallowed:
        if str(s).replace(' ', '') in str(user_answer):
            return True
    return False
def required_check(user_answer, required, variables):
    """Checks if the user answer meets the requirements set by the teacher"""
    return_value = False
    for x in range(0, len(required)):
        required[x] = replace_variables_from_array(variables, required[x])
    for s in required:
        try:
            t_s = parse_solution(s, '')
            t_s = parenthesis_removal(t_s)
            if str(t_s).replace(' ', '') in str(user_answer):
                break
            #elif parse_using_sympy(latex_to_sympy(t_s) + '+0' + '==' + latex_to_sympy(user_answer) + '+0'):
            #    break
            return_value = True

        except Exception as e:
            print('in exception ')
            print(e)
            if str(s) not in str(user_answer):
                return_value = True
                break
    return return_value
def make_answer_context_dict(form_values):
    """Returns context dict for use on the answer page"""
    user_answer = form_values['user_answer']
    user_answer = user_answer.replace(',','.')
    user_answer = user_answer.replace('..', ',')  # A cheeky way to circumvent removal of ','
    template_type = form_values['template_type']
    template_specific = form_values['template_specific']
    q = Template.objects.get(pk=form_values['primary_key'])
    variable_dictionary = form_values['variable_dictionary'].split('§')
    replacing_words = form_values['replacing_words']
    random_domain = q.random_domain

    if template_type != 'blanks':
        answer = q.answer.replace('\\\\', '\\')
        answer = answer.replace('(', '+parenthesisleft+')  # Done to preserve original parenthesis
        answer = answer.replace(')', '+parenthesisright+')  # Done to preserve original parenthesis
        answer = replace_variables_from_array(variable_dictionary, answer)
        #answer = add_phantom_minus(answer)
    else:
        #answer = get_values_from_position(template_specific, q.solution.replace('\\\\', '\\'))
        answer = get_fillin_answers(q.fill_in.replace('\\\\', '\\'))
        answer = answer.replace('(', '+parenthesisleft+')  # Done to preserve original parenthesis
        answer = answer.replace(')', '+parenthesisright+')  # Done to preserve original parenthesis
        answer = replace_variables_from_array(variable_dictionary, answer)

    original_user_answer = user_answer.replace('§', '\\text{ og }')
    #answer = remove_pm_and_add_parenthesis(answer) # Replace with new parenthesis parsing
    answer = parse_answer(answer, random_domain)
    answer = parenthesis_removal(answer)
    answer = answer.replace('`', '')
    answer = answer.split('§')
    solution = str(q.question_text.replace('\\\\', '\\')) + "§" + str(q.solution.replace('\\\\', '\\'))
    #solution = add_phantom_minus(solution)
    solution = solution.replace('(', '+parenthesisleft+')  # Done to preserve original parenthesis
    solution = solution.replace(')', '+parenthesisright+')  # Done to preserve original parenthesis
    solution = replace_variables_from_array(variable_dictionary, solution)
    #solution = remove_pm_and_add_parenthesis(solution)
    solution = parse_solution(solution, random_domain)
    solution = parenthesis_removal(solution)
    if len(replacing_words) > 0:
        solution = replace_words(solution, replacing_words)['sentence']
    user_answer = user_answer.split('§')  # If a string doesn't contain the character it returns a list with 1 element
    # We format both the user answer and the answer the same way.
    user_answer = [after_equal_sign(x) for x in user_answer]  # Only get the values after last equal sign.
    #user_answer = calculate_array(user_answer, random_domain)
    answer = [after_equal_sign(x) for x in answer]
    #answer = calculate_array(answer, random_domain)
    answer_text = "\\text{Du har svart }" + original_user_answer + \
                      "\\text{. Det er feil. Svaret er: }" + '\\text{ og }'.join(answer)

    correct_answer = check_answer(user_answer, answer, template_type, q.margin_of_error)  # Check if the user answered correctly.

    if correct_answer:
        answer_text = "\\text{Du har svart riktig!}"

    answer_text = latex_exceptions(answer_text)

    graph = q.graph
    if graph:
        graph = json.loads(graph)

    for x in range(0, len(graph)):
            graph[x] = replace_variables_from_array(variable_dictionary, graph[x])
            graph[x] = parse_solution(graph[x], q.random_domain)

    if graph != None and graph != '':  # to prevent error if none
        graph = json.dumps(graph)
    context_dict = {'title': "Oppgavegen", 'answer': str(answer_text),
                    'solution': solution, 'user_won': correct_answer, 'graph': graph,
                    'graph_color' : q.graph_color, 'graph_settings': q.graph_settings}
    return context_dict
Beispiel #5
0
def generate_task(user, template_extra, desired_type=''):
    """ Generates a valid math problem at the correct rating from a template in the database.

    :param user: The user requesting a template
    :param template_extra: (optional) A id used for requesting a specific template.
    :param desired_type: (optional) A string for requesting a specific template type.
    :return: Returns a complete math question with generated numbers. """

    if template_extra == "":
        get_question_dict = get_question(user, '')  # Gets a question from the DB
    else:
        get_question_dict = get_question(user, template_extra)

    q = get_question_dict['template']
    if desired_type == '':
        desired_type = get_question_dict['type']
    if desired_type != 'normal':
        if (desired_type == 'multiple' or desired_type == 'multifill') and not q.multiple_support:
            return {'question': 'error'}
        if desired_type == 'blanks' and not q.fill_in:
            return {'question': 'error'}

    # The domain of random numbers that can be generated for the question
    random_domain_list = q.random_domain
    task = str(q.question_text)
    task = task.replace('\\\\', '\\') # Replaces double \\ with \
    task = task.replace('(', '+parenthesisleft+')  # Done to preserve original parenthesis
    task = task.replace(')', '+parenthesisright+')  # Done to preserve original parenthesis

    template_type = desired_type
    choices = q.choices.replace('\\\\', '\\')
    choices = choices.replace('(', '+parenthesisleft+')  # Done to preserve original parenthesis
    choices = choices.replace(')', '+parenthesisright+')  # Done to preserve original parenthesis
    conditions = q.conditions.replace('\\\\', '\\')
    dictionary = q.dictionary
    answer = q.answer.replace('\\\\', '\\')
    primary_key = q.pk
    fill_in = q.fill_in.replace('\\\\', '\\')
    fill_in = fill_in.replace('(', '+parenthesisleft+')  # Done to preserve original parenthesis
    fill_in = fill_in.replace(')', '+parenthesisright+')  # Done to preserve original parenthesis
    template_specific = ""  # A variable that holds the extra values for a given type. ie. choices for multiple.
    variables_used = ""  # Sends a splitable string since dictionaries can't be passed between layers.
    replacing_words = ''  # The words that got replaced, and the words that replaced them

    graph = q.graph  # took out .replace('\\\\', '\\')
    if graph:
        graph = json.loads(graph)

    #task = add_phantom_minus(task)
    #answer = add_phantom_minus(answer)
    #choices = add_phantom_minus(choices)
    new_choices = ''
    new_task = ''
    new_answer = ''
    variable_dict = ''

    valid_solution = False
    while valid_solution is False:  # Loop until we get a form of the task that has a valid solution
        variable_dict = generate_valid_numbers(task, random_domain_list, conditions, False)
        variables_used = dict_to_string(variable_dict)  # Get a string with the variables used
        new_task = string_replace(task, variable_dict)
        new_answer = string_replace(answer, variable_dict)
        new_choices = string_replace(choices, variable_dict)

        for x in range(0, len(graph)):
            graph[x] = string_replace(graph[x], variable_dict)
            graph[x] = parse_solution(graph[x], q.random_domain)

        if new_answer == 'error':
            continue  # Retry if the current template resulted in a error.
        valid_solution = True

    if template_type.lower() == 'multiple':
        new_choices = new_choices.split('§')
        for x in range(len(new_choices)):
            new_choices[x] = parse_solution(new_choices[x], q.random_domain)
        new_choices.append(parse_solution(new_answer, q.random_domain).replace('§', 'og'))
        shuffle(new_choices)  # Shuffles the choices so that the answer is not always in the same place.
        new_choices = '§'.join(new_choices)
        new_choices = parenthesis_removal(new_choices)
        template_specific = new_choices
        #template_specific = remove_pm_and_add_parenthesis(template_specific)
    elif template_type == 'blanks':
        fill_in_dict = fill_in_the_blanks(fill_in)
        # new_task = new_task + '\n' + fill_in_dict['fill_in'].replace('\\n', '\n')
        new_task = new_task + '§' + fill_in_dict['fill_in']
        new_task = replace_variables_from_array(variables_used.split('§'), new_task)
        new_task = parse_solution(new_task, q.random_domain)
        template_specific = fill_in_dict['hole_positions']
    elif template_type == 'multifill':
        new_choices = choices + '§' + answer.replace('§', 'og')
        new_choices = parenthesis_removal(new_choices)
        template_specific = multifill(new_choices, variable_dict)

    if dictionary is not None:
        replace_words_dict = replace_words(new_task, dictionary)
        new_task = replace_words_dict['sentence']
        replacing_words = replace_words_dict['replace_string']
    number_of_answers = len(new_answer.split('§'))

    if graph != None and graph != '':  # to prevent error if none
        graph = json.dumps(graph)
    new_task = parse_solution(new_task, q.random_domain)
    #new_task = remove_pm_and_add_parenthesis(new_task)
    new_task = parenthesis_removal(new_task)

    return_dict = {'question': new_task,
                   'variable_dictionary': variables_used, 'template_type': template_type,
                   'template_specific': template_specific, 'primary_key': primary_key,
                   'number_of_answers': number_of_answers, 'replacing_words': replacing_words,
                   'graph': graph, 'graph_settings': q.graph_settings, 'graph_color': q.graph_color}
    return return_dict