class sub_object(object): def __init__(self, numbers_to_use, **options): nb_list = list(numbers_to_use) hole = Item(Value('...')) self.hidden_one = None visible_one = None self.product = Item(Product([nb_list[0], nb_list[1]]).evaluate()) if isinstance(nb_list[1], Fraction): self.hidden_one = nb_list[1] visible_one = nb_list[0] else: nb1 = randomly.pop(nb_list) nb2 = randomly.pop(nb_list) nb_list = [nb1, nb2] self.hidden_one = Item(randomly.pop(nb_list)) visible_one = randomly.pop(nb_list) factors = [visible_one, hole] self.holed_product = Product([randomly.pop(factors), randomly.pop(factors)]) self.holed_product.set_compact_display(False) def q(self, **options): m_expr = Equality([self.holed_product, self.product]).printed return _("Which number can fill the hole in: {math_expr}?")\ .format(math_expr=shared.machine.write_math_style2(m_expr)) def a(self, **options): return shared.machine.write_math_style2(self.hidden_one.printed)
def level_02(q_subkind, **options): max_coeff = 20 if 'max_coeff' in options and is_.an_integer(options['max_coeff']): max_coeff = options['max_coeff'] attribute_a_minus_sign = 'randomly' if 'minus_sign' in options and options['minus_sign']: attribute_a_minus_sign = 'yes' elif 'minus_sign' in options and not options['minus_sign']: attribute_a_minus_sign = 'no' # Creation of the objects # The three Monomials: ax², bx and c # Maybe we don't need to keep the integer values... a_val = randomly.integer(1, max_coeff) b_val = randomly.integer(1, max_coeff) c_val = randomly.integer(1, max_coeff) if q_subkind in [ 'type_1_A0', 'type_1_B0', 'type_1_C0', 'type_1_A1', 'type_1_B1', 'type_1_C1' ]: # __ c_val = randomly.integer(2, max_coeff) ax2 = Monomial((randomly.sign(), a_val, 2)) bx = Monomial((randomly.sign(), b_val, 1)) c = Monomial((randomly.sign(), c_val, 0)) # deg1: mx + p # and we need two of them deg1 = [] for i in range(2): deg1_mx = Monomial((randomly.sign(), randomly.integer(1, max_coeff), 1)) deg1_p = None if q_subkind in [ 'type_1_A0', 'type_1_B0', 'type_1_C0', 'type_1_D0', 'type_1_E0', 'type_1_F0', 'type_1_G0', 'type_1_H0', 'type_1_I0', 'type_1_A1', 'type_1_B1', 'type_1_D1', 'type_1_E1', 'type_1_G1', 'type_1_H1', 'type_4_A0' ]: # __ deg1_p = Monomial( (randomly.sign(), randomly.integer(1, max_coeff), 0)) else: deg1_p = Monomial( (randomly.sign(), randomly.integer(0, max_coeff), 0)) if not deg1_p.is_null(): lil_box = [deg1_mx, deg1_p] deg1.append( Polynomial([randomly.pop(lil_box), randomly.pop(lil_box)])) else: deg1.append(deg1_mx) # deg2: mx² + px + r # and we also need two of them deg2 = [] for i in range(2): deg2_mx2 = Monomial((randomly.sign(), randomly.integer(1, max_coeff), 2)) deg2_px = None deg2_r = None if q_subkind in [ 'type_1_A0', 'type_1_B0', 'type_1_C0', 'type_1_D0', 'type_1_E0', 'type_1_F0', 'type_1_G0', 'type_1_H0', 'type_1_I0', 'type_1_A1', 'type_1_B1', 'type_1_D1', 'type_1_E1', 'type_1_G1', 'type_1_H1' ]: # __ if randomly.heads_or_tails(): deg2_px = Monomial( (randomly.sign(), randomly.integer(1, max_coeff), 1)) deg2_r = Monomial( (randomly.sign(), randomly.integer(0, max_coeff), 0)) else: deg2_px = Monomial( (randomly.sign(), randomly.integer(0, max_coeff), 1)) deg2_r = Monomial( (randomly.sign(), randomly.integer(1, max_coeff), 0)) else: deg2_px = Monomial( (randomly.sign(), randomly.integer(0, max_coeff), 1)) deg2_r = Monomial( (randomly.sign(), randomly.integer(0, max_coeff), 0)) lil_box = [deg2_mx2] if not deg2_px.is_null(): lil_box.append(deg2_px) if not deg2_r.is_null(): lil_box.append(deg2_r) monomials_list_for_deg2 = [] for i in range(len(lil_box)): monomials_list_for_deg2.append(randomly.pop(lil_box)) deg2.append(Polynomial(monomials_list_for_deg2)) # Let's attribute the common factor C according to the required type # (NB: expression ± C×F1 ± C×F2) C = None if q_subkind in [ 'type_1_A0', 'type_1_B0', 'type_1_C0', 'type_1_A1', 'type_1_B1' ]: # __ C = c elif q_subkind in [ 'type_1_D0', 'type_1_E0', 'type_1_F0', 'type_1_D1', 'type_1_E1' ]: # __ C = bx elif q_subkind in [ 'type_1_G0', 'type_1_H0', 'type_1_I0', 'type_1_G1', 'type_1_H1' ]: # __ C = ax2 elif q_subkind in [ 'type_2_A0', 'type_2_B0', 'type_2_C0', 'type_2_A1', 'type_2_B1', 'type_4_A0' ]: # __ C = Polynomial([bx, c]) elif q_subkind in [ 'type_2_D0', 'type_2_E0', 'type_2_F0', 'type_2_D1', 'type_2_E1' ]: # __ C = Polynomial([ax2, c]) elif q_subkind in [ 'type_3_A0', 'type_3_B0', 'type_3_C0', 'type_3_A1', 'type_3_B1' ]: # __ C = Polynomial([ax2, bx, c]) # Let's attribute F1 and F2 according to the required type # (NB: expression ± C×F1 ± C×F2) F1 = None F2 = None if q_subkind in [ 'type_1_A0', 'type_1_A1', 'type_1_D0', 'type_1_D1', 'type_1_G0', 'type_1_G1', 'type_2_A0', 'type_2_A1', 'type_2_D0', 'type_2_D1', 'type_3_A0', 'type_3_A1' ]: # __ F1 = deg1[0] F2 = deg1[1] elif q_subkind in [ 'type_1_B0', 'type_1_B1', 'type_1_E0', 'type_1_E1', 'type_1_H0', 'type_1_H1', 'type_2_B0', 'type_2_B1', 'type_2_E0', 'type_2_E1', 'type_3_B0', 'type_3_B1' ]: # __ F1 = deg2[0] F2 = deg2[1] elif q_subkind in [ 'type_1_C0', 'type_1_F0', 'type_1_I0', 'type_2_C0', 'type_2_F0', 'type_3_C0' ]: # __ F1 = deg1[0] F2 = deg2[0] # The special case type_4_A0: (ax+b)² + (ax+b)×deg1' # aka C² + C×F1 elif q_subkind == 'type_4_A0': F1 = C.clone() F2 = deg1[0] # Let's put a "1" somewhere in the type_*_*1 if q_subkind in [ 'type_1_A1', 'type_1_D1', 'type_1_G1', 'type_2_A1', 'type_2_D1', 'type_3_A1', 'type_1_B1', 'type_1_E1' 'type_1_H1', 'type_2_B1', 'type_2_E1', 'type_3_B1' ]: # __ if randomly.heads_or_tails(): F1 = Item(1) else: F2 = Item(1) # Let's possibly attribute a minus_sign # (NB: expression ± C×F1 ± C×F2) minus_sign = None # this will contain the name of the factor having # a supplementary minus sign in such cases: # C×F1 - C×F2# - C×F1 + C×F2 # in all the following cases, it doesn't bring anything to attribute # a minus sign if ((q_subkind in ['type_1_A0', 'type_1_B0', 'type_1_C0', 'type_1_A1', 'type_1_B1'] and c_val < 0) or ((q_subkind in ['type_1_D0', 'type_1_E0', 'type_1_F0', 'type_1_D1', 'type_1_E1']) and b_val < 0) or ((q_subkind in ['type_1_G0', 'type_1_H0', 'type_1_I0', 'type_1_G1', 'type_1_H1']) and a_val < 0)): # __ pass # here we let minus_sign equal to None # otherwise, let's attribute one randomly, # depending on attribute_a_minus_sign else: if attribute_a_minus_sign in ['yes', 'randomly']: # __ if (attribute_a_minus_sign == 'yes' or randomly.heads_or_tails()): # __ if randomly.heads_or_tails(): minus_sign = "F1" else: minus_sign = "F2" else: pass # here we let minus_sign equal to None # Now let's build the expression ! expression = None box_product1 = [C, F1] box_product2 = [C, F2] if q_subkind == 'type_4_A0': CF1 = Product([C]) CF1.set_exponent(Value(2)) else: CF1 = Product([randomly.pop(box_product1), randomly.pop(box_product1)]) CF2 = Product([randomly.pop(box_product2), randomly.pop(box_product2)]) if minus_sign == "F1": if len(F1) >= 2: CF1 = Expandable((Item(-1), CF1)) else: CF1 = Product([Item(-1), CF1]) elif minus_sign == "F2": if len(F2) >= 2: CF2 = Expandable((Item(-1), CF2)) else: CF2 = Product([Item(-1), CF2]) expression = Sum([CF1, CF2]) # Now let's build the factorization steps ! steps = [] steps.append(expression) F1F2_sum = None if minus_sign is None: F1F2_sum = Sum([F1, F2]) elif minus_sign == "F1": if len(F1) >= 2: F1F2_sum = Sum([Expandable((Item(-1), F1)), F2]) else: F1F2_sum = Sum([Product([Item(-1), F1]), F2]) elif minus_sign == "F2": if len(F2) >= 2: F1F2_sum = Sum([F1, Expandable((Item(-1), F2))]) else: F1F2_sum = Sum([F1, Product([Item(-1), F2])]) temp = Product([C, F1F2_sum]) temp.set_compact_display(False) steps.append(temp) F1F2_sum = F1F2_sum.expand_and_reduce_next_step() while F1F2_sum is not None: steps.append(Product([C, F1F2_sum])) F1F2_sum = F1F2_sum.expand_and_reduce_next_step() # This doesn't fit the need, because too much Products are # wrongly recognized as reducible ! if steps[len(steps) - 1].is_reducible(): steps.append(steps[len(steps) - 1].reduce_()) return steps
def test_7_times_product_minusa_minusb_bis_printed(): """Is this Product correctly printed?""" p1 = Product([Item(('-', "a")), Item(('+', "b"))]) p1.set_compact_display(False) p = Product([Item(7), p1]) assert p.printed == wrap_nb('7\\times (-a)\\times b')
def test_product_9_times_minus2a_times_4b_bis_printed(): """Is this Product correctly printed?""" p1 = Product([Item(-2), Item('a'), Item(4), Item('b')]) p1.set_compact_display(False) assert Product([Item(9), p1]).printed == \ wrap_nb('9\\times (-2)\\times a\\times 4\\times b')
def test_product_monom_minus1_times_minus7x_printed(): """Is this Product correctly printed?""" p = Product([Item(-1), Product([Monomial(('-', 7, 1))])]) p.set_compact_display(False) assert p.printed == wrap_nb('-1\\times (-7x)')
def test_mon_deg0_by_mon_deg0_notcompact_printed(): """Is this Product correctly printed?""" p = Product([Monomial((4, 0)), Monomial((-3, 0))]) p.set_compact_display(False) assert p.printed == wrap_nb('4\\times (-3)')
def test_1_by_7x_is_reducible(): """Is Product([Item(1), (Monomial((7, 1)))]) reducible?""" p = Product([Item(1), (Monomial((7, 1)))]) p.set_compact_display(False) assert p.is_reducible()
def test_2_by_1_is_reducible(): """Is Product([Item(2), (Item(1))]) reducible?""" p = Product([Item(2), (Item(1))]) p.set_compact_display(False) assert p.is_reducible()
def test_a_by_negb_bis_is_reducible(): """Is this Product reducible?""" p = Product([Item('a'), Item(('+', "-b", 1))]) p.set_compact_display(False) assert p.is_reducible()