def calculate_answer(s, domain):
    """Calculates a string using sympy.

    :param s: String to be calculated
    :param domain: The domain of the variables.
    :return: A latex version of the calculated string.
    """

    try:
        domain = json.loads(domain)
    except ValueError:
        pass
    try:
        if not is_number(s):  # Small optimization
            s = remove_unnecessary(s)
            s = str(latex_to_sympy(s))
            s = s.replace('*)', ')*')
            s = s.replace('?)@', ')?@')
            s = parse_expr(s, transformations=standard_transformations +
                           (convert_xor, implicit_multiplication_application,), global_dict=None, evaluate=False)
            s = latex(sympify(str(s)))
            # Sometimes sympify returns the value 'zoo'
        else:
            if domain != '':
                s = round_answer(domain, float(s))
    except Exception as e:
        print('exception in calculate answer')
        print(e)
    return str(s)
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
Exemplo n.º 3
0
def check_answer(user_answer, answer, template_type, margin_for_error=0):
    """Checks if the answer the user gave is correct.

    :param user_answer: A list containing the answer(s) the user gave.
    :param answer: A list containing the answer(s) to the template.
    :param template_type: A string detailing how the template is presented.
    :return: Boolean of whether the answer is correct
    """
    if (margin_for_error is None) or (margin_for_error == ''):
        margin_for_error = '0'

    if template_type != 'normal':
        # Reverse iteration to avoid index out of bounds when elements get deleted.
        for s in range(len(answer)-1, -1, -1):
                try:
                    if s == '':
                        del user_answer[s]

                    elif parse_using_sympy_simplify(latex_to_sympy('(' + user_answer[s] + ') - ' + str(margin_for_error)) + ' <= ' + latex_to_sympy(answer[s]) +
                       ' <= ' + latex_to_sympy('(' + user_answer[s] + ') + '+ str(margin_for_error))):
                        del user_answer[s]
                except TypeError or SyntaxError:
                    if parse_using_sympy_simplify(latex_to_sympy(answer[s]) + ' == ' + latex_to_sympy(user_answer[s])):
                        del user_answer[s]
                        break

    else:
        for s in answer:
            for us in user_answer:
                print('testing')
                print(margin_for_error)
                if margin_for_error != 0:
                    try:
                        if parse_using_sympy_simplify(latex_to_sympy('(' + us + ') - ' + margin_for_error) + ' <= ' + latex_to_sympy(s) +
                           ' <= ' + latex_to_sympy('(' + us + ') + '+ margin_for_error)):
                            user_answer.remove(us)
                            break
                    except TypeError:
                        if parse_using_sympy_simplify(latex_to_sympy(s) + ' == ' + latex_to_sympy(us)):
                            user_answer.remove(us)
                            break
                elif parse_using_sympy_simplify(latex_to_sympy(s) + ' == ' + latex_to_sympy(us)):
                    user_answer.remove(us)
                    break

    if user_answer == []:  # Can not be written as user_answer is [], even though pep says otherwise.
        right_answer = True
    else:
        right_answer = False
    return right_answer
def parenthesis_remover(s):
    """removes parenthesises from expressions and checks if the expression is still valid."""
    s = s.replace(')(', ')*(')
    s = s.replace('§', '+paragraftegn+')
    s = s.replace('(+', '(')
    s = s.replace('(+', '(')

    pairs = find_pairs(s, '(', ')')
    removable = []
    for pair in pairs:
        temp_s =  remove_all_from_list(s, pair)
        try:
            #  Note: +0 is added so the string never ends with + (which would stop sympy)
            if  parse_using_sympy(latex_to_sympy(temp_s) + '+0' + '==' + latex_to_sympy(s) + '+0'):
                removable.append(pair[0])
                removable.append(pair[1])
        except Exception as e:
            print('exception in parenthesis remover:')
            print(e)
            print(s)
            print('^ string that failed. end of exception.')

    s = remove_all_from_list(s, removable)
    #s = replace_key_with_value(s, replace_dict)
    s = s.replace('+parenthesisleft+', '(')
    s = s.replace('+parenthesisright+', ')')
    s = s.replace('+erlik+', '=')
    s = s.replace('+paragraftegn+', '§')

    s = s.replace('+-', '-')
    s = s.replace('--', '+')
    s = s.replace('- -', '+')
    s = s.replace('+ -', '-')

    s = s.replace('§+', '§')
    s = s.replace('=+', '=')
    s = s.replace('^{+', '^{')
    s = s.replace('(+', '(')

    return s
Exemplo n.º 5
0
def check_conditions(conditions, variable_dict, domain_dict, domain_list):
    """A function that checks if the generated variables pass the conditions and generates new ones until they do.
    :param conditions: The conditions of the template.
    :param variable_dict: List of variables.
    :param domain_dict: the domain of the variables.
    :param domain_list: a dict with the domain list.
    :return: List of variables that pass the conditions of the given template.
    """
    conditions = remove_unnecessary(conditions)
    # Check conditions --> if false: change a variable -> check conditions
    inserted_conditions = string_replace(conditions, variable_dict)
    while not parse_expr(latex_to_sympy(inserted_conditions), transformations=standard_transformations +
                         (convert_xor, implicit_multiplication_application,), global_dict=None, evaluate=True):
        variable_to_change = choice(list(variable_dict.keys()))  # Chose a random key from variable_dict
        if domain_list[variable_to_change]:
            variable_dict[variable_to_change] = make_number_from_list(domain_dict[variable_to_change])
        else:
            variable_dict[variable_to_change] = new_random_value(variable_to_change, domain_dict)
        inserted_conditions = string_replace(conditions, variable_dict)
    return variable_dict
Exemplo n.º 6
0
def make_number_from_list(domain):
    return sympify(latex_to_sympy(choice(domain)))