Exemplo n.º 1
0
def level_03(q_subkind, **options):

    a = randomly.integer(1, 10)
    b = randomly.integer(1, 10)

    steps = []

    if q_subkind in [
            'sum_square', 'sum_square_mixed', 'difference_square',
            'difference_square_mixed'
    ]:
        # __
        first_term = Monomial(('+', Item(('+', a, 2)).evaluate(), 2))

        second_term = Monomial(
            ('+', Item(('+', Product([2, a, b]).evaluate(), 1)).evaluate(), 1))

        third_term = Monomial(('+', Item(('+', b, 2)).evaluate(), 0))

        if q_subkind in ['difference_square', 'difference_square_mixed']:
            second_term.set_sign('-')

        if q_subkind in ['sum_square_mixed', 'difference_square_mixed']:
            ordered_expression = Polynomial(
                [first_term, second_term, third_term])

            [first_term, second_term,
             third_term] = randomly.mix([first_term, second_term, third_term])

        steps.append(Polynomial([first_term, second_term, third_term]))

        if q_subkind in ['sum_square_mixed', 'difference_square_mixed']:
            steps.append(ordered_expression)

        sq_a_monom = Monomial(('+', a, 1))
        sq_b_monom = Monomial(('+', b, 0))

        let_a_eq = Equality([Item('a'), sq_a_monom])

        let_b_eq = Equality([Item('b'), sq_b_monom])

        steps.append(
            _("Let") + " " + let_a_eq.into_str(force_expression_markers=True) +
            " " + _("and") + " " +
            let_b_eq.into_str(force_expression_markers=True))

        sq_a_monom.set_exponent(2)
        sq_b_monom.set_exponent(2)

        a_square_eq = Equality(
            [Item(('+', 'a', 2)), sq_a_monom,
             sq_a_monom.reduce_()])

        b_square_eq = Equality(
            [Item(('+', 'b', 2)), sq_b_monom,
             sq_b_monom.reduce_()])

        steps.append(
            _("then") + " " +
            a_square_eq.into_str(force_expression_markers=True))

        steps.append(
            _("and") + " " +
            b_square_eq.into_str(force_expression_markers=True))

        two_times_a_times_b_numeric = Product(
            [Item(2), Monomial(('+', a, 1)),
             Item(b)])

        two_times_a_times_b_reduced = two_times_a_times_b_numeric.reduce_()

        two_times_a_times_b_eq = Equality([
            Product([Item(2), Item('a'), Item('b')]),
            two_times_a_times_b_numeric, two_times_a_times_b_reduced
        ])

        steps.append(
            _("and") + " " +
            two_times_a_times_b_eq.into_str(force_expression_markers=True))

        steps.append(_("So it is possible to factorize:"))

        if q_subkind in ['difference_square', 'difference_square_mixed']:
            b = -b

        factorized_expression = Sum([Monomial(('+', a, 1)), Item(b)])
        factorized_expression.set_exponent(2)

        steps.append(factorized_expression)

    elif q_subkind in ['squares_difference', 'squares_difference_mixed']:
        # To have some (ax)² - b² but also sometimes b² - (ax)²:
        degrees = [2, 0, 1, 0]

        if randomly.integer(1, 10) >= 8:
            degrees = [0, 2, 0, 1]

        first_term = Monomial(('+', Item(('+', a, 2)).evaluate(), degrees[0]))

        second_term = Monomial(('-', Item(('+', b, 2)).evaluate(), degrees[1]))

        sq_first_term = Monomial(('+', Item(
            ('+', a, 1)).evaluate(), degrees[2]))

        sq_second_term = Monomial(('-', Item(
            ('+', b, 1)).evaluate(), degrees[3]))

        # The 'mixed' cases are: -b² + (ax)² and -(ax)² + b²
        if q_subkind == 'squares_difference_mixed':
            [first_term, second_term] = randomly.mix([first_term, second_term])
            [sq_first_term,
             sq_second_term] = randomly.mix([sq_first_term, sq_second_term])

        positive_sq_first = sq_first_term.clone()
        positive_sq_first.set_sign('+')
        positive_sq_second = sq_second_term.clone()
        positive_sq_second.set_sign('+')

        steps.append(Polynomial([first_term, second_term]))

        first_inter = None
        second_inter = None

        if sq_second_term.is_negative():
            first_inter = positive_sq_first.clone()
            first_inter.set_exponent(2)
            temp_second_inter = positive_sq_second.clone()
            temp_second_inter.set_exponent(2)
            second_inter = Product([-1, temp_second_inter])
        else:
            temp_first_inter = positive_sq_first.clone()
            temp_first_inter.set_exponent(2)
            first_inter = Product([-1, temp_first_inter])
            second_inter = positive_sq_second.clone()
            second_inter.set_exponent(2)

        steps.append(Sum([first_inter, second_inter]))

        if q_subkind == 'squares_difference_mixed':
            steps.append(Sum([second_inter, first_inter]))

        steps.append(_("So, this expression can be factorized:"))

        sum1 = None
        sum2 = None

        if sq_second_term.is_negative():
            sum1 = Sum([sq_first_term, sq_second_term])
            sq_second_term.set_sign('+')
            sum2 = Sum([sq_first_term, sq_second_term])

        else:
            sum1 = Sum([sq_second_term, sq_first_term])
            sq_first_term.set_sign('+')
            sum2 = Sum([sq_second_term, sq_first_term])

        lil_box = [sum1, sum2]

        steps.append(Product([randomly.pop(lil_box), randomly.pop(lil_box)]))

    elif q_subkind in [
            'fake_01', 'fake_01_mixed', 'fake_02', 'fake_02_mixed', 'fake_03',
            'fake_03_mixed', 'fake_04_A', 'fake_04_A_mixed', 'fake_04_B',
            'fake_04_B_mixed', 'fake_04_C', 'fake_04_C_mixed', 'fake_04_D',
            'fake_04_D_mixed'
    ]:
        # __
        straight_cases = [
            'fake_01', 'fake_02', 'fake_03', 'fake_04_A', 'fake_04_B',
            'fake_04_C', 'fake_04_D'
        ]
        match_pb_cases = [
            'fake_01', 'fake_02', 'fake_01_mixed', 'fake_02_mixed'
        ]
        sign_pb_cases = [
            'fake_03', 'fake_03_mixed', 'fake_04_A', 'fake_04_B', 'fake_04_C',
            'fake_04_D', 'fake_04_A_mixed', 'fake_04_B_mixed',
            'fake_04_C_mixed', 'fake_04_D_mixed'
        ]

        ax = Monomial(('+', a, 1))
        b_ = Monomial(('+', b, 0))

        ax_2 = ax.clone()
        ax_2.set_exponent(2)
        a2x2 = Monomial(('+', a * a, 2))

        b_2 = Monomial(('+', b, 0))
        b_2.set_exponent(2)

        b2 = Monomial(('+', b * b, 0))

        two_ax_b = Product([Item(2), Monomial(('+', a, 1)), Item(b)])

        twoabx = Monomial(('+', 2 * a * b, 1))

        fake_twoabx = Monomial(('+', a * b, 1))

        if randomly.integer(1, 10) >= 8:
            fake_twoabx = Monomial(
                ('+',
                 2 * a * b + randomly.pop([-1, 1]) * randomly.integer(1, 5),
                 1))
        first_term = None
        second_term = None
        third_term = None

        ordered_expression = None
        mixed_expression = None

        if q_subkind == 'fake_03' or q_subkind == 'fake_03_mixed':
            first_term = a2x2.clone()
            second_term = b2.clone()
            ordered_expression = Polynomial([first_term, second_term])
            mixed_expression = Polynomial([second_term, first_term])

        else:
            first_term = a2x2.clone()
            third_term = b2.clone()

            if q_subkind in [
                    'fake_01', 'fake_01_mixed', 'fake_02', 'fake_02_mixed'
            ]:
                # __
                second_term = fake_twoabx.clone()

            else:
                second_term = twoabx.clone()

            if q_subkind == 'fake_02' or q_subkind == 'fake_02_mixed':
                second_term.set_sign('-')

            elif q_subkind == 'fake_04_A' or q_subkind == 'fake_04_A_mixed':
                third_term.set_sign('-')

            elif q_subkind == 'fake_04_B' or q_subkind == 'fake_04_B_mixed':
                first_term.set_sign('-')

            elif q_subkind == 'fake_04_C' or q_subkind == 'fake_04_C_mixed':
                second_term.set_sign('-')
                third_term.set_sign('-')

            elif q_subkind == 'fake_04_D' or q_subkind == 'fake_04_D_mixed':
                first_term.set_sign('-')
                second_term.set_sign('-')

            ordered_expression = Polynomial(
                [first_term, second_term, third_term])

            mixed_expression = Polynomial(
                randomly.mix([first_term, second_term, third_term]))
        if q_subkind in straight_cases:
            steps.append(ordered_expression)

        elif q_subkind == 'fake_03_mixed':
            steps.append(mixed_expression)

        else:
            steps.append(mixed_expression)
            steps.append(ordered_expression)

        if q_subkind in match_pb_cases:
            let_a_eq = Equality([Item('a'), ax])

            let_b_eq = Equality([Item('b'), b_])

            steps.append(
                _("Let") + " " +
                let_a_eq.into_str(force_expression_markers=True) + " " +
                _("and") + " " +
                let_b_eq.into_str(force_expression_markers=True))

            a_square_eq = Equality([Item(('+', 'a', 2)), ax_2, a2x2])

            b_square_eq = Equality([Item(('+', 'b', 2)), b_2, b2])

            steps.append(
                _("then") + " " +
                a_square_eq.into_str(force_expression_markers=True))

            steps.append(
                _("and") + " " +
                b_square_eq.into_str(force_expression_markers=True))

            two_times_a_times_b_eq = Equality([
                Product([Item(2), Item('a'), Item('b')]), two_ax_b, twoabx,
                fake_twoabx
            ],
                                              equal_signs=['=', '=', 'neq'])

            steps.append(
                _("but") + " " +
                two_times_a_times_b_eq.into_str(force_expression_markers=True))

            steps.append(_("So it does not match a binomial identity."))
            steps.append(_("This expression cannot be factorized."))

        elif q_subkind in sign_pb_cases:
            steps.append(_("Because of the signs,"))
            steps.append(_("it does not match a binomial identity."))
            steps.append(_("This expression cannot be factorized."))

    return steps
Exemplo n.º 2
0
def level_01(q_subkind, **options):
    if q_subkind == 'default' \
       or q_subkind == 'three_terms' \
       or q_subkind == 'ax + b' \
       or q_subkind == 'ax² + b' \
       or q_subkind == 'ax² + bx':
        # __
        # the idea is to build the final factorized result first and to
        # expand it to get the question (and the solution's steps
        # in the same time)

        if q_subkind == 'default':
            common_factor = Monomial((RANDOMLY, 6, 1))
            # In order to reduce the number of cases where x² appears,
            # let the common factor be of degree 0 most of the time.
            common_factor.set_degree(
                randomly.integer(0, 1, weighted_table=[0.85, 0.15]))
        elif q_subkind in ['three_terms', 'ax + b', 'ax² + b']:
            common_factor = Monomial((RANDOMLY, 6, 0))

        elif q_subkind == 'ax² + bx':
            common_factor = Monomial((RANDOMLY, 6, 1))
            common_factor.set_degree(1)

        # to avoid having a situation like 1×(2x + 3) which isn't
        # factorizable:
        if common_factor.get_degree() == 0:
            common_factor.set_coeff(randomly.integer(2, 6))

        # signs are randomly chosen ; the only case that is to be avoided
        # is all signs are negative (then it wouldn't factorize well...
        # I mean then the '-' should be factorized and not left in the final
        # result)
        signs_box = [['+', '+'], ['+', '-']]
        signs = randomly.pop(signs_box)

        # this next test is to avoid -2x + 6 being factorized -2(x - 3)
        # which is not wrong but not "natural" to pupils
        # this test should be changed when a third term is being used.
        if signs == ['+', '-']:
            common_factor.set_sign('+')

        coeff_1 = randomly.integer(2, 10)
        coeff_2 = randomly.coprime_to(coeff_1, [i + 1 for i in range(10)])
        coeff_3 = None

        if q_subkind == 'three_terms':
            coeff_3 = randomly.coprime_to(coeff_1 * coeff_2,
                                          [i + 1 for i in range(9)])
            third_sign = randomly.sign()
            if third_sign == '-':
                common_factor.set_sign('+')

            signs.append(third_sign)

        lil_box = []
        lil_box.append(Monomial(('+', 1, 0)))

        if q_subkind == 'ax² + b':
            lil_box.append(Monomial(('+', 1, 2)))
        else:
            lil_box.append(Monomial(('+', 1, 1)))

        if ((common_factor.get_degree() == 0 and randomly.integer(1, 20) > 17
             and q_subkind == 'default') or q_subkind == 'three_terms'):
            # __
            lil_box.append(Monomial(('+', 1, 2)))

        first_term = randomly.pop(lil_box)
        second_term = randomly.pop(lil_box)
        third_term = None

        first_term.set_coeff(coeff_1)
        first_term.set_sign(randomly.pop(signs))
        second_term.set_coeff(coeff_2)
        second_term.set_sign(randomly.pop(signs))

        if q_subkind == 'three_terms':
            third_term = randomly.pop(lil_box)
            third_term.set_coeff(coeff_3)
            third_term.set_sign(randomly.pop(signs))
            if first_term.is_positive() and second_term.is_positive()\
               and third_term.is_positive():
                # __
                common_factor.set_sign(randomly.sign())

        if not (q_subkind == 'three_terms'):
            if common_factor.get_degree() == 0 \
               and first_term.get_degree() >= 1 \
               and second_term.get_degree() >= 1:
                # __
                if randomly.heads_or_tails():
                    first_term.set_degree(0)
                else:
                    second_term.set_degree(0)

        if q_subkind == 'three_terms':
            solution = Expandable(
                (common_factor, Sum([first_term, second_term, third_term])))

        else:
            solution = Expandable(
                (common_factor, Sum([first_term, second_term])))

        # now create the expanded step and the reduced step (which will
        # be given as a question)
        temp_steps = []
        current_step = solution.clone()

        while current_step is not None:
            temp_steps.append(current_step)
            current_step = current_step.expand_and_reduce_next_step()

        # now we put the steps in the right order
        steps = []
        for i in range(len(temp_steps)):
            steps.append(temp_steps[len(temp_steps) - 1 - i])

        return steps

    elif q_subkind == 'not_factorizable':
        signs_box = [['+', '+'], ['+', '-']]
        signs = randomly.pop(signs_box)

        coeff_1 = randomly.integer(2, 10)
        coeff_2 = randomly.coprime_to(coeff_1, [i + 1 for i in range(10)])

        lil_box = []
        lil_box.append(Monomial(('+', 1, 0)))
        lil_box.append(Monomial(('+', 1, 1)))
        lil_box.append(Monomial(('+', 1, 2)))

        first_term = randomly.pop(lil_box)
        second_term = randomly.pop(lil_box)

        first_term.set_coeff(coeff_1)
        first_term.set_sign(randomly.pop(signs))

        second_term.set_coeff(coeff_2)
        second_term.set_sign(randomly.pop(signs))

        if first_term.get_degree() >= 1 \
           and second_term.get_degree() >= 1:
            # __
            if randomly.heads_or_tails():
                first_term.set_degree(0)
            else:
                second_term.set_degree(0)

        steps = []
        solution = _("So far, we don't know if this expression can be "
                     "factorized.")
        steps.append(Sum([first_term, second_term]))
        steps.append(solution)

        return steps