def __init__(self, arg, **options): if not (type(arg) == list or isinstance(arg, Point)): raise error.WrongArgument(' list|Point ', str(type(arg))) elif type(arg) == list: if not len(arg) == 2: raise error.WrongArgument(' a list of length ' + str(len(arg)), ' a list of length 2 ') if not type(arg[0]) == str: raise error.WrongArgument(str(type(arg[0])), ' a str ') if not (type(arg[1]) == tuple and len(arg[1]) == 2 and is_.a_number(arg[1][0]) and is_.a_number(arg[1][1])): # __ raise error.WrongArgument(str(arg), ' (x, y) ') self._name = arg[0] self._x = Decimal(arg[1][0]) self._y = Decimal(arg[1][1]) else: self._name = arg.name self._x = arg.x self._y = arg.y self._x_exact = self._x self._y_exact = self._y
def label_display_angle(self, arg): if not is_.a_number(arg): raise error.WrongArgument(arg, ' a number ') else: self._label_display_angle = round(Decimal(str(arg)), Decimal('0.1'), rounding=ROUND_HALF_UP)
def rotate(self, center, angle, **options): if not isinstance(center, Point): raise error.WrongArgument(' a Point ', str(type(center))) if not is_.a_number(angle): raise error.WrongArgument(' a number ', str(type(angle))) delta_x = self.x_exact - center.x_exact delta_y = self.y_exact - center.y_exact rx = delta_x * Decimal(str(math.cos(deg_to_rad(angle)))) \ - delta_y * Decimal(str(math.sin(deg_to_rad(angle)))) \ + center.x_exact ry = delta_x * Decimal(str(math.sin(deg_to_rad(angle)))) \ + delta_y * Decimal(str(math.cos(deg_to_rad(angle)))) \ + center.y_exact new_name = self.name + "'" if 'keep_name' in options and options['keep_name']: new_name = self.name elif 'new_name' in options and type(options['new_name']) == str: new_name = options['new_name'] return Point([new_name, (rx, ry)])
def type_string(self, objct, **options): if isinstance(objct, Printable): options.update({'force_expression_begins': True}) return objct.into_str(**options) elif is_.a_number(objct) or is_.a_string(objct): return str(objct) else: raise error.UncompatibleType(objct, "String|Number|Printable")
def __init__(self, arg, **options): self._x_exact = Decimal('1') self._y_exact = Decimal('1') if isinstance(arg, Point): Point.__init__(self, Point(["", (arg.x_exact, arg.y_exact)]), **options) elif isinstance(arg, tuple) and len(arg) == 2: if all([isinstance(elt, Point) for elt in arg]): Point.__init__(self, Point(["", (arg[1].x_exact - arg[0].x_exact, arg[1].y_exact - arg[0].y_exact)])) elif all([is_.a_number(elt) for elt in arg]): Point.__init__(self, Point(["", (arg[0], arg[1])])) else: raise error.WrongArgument("a tuple not only of Points or" " numbers", "(Point,Point)|(x,y)") else: raise error.WrongArgument(str(type(arg)), "Point|(,)")
def __init__(self, x_kind='default_nothing', **options): self.derived = True X_Structure.__init__(self, x_kind, AVAILABLE_X_KIND_VALUES, X_LAYOUTS, X_LAYOUT_UNIT, **options) # The purpose of this next line is to get the possibly modified # value of **options options = self.options default_question = question.Q_AlgebraExpressionExpansion # TEXTS OF THE EXERCISE self.text = {'exc': _("Expand and reduce") + ": ", 'ans': ""} # alternate texts section if self.x_subkind == 'three_numeric_binomials': self.text = { 'exc': _("Calculate thanks to a binomial " "identity:"), 'ans': "" } # PREFORMATTED EXERCISES if self.x_kind == 'short_test': if self.x_subkind == 'sign_expansion': q = default_question(q_kind='sign_expansion_short_test', expression_number=self.start_number, **options) self.questions_list.append(q) elif self.x_subkind == 'medium_level': q = default_question(q_kind='monom01_polyn1', expression_number=self.start_number, **options) self.questions_list.append(q) q = default_question(q_kind='polyn1_polyn1', expression_number=self.start_number, **options) self.questions_list.append(q) q = default_question(q_kind='sum_of_any_basic_expd', expression_number=self.start_number, **options) self.questions_list.append(q) elif self.x_subkind == 'three_binomials': kinds_list = [ 'sum_square', 'difference_square', 'squares_difference' ] for i in range(3): q = default_question(q_kind=randomly.pop(kinds_list), expression_number=i, **options) self.questions_list.append(q) elif self.x_subkind == 'three_numeric_binomials': a_list1 = [20, 30, 40, 50, 60, 70, 80, 90, 100] a_list2 = [200, 300, 400, 500, 600, 700, 800, 1000] b_list = [1, 2, 3] a1_choice = randomly.pop(a_list2) b1_choice = randomly.pop(b_list) a2_choice = randomly.pop(a_list1) b2_choice = randomly.pop(b_list) a3_choice = randomly.pop(a_list1) b3_choice = randomly.pop(b_list) a1 = Monomial(('+', a1_choice, 0)) b1 = Monomial(('+', b1_choice, 0)) a2 = Monomial(('+', a2_choice, 0)) b2 = Monomial(('+', b2_choice, 0)) a3 = Monomial(('+', a3_choice, 0)) b3 = Monomial(('+', b3_choice, 0)) kinds_list = [ 'numeric_sum_square', 'numeric_difference_square', 'numeric_squares_difference' ] monomials_to_use = [(a1, b1), (a2, b2), (a3, b3)] ordered_kinds_list = [] squares_differences_option = [0, 0, 0] for i in range(3): ordered_kinds_list.append(randomly.pop(kinds_list)) if ordered_kinds_list[i] == 'numeric_difference_square': monomials_to_use[i][1].set_sign('-') elif ordered_kinds_list[i] == 'numeric_squares_difference': squares_differences_option[i] = 1 for i in range(3): if squares_differences_option[i] == 1: q = default_question(q_kind=ordered_kinds_list[i], couple=monomials_to_use[i], squares_difference=True, expression_number=i, **options) else: q = default_question(q_kind=ordered_kinds_list[i], couple=monomials_to_use[i], expression_number=i, **options) self.questions_list.append(q) else: # default short_test option if randomly.heads_or_tails(): q1 = default_question(q_kind='monom0_polyn1', expression_number=0 + self.start_number) q2 = default_question(q_kind='monom1_polyn1', expression_number=1 + self.start_number, reversed='OK') else: q1 = default_question(q_kind='monom0_polyn1', reversed='OK', expression_number=0 + self.start_number) q2 = default_question(q_kind='monom1_polyn1', expression_number=1 + self.start_number) q3 = default_question(q_kind='polyn1_polyn1', expression_number=2 + self.start_number) self.questions_list.append(q1) self.questions_list.append(q2) self.questions_list.append(q3) elif self.x_kind == 'mini_test': if self.x_subkind == 'two_expansions_hard': if randomly.heads_or_tails(): q1 = default_question(q_kind='sum_of_any_basic_expd', q_subkind='harder', expression_number=0 + self.start_number) q2 = default_question(q_kind='sum_of_any_basic_expd', q_subkind='with_a_binomial', expression_number=1 + self.start_number) else: q1 = default_question(q_kind='sum_of_any_basic_expd', q_subkind='with_a_binomial', expression_number=0 + self.start_number) q2 = default_question(q_kind='sum_of_any_basic_expd', q_subkind='harder', expression_number=1 + self.start_number) self.questions_list.append(q1) self.questions_list.append(q2) elif self.x_subkind == 'two_randomly': if randomly.heads_or_tails(): q = default_question(q_kind='sign_expansion_short_test', expression_number=self.start_number, **options) self.questions_list.append(q) q = default_question(q_kind='polyn1_polyn1', expression_number=self.start_number + 1, **options) self.questions_list.append(q) else: q = default_question(q_kind='monom01_polyn1', expression_number=self.start_number, **options) self.questions_list.append(q) q = default_question(q_kind='sum_of_any_basic_expd', q_subkind='easy', expression_number=self.start_number + 1, **options) self.questions_list.append(q) elif self.x_kind == 'preformatted': # Mixed expandable expressions from the following types: # 0-degree Monomial × (1st-degree Polynomial) # 1-degree Monomial × (1st-degree Polynomial) # The Monomial & the polynomial may be swapped: it depends # if the option 'reversed' has been given in # argument in this method if self.x_subkind == 'mixed_monom_polyn1': choices_list = list() ratio = DEFAULT_RATIO_MIXED_MONOM_POLYN1 if 'ratio_mmp' in options \ and is_.a_number(options['ratio_mmp']) \ and options['ratio_mmp'] > 0 \ and options['ratio_mmp'] < 1: # __ ratio = options['ratio_mmp'] else: raise error.ArgumentNeeded("the ratio_mmp option " "because the " "mixed_monom_polyn1 option " "has been specified.") for i in range(int(self.q_nb * ratio) + 1): choices_list.append('monom0_polyn1') for i in range(int(self.q_nb - self.q_nb * ratio)): choices_list.append('monom1_polyn1') temp_nb = len(choices_list) for i in range(temp_nb): choice = randomly.pop(choices_list) if choice == 'monom0_polyn1': q = default_question(q_kind='monom0_polyn1', expression_number=i + self.start_number, **options) self.questions_list.append(q) else: q = default_question(q_kind='monom1_polyn1', expression_number=i + self.start_number, **options) self.questions_list.append(q) # OTHER EXERCISES else: for i in range(self.q_nb): q = default_question(q_kind=self.x_subkind, expression_number=i + self.start_number, **options) self.questions_list.append(q)
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 = randomly.integer(2, 19, weighted_table=[ 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 ]) factors_list = [j + 1 for j in range(10)] ten_power_factor1 = 1 ten_power_factor2 = 1 if 'with_ten_powers' in options \ and is_.a_number(options['with_ten_powers']) \ and options['with_ten_powers'] <= 1 \ and options['with_ten_powers'] >= 0: # __ if randomly.decimal_0_1() < options['with_ten_powers']: ten_powers_list = [10, 10, 100, 100] ten_power_factor1 = randomly.pop(ten_powers_list) ten_power_factor2 = randomly.pop(ten_powers_list) self.objct = Fraction( ('+', root * randomly.pop(factors_list) * ten_power_factor1, root * randomly.pop(factors_list) * 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 randomly.decimal_0_1() < 0: lil_box = [n + 2 for n in range(18)] a = randomly.pop( lil_box, weighted_table=FRACTION_PRODUCT_AND_QUOTIENT_TABLE) b = randomly.pop( lil_box, weighted_table=FRACTION_PRODUCT_AND_QUOTIENT_TABLE) lil_box = [n + 2 for n in range(18)] c = randomly.pop( lil_box, weighted_table=FRACTION_PRODUCT_AND_QUOTIENT_TABLE) d = randomly.pop( lil_box, weighted_table=FRACTION_PRODUCT_AND_QUOTIENT_TABLE) f1 = Fraction((randomly.sign(plus_signs_ratio=0.75), Item((randomly.sign(plus_signs_ratio=0.80), a)), Item( (randomly.sign(plus_signs_ratio=0.80), b)))) f2 = Fraction((randomly.sign(plus_signs_ratio=0.75), Item((randomly.sign(plus_signs_ratio=0.80), c)), Item( (randomly.sign(plus_signs_ratio=0.80), 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 = randomly.integer(2, 8) lil_box = [i + 2 for i in range(7)] i = randomly.pop(lil_box) j = randomly.pop(lil_box) b = randomly.coprime_to(a * i, [n + 2 for n in range(15)]) c = randomly.not_coprime_to(b, [n + 2 for n in range(30)], excepted=a * j) f1 = Fraction( (randomly.sign(plus_signs_ratio=0.75), Item((randomly.sign(plus_signs_ratio=0.80), a * i)), Item((randomly.sign(plus_signs_ratio=0.80), b)))) f2 = Fraction( (randomly.sign(plus_signs_ratio=0.75), Item((randomly.sign(plus_signs_ratio=0.80), c)), Item((randomly.sign(plus_signs_ratio=0.80), a * j)))) if randomly.heads_or_tails(): 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 = randomly\ .integer(0, 16, weighted_table=FRACTIONS_SUMS_SCALE_TABLE) chosen_seed_and_generator = FRACTIONS_SUMS_TABLE[randomly_position] seed = randomly.integer(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 = randomly.integer(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 = randomly.integer(1, 20) temp2 = randomly.integer(1, 20) num1 = Item(temp1 // gcd(temp1, gen1 * seed)) num2 = Item(temp2 // gcd(temp2, gen2 * seed)) f1 = Fraction((randomly.sign(plus_signs_ratio=0.7), num1, den1)) f2 = Fraction((randomly.sign(plus_signs_ratio=0.7), 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_.a_natural_int(options['expression_number']): # __ number = options['expression_number'] self.expression = Expression(number, self.objct)
def create_table(self, size, content, **options): n_col = size[1] n_lin = size[0] result = "" length_unit = 'cm' if 'unit' in options: length_unit = options['unit'] tabular_format = "" v_border = "" h_border = "" justify = ["" for _ in range(n_col)] new_line_sep = "\\\\" + "\n" min_row_height = "" # The last column is not centered vertically (LaTeX bug?) # As a workaround it's possible to add an extra empty column... extra_last_column = "" extra_col_sep = "" if 'justify' in options and type(options['justify']) == list: if not len(options['justify']) == n_col: raise ValueError("The number of elements of this list should " "be equal to the number of columns of the " "tabular.") new_line_sep = "\\tabularnewline" + "\n" extra_last_column = "@{}m{0pt}@{}" extra_col_sep = " & " justify = [] for i in range(n_col): if options['justify'][i] == 'center': justify.append(">{\centering}") elif options['justify'][i] == 'left': justify.append(">{}") else: raise ValueError("Expecting 'left' or 'center' as values " "of this list.") elif 'center' in options: new_line_sep = "\\tabularnewline" + "\n" extra_last_column = "@{}m{0pt}@{}" extra_col_sep = " & " justify = [">{\centering}" for _ in range(n_col)] if 'min_row_height' in options: min_row_height = " [" + str(options['min_row_height']) \ + length_unit + "] " cell_fmt = "p{" if 'center_vertically' in options and options['center_vertically']: cell_fmt = "m{" if 'borders' in options and options['borders'] in [ 'all', 'v_internal', 'penultimate' ]: v_border = "|" h_border = "\\hline \n" col_fmt = ['c' for i in range(n_col)] if ('col_fmt' in options and type(options['col_fmt']) == list and len(options['col_fmt']) == n_col): # __ for i in range(len(col_fmt)): col_fmt[i] = options['col_fmt'][i] for i in range(len(col_fmt)): t = col_fmt[i] if is_.a_number(col_fmt[i]): t = cell_fmt + str(col_fmt[i]) + " " + str(length_unit) + "}" vb = v_border if 'borders' in options and options['borders'] == "penultimate": if i == n_col - 1: vb = "|" else: vb = "" tabular_format += vb + justify[i] + t if 'borders' in options and options['borders'] == "penultimate": v_border = "" tabular_format += extra_last_column + v_border if 'borders' in options and options['borders'] in ['v_internal']: tabular_format = tabular_format[1:-1] result += "\\begin{tabular}{" + tabular_format + "}" + "\n" result += h_border for i in range(int(n_lin)): for j in range(n_col): result += str(content[i * n_col + j]) if j != n_col - 1: result += "&" + "\n" if i != n_lin - 1: result += extra_col_sep + new_line_sep + min_row_height \ + h_border result += extra_col_sep + new_line_sep + min_row_height + h_border result += "\end{tabular}" + "\n" return result.replace(" $~", "$~").replace("~$~", "$~")
def y(self, arg): if not is_.a_number(arg): raise error.WrongArgument(' a number ', str(arg)) self._y = arg