def test_product_sum_2_3x_times_sum_minus4_6x_is_not_reducible(): """Is this Product not reducible?""" p = Product([ Sum([Item(2), Monomial(('+', 3, 1))]), Sum([Item(-4), Monomial(('+', 6, 1))]) ]) assert not p.is_reducible()
def expP(): t = Sum([Expandable((Monomial(('+', 7, 0)), Sum([Monomial(('-', 6, 1)), Monomial((6, 0))]))), BinomialIdentity((Monomial(('-', 10, 1)), Monomial(('-', 3, 0))), difference_square='OK')]) return Expression("P", t)
def test_complicated_sum_02(): """Is this Sum correctly printed as (6+x)^{2}+12(2+11x)?""" assert Sum([ BinomialIdentity((Monomial(('+', 6, 0)), Monomial(('+', 1, 1)))), Expandable( (Monomial(('+', 12, 0)), Sum([Polynomial([Monomial(('+', 2, 0)), Monomial(('+', 11, 1))])]))) ]).printed == wrap_nb('(6+x)^{2}+12(2+11x)')
def expN(): t = Sum([Expandable((Monomial(('-', 1, 0)), Expandable((Sum([Monomial((2, 1)), Monomial((9, 0))]), Sum([Monomial((-3, 1)), Monomial((-7, 0))]))))), Expandable((Monomial((4, 0)), Sum([Monomial((-3, 1)), Monomial((9, 0))]))), Monomial((13, 0))]) return Expression("N", t)
def __init__(self, numbers_to_use, **options): super().setup("minimal", **options) super().setup("numbers", nb=numbers_to_use, **options) super().setup("nb_variants", nb=numbers_to_use, **options) the_sum = Sum([self.nb1, self.nb2]) self.sum_str = the_sum.printed self.result = the_sum.evaluate() if self.context == 'mini_problem': super().setup("mini_problem_wording", q_id=os.path.splitext(os.path.basename(__file__))[0], **options)
def big_product(): s = Sum(['x', 3]) s.set_exponent(3) p = Product(Monomial((1, 2))) p.set_exponent(3) p1 = Product([2, 3]) p1.set_exponent(3) return Product([ Monomial((2, 1)), Monomial((-4, 2)), s, Item(5), p, Item(('+', -1, 2)), p1 ])
def complicated_sum_to_reduce(): return Sum([ Monomial(('+', 3, 1)), Item(4), Sum([ Monomial(('+', 3, 1)), Monomial(('+', 5, 2)), Product([Item(-7), Item('a'), Item('b')]) ]), Product([Item('-a'), Item('b')]), Monomial(('+', 5, 2)), Item(2), Monomial(('-', 2, 1)), Product([Item(2), Item('a'), Item('b')]) ])
def expI(): t = Sum([Monomial(('+', 4, 1)), Expandable((Monomial(('+', 1, 0)), Polynomial([Monomial(('-', 15, 1)), Monomial(('+', 8, 0)), Monomial(('-', 5, 1))])))]) return Expression("I", t)
def __init__(self, numbers_to_use, **options): super().setup("minimal", **options) super().setup("numbers", nb=numbers_to_use, **options) super().setup("nb_variants", nb=numbers_to_use, **options) ## # @todo Leave it possible to have negative results (relative nb) self.nb1, self.nb2 = max(self.nb1, self.nb2), min(self.nb1, self.nb2) the_diff = Sum([self.nb1, -self.nb2]) self.diff_str = the_diff.printed self.result = the_diff.evaluate() if self.context == 'mini_problem': super().setup("mini_problem_wording", q_id=os.path.splitext(os.path.basename(__file__))[0], **options)
def test_eq23_autoresolution(): """Is this Equation correctly auto-resolved?""" eq = Equation( (Item(5), Sum([ Expandable( (Item(1), Sum([Monomial(('+', 1, 1)), Monomial(('-', 2, 0))]))), Item(7) ])), number=1) assert eq.auto_resolution() == wrap_nb('$(\\text{E}_{1}): $' '\[5=(x-2)+7\]' '\[5=x-2+7\]' '\[5=x+5\]' '\[x=5-5\]' '\[x=0\]')
def test_eq17_autoresolution(): """Is this Equation correctly auto-resolved?""" eq = Equation( (Expandable((Item(-1), Sum([Monomial( (-11, 1)), Item(-10)]))), Sum([ Expandable((Item(1), Sum([Item(-15), Monomial((12, 1))]))), Item(-1) ])), number=1) assert eq.auto_resolution() == wrap_nb('$(\\text{E}_{1}): $' '\[-(-11x-10)=(-15+12x)-1\]' '\[11x+10=-15+12x-1\]' '\[11x+10=-15-1+12x\]' '\[11x+10=-16+12x\]' '\[11x-12x=-16-10\]' '\[(11-12)x=-26\]' '\[-x=-26\]' '\[x=26\]')
def test_eq16_autoresolution(): """Is this Equation correctly auto-resolved?""" eq = Equation((Sum([ Monomial(('+', 9, 1)), Expandable((Monomial( ('+', 9, 0)), Sum([Monomial( ('-', 4, 0)), Monomial(('-', 1, 1))]))) ]), Item(8)), number=1) assert eq.auto_resolution() == wrap_nb('$(\\text{E}_{1}): $' '\[9x+9(-4-x)=8\]' '\[9x+9\\times (-4)+9\\times ' '(-x)=8\]' '\[9x-36-9x=8\]' '\[(9-9)x-36=8\]' '\[0x-36=8\]' '\[-36=8\]' 'This equation has no solution.' '\\newline ')
def test_eq18_autoresolution(): """Is this Equation correctly auto-resolved?""" eq = Equation((Sum([ Monomial(('-', 8, 0)), Monomial(('+', 9, 0)), Monomial(('-', 1, 0)) ]), Expandable((Item(10), Sum([Item(-2), Monomial((-12, 1))])))), number=1) assert eq.auto_resolution() == \ wrap_nb('$(\\text{E}_{1}): $' '\[-8+9-1=10(-2-12x)\]' '\[0=10\\times (-2)+10\\times (-12x)\]' '\[0=-20-120x\]' '\[120x=-20\]' '\[x=-\\frac{20}{120}\]' '\[x=-\\frac{\\bcancel{10}\\times' ' 2}{\\bcancel{10}\\times 12}\]' '\[x=-\\frac{\\bcancel{2}}' '{\\bcancel{2}\\times 6}\]' '\[x=-\\frac{1}{6}\]')
def test_eq25_autoresolution(): """Is this Equation correctly auto-resolved?""" eq = Equation((Item( ('+', 5, 2)), Sum([Item( ('+', 4, 2)), Monomial(('+', 1, 1))])), number=1) assert eq.auto_resolution(dont_display_equations_name=True) == \ wrap_nb('\[5^{2}=4^{2}+x\]' '\[25=16+x\]' '\[x=25-16\]' '\[x=9\]')
def test_eq20_autoresolution(): """Is this Equation correctly auto-resolved?""" eq = Equation( (Sum([Monomial(('+', 5, 1))]), Sum([ Expandable( (Item(1), Sum([Monomial(('+', 2, 0)), Monomial(('-', 5, 1))]))), Monomial(('-', 2, 0)) ])), number=1) assert eq.auto_resolution() == wrap_nb('$(\\text{E}_{1}): $' '\[5x=(2-5x)-2\]' '\[5x=2-5x-2\]' '\[5x=2-2-5x\]' '\[5x=-5x\]' '\[5x+5x=0\]' '\[(5+5)x=0\]' '\[10x=0\]' '\[x=0\]')
def test_eq14_autoresolution(): """Is this Equation correctly auto-resolved?""" eq = Equation((Sum([Monomial(('+', 3, 0)), Monomial(('+', 10, 1))]), Monomial(('+', 10, 1)))) assert eq.auto_resolution() == wrap_nb('$(\\text{E}): $' '\[3+10x=10x\]' '\[10x-10x=-3\]' '\[(10-10)x=-3\]' '\[0x=-3\]' '\[0=-3\]' 'This equation has no solution.' '\\newline ')
def test_eq22_autoresolution(): """Is this Equation correctly auto-resolved?""" eq = Equation((Sum([ Expandable( (Item(3), Sum([Monomial( ('-', 9, 0)), Monomial(('+', 6, 1))]))), Item(-8) ]), Sum([Item(9)])), number=1) assert eq.auto_resolution() == wrap_nb('$(\\text{E}_{1}): $' '\[3(-9+6x)-8=9\]' '\[3\\times (-9)+3\\times 6x-8=9\]' '\[-27+18x-8=9\]' '\[-27-8+18x=9\]' '\[-35+18x=9\]' '\[18x=9+35\]' '\[18x=44\]' '\[x=\\frac{44}{18}\]' '\[x=\\frac{\\bcancel{2}\\times 22}' '{\\bcancel{2}\\times 9}\]' '\[x=\\frac{22}{9}\]')
def test_eq21_autoresolution(): """Is this Equation correctly auto-resolved?""" eq = Equation((Sum([Monomial(('-', 1, 0)), Monomial(('-', 4, 1))]), Monomial(('-', 9, 0)))) assert eq.auto_resolution() == wrap_nb('$(\\text{E}): $' '\[-1-4x=-9\]' '\[-4x=-9+1\]' '\[-4x=-8\]' '\[x=\\frac{-8}{-4}\]' '\[x=\\frac{+\\bcancel{4}\\times 2}' '{+\\bcancel{4}}\]' '\[x=2\]')
def test_eq19_autoresolution(): """Is this Equation correctly auto-resolved?""" eq = Equation( (Sum([ Monomial(('-', 1, 1)), Monomial(('-', 2, 1)), Monomial(('+', 7, 0)) ]), Expandable( (Item(1), Sum([Monomial( ('+', 7, 1)), Monomial(('+', 5, 0))])))), number=1) assert eq.auto_resolution() == wrap_nb('$(\\text{E}_{1}): $' '\[-x-2x+7=(7x+5)\]' '\[(-1-2)x+7=7x+5\]' '\[-3x+7=7x+5\]' '\[-3x-7x=5-7\]' '\[(-3-7)x=-2\]' '\[-10x=-2\]' '\[x=\\frac{-2}{-10}\]' '\[x=\\frac{+\\bcancel{2}}' '{+\\bcancel{2}\\times 5}\]' '\[x=\\frac{1}{5}\]')
def test_eq39_autoresolution(): """Is this Equation correctly auto-resolved?""" eq = Equation((Sum([ Monomial((Fraction((Item(2), Item(1))).simplified(), 1)), Fraction((Item(1), Item(5))) ]), Fraction(('-', Item(4), Item(5))))) assert eq.auto_resolution(dont_display_equations_name=True) == \ wrap_nb('\[2x+\\frac{1}{5}=-\\frac{4}{5}\]' '\[2x=-\\frac{4}{5}-\\frac{1}{5}\]' '\[2x=\\frac{-4-1}{5}\]' '\[2x=-\\frac{5}{5}\]' '\[2x=-\\frac{\\bcancel{5}}{\\bcancel{5}}\]' '\[2x=-1\]' '\[x=-\\frac{1}{2}\]')
def test_eq29_autoresolution(): """Is this Equation correctly auto-resolved?""" eq = Equation( (Monomial(('+', 1, 1)), Sum([Fraction((Item(1), Item(4))), Fraction((Item(1), Item(8)))])), number=1) assert eq.auto_resolution(decimal_result=2) == \ wrap_nb('$(\\text{E}_{1}): $' '\[x=\\frac{1}{4}+\\frac{1}{8}\]' '\[x=\\frac{1\\times 2}{4\\times 2}' '+\\frac{1}{8}\]' '\[x=\\frac{2}{8}+\\frac{1}{8}\]' '\[x=\\frac{2+1}{8}\]' '\[x=\\frac{3}{8}\]' '\[x\\simeq0.38\]')
def test_eq36_autoresolution(): """Is this Equation correctly auto-resolved?""" eq = Equation((Item( ('+', "EF", 2)), Sum([Item( ('+', 60, 2)), Item(('+', 91, 2))])), number=1, variable_letter_name="AB") assert eq.auto_resolution(dont_display_equations_name=True, pythagorean_mode=True, unit='cm') == \ wrap_nb('\[\\text{EF}^{2}=60^{2}+91^{2}\]' '\[\\text{EF}^{2}=3600+8281\]' '\[\\text{EF}^{2}=11881\]' '\[\\text{EF}=' '\\sqrt{\mathstrut 11881}' '\\text{ because \\text{EF} ' 'is positive.}\]' '\[\\text{EF}=109\\text{ cm}\]')
def test_eq35_autoresolution(): """Is this Equation correctly auto-resolved?""" eq = Equation((Item( ('+', 73, 2)), Sum([Item( ('+', 48, 2)), Item(('+', "AB", 2))])), number=1, variable_letter_name="AB") assert eq.auto_resolution(dont_display_equations_name=True, decimal_result=2, pythagorean_mode=True) == \ wrap_nb('\[73^{2}=48^{2}+\\text{AB}^{2}\]' '\[5329=2304+\\text{AB}^{2}\]' '\[\\text{AB}^{2}=5329-2304\]' '\[\\text{AB}^{2}=3025\]' '\[\\text{AB}=' '\\sqrt{\mathstrut 3025}' '\\text{ because \\text{AB} ' 'is positive.}\]' '\[\\text{AB}=55\]')
def put_term_in_lexicon(provided_key, associated_coeff, lexi): from mathmaker.lib.core.base_calculus import Sum # This flag will remain False as long as the key isn't found in the lexicon key_s_been_found = False # We check the lexicon's keys one after the other # IMPORTANT NOTICE: the 'in' operator can't be used because it returns # True ONLY if the SAME OBJECT has been used as a key (and will return # False if another object of same kind and content is already there) for key in lexi: if provided_key == key: # it is important to use the key that was already there to put the # new coefficient in the lexicon lexi[key].append(associated_coeff) key_s_been_found = True if not key_s_been_found: new_coeff_sum = Sum([associated_coeff]) lexi[provided_key] = new_coeff_sum
def test_eq38_autoresolution(): """Is this Equation correctly auto-resolved?""" eq = Equation((Sum([ Monomial((Fraction((Item(1), Item(4))), 1)), Fraction((Item(1), Item(7))) ]), Fraction(('-', Item(3), Item(14))))) assert eq.auto_resolution(dont_display_equations_name=True) == \ wrap_nb('\[\\frac{1}{4}x+\\frac{1}{7}=-\\frac{3}{14}\]' '\[\\frac{1}{4}x=-\\frac{3}{14}-\\frac{1}{7}\]' '\[\\frac{1}{4}x=-\\frac{3}{14}-\\frac{1\\times 2}' '{7\\times 2}\]' '\[\\frac{1}{4}x=-\\frac{3}{14}-\\frac{2}{14}\]' '\[\\frac{1}{4}x=\\frac{-3-2}{14}\]' '\[\\frac{1}{4}x=-\\frac{5}{14}\]' '\[x=-\\frac{5}{14}\div \\frac{1}{4}\]' '\[x=-\\frac{5}{14}\\times \\frac{4}{1}\]' '\[x=-\\frac{5\\times 4}{14\\times 1}\]' '\[x=-\\frac{5\\times \\bcancel{2}\\times 2}' '{\\bcancel{2}\\times 7}\]' '\[x=-\\frac{10}{7}\]')
def __init__(self, q_kind='default_nothing', **options): self.derived = True # The call to the mother class __init__() method will set the # fields matching optional arguments which are so far: # self.q_kind, self.q_subkind # plus self.options (modified) Q_Structure.__init__(self, q_kind, AVAILABLE_Q_KIND_VALUES, **options) # The purpose of this next line is to get the possibly modified # value of **options options = self.options init_caller = INIT_CALLER[q_kind] self.expandable_objct = None self.numeric_aux = None if q_kind == 'any_basic_expd': randomly_drawn = randomly.decimal_0_1() if randomly_drawn <= 0.25: self.expandable_objct = Expandable((RANDOMLY, 'monom0_polyn1'), randomly_reversed=0.5) elif randomly_drawn <= 0.50: self.expandable_objct = Expandable((RANDOMLY, 'monom1_polyn1'), randomly_reversed=0.5) else: self.expandable_objct = Expandable((RANDOMLY, 'polyn1_polyn1')) elif q_kind in ['monom0_polyn1', 'monom1_polyn1']: self.expandable_objct = Expandable((RANDOMLY, q_kind), randomly_reversed=0.5) elif q_kind == 'monom01_polyn1': self.expandable_objct = Expandable( (RANDOMLY, randomly.pop(['monom0_polyn1', 'monom1_polyn1'])), randomly_reversed=0.5) elif q_kind == 'polyn1_polyn1': self.expandable_objct = Expandable((RANDOMLY, 'polyn1_polyn1')) elif q_kind == 'sum_of_any_basic_expd': if self.q_subkind in ['harder', 'with_a_binomial']: # __ choices = ['monom0_polyn1', 'monom1_polyn1'] drawn_types = list() drawn_types.append(randomly.pop(choices)) if self.q_subkind == 'with_a_binomial': drawn_types.append('any_binomial') else: drawn_types.append('minus_polyn1_polyn1') aux_expd_list = list() for t in drawn_types: if t == 'any_binomial': aux_expd_list.append( BinomialIdentity((RANDOMLY, 'any'), **options)) else: aux_expd_list.append(Expandable((RANDOMLY, t))) final_list = list() for i in range(len(aux_expd_list)): final_list.append(randomly.pop(aux_expd_list)) self.expandable_objct = Sum(final_list) elif self.q_subkind == 'easy': choices = ['monom0_polyn1', 'monom1_polyn1'] aux_expd_list = list() aux_expd_list.append( Expandable((RANDOMLY, randomly.pop(choices)))) if randomly.heads_or_tails(): aux_expd_list.append(Expandable((RANDOMLY, 'sign_exp'))) else: aux_expd_list.append( Monomial((RANDOMLY, 15, randomly.integer(0, 2)))) final_list = list() for i in range(len(aux_expd_list)): final_list.append(randomly.pop(aux_expd_list)) self.expandable_objct = Sum(final_list) else: choices = [ 'monom0_polyn1', 'monom0_polyn1', 'monom1_polyn1', 'monom1_polyn1', 'polyn1_polyn1', 'minus_polyn1_polyn1' ] drawn_types = list() drawn_types.append(randomly.pop(choices)) drawn_types.append(randomly.pop(choices)) aux_expd_list = list() for element in drawn_types: aux_expd_list.append(Expandable((RANDOMLY, element))) aux_expd_list.append(Monomial((RANDOMLY, 15, 2))) final_list = list() for i in range(len(aux_expd_list)): final_list.append(randomly.pop(aux_expd_list)) self.expandable_objct = Sum(final_list) elif q_kind in ['sign_expansion', 'sign_expansion_short_test']: sign_exp_kind = options.get('sign_exp_kind', 0) if q_kind == 'sign_expansion_short_test': sign_exp_kind = 1 if sign_exp_kind == 0: sign_exp_kind = randomly.integer(1, 5) # Creation of the terms aux_terms_list = list() aux_expd_1 = Expandable((Monomial( (randomly.sign(), 1, 0)), Polynomial((RANDOMLY, 15, 2, 2)))) aux_expd_2 = Expandable((Monomial( (randomly.sign(), 1, 0)), Polynomial((RANDOMLY, 15, 2, 2)))) aux_expd_3 = Expandable((Monomial( (randomly.sign(), 1, 0)), Polynomial((RANDOMLY, 15, 2, 2)))) long_aux_expd = Expandable((Monomial( (randomly.sign(), 1, 0)), Polynomial((RANDOMLY, 15, 2, 3)))) if q_kind == 'sign_expansion_short_test': long_aux_expd = Expandable((Monomial( ('-', 1, 0)), Polynomial((RANDOMLY, 15, 2, 3)))) aux_monomial = Monomial((RANDOMLY, 15, 2)) # 1st kind: a Monomial and ± (long Polynomial) # (like in a short test) if sign_exp_kind == 1: aux_terms_list.append(long_aux_expd) aux_terms_list.append(aux_monomial) # 2d kind: ± (x+3) ± (4x - 7) elif sign_exp_kind == 2: aux_terms_list.append(aux_expd_1) aux_terms_list.append(aux_expd_2) # 3d kind: ± (x+3) ± (4x - 7) ± (x² - 5x) elif sign_exp_kind == 3: aux_terms_list.append(aux_expd_1) aux_terms_list.append(aux_expd_2) aux_terms_list.append(aux_expd_3) # 4th kind: ± (x+3) ± (4x - 7) ± Monomial elif sign_exp_kind == 4: aux_terms_list.append(aux_expd_1) aux_terms_list.append(aux_expd_2) aux_terms_list.append(aux_monomial) # 5th kind: ± (x+3) ± Monomial ± (long Polynomial) elif sign_exp_kind == 5: aux_terms_list.append(aux_expd_2) aux_terms_list.append(aux_monomial) aux_terms_list.append(long_aux_expd) # add as many possibilities as wanted, # don't forget to increase the last number here: # sign_exp_kind = randomly.integer(1, 5) (what's a bit above) # Now let's distribute the terms randomly final_terms_list = list() for i in range(len(aux_terms_list)): final_terms_list.append(randomly.pop(aux_terms_list)) self.expandable_objct = Sum(final_terms_list) elif q_kind in [ 'numeric_sum_square', 'numeric_difference_square', 'numeric_squares_difference' ]: # __ self.expandable_objct = init_caller( (options['couple'][0], options['couple'][1]), **options) if q_kind in ['numeric_sum_square', 'numeric_difference_square']: self.numeric_aux = Sum( [options['couple'][0], options['couple'][1]]).reduce_() self.numeric_aux.set_exponent(2) else: # squares_difference's case aux1 = Sum([options['couple'][0], options['couple'][1]]).reduce_() temp = options['couple'][1].clone() temp.set_sign('-') aux2 = Sum([options['couple'][0], temp]).reduce_() self.numeric_aux = Product([aux1, aux2]) else: if q_kind == 'any_binomial': q_kind = 'any' self.expandable_objct = init_caller((RANDOMLY, q_kind), **options) # Creation of the expression: number = 0 if 'expression_number' in options \ and is_.a_natural_int(options['expression_number']): # __ number = options['expression_number'] self.expression = Expression(number, self.expandable_objct) if self.numeric_aux is not None: self.numeric_aux = Expression(number, self.numeric_aux)
def __init__(self, build_data, **options): super().setup("minimal", **options) super().setup("numbers", nb=build_data, **options) super().setup("nb_variants", nb=build_data, **options) self.transduration = 8 if (self.nb1 > 20 and self.nb2 > 20 and abs(self.nb1 - self.nb2) > 10 and abs(self.nb1 - self.nb2) % 10 != 0): self.transduration = 12 elif abs(self.nb1 - self.nb2) % 1 != 0: self.transduration = 10 if self.subvariant == 'only_positive': self.nb1, self.nb2 = max(self.nb1, self.nb2), min(self.nb1, self.nb2) if (options.get('nb_source', 'default').startswith('complement') and self.nb_variant.startswith('decimal')): self.nb1 //= 10 if (options.get('nb_source', 'default').startswith('complement') and random.choice([True, False])): self.nb2 = self.nb1 - self.nb2 the_diff = Sum([self.nb1, -self.nb2]) self.diff_str = the_diff.printed self.result = the_diff.evaluate() if self.context == 'mini_problem': self.transduration = 25 super().setup('mini_problem_wording', q_id=os.path.splitext(os.path.basename(__file__))[0], **options) elif self.context.startswith('complement_wording'): self.transduration = 12 super().setup('complement_wording', q_id=os.path.splitext(os.path.basename(__file__))[0], **options) elif self.context == 'angles': self.transduration = 25 deg = r'\textdegree' from mathmakerlib.geometry import AngleDecoration self.result = Number(self.nb1 - self.nb2) self.hint = deg required.package['xcolor'] = True required.options['xcolor'].add('dvipsnames') extra_deco = {'0:1': AngleDecoration(label='?', thickness='ultra thick', color='BrickRed', radius=Number('0.5', unit='cm')), } extra_deco2 = {} if self.nb1 != 90: extra_deco.update({'0:2': AngleDecoration(label=None, thickness='ultra thick', color='NavyBlue', radius=Number('1.6', unit='cm'), eccentricity=2, arrow_tips='<->')}) extra_deco2.update({'1:2': AngleDecoration(label=Number(self.nb1, unit=deg), do_draw=False, color='NavyBlue', radius=Number('1.6', unit='cm'))}) else: extra_deco.update({'0:2': AngleDecoration(label=None, radius=Number('0.25', unit='cm'))}) super().setup('angles_bunch', extra_deco=extra_deco, extra_deco2=extra_deco2, labels=nndist([self.nb1, self.nb2])[::-1], subvariant_nb=options.get('subvariant_nb', None), variant=options.get('variant', None), subtr_shapes=True) self.hint = r'\si{\degree}'
def neg2_inside_exp_sum_of_product_of_1plus1(): return Item(('+', -2, Sum([Product([Sum([1, 1])])])))
def neg3_inside_exp_2plus5(): return Item(('+', -3, Sum([-2, 5])))
def pos3_exp_2plus6(): return Item(('+', 3, Sum([-2, 6])))
def test_neg2_inside_exp_sum_of_product_of_sum_of_2_printed(): """Is Item(('+', -2, Sum([Product([Sum([2])])]))) correctly printed?""" assert Item(('+', -2, Sum([Product([Sum([2])])]))).printed == \ wrap_nb('(-2)^{2}')
def __init__(self, q_kind='default_nothing', **options): self.derived = True # The call to the mother class __init__() method will set the # fields matching optional arguments which are so far: # self.q_kind, self.q_subkind # plus self.options (modified) Q_Structure.__init__(self, q_kind, AVAILABLE_Q_KIND_VALUES, **options) # The purpose of this next line is to get the possibly modified # value of **options options = self.options # That's the number of the question, not of the expressions it might # contain ! self.number = "" if 'number_of_questions' in options: self.number = options['number_of_questions'] self.objct = None # 1st OPTION if q_kind == 'fraction_simplification': root = random.choices([n + 2 for n in range(19 - 2 + 1)], weights=[0.225, 0.225, 0, 0.2, 0, 0.2, 0, 0, 0, 0.07, 0, 0.0375, 0, 0, 0, 0.0375, 0, 0.005])[0] ten_power_factor1 = 1 ten_power_factor2 = 1 if 'with_ten_powers' in options \ and is_number(options['with_ten_powers']) \ and options['with_ten_powers'] <= 1 \ and options['with_ten_powers'] >= 0: # __ if random.random() < options['with_ten_powers']: ten_powers_list = [10, 10, 100, 100] random.shuffle(ten_powers_list) ten_power_factor1 = ten_powers_list.pop() ten_power_factor2 = ten_powers_list.pop() factors_list = [j + 1 for j in range(10)] random.shuffle(factors_list) self.objct = Fraction(('+', root * factors_list.pop() * ten_power_factor1, root * factors_list.pop() * ten_power_factor2)) # 2d & 3d OPTIONS # Fractions Products | Quotients elif q_kind in ['fractions_product', 'fractions_quotient']: # In some cases, the fractions will be generated # totally randomly if random.random() < 0: lil_box = [n + 2 for n in range(18)] a = random.choices( lil_box, weights=FRACTION_PRODUCT_AND_QUOTIENT_TABLE)[0] b = random.choices( lil_box, weights=FRACTION_PRODUCT_AND_QUOTIENT_TABLE)[0] lil_box = [n + 2 for n in range(18)] c = random.choices( lil_box, weights=FRACTION_PRODUCT_AND_QUOTIENT_TABLE)[0] d = random.choices( lil_box, weights=FRACTION_PRODUCT_AND_QUOTIENT_TABLE)[0] f1 = Fraction((random.choices(['+', '-'], cum_weights=[0.75, 1])[0], Item((random.choices(['+', '-'], cum_weights=[0.80, 1])[0], a)), Item((random.choices(['+', '-'], cum_weights=[0.80, 1])[0], b)))) f2 = Fraction((random.choices(['+', '-'], cum_weights=[0.75, 1])[0], Item((random.choices(['+', '-'], cum_weights=[0.80, 1])[0], c)), Item((random.choices(['+', '-'], cum_weights=[0.80, 1])[0], d)))) # f1 = f1.simplified() # f2 = f2.simplified() # In all other cases (80%), we'll define a "seed" a plus two # randomly numbers i and j to form the Product | Quotient: # a×i / b × c / a × j # Where b is a randomly number coprime to a×i # and c is a randomly number coprime to a×j else: a = random.randint(2, 8) lil_box = [i + 2 for i in range(7)] random.shuffle(lil_box) i = lil_box.pop() j = lil_box.pop() b = random.choice(coprimes_to(a * i, [n + 2 for n in range(15)])) c = random.choice(not_coprimes_to(b, [n + 2 for n in range(30)], exclude=[a * j])) f1 = Fraction((random.choices(['+', '-'], cum_weights=[0.75, 1])[0], Item((random.choices(['+', '-'], cum_weights=[0.80, 1])[0], a * i)), Item((random.choices(['+', '-'], cum_weights=[0.80, 1])[0], b)))) f2 = Fraction((random.choices(['+', '-'], cum_weights=[0.75, 1])[0], Item((random.choices(['+', '-'], cum_weights=[0.80, 1])[0], c)), Item((random.choices(['+', '-'], cum_weights=[0.80, 1])[0], a * j)))) if random.choice([True, False]): f3 = f1.clone() f1 = f2.clone() f2 = f3.clone() if q_kind == 'fractions_quotient': f2 = f2.invert() if q_kind == 'fractions_product': self.objct = Product([f1, f2]) elif q_kind == 'fractions_quotient': self.objct = Quotient(('+', f1, f2, 1, 'use_divide_symbol')) # 4th OPTION # Fractions Sums elif q_kind == 'fractions_sum': randomly_position = random\ .choices([n for n in range(17)], weights=FRACTIONS_SUMS_SCALE_TABLE)[0] chosen_seed_and_generator = FRACTIONS_SUMS_TABLE[randomly_position] seed = random.randint(2, chosen_seed_and_generator[1]) # The following test is only intended to avoid having "high" # results too often. We just check if the common denominator # will be higher than 75 (arbitrary) and if yes, we redetermine # it once. We don't do it twice since we don't want to totally # forbid high denominators. if seed * chosen_seed_and_generator[0][0] \ * chosen_seed_and_generator[0][1] >= 75: # __ seed = random.randint(2, chosen_seed_and_generator[1]) lil_box = [0, 1] gen1 = chosen_seed_and_generator[0][lil_box.pop()] gen2 = chosen_seed_and_generator[0][lil_box.pop()] den1 = Item(gen1 * seed) den2 = Item(gen2 * seed) temp1 = random.randint(1, 20) temp2 = random.randint(1, 20) num1 = Item(temp1 // gcd(temp1, gen1 * seed)) num2 = Item(temp2 // gcd(temp2, gen2 * seed)) f1 = Fraction((random.choices(['+', '-'], cum_weights=[0.7, 1])[0], num1, den1)) f2 = Fraction((random.choices(['+', '-'], cum_weights=[0.7, 1])[0], num2, den2)) self.objct = Sum([f1.simplified(), f2.simplified()]) # 5th # still to imagine:o) # Creation of the expression: number = 0 if 'expression_number' in options \ and is_natural(options['expression_number']): # __ number = options['expression_number'] self.expression = Expression(number, self.objct)