Пример #1
0
    def __init__(self, build_data, **options):
        super().setup('minimal', **options)
        level = int(build_data[5])
        # super().setup('numbers', nb=, **options)
        # super().setup('nb_variants', **options)
        super().setup('length_units', **options)

        # We know the wording will be in two lines:
        super().setup('polygon', polygon_data=build_data, wlines_nb=2)

        self.wording = {
            3: _(r'Perimeter of this triangle?\newline '
                 r'(length unit: {length_unit}) |hint:length_unit|'),
            4: _(r'Perimeter of this quadrilateral?\newline '
                 r'(length unit: {length_unit}) |hint:length_unit|'),
            5: _(r'Perimeter of this pentagon?\newline '
                 r'(length unit: {length_unit}) |hint:length_unit|'),
            6: _(r'Perimeter of this hexagon?\newline '
                 r'(length unit: {length_unit}) |hint:length_unit|')
        }[len(self.polygon.sides)]

        self.transduration = 12 + 3 * (level - 1)

        setup_wording_format_of(self)
        self.wording = self.wording.format(**self.wording_format)
Пример #2
0
 def __init__(self, build_data, **options):
     """
     :param build_data: tuple containing: wording's context and type, the
     wording itself and two ClockTime objects: start and arrival hours.
     :type build_data: tuple
     """
     super().setup("minimal", **options)
     wording_type = build_data[1]
     self.wording = _(build_data[2])
     lang = settings.language[:2]
     start_time = ClockTime(build_data[3], context=TIME_CONTEXT[lang])
     arrival_time = ClockTime(build_data[4], context=TIME_CONTEXT[lang])
     duration_ctxt = TIME_CONTEXT[lang] if wording_type == 'duration' \
         else DURATION_CONTEXT[lang]
     duration_time = ClockTime(arrival_time - start_time,
                               context=duration_ctxt)
     self.start_time = start_time.printed
     self.arrival_time = arrival_time.printed
     self.duration_time = duration_time.printed
     self.solution = {'duration': duration_time,
                      'start': start_time,
                      'arrival': arrival_time}[wording_type]
     self.transduration = 24
     self.time_unit = ('', TIME_CONTEXT[lang]['h'],
                       '', TIME_CONTEXT[lang]['min'])
     setup_wording_format_of(self)
Пример #3
0
    def __init__(self, build_data, **options):
        super().setup('minimal', **options)
        super().setup('numbers', nb=build_data, shuffle_nbs=False,
                      **options)
        source_id = options.get('nb_source')
        if source_id == r'10%of...':
            self.transduration = 12
        elif source_id in [r'25%of...', r'50%of...'] and self.nb2 < 40:
            self.transduration = 16
        else:
            self.transduration = 20
        if self.nb_variant.startswith('decimal'):
            deci_nb = int(self.nb_variant[-1])
            self.nb2 = self.nb2 / Number(10) ** Number(deci_nb)

        self.result = self.nb1 * self.nb2 / Number(100)
        self.n1 = self.nb1.printed
        hint = ''
        if self.context == 'simple_unit':
            u = shared.unitspairs_source.next(direction='left', level=1)[0]
            pq = physical_quantity(u)
            self.n2 = Number(self.nb2, unit=Unit(u)).printed
            hint = ' |hint:{}_unit|'.format(pq)
            setattr(self, pq + '_unit', u)
            self.result = Number(self.result, unit=u)
        else:
            self.n2 = self.nb2.printed
        # This default wording is meant for mental calculation.
        self.wording = options.get('wording',
                                   _('{n1} {percent_symbol} of {n2}?')
                                   + hint)
        setup_wording_format_of(self)
Пример #4
0
def ow2ter():
    o = raw_obj()
    o.nb1 = 27
    o.wording = 'What\'s the area of the side of a cube whose volume '\
                'is {nb1} {volume_unit=cm}? |hint:area_unit|'
    setup_wording_format_of(o)
    return o
Пример #5
0
 def _setup_ask_question(self, **kwargs):
     values = kwargs.get('values')
     self.wording = self.q_wordings_collection[kwargs['q_key']]\
         .format(*values)
     if kwargs.get('fix_math_style2_fontsize', False):
         self.wording = fix_math_style2_fontsize(self.wording)
     setup_wording_format_of(self)
Пример #6
0
def ow2ter():
    o = raw_obj()
    o.nb1 = 27
    o.wording = 'What\'s the area of the side of a cube whose volume '\
                'is {nb1} {volume_unit=cm}? |hint:area_unit|'
    setup_wording_format_of(o)
    return o
Пример #7
0
def ow_units1():
    o = raw_obj()
    o.nb1 = 7
    o.wording = 'The first weighs {nb1} {mass_unit=kg} and the second\'s ' \
        '{mass_unit}.'
    setup_wording_format_of(o)
    return o
Пример #8
0
 def _setup_complement_wording(self, **kwargs):
     upper_bound = self.nb1
     if self.context == 'complement_wording':
         self.context += str(random.choice([1, 2]))
     if self.context == 'complement_wording1':
         self.wording = _('What number must be added to'
                          ' {number1} to make {number2}?')\
             .format(number1=self.nb2.printed, number2=self.nb1.printed)
     elif self.context == 'complement_wording2':
         if upper_bound == 10:
             self.wording = _('What is the tens complement '
                              'of {number}?')\
                 .format(number=self.nb2.printed)
         elif upper_bound == 100:
             self.wording = _('What is the hundreds complement '
                              'of {number}?')\
                 .format(number=self.nb2.printed)
         else:
             self.wording = _('What is the complement to {number1} '
                              'of {number2}?')\
                 .format(number1=self.nb1.printed, number2=self.nb2.printed)
     else:
         raise ValueError('Cannot recognize context: {}\n'
                          .format(self.context))
     setup_wording_format_of(self)
Пример #9
0
def ow1():
    o = raw_obj()
    o.nb1 = 4
    o.wording = 'Calculate the volume of a cube whose side\'s length is ' \
                '{nb1} {length_unit=cm}. |hint:volume_unit|'
    setup_wording_format_of(o)
    return o
Пример #10
0
    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)
        super().setup("length_units", **options)
        hypotenuse_length = \
            Number(Number(build_data[0]) * Number(build_data[0])
                   + Number(build_data[1]) * Number(build_data[1]))\
            .sqrt().rounded(Decimal('0.1'))
        super().setup("polygon",
                      polygon_data=(3, 'triangle', 'right_triangle',
                                    'triangle_1_1_1', 'all_different', 2, 1,
                                    0, 0, 0, 0, 0, build_data[0],
                                    build_data[1], hypotenuse_length),
                      wlines_nb=1)
        self.transduration = 21

        if self.slideshow:
            self.polygon.scale = 2
            self.wording = _('Area?')
            self.part2_wording = r'{\small' + _('(Length unit: {})')\
                .format(self.length_unit) + '}'
        else:
            self.wording = _('Area of this triangle? |hint:area_unit|')
            self.part2_wording = r'{\small' + _('(Lengths in {})')\
                .format(self.length_unit) + '}'
        setup_wording_format_of(self)
        self.polygon_area = Number(build_data[0] * build_data[1] / 2)\
            .standardized()
Пример #11
0
    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)
        super().setup("length_units", **options)
        super().setup("rectangle", **options)
        self.transduration = 14

        if self.picture:
            if self.slideshow:
                self.wording = _('Area of this rectangle?')
                self.part2_wording = r'{\small' + _('(Length unit: {})')\
                    .format(self.length_unit) + '}'
            else:
                self.wording = _('Area of this rectangle? |hint:area_unit|')
                self.part2_wording = r'{\small' + _('(Lengths in {})')\
                    .format(self.length_unit) + '}'
            setup_wording_format_of(self)
        else:
            self.transduration = 20
            self.nb1, self.nb2 = \
                self.rectangle.lbl_width, self.rectangle.lbl_length
            self.wording = _("Area of a rectangle whose width is {nb1} \
{length_unit} and length is {nb2} {length_unit}? |hint:area_unit|")
            setup_wording_format_of(self)
Пример #12
0
def ow1():
    o = raw_obj()
    o.nb1 = 4
    o.wording = 'Calculate the volume of a cube whose side\'s length is ' \
                '{nb1} {length_unit=cm}. |hint:volume_unit|'
    setup_wording_format_of(o)
    return o
    def __init__(self, build_data, **options):
        super().setup("minimal", **options)
        if self.nb_source.startswith('complement'):
            maxi, mini = max(build_data), min(build_data)
            build_data = [mini, maxi - mini]
        super().setup("numbers", nb=build_data, **options)
        super().setup("nb_variants", nb=build_data, **options)
        super().setup("length_units", **options)
        super().setup("rectangle", **options)
        self.transduration = 14

        if self.picture:
            if self.slideshow:
                self.wording = _('Perimeter of this rectangle?')
                self.part2_wording = r'{\small' + _('(Length unit: {})')\
                    .format(self.length_unit) + '}'
            else:
                self.wording = _('Perimeter of this rectangle? '
                                 '|hint:length_unit|')
                self.part2_wording = r'{\small' + _('(Lengths in {})')\
                    .format(self.length_unit) + '}'
            setup_wording_format_of(self)
        else:
            self.transduration = 20
            self.nb1, self.nb2 = \
                self.rectangle.lbl_width, self.rectangle.lbl_length
            self.wording = _("Perimeter of a rectangle whose width "
                             "is {nb1} {length_unit} and length is "
                             "{nb2} {length_unit}? |hint:length_unit|")
            setup_wording_format_of(self)
Пример #14
0
def ow2bis():
    o = raw_obj()
    o.nb1 = 4
    o.nb2 = 7
    o.wording = 'How much is {nb1} {length_unit1=dm} '\
                '+ {nb2} {length_unit2=cm}? |hint:length_unit1|'
    setup_wording_format_of(o)
    return o
Пример #15
0
def ow2bis():
    o = raw_obj()
    o.nb1 = 4
    o.nb2 = 7
    o.wording = 'How much is {nb1} {length_unit1=dm} '\
                '+ {nb2} {length_unit2=cm}? |hint:length_unit1|'
    setup_wording_format_of(o)
    return o
Пример #16
0
def ow2qua():
    o = raw_obj()
    o.line1 = 'AB'
    o.line2 = 'MN'
    o.s = 'BC'
    o.wording = '({line1}) is parallel to ({line2}). '\
                'Calculate the length of segment [{s}].'
    setup_wording_format_of(o)
    return o
Пример #17
0
def ow2qua():
    o = raw_obj()
    o.line1 = 'AB'
    o.line2 = 'MN'
    o.s = 'BC'
    o.wording = '({line1}) is parallel to ({line2}). '\
                'Calculate the length of segment [{s}].'
    setup_wording_format_of(o)
    return o
    def __init__(self, build_data, **options):
        super().setup("minimal", **options)
        super().setup("length_units", **options)
        self.transduration = 16
        if self.picture:
            self.transduration = 12

        if self.context == "from_area":
            super().setup("division", nb=build_data, **options)
            self.nb1, self.nb2, self.nb3 = (self.result, self.divisor,
                                            self.dividend)
            super().setup("rectangle", **options)
            wordings = {'w': _("A rectangle has an area of {nb3} {area_unit} "
                               "and a length of {nb2} {length_unit}. What is "
                               "its width? |hint:length_unit|"),
                        'l': _("A rectangle has an area of {nb3} {area_unit} "
                               "and a width of {nb2} {length_unit}. What is "
                               "its length? |hint:length_unit|")
                        }
            self.wording = wordings[self.subcontext]
            setup_wording_format_of(self)

        elif self.context == "from_perimeter":
            super().setup("numbers", nb=build_data, **options)
            super().setup("nb_variants", nb=build_data, **options)
            super().setup("rectangle", **options)
            self.subcontext = random.choice(['w', 'l'])
            self.nb1 = self.rectangle.lbl_perimeter
            if self.subcontext == 'l':
                self.nb2, self.nb3 = (self.rectangle.lbl_width,
                                      self.rectangle.lbl_width)
            else:
                self.nb2, self.nb3 = (self.rectangle.lbl_length,
                                      self.rectangle.lbl_width)
            self.result = self.nb3
            wordings = {'w': _("What is the width of a rectangle whose "
                               "perimeter is {nb1} {length_unit} and length "
                               "is {nb2} {length_unit}? |hint:length_unit|"),
                        'l': _("What is the length of a rectangle whose "
                               "perimeter is {nb1} {length_unit} and width "
                               "is {nb2} {length_unit}? |hint:length_unit|")
                        }
            self.wording = wordings[self.subcontext]
            setup_wording_format_of(self)

        else:
            raise RuntimeError('Impossible to create this question without '
                               'any context.')

        if self.subcontext == 'w':
            self.rectangle.setup_labels(labels=[self.rectangle.lbl_width,
                                                self.rectangle.lbl_length],
                                        masks=[' ', ' ', None, '?'])
        elif self.subcontext == 'l':
            self.rectangle.setup_labels(labels=[self.rectangle.lbl_width,
                                                self.rectangle.lbl_length],
                                        masks=[' ', ' ', '?', None])
Пример #19
0
 def __init__(self, build_data, **options):
     super().setup('minimal', **options)
     # if (self.nb1 > 20 and self.nb2 > 20
     #     and not self.nb1 % 10 == 0 and not self.nb2 % 10 == 0):
     #     self.transduration = 12
     unit1, unit2, direction, category, level, dimension = build_data
     self.transduration = {1: 15, 2: 20, 3: 25, 4: 25, 5: 25}\
         .get(int(level), 30)
     unit1 = Unit(unit1)
     unit2 = Unit(unit2)
     if physical_quantity(unit1) == 'length' and dimension != 1:
         self.length_unit1 = unit1.content
         unit1 = Unit(unit1.content, exponent=dimension)
     if physical_quantity(unit2) == 'length' and dimension != 1:
         self.length_unit2 = unit2.content
         unit2 = Unit(unit2.content, exponent=dimension)
     if xor(hasattr(self, 'length_unit1'), hasattr(self, 'length_unit2')):
         if hasattr(self, 'length_unit1'):
             self.length_unit = getattr(self, 'length_unit1')
         else:
             self.length_unit = getattr(self, 'length_unit2')
     start_position = [Decimal('10'), Decimal('1'), Decimal('0.1')]
     if difference_of_orders_of_magnitude(unit1, unit2) >= Decimal('100'):
         start_position = [Decimal('1'), Decimal('0.1'), Decimal('0.01')]
     if difference_of_orders_of_magnitude(unit1, unit2) <= Decimal('0.01'):
         start_position = [Decimal('100'), Decimal('10'), Decimal('1')]
     sp = random.choice(start_position)
     nb1 = \
         generate_random_decimal_nb(position=sp,
                                    width=random.choice([1, 2, 3]),
                                    unique_figures=options.get(
                                        'unique_figures', False),
                                    generation_type='default')[0]
     super().setup('numbers',
                   nb=[Number(nb1),  # self.nb1
                       Number(Number(nb1,
                                     unit=unit1).converted_to(unit2),
                              unit=None)  # self.nb2
                       ],
                   shuffle_nbs=False, standardize_decimal_numbers=True)
     self.answer = Number(self.nb2, unit=unit2).printed
     self.js_answer = self.nb2.uiprinted
     phq1 = physical_quantity(unit1)
     phq2 = physical_quantity(unit2)
     suffix1 = suffix2 = ''
     if phq1 == phq2:
         suffix1 = '1'
         suffix2 = '2'
     unit1_attr_name = phq1 + '_unit' + suffix1
     unit2_attr_name = phq2 + '_unit' + suffix2
     hint = ' |hint:{}_unit{}|'.format(phq2, suffix2)
     setattr(self, unit1_attr_name, unit1)
     setattr(self, unit2_attr_name, unit2)
     self.wording = '{{nb1}} {{{u1}}} = QUESTION_MARK~{{{u2}}}{h}'\
         .format(u1=unit1_attr_name, u2=unit2_attr_name, h=hint)
     setup_wording_format_of(self)
Пример #20
0
    def __init__(self, numbers_to_use, **options):
        super().setup("minimal", **options)
        super().setup("length_units", **options)

        if self.context == "from_area":
            super().setup("division", nb=numbers_to_use, **options)
            self.nb1, self.nb2 = self.dividend, self.divisor
            super().setup("rectangle", **options)
            wordings = {
                'w':
                _("A rectangle has an area of {nb1} {area_unit} "
                  "and a length of {nb2} {length_unit}. What is "
                  "its width? |hint:length_unit|"),
                'l':
                _("A rectangle has an area of {nb1} {area_unit} "
                  "and a width of {nb2} {length_unit}. What is "
                  "its length? |hint:length_unit|")
            }
            self.wording = wordings[self.subcontext]
            setup_wording_format_of(self)

        elif self.context == "from_perimeter":
            super().setup("numbers", nb=numbers_to_use, **options)
            super().setup("nb_variants", nb=numbers_to_use, **options)
            super().setup("rectangle", **options)
            self.subcontext = random.choice(['w', 'l'])
            self.nb1 = self.rectangle.perimeter
            if self.subcontext == 'l':
                self.nb2, self.nb3 = (self.rectangle.width,
                                      self.rectangle.length)
            else:
                self.nb2, self.nb3 = (self.rectangle.length,
                                      self.rectangle.width)
            self.result = self.nb3
            wordings = {
                'w':
                _("What is the width of a rectangle whose "
                  "perimeter is {nb1} {length_unit} and length "
                  "is {nb2} {length_unit}? |hint:length_unit|"),
                'l':
                _("What is the length of a rectangle whose "
                  "perimeter is {nb1} {length_unit} and width "
                  "is {nb2} {length_unit}? |hint:length_unit|")
            }
            self.wording = wordings[self.subcontext]
            setup_wording_format_of(self)

        else:
            raise error.ImpossibleAction("Create this question without any "
                                         "context.")

        if self.subcontext == "w":
            self.rectangle.setup_labels([False, False, True, "?"])
        elif self.subcontext == "l":
            self.rectangle.setup_labels([False, False, "?", True])
Пример #21
0
    def _setup_mini_problem_wording(self, **kwargs):
        wording_kwargs = {'nb1_to_check': self.nb1, 'nb2_to_check': self.nb2}
        if kwargs.get('proportionality', False):
            source = shared.mini_problems_prop_wordings_source
            wording_kwargs.update({'coeff_to_check': self.coeff,
                                   'nb3_to_check': self.nb3,
                                   'solution_to_check': self.nb4,
                                   'lock_equal_contexts': True})
            if not is_integer(self.nb1):
                wording_kwargs.update({'nb1_may_be_deci': 1})
            if not is_integer(self.nb2):
                wording_kwargs.update({'nb2_may_be_deci': 1})
            if not is_integer(self.nb3):
                wording_kwargs.update({'nb3_may_be_deci': 1})
            if not is_integer(self.nb4):
                wording_kwargs.update({'solution_may_be_deci': 1})
            wording_kwargs.update(preprocess_qkw('mini_pb_prop_wordings',
                                                 qkw=kwargs))
        else:
            source = shared.mini_problems_wordings_source
            wording_kwargs.update({'q_id': kwargs['q_id']})
            if 'back_to_unit' in kwargs:
                val = 1 if BOOLEAN[kwargs['back_to_unit']]() else 0
                wording_kwargs.update({'back_to_unit': val})
        drawn_wording = source.next(**wording_kwargs)
        self.wording = _(drawn_wording[1])
        self.wording_context = drawn_wording[0]
        if kwargs.get('proportionality', False):
            self.solution = self.nb4
            nb1_xcoeff = Number(str(drawn_wording[2]))
            nb2_xcoeff = Number(str(drawn_wording[3]))
            nb3_xcoeff = Number(str(drawn_wording[4]))
            if nb1_xcoeff != 1:
                self.nb1 *= nb1_xcoeff
                self.solution /= nb1_xcoeff
            if nb2_xcoeff != 1:
                self.nb2 *= nb2_xcoeff
                self.solution *= nb2_xcoeff
            if nb3_xcoeff != 1:
                self.nb3 *= nb3_xcoeff
                self.solution *= nb3_xcoeff
            if self.wording_context in ['price', 'groceries']:
                self.solution = self.solution.rounded(Number('0.01'))
                if self.solution.fracdigits_nb() > 0:
                    self.solution = self.solution.quantize(Number('0.01'))
            else:
                if self.solution.fracdigits_nb() == 0:
                    self.solution = self.solution.quantize(Number('1'))
                if self.nb3.fracdigits_nb() == 0:
                    self.nb3 = self.nb3.quantize(Number('1'))

        setup_wording_format_of(self)
    def __init__(self, build_data, picture='true', **options):
        super().setup("minimal", **options)
        super().setup("length_units", **options)
        super().setup("right_triangle", **options)
        # There's no need to setup numbers for this question.

        if self.variant in ['default', 'random']:
            variant = shared.trigo_vocabulary_source.next()[0]
        else:
            variant = self.variant

        if variant not in ['adjacent', 'opposite']:
            raise ValueError('XMLFileFormatError: Invalid variant: {v}, '
                             .format(v=variant)
                             + 'It should be in: '
                             '[\'adjacent\', \'opposite\']')

        angle_nb = random.choice([0, 2])

        self.right_triangle.setup_for_trigonometry(
            angle_nb=angle_nb,
            trigo_fct='cos',
            down_length_val=Value(''),
            up_length_val=Value(''),
            length_unit=self.length_unit,
            only_mark_unknown_angle=True)

        self.acute_angle = shared.machine.write_math_style2(
            self.right_triangle.angle[angle_nb].printed)

        self.wording = {
            'adjacent': _('Which side is adjacent to {acute_angle} ?'),
            'opposite': _('Which side is opposite to {acute_angle} ?')
        }[variant]
        setup_wording_format_of(self)

        side_getter = getattr(self.right_triangle,
                              'side_' + variant + '_to')
        self.correct_answer = side_getter(
            angle=self.right_triangle.angle[angle_nb]).length_name

        self.answer_wording = {
            'adjacent': _('The side adjacent to {acute_angle} is:'
                          ' {correct_answer}'),
            'opposite': _('The side opposite to {acute_angle} is:'
                          ' {correct_answer}')
        }[variant]
        setup_wording_format_of(self, w_prefix='answer_')
        self.q_nb_included_in_wording = False
    def __init__(self, build_data, picture='true', **options):
        super().setup("minimal", **options)
        super().setup("length_units", **options)
        super().setup("right_triangle", **options)
        # nb1 and nb2 are sides' lengths,
        # they may require to be ordered, later on...
        super().setup("numbers", nb=build_data,
                      shuffle_nbs=False, sort_nbs=True, **options)

        if self.variant in ['default', 'random']:
            variant = shared.trigo_functions_source.next()[0]
        else:
            variant = self.variant

        if variant not in ['cos', 'sin', 'tan']:
            raise ValueError('XMLFileFormatError: invalid variant: {v}, '
                             .format(v=variant) + 'It should be in: '
                             '[\'cos\', \'sin\', \'tan\']')

        # nb2 being the greatest length (the numbers have been ordered at
        # setup), it must be used as hypotenuse's length in cosine and sine
        # cases
        up_val = self.nb1
        down_val = self.nb2
        if variant == 'tan' and random.choice([True, False]):
            up_val, down_val = down_val, up_val

        self.right_triangle.setup_for_trigonometry(
            angle_nb=random.choice([0, 2]),
            trigo_fct=variant,
            down_length_val=down_val,
            up_length_val=up_val,
            length_unit=self.length_unit)

        self.wording = ''
        setup_wording_format_of(self)

        trigo_eq = self.right_triangle.trigonometric_equality(autosetup=True)
        self.resolution = trigo_eq.auto_resolution(
            dont_display_equations_name=True,
            skip_fraction_simplification=True,
            decimal_result=self.decimal_result,
            unit='\\textdegree')
        self.answer_wording = \
            _('The triangle {triangle_name} has a right angle in'
              ' {right_vertex_name}. {newline} Hence: {resolution}')
        self.triangle_name = self.right_triangle.name
        self.right_vertex_name = self.right_triangle.vertex[1].name
        setup_wording_format_of(self, w_prefix='answer_')
Пример #24
0
 def __init__(self, build_data, **options):
     super().setup("minimal", **options)
     # Possible options: allow_null_remainder (defaults to False)
     #                   force_null_remainder (defaults to False)
     super().setup("euclidean_division", nb=build_data, **options)
     self.transduration = 15
     if self.divisor > 5 and self.divisor % 10 != 0:
         self.transduration += 3
     if self.divisor > 10 and self.divisor % 10 != 0:
         self.transduration += 3
     self.wording = _('Euclidean division of {dividend} by {divisor}?')
     setup_wording_format_of(self)
     # This is actually meant for self.preset == 'mental calculation'
     self.answer = '{quotient} r {remainder}'\
         .format(quotient=self.quotient, remainder=self.remainder)
Пример #25
0
    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)
        super().setup("length_units", **options)
        super().setup("rectangle", **options)

        if self.picture:
            self.wording = _("Area of this rectangle? |hint:area_unit|")
            setup_wording_format_of(self)
        else:
            self.nb1, self.nb2 = self.rectangle.width, self.rectangle.length
            self.wording = _("Area of a rectangle whose width is {nb1} \
{length_unit} and length is {nb2} {length_unit}? |hint:area_unit|")
            setup_wording_format_of(self)
Пример #26
0
    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)
        super().setup("length_units", **options)
        super().setup("square", **options)

        if self.picture:
            self.wording = _("Perimeter of this square? |hint:length_unit|")
            setup_wording_format_of(self)
        else:
            self.nb1 = self.square.side_length
            self.wording = _("Perimeter of a square whose side's length \
is {nb1} {length_unit}? |hint:length_unit|")
            setup_wording_format_of(self)
    def __init__(self, build_data, picture='true', **options):
        super().setup("minimal", **options)
        super().setup("length_units", **options)
        super().setup("right_triangle", **options)
        # There's no need to setup numbers for this question.

        if self.variant in ['default', 'random']:
            variant = shared.trigo_functions_source.next()[0]
        else:
            variant = self.variant

        if variant not in ['cos', 'sin', 'tan']:
            raise ValueError('XMLFileFormatError: invalid variant: {v}, '
                             .format(v=variant) + 'It should be in: '
                             '[\'cos\', \'sin\', \'tan\']')

        angle_nb = random.choice([0, 2])

        self.right_triangle.setup_for_trigonometry(
            angle_nb=angle_nb,
            trigo_fct=variant,
            down_length_val=Value(''),
            up_length_val=Value(''),
            length_unit=self.length_unit,
            only_mark_unknown_angle=True)

        self.trigo_fct = variant
        self.the_formula_of_trigo_fct = {
            'cos': _('the formula of cosine'),
            'sin': _('the formula of sine'),
            'tan': _('the formula of tangent')}[variant]
        self.acute_angle = shared.machine.write_math_style2(
            self.right_triangle.angle[angle_nb].printed)

        self.wording = options.get('text', options.get('wording', ''))
        if self.wording:
            self.wording = _(self.wording)
        setup_wording_format_of(self)

        self.formula = shared.machine.write_math_style1(
            self.right_triangle.trigonometric_equality(
                angle=self.right_triangle.angle[angle_nb],
                trigo_fct=variant).printed)

        self.answer_wording = \
            _('The formula is: {formula}')
        setup_wording_format_of(self, w_prefix='answer_')
        self.q_nb_included_in_wording = False
    def __init__(self, build_data, **kwargs):
        """
        The two numbers in build_data are the factors of the product.

        kwargs may contain a 'variant' parameter.
        It can contain these values:
        - 'random' (default), then it will randomly be replaced by 'true'
          or 'false'
        - 'true', then the answer will be true
        - 'false', then it will randomly replaced by 'remainder' or 'reversed'
        - 'remainder' then a non zero remainder will be added:
          result = nb1 × nb2 + remainder
           and the answer will be false
        - 'reversed' then the result and nb1 or nb2 will be exchanged and the
          answer will be false

        :param nb_to_use: a tuple of 2 numbers
        :type nb_to_use: tuple
        """
        super().setup('minimal', **kwargs)
        # super().setup("numbers", nb=nb_to_use, **kwargs)
        # super().setup("nb_variants", nb=nb_to_use, **kwargs)
        super().setup('division', nb=build_data, **kwargs)

        variant = kwargs.get('variant', 'random')
        if variant == 'random':
            variant = random.choice(['true', 'false'])
        if variant == 'true':
            self.n2 = self.dividend
            self.n1 = self.divisor
            self.answer = _('True')
        else:
            if variant == 'false':
                variant = random.choice(['remainder', 'reversed'])
            self.answer = _('False')
            if variant == 'remainder':
                remainder = random.randint(1, self.divisor - 1)
                self.n2 = self.dividend + remainder
                self.n1 = self.divisor
            elif variant == 'reversed':
                self.n1 = self.dividend
                self.n2 = self.divisor
        statement = _(next(shared.divisibility_statements_source)[0])
        nl = r'\newline' if self.slideshow else ''
        self.wording = r'{} {} {}'.format(statement, nl,
                                          _('(True or false?)'))
        setup_wording_format_of(self)
        self.transduration = 18
    def __init__(self, build_data, picture='true', **options):
        super().setup("minimal", **options)
        super().setup("intercept_theorem_figure", set_lengths=False,
                      butterfly=True, **options)

        all_segments = self.figure.small + self.figure.side

        self.figure.setup_labels([False for _ in range(len(all_segments))],
                                 segments_list=all_segments)

        self.ratios = shared.machine.write_math_style1(
            self.figure.ratios_equalities().into_str())

        self.wording = _(' {line1} {parallel_to} {line2}')
        self.line1 = self.figure.small[1].length_name
        self.line2 = self.figure.side[1].length_name
        setup_wording_format_of(self)
Пример #30
0
 def __init__(self, nbs_to_use, **kwargs):
     result_fct = kwargs.pop('result_fct', None)
     wording = kwargs.pop('wording', "")
     super().setup("minimal", **kwargs)
     super().setup("numbers", nb=nbs_to_use, **kwargs)
     super().setup("nb_variants", nb=nbs_to_use, **kwargs)
     self.result = Value(result_fct(self.nb1,
                                    self.nb2).evaluate()).into_str()
     if 'swap_nb1_nb2' in kwargs and kwargs['swap_nb1_nb2']:
         self.nb1, self.nb2 = self.nb2, self.nb1
     if ('permute_nb1_nb2_result' in kwargs
             and kwargs['permute_nb1_nb2_result']):
         # __
         self.nb1, self.nb2, self.result = self.result, self.nb1, self.nb2
     self.nb1 = Value(self.nb1)
     self.nb2 = Value(self.nb2)
     self.wording = wording
     setup_wording_format_of(self)
Пример #31
0
    def __init__(self, numbers_to_use, picture='true', **options):
        super().setup("minimal", **options)
        super().setup("intercept_theorem_figure", set_lengths=False, **options)

        all_segments = self.figure.small \
            + self.figure.side \
            + [self.figure.u, self.figure.v]\
            + self.figure.chunk

        self.figure.setup_labels([False for _ in range(len(all_segments))],
                                 segments_list=all_segments)

        self.ratios = shared.machine.write_math_style1(
            self.figure.ratios_equalities().into_str(
                as_a_quotients_equality=True))

        self.wording = _(' {line1} {parallel_to} {line2}')
        self.line1 = self.figure.small[1].length_name
        self.line2 = self.figure.side[1].length_name
        setup_wording_format_of(self)
Пример #32
0
    def __init__(self, build_data, **options):
        super().setup('minimal', **options)
        super().setup('numbers', nb=build_data, **options)
        super().setup('length_units', **options)

        direction = options.get('direction',
                                shared.directions_source.next()[0])
        if 'variant' in options:
            variant = int(options['variant'])
        else:
            faces_nb, variant = shared.rightcuboids_source.next()

        labels = [n.standardized() for n in self.nb_list]
        super().setup('rightcuboid', variant=variant, labels=labels,
                      direction=direction)

        self.wording = _(r'Volume of this right cuboid?\newline '
                         r'(length unit: {length_unit}) |hint:volume_unit|')

        self.transduration = 21

        setup_wording_format_of(self)
        self.wording = self.wording.format(**self.wording_format)
Пример #33
0
def test_setup_wording_format_of_01(ow2):
    """Checks if obj.wording is correctly setup."""
    setup_wording_format_of(ow2)
    assert ow2.wording == 'Just a try for a {name}, a {nb_capacity_unit}; '\
                          'a {nb1_length_unit1} and finally '\
                          '{nb3_volume_unit3}.'
Пример #34
0
    def setup(self, arg, shuffle_nbs=True, **options):
        if arg == "minimal":
            self.newline = '\\newline'
            self.parallel_to = '$\parallel$'
            self.belongs_to = '$\in$'
            if 'variant' in options and options['variant'] == 'decimal':
                options['variant'] = random.choice(['decimal1', 'decimal2'])

            self.variant = options.get('variant', "default")
            self.context = options.get('context', "default")
            self.picture = XML_BOOLEANS[options.get('picture', "false")]()

        elif arg == "length_units":
            if 'unit' in options:
                self.unit_length = Unit(options['unit'])
                self.unit_area = Unit(self.unit_length.name, exponent=2)
                self.length_unit = self.unit_length.name
            else:
                if hasattr(self, 'length_unit'):
                    self.unit_length = Unit(self.length_unit)
                    self.unit_area = Unit(self.unit_length.name, exponent=2)
                elif hasattr(self, 'unit_length'):
                    self.length_unit = self.unit_length.name
                    self.unit_area = Unit(self.unit_length.name, exponent=2)
                else:
                    length_units_names = copy.deepcopy(COMMON_LENGTH_UNITS)
                    self.unit_length = Unit(random.choice(length_units_names))
                    self.unit_area = Unit(self.unit_length.name, exponent=2)
                    self.length_unit = self.unit_length.name

        elif arg == "numbers":
            nb_list = list(options['nb'])
            if shuffle_nbs:
                random.shuffle(nb_list)
            for i in range(len(nb_list)):
                setattr(self, 'nb' + str(i + 1), nb_list[i])
            self.nb_nb = len(nb_list)

        elif arg == "nb_variants":
            if self.variant.startswith('decimal'):
                deci_nb = int(self.variant[-1])  # so, from decimal1 up to 9
                chosen_ones = random.sample([i for i in range(self.nb_nb)],
                                            deci_nb)
                for i in chosen_ones:
                    setattr(self, 'nb' + str(i + 1),
                            getattr(self, 'nb' + str(i + 1)) / 10)

        elif arg == "division":
            nb_list = list(options['nb'])
            self.divisor = self.result = self.dividend = 0
            self.result_str = self.quotient_str = ""

            if '10_100_1000' in options and options['10_100_1000']:
                self.divisor, self.dividend = nb_list[0], nb_list[1]
                self.result = Quotient(('+', self.dividend, self.divisor))\
                    .evaluate()
            else:
                self.divisor = nb_list.pop(random.choice([0, 1]))
                self.result = nb_list.pop()
                if self.variant[:-1] == 'decimal':
                    self.result /= 10
                self.dividend = Product([self.divisor, self.result]).evaluate()

            if self.context == "from_area":
                self.subcontext = "w" if self.result < self.divisor else "l"

            self.dividend_str = Item(self.dividend).printed
            self.divisor_str = Item(self.divisor).printed
            self.result_str = Item(self.result).printed
            q = Quotient(('+', self.dividend, self.divisor),
                         use_divide_symbol=True)
            self.quotient_str = q.printed

        elif arg == "rectangle":
            if hasattr(self, 'nb1') and hasattr(self, 'nb2'):
                nb1, nb2 = self.nb1, self.nb2
            elif 'nb' in options:
                nb1, nb2 = options['nb'][0], options['nb'][1]
            else:
                raise error.ImpossibleAction("Setup a rectangle if no width "
                                             "nor length have been provided"
                                             " yet.")
            if (not hasattr(self, 'unit_length')
                or not hasattr(self, 'unit_area')):
                self.setup(self, "units", **options)

            # nb1 = Decimal(str(nb1))
            # nb2 = Decimal(str(nb2))

            w = Value(min([nb1, nb2]), unit=self.unit_length)
            l = Value(max([nb1, nb2]), unit=self.unit_length)

            rectangle_name = "DCBA"
            if self.picture:
                rectangle_name = next(shared.four_letters_words_source)
            self.rectangle = Rectangle([Point([rectangle_name[3], (0, 0)]),
                                        3,
                                        1.5,
                                        rectangle_name[2],
                                        rectangle_name[1],
                                        rectangle_name[0]],
                                       read_name_clockwise=True)
            self.rectangle.set_lengths([l, w])
            self.rectangle.setup_labels([False, False, True, True])

        elif arg == "square":
            if hasattr(self, 'nb1'):
                nb1 = self.nb1
            elif 'nb' in options:
                nb1 = options['nb'][0]
            else:
                raise error.ImpossibleAction("Setup a square if no side's "
                                             "length have been provided "
                                             "yet.")
            if (not hasattr(self, 'unit_length')
                or not hasattr(self, 'unit_area')):
                # __
                self.setup(self, "units", **options)

            square_name = "DCBA"
            if self.picture:
                square_name = next(shared.four_letters_words_source)
            self.square = Square([Point([square_name[3], (0, 0)]),
                                 2,
                                 square_name[2],
                                 square_name[1],
                                 square_name[0]],
                                 read_name_clockwise=True)
            self.square.set_lengths([Value(nb1, unit=self.unit_length)])
            self.square.setup_labels([False, False, True, False])
            self.square.set_marks(random.choice(["simple", "double",
                                                 "triple"]))

        elif arg == 'intercept_theorem_figure':
            butterfly = options.get('butterfly', False)
            set_lengths = options.get('set_lengths', True)
            if set_lengths:
                if not all([hasattr(self, 'nb1'), hasattr(self, 'nb2'),
                            hasattr(self, 'nb3'), hasattr(self, 'nb4')]):
                    # __
                    raise error.ImpossibleAction("Setup an intercept theorem "
                                                 "figure without a "
                                                 "coefficient and 3 other "
                                                 "lengths provided.")
            points_names = next(shared.five_letters_words_source)
            if butterfly:
                points_names = list(rotate(points_names, -1))
                (points_names[0], points_names[1]) = (points_names[1],
                                                      points_names[0])
                points_names = ''.join(points_names)
            else:
                points_names = rotate(points_names, random.choice(range(5)))
            alpha, beta = next(shared.angle_ranges_source)
            rotation_angle = alpha + random.choice(range(beta - alpha))
            self.figure = InterceptTheoremConfiguration(
                points_names=points_names,
                build_ratio=random.choice(range(25, 75)) / 100,
                sketch=False,
                butterfly=butterfly,
                build_dimensions={
                    False: {'side0': Decimal('5'),
                            'angle1':
                            Decimal(str(random.choice(range(45, 120)))),
                            'side1':
                            Decimal(str(random.choice(range(20, 60)) / 10))},
                    True: {'side0': Decimal('4'),
                           'angle1':
                           Decimal(str(random.choice(range(55, 110)))),
                           'side1':
                           Decimal(str(random.choice(range(15, 50)) / 10))}
                }[butterfly],
                rotate_around_isobarycenter=rotation_angle)

            if set_lengths:
                self.figure.set_lengths([self.nb2, self.nb3, self.nb4],
                                        Value(self.nb1))
            self.figure.side[2].invert_length_name()
            self.figure.small[2].invert_length_name()
            self.point0_name = self.figure.point[0].name
            self.point1_name = self.figure.point[1].name
            self.main_vertex_name = self.figure.vertex[0].name
            self.vertex1_name = self.figure.vertex[1].name
            self.vertex2_name = self.figure.vertex[2].name
            self.side0_length_name = self.figure.side[0].length_name
            self.small0_length_name = self.figure.small[0].length_name
            self.chunk0_length_name = self.figure.chunk[0].length_name
            self.side0_length = str(self.figure.side[0].length)
            self.small0_length = str(self.figure.small[0].length)
            self.chunk0_length = str(self.figure.chunk[0].length)
            self.side1_length_name = self.figure.side[2].length_name
            self.small1_length_name = self.figure.small[2].length_name
            self.chunk1_length_name = self.figure.chunk[1].length_name
            self.side1_length = str(self.figure.side[2].length)
            self.small1_length = str(self.figure.small[2].length)
            self.chunk1_length = str(self.figure.chunk[1].length)

        elif arg == 'mini_problem_wording':
            self.wording = _(shared.mini_problems_wordings_source
                             .next(q_id=options['q_id'],
                                   nb1_to_check=self.nb1,
                                   nb2_to_check=self.nb2))
            setup_wording_format_of(self)
Пример #35
0
def test_setup_wording_format_of_exceptions2(owbuggy2):
    """Check if a wrong hint correctly raises an exception."""
    with pytest.raises(RuntimeError):
        setup_wording_format_of(owbuggy2)
Пример #36
0
def test_setup_wording_format_of_05(ow2):
    """Checks if obj.wording is correctly setup."""
    setup_wording_format_of(ow2)
    assert hasattr(ow2, 'nb_capacity_unit')
Пример #37
0
def test_setup_wording_format_of_04(ow2):
    """Checks if obj.wording is correctly setup."""
    setup_wording_format_of(ow2)
    assert ow2.nb1_length_unit1.startswith('\\SI{8}{')
Пример #38
0
    def __init__(self, numbers_to_use, picture='true', **options):
        super().setup("minimal", **options)
        if numbers_to_use[0] < 11:
            raise ValueError('numbers_to_use[0] == {} whereas it should be '
                             '>= 11'.format(str(numbers_to_use[0])))
        numbers_to_use = (numbers_to_use[0] / 10, ) + numbers_to_use[1:]
        super().setup("numbers", nb=numbers_to_use,
                      shuffle_nbs=False, **options)
        super().setup("length_units", **options)
        super().setup("intercept_theorem_figure", butterfly=True, **options)

        if self.variant == 'default':
            variant = ['random', 'random']
        else:
            if self.variant.count('_') != 1:
                raise error.XMLFileFormatError('The variant for '
                                               'intercept_theorem_butterfly '
                                               'shoud contain one _')
            variant = self.variant.split(sep='_')

        valid_variant = [['random', 'oneside', 'twosides'],
                         ['random', 'all', 'twocouples']]

        for v, valid, n in zip(variant, valid_variant,
                               ['first', 'second', 'third']):
            if v not in valid:
                raise error.XMLFileFormatError('Invalid {} part of the '
                                               'variant. It should be in: {}'
                                               .format(n, str(valid)))

        if variant[0] == 'random':
            if variant[1] == 'twocouples':
                variant[0] = 'oneside'
            else:
                variant[0] = random.choice(['oneside', 'twosides'])
        if variant[1] == 'random':
            if variant[0] == 'twosides':
                variant[1] = 'twocouples'
            else:
                variant[1] == random.choice(['all', 'twocouples'])

        if variant == ['twosides', 'twocouples']:
            raise error.XMLFileFormatError('The twosides_twocouples '
                                           'variant is impossible.')

        # The order is:
        # small[0] small[1] small[2] side[0] side[1] side[2]
        labels_configurations = {
            'oneside_all': [
                ['?', True, True, True, True, True],
                [True, '?', True, True, True, True],
                [True, True, '?', True, True, True],
                [True, True, True, '?', True, True],
                [True, True, True, True, '?', True],
                [True, True, True, True, True, '?']
            ],
            'oneside_twocouples': [
                ['?', True, False, True, True, False],
                [False, True, '?', False, True, True],
                [True, True, False, True, '?', False],
                [False, True, True, False, '?', True],
                ['?', False, True, True, False, True],
                [True, False, '?', True, False, True],
                [True, '?', False, True, True, False],
                [False, '?', True, False, True, True],
                [False, True, True, False, True, '?'],
                [True, True, False, '?', True, False],
                [True, False, True, True, False, '?'],
                [True, False, True, '?', False, True],
            ],
            'twosides_all': [
                ['?', '?', True, True, True, True],
                ['?', True, '?', True, True, True],
                [True, '?', '?', True, True, True],
                ['?', True, True, True, '?', True],
                ['?', True, True, True, True, '?'],
                [True, '?', True, '?', True, True],
                [True, '?', True, True, True, '?'],
                [True, True, '?', True, '?', True],
                [True, True, '?', '?', True, True],
                [True, True, True, '?', '?', True],
                [True, True, True, '?', True, '?'],
                [True, True, True, True, '?', '?'],
            ]
        }

        variant_key = '_'.join(variant)
        labels_conf = random.choice(labels_configurations[variant_key])

        self.figure.setup_labels(labels_conf,
                                 segments_list=self.figure.small
                                 + self.figure.side)

        lengths_to_calculate = [s.length_name
                                for s in self.figure.small + self.figure.side
                                if s.label == Value('?')]

        self.line1 = self.figure.small[1].length_name
        self.line2 = self.figure.side[1].length_name
        self.length1_name = lengths_to_calculate[0]
        if len(lengths_to_calculate) == 2:
            self.length2_name = lengths_to_calculate[1]

        if len(lengths_to_calculate) == 1:
            self.wording = _('The drawn figure is out of shape. {newline} '
                             'The lengths are given in {length_unit}. '
                             '{newline} '
                             'The {line1} is parallel to {line2}. {newline} '
                             '{newline} '
                             'Determine the length of {length1_name}.')
        else:
            self.wording = _('The drawn figure is out of shape. {newline} '
                             'The lengths are given in {length_unit}. '
                             '{newline} '
                             'The {line1} is parallel to {line2}. {newline} '
                             '{newline} '
                             'Determine the lengths of {length1_name} '
                             'and {length2_name}.')
        setup_wording_format_of(self)

        self.ratios = shared.machine.write_math_style1(
            self.figure.ratios_equalities()
            .into_str(as_a_quotients_equality=True))
        self.ratios_substituted = shared.machine.write_math_style1(
            self.figure.ratios_equalities_substituted()
            .into_str(as_a_quotients_equality=True))

        self.resolution0 = self.figure.ratios_equalities_substituted()\
            .into_crossproduct_equation(Item(lengths_to_calculate[0]))\
            .auto_resolution(dont_display_equations_name=True,
                             skip_first_step=True,
                             skip_fraction_simplification=True,
                             decimal_result=2,
                             unit=self.length_unit,
                             underline_result=True)
        lengths_resolutions_part = _('hence: {resolution0} ')
        if len(lengths_to_calculate) == 2:
            self.resolution1 = self.figure.ratios_equalities_substituted()\
                .into_crossproduct_equation(Item(lengths_to_calculate[1]))\
                .auto_resolution(dont_display_equations_name=True,
                                 skip_first_step=True,
                                 skip_fraction_simplification=True,
                                 decimal_result=2,
                                 unit=self.length_unit,
                                 underline_result=True)
            lengths_resolutions_part = shared.machine.write(
                lengths_resolutions_part + _('and: {resolution1} '),
                multicolumns=2)

        ans_variant = options.get('ans_variant', 'default')
        ans_texts = {
            'default': _('As: {line1} {parallel_to} {line2}, '
                         '{main_vertex_name} {belongs_to} {chunk0_length_name}'
                         ' and '
                         '{main_vertex_name} {belongs_to} {chunk1_length_name}'
                         ', then by the intercept theorem: {newline} '
                         '{ratios} '
                         'thus: {ratios_substituted} '),
            'alternative1': _('As {line1} is parallel to {line2}, '
                              'and as the line {chunk0_length_name} cuts '
                              'the line {chunk1_length_name} at point '
                              '{main_vertex_name}, '
                              'then by the intercept theorem: {newline} '
                              '{ratios} '
                              'thus: {ratios_substituted} '),
            'alternative2': _('As: {line1} is parallel to {line2}, '
                              'and as {point0_name}, {main_vertex_name} and '
                              '{vertex1_name} on one hand, '
                              '{point1_name}, {main_vertex_name} and '
                              '{vertex2_name} on the other hand,'
                              'are aligned in the same order, '
                              'then by the intercept theorem: {newline} '
                              '{ratios} '
                              'thus: {ratios_substituted} ')
        }

        self.answer_wording = ans_texts[ans_variant] + lengths_resolutions_part

        setup_wording_format_of(self, w_prefix='answer_')
Пример #39
0
def test_setup_wording_format_of_05(ow2):
    """Checks if obj.wording is correctly setup."""
    setup_wording_format_of(ow2)
    assert hasattr(ow2, 'nb_capacity_unit')
Пример #40
0
def test_setup_wording_format_of_01(ow2):
    """Checks if obj.wording is correctly setup."""
    setup_wording_format_of(ow2)
    assert ow2.wording == 'Just a try for a {name}, a {nb_capacity_unit}; '\
                          'a {nb1_length_unit1} and finally '\
                          '{nb3_volume_unit3}.'
Пример #41
0
def test_setup_wording_format_of_02(ow2):
    """Checks if obj.wording is correctly setup."""
    setup_wording_format_of(ow2)
    assert hasattr(ow2, 'name')
Пример #42
0
def test_setup_wording_format_of_03(ow2):
    """Checks if obj.wording is correctly setup."""
    setup_wording_format_of(ow2)
    assert ow2.nb3_volume_unit3 == '\\SI{11}{cm^{\\text{3}}}'
Пример #43
0
    def __init__(self, numbers_to_use, picture='true', **options):
        super().setup("minimal", **options)
        if numbers_to_use[0] < 11:
            raise ValueError('numbers_to_use[0] == {} whereas it should be '
                             '>= 11'.format(str(numbers_to_use[0])))
        numbers_to_use = (numbers_to_use[0] / 10, ) + numbers_to_use[1:]
        super().setup("numbers",
                      nb=numbers_to_use,
                      shuffle_nbs=False,
                      **options)
        super().setup("length_units", **options)
        super().setup("intercept_theorem_figure", **options)

        if self.variant == 'default':
            variant = ['oneside', 'random', 'false']
        else:
            if self.variant.count('_') != 2:
                raise error.XMLFileFormatError('The variant for '
                                               'intercept_theorem_triangle '
                                               'shoud contain two _')
            variant = self.variant.split(sep='_')

        valid_variant = [[
            'onerandom', 'tworandom', 'random', 'oneside', 'onechunk',
            'twosides', 'twochunks', 'onesideonechunk'
        ], ['random', 'all', 'twocouples'], ['random', 'true', 'false']]

        for v, valid, n in zip(variant, valid_variant,
                               ['first', 'second', 'third']):
            if v not in valid:
                raise error.XMLFileFormatError(
                    'Invalid {} part of the '
                    'variant. It should be in: {}'.format(n, str(valid)))

        if variant[0] == 'onerandom':
            variant[0] = random.choice(['oneside', 'onechunk'])
        elif variant[0] == 'tworandom':
            if variant[1] == 'twocouples':
                raise error.XMLFileFormatError('The tworandom_twocouples_* '
                                               'variants are impossible.')
            if variant[2] == 'random':
                variant[2] = random.choice(['true', 'false'])

            if variant[2] == 'false':
                variant[0] = random.choice(
                    ['twosides', 'twochunks', 'onesideonechunk'])
            elif variant[2] == 'true':
                variant[0] = random.choice(['twosides', 'onesideonechunk'])
            else:
                raise error.XMLFilFormatError('The third part of the variant '
                                              'should be "true" or "false".')

        # The order is:
        # small[0] small[1] small[2] side[0] side[1] side[2] chunk[0] chunk[1]
        # 'hid' means 'hidden', e.g. the length won't be displayed but can be
        # easily calculated before using the intercept theorem.
        labels_configurations = {
            'oneside_all_false':
            [['?', True, True, True, True, True, False, False],
             [True, '?', True, True, True, True, False, False],
             [True, True, '?', True, True, True, False, False],
             [True, True, True, '?', True, True, False, False],
             [True, True, True, True, '?', True, False, False],
             [True, True, True, True, True, '?', False, False]],
            'oneside_all_true': [
                ['?', True, True, True, True, 'hid', False, True],
                [True, '?', True, 'hid', True, 'hid', True, True],
                [True, '?', True, 'hid', True, True, True, False],
                [True, '?', True, True, True, 'hid', False, True],
                [True, True, '?', 'hid', True, True, True, False],
                [True, True, True, '?', True, 'hid', False, True],
                [True, True, True, True, '?', 'hid', False, True],
                [True, True, True, 'hid', '?', 'hid', True, True],
                [True, True, True, 'hid', '?', True, True, False],
                [True, True, True, 'hid', True, '?', True, False],
            ],
            'onechunk_all_false':
            [[True, True, True, False, True, True, '?', False],
             [True, True, True, True, True, False, False, '?']],
            'onechunk_all_true':
            [[True, True, True, False, True, 'hid', '?', True],
             [True, True, True, 'hid', True, False, True, '?']],
            'twosides_all_false': [
                ['?', '?', True, True, True, True, False, False],
                ['?', True, '?', True, True, True, False, False],
                [True, '?', '?', True, True, True, False, False],
                ['?', True, True, True, '?', True, False, False],
                ['?', True, True, True, True, '?', False, False],
                [True, '?', True, '?', True, True, False, False],
                [True, '?', True, True, True, '?', False, False],
                [True, True, '?', True, '?', True, False, False],
                [True, True, '?', '?', True, True, False, False],
                [True, True, True, '?', '?', True, False, False],
                [True, True, True, '?', True, '?', False, False],
                [True, True, True, True, '?', '?', False, False],
            ],
            'twosides_all_true': [
                ['?', '?', True, True, True, 'hid', False, True],
                [True, '?', '?', 'hid', True, True, True, False],
                ['?', True, True, True, '?', 'hid', False, True],
                [True, '?', True, '?', True, 'hid', False, True],
                [True, '?', True, False, True, '?', True, False],
                [True, True, '?', False, '?', True, True, False],
                [True, True, True, '?', '?', 'hid', False, True],
                [True, True, True, 'hid', '?', '?', True, False],
            ],
            'twochunks_all_false': [
                [False, True, False, True, True, True, '?', '?'],
                [True, True, False, False, True, True, '?', '?'],
                [False, True, True, True, True, False, '?', '?'],
                [True, True, True, False, True, False, '?', '?'],
            ],
            'onesideonechunk_all_false': [
                [False, '?', True, True, True, True, '?', False],
                [True, '?', False, True, True, True, False, '?'],
                [True, '?', True, False, True, True, '?', False],
                [True, '?', True, True, True, False, False, '?'],
                [False, True, '?', True, True, True, '?', False],
                ['?', True, False, True, True, True, False, '?'],
                [True, True, '?', False, True, True, '?', False],
                ['?', True, True, True, True, False, False, '?'],
                [True, True, True, False, True, '?', '?', False],
                [True, True, True, '?', True, False, False, '?'],
                [False, True, True, True, True, '?', '?', False],
                [True, True, False, '?', True, True, False, '?'],
                [False, True, True, True, '?', True, '?', False],
                [True, True, False, True, '?', True, False, '?'],
                [True, True, True, False, '?', True, '?', False],
                [True, True, True, True, '?', False, False, '?'],
            ],
            'onesideonechunk_all_true': [
                [True, '?', True, False, True, 'hid', '?', True],
                [True, '?', True, 'hid', True, False, True, '?'],
                [False, '?', True, True, True, 'hid', '?', True],
                [True, '?', False, 'hid', True, True, True, '?'],
                [True, True, True, False, '?', 'hid', '?', True],
                [True, True, True, 'hid', '?', False, True, '?'],
                [False, True, True, True, '?', 'hid', '?', True],
                [True, True, False, 'hid', '?', True, True, '?'],
            ],
            'oneside_twocouples_false': [
                ['?', True, False, True, True, False, False, False],
                [False, True, '?', False, True, True, False, False],
                [True, True, False, True, '?', False, False, False],
                [False, True, True, False, '?', True, False, False],
                ['?', False, True, True, False, True, False, False],
                [True, False, '?', True, False, True, False, False],
                [True, '?', False, True, True, False, False, False],
                [False, '?', True, False, True, True, False, False],
                [False, True, True, False, True, '?', False, False],
                [True, True, False, '?', True, False, False, False],
                [True, False, True, True, False, '?', False, False],
                [True, False, True, '?', False, True, False, False],
            ],
            'oneside_twocouples_true': [
                ['?', False, True, True, False, 'hid', False, True],
                [True, False, '?', 'hid', False, True, True, False],
                [True, '?', False, 'hid', True, False, True, False],
                [False, '?', True, False, True, 'hid', False, True],
                [True, True, False, 'hid', '?', False, True, False],
                [False, True, True, False, '?', 'hid', False, True],
                [True, False, True, '?', False, 'hid', False, True],
                [True, False, True, 'hid', False, '?', True, False],
            ],
            'onechunk_twocouples_false': [
                [True, True, False, False, True, False, '?', False],
                [False, True, True, False, True, False, False, '?'],
                [True, False, True, False, False, True, '?', False],
                [True, False, True, True, False, False, False, '?'],
            ],
            'onechunk_twocouples_true': [
                [True, False, True, False, False, 'hid', '?', True],
                [True, False, True, 'hid', False, False, True, '?'],
            ]
        }

        random_nb = variant.count('random')
        if random_nb == 3:
            variant = random.choice(list(
                labels_configurations.keys())).split(sep='_')
        elif random_nb == 2:
            if variant[0] == 'random' and variant[1] == 'random':
                if variant[2] == 'false':
                    variant[0] = random.choice(ALL_LENGTHS_TO_CALCULATE)
                    if variant[0] in [
                            'twosides', 'twochunks', 'onesideonechunk'
                    ]:
                        variant[1] = 'all'
                    else:
                        variant[1] = random.choice(['all', 'twocouples'])
                elif variant[2] == 'true':
                    variant[0] = random.choice(
                        ['oneside', 'onechunk', 'twosides', 'onesideonechunk'])
                    if variant[0] in ['oneside', 'onechunk']:
                        variant[1] = random.choice(['all', 'twocouples'])
                    else:
                        variant[1] = 'all'
            elif variant[0] == 'random' and variant[2] == 'random':
                if variant[1] == 'all':
                    variant[0] = random.choice(ALL_LENGTHS_TO_CALCULATE)
                    if variant[0] == 'twochunks':
                        variant[2] = 'false'
                    else:
                        variant[2] = random.choice(['true', 'false'])
                elif variant[1] == 'twocouples':
                    variant[0] = random.choice(['oneside', 'onechunk'])
                    variant[2] = random.choice(['true', 'false'])
            elif variant[1] == 'random' and variant[2] == 'random':
                if variant[0] in ['oneside', 'onechunk']:
                    variant[1] = random.choice(['all', 'twocouples'])
                    variant[2] = random.choice(['true', 'false'])
                elif variant[0] in ['twosides', 'onesideonechunk']:
                    variant[1] = 'all'
                    variant[2] = random.choice(['true', 'false'])
                elif variant[0] == 'twochunks':
                    variant[1] = 'all'
                    variant[2] = 'false'
        elif random_nb == 1:
            if variant[0] == 'random':
                if variant[1] == 'twocouples':
                    variant[0] = random.choice(['oneside', 'onechunk'])
                elif variant[1] == 'all':
                    if variant[2] == 'true':
                        variant[0] = random.choice([
                            'oneside', 'onechunk', 'twosides',
                            'onesideonechunk'
                        ])
                    elif variant[2] == 'false':
                        variant[0] = random.choice(ALL_LENGTHS_TO_CALCULATE)
            elif variant[1] == 'random':
                if variant[0] in ['oneside', 'onechunk']:
                    variant[1] = random.choice(['all', 'twocouples'])
                elif variant[0] in ['twosides', 'onesideonechunk']:
                    variant[1] = 'all'
                elif variant[0] == 'twochunks':
                    if variant[2] == 'false':
                        variant[1] = 'all'
                    else:
                        raise error.XMLFileFormatError('Invalid variants: '
                                                       '"twochunks_*_true".')
            elif variant[2] == 'random':
                if variant[0] in ['oneside', 'onechunk']:
                    variant[2] = random.choice(['true', 'false'])
                elif variant[1] == 'twocouples':
                    raise error.XMLFileFormatError('Invalid variants: '
                                                   '"two..._twocouples_*".')
                else:
                    if variant[0] == 'twochunks':
                        variant[2] = 'false'
                    else:
                        variant[2] = random.choice(['true', 'false'])

        variant_key = '_'.join(variant)
        labels_conf = random.choice(labels_configurations[variant_key])

        self.figure.setup_labels(
            labels_conf,
            segments_list=self.figure.small +
            [self.figure.u, self.figure.side[1], self.figure.v] +
            self.figure.chunk)

        self.figure.setup_labels(
            [labels_conf[3], labels_conf[5]],
            segments_list=[self.figure.side[0], self.figure.side[2]])

        lengths_to_calculate = [
            s.length_name for s in self.figure.small + self.figure.side
            if s.label == Value('?')
        ]

        chunks_to_calculate = []
        chunks_infos = []

        if 'chunk' in variant_key:
            if len(lengths_to_calculate) == 1:
                chunks_to_calculate = [None]
                chunks_infos = [None]
            if labels_conf[6] == '?':
                # This matches chunk0
                chunks_to_calculate += [self.figure.chunk[0].length_name]
                chunks_infos += [
                    (self.figure.side[0].length_name,
                     self.figure.small[0].length_name,
                     self.figure.side[0].length, self.figure.small[0].length)
                ]
                if not labels_conf[0]:
                    lengths_to_calculate += [self.figure.small[0].length_name]
                else:
                    lengths_to_calculate += [self.figure.side[0].length_name]
            if labels_conf[7] == '?':
                # This matches chunk1
                chunks_to_calculate += [self.figure.chunk[1].length_name]
                chunks_infos += [
                    (self.figure.side[2].length_name,
                     self.figure.small[2].length_name,
                     self.figure.side[2].length, self.figure.small[2].length)
                ]
                if not labels_conf[2]:
                    lengths_to_calculate += [self.figure.small[2].length_name]
                else:
                    lengths_to_calculate += [self.figure.side[2].length_name]

        self.line1 = self.figure.small[1].length_name
        self.line2 = self.figure.side[1].length_name
        lengths_asked_for = [
            s.length_name
            for s in self.figure.small + self.figure.side + self.figure.chunk
            if s.label == Value('?')
        ]
        self.length1_name = lengths_asked_for[0]
        if len(lengths_asked_for) == 2:
            self.length2_name = lengths_asked_for[1]

        if len(lengths_asked_for) == 1:
            self.wording = _('The drawn figure is out of shape. {newline} '
                             'The lengths are given in {length_unit}. '
                             '{newline} '
                             'The {line1} is parallel to {line2}. {newline} '
                             '{newline} '
                             'Determine the length of {length1_name}.')
        else:
            self.wording = _('The drawn figure is out of shape. {newline} '
                             'The lengths are given in {length_unit}. '
                             '{newline} '
                             'The {line1} is parallel to {line2}. {newline} '
                             '{newline} '
                             'Determine the lengths of {length1_name} '
                             'and {length2_name}.')
        setup_wording_format_of(self)

        preamble = ''
        if variant_key.endswith('true'):
            self.pre_reso0 = self.pre_reso1 = ''
            if labels_conf[6] is True:
                pre_equality0 = SubstitutableEquality(
                    [
                        Item(self.side0_length_name),
                        Sum([
                            Item(self.small0_length_name),
                            Item(self.chunk0_length_name)
                        ])
                    ], {
                        Value(self.small0_length_name):
                        Value(self.figure.small[0].length),
                        Value(self.chunk0_length_name):
                        Value(self.figure.chunk[0].length)
                    })
                pre_equality0_str = pre_equality0.into_str()
                pre_equation0 = Equation(pre_equality0.substitute())
                self.pre_reso0 = shared.machine.write_math_style1(
                    pre_equality0_str) \
                    + pre_equation0.auto_resolution(
                        dont_display_equations_name=True,
                        decimal_result=2,
                        unit=self.length_unit,
                        underline_result=True)
            if labels_conf[7] is True:
                pre_equality1 = SubstitutableEquality(
                    [
                        Item(self.side1_length_name),
                        Sum([
                            Item(self.small1_length_name),
                            Item(self.chunk1_length_name)
                        ])
                    ], {
                        Value(self.small1_length_name):
                        Value(self.figure.small[2].length),
                        Value(self.chunk1_length_name):
                        Value(self.figure.chunk[1].length)
                    })
                pre_equality1_str = pre_equality1.into_str()
                pre_equation1 = Equation(pre_equality1.substitute())
                self.pre_reso1 = shared.machine.write_math_style1(
                    pre_equality1_str) \
                    + pre_equation1.auto_resolution(
                        dont_display_equations_name=True,
                        decimal_result=2,
                        unit=self.length_unit,
                        underline_result=True)
            if labels_conf[6] is True and labels_conf[7] is True:
                preamble = _('Note: {pre_reso0} {newline} and: {pre_reso1} '
                             '{newline} ')
            elif labels_conf[6] is True:
                preamble = _('Note: {pre_reso0} {newline} ')
            elif labels_conf[7] is True:
                preamble = _('Note: {pre_reso1} {newline} ')

        self.ratios = shared.machine.write_math_style1(
            self.figure.ratios_equalities().into_str(
                as_a_quotients_equality=True))
        self.ratios_substituted = shared.machine.write_math_style1(
            self.figure.ratios_equalities_substituted().into_str(
                as_a_quotients_equality=True))

        self.resolution0 = self.figure.ratios_equalities_substituted()\
            .into_crossproduct_equation(Item(lengths_to_calculate[0]))\
            .auto_resolution(dont_display_equations_name=True,
                             skip_first_step=True,
                             skip_fraction_simplification=True,
                             decimal_result=2,
                             unit=self.length_unit,
                             underline_result=True)
        lengths_resolutions_part = _('hence: {resolution0} ')
        if len(lengths_to_calculate) == 2:
            self.resolution1 = self.figure.ratios_equalities_substituted()\
                .into_crossproduct_equation(Item(lengths_to_calculate[1]))\
                .auto_resolution(dont_display_equations_name=True,
                                 skip_first_step=True,
                                 skip_fraction_simplification=True,
                                 decimal_result=2,
                                 unit=self.length_unit,
                                 underline_result=True)
            lengths_resolutions_part = shared.machine.write(
                lengths_resolutions_part + _('and: {resolution1} '),
                multicolumns=2)

        chunks_part = ''
        if len(chunks_to_calculate):
            if chunks_to_calculate[0] is not None:
                chunk_equality0 = SubstitutableEquality(
                    [
                        Item(chunks_to_calculate[0]),
                        Sum([
                            Item(chunks_infos[0][0]),
                            Item(('-', chunks_infos[0][1]))
                        ])
                    ], {
                        Value(chunks_infos[0][0]): Value(chunks_infos[0][2]),
                        Value(chunks_infos[0][1]): Value(chunks_infos[0][3])
                    })
                chunk_equality0_str = chunk_equality0.into_str()
                chunk_equation0 = Equation(chunk_equality0.substitute())
                self.chunk_reso0 = shared.machine.write_math_style1(
                    chunk_equality0_str) \
                    + chunk_equation0.auto_resolution(
                        dont_display_equations_name=True,
                        decimal_result=2,
                        unit=self.length_unit,
                        underline_result=True)
                chunks_part += _('so: {chunk_reso0} ')
            else:
                chunks_part += '~\n\n\\newline\\newline\\newline\\newline\n\n'

            if len(chunks_to_calculate) == 2:
                chunk_equality1 = SubstitutableEquality(
                    [
                        Item(chunks_to_calculate[1]),
                        Sum([
                            Item(chunks_infos[1][0]),
                            Item(('-', chunks_infos[1][1]))
                        ])
                    ], {
                        Value(chunks_infos[1][0]): Value(chunks_infos[1][2]),
                        Value(chunks_infos[1][1]): Value(chunks_infos[1][3])
                    })
                chunk_equality1_str = chunk_equality1.into_str()
                chunk_equation1 = Equation(chunk_equality1.substitute())
                self.chunk_reso1 = shared.machine.write_math_style1(
                    chunk_equality1_str) \
                    + chunk_equation1.auto_resolution(
                        dont_display_equations_name=True,
                        decimal_result=2,
                        unit=self.length_unit,
                        underline_result=True)
                chunks_part = shared.machine.write(chunks_part +
                                                   _('so: {chunk_reso1} '),
                                                   multicolumns=2)

        ans_variant = options.get('ans_variant', 'default')
        ans_texts = {
            'default':
            _('As: {line1} {parallel_to} {line2}, '
              '{point0_name} {belongs_to} {side0_length_name} and '
              '{point1_name} {belongs_to} {side1_length_name}, '
              'then by the intercept theorem: {newline} '
              '{ratios} '
              'thus: {ratios_substituted} '),
            'alternative1':
            _('As {line1} is parallel to {line2}, '
              'and as the line {chunk0_length_name} cuts '
              'the line {chunk1_length_name} at point '
              '{main_vertex_name}, '
              'then by the intercept theorem: {newline} '
              '{ratios} '
              'thus: {ratios_substituted} '),
            'alternative2':
            _('As: {line1} is parallel to {line2}, '
              'and as {vertex1_name}, {point0_name} and '
              '{main_vertex_name} on one hand, '
              '{vertex2_name}, {point1_name} and '
              '{main_vertex_name} on the other hand,'
              'are aligned in the same order, '
              'then by the intercept theorem: {newline} '
              '{ratios} '
              'thus: {ratios_substituted} ')
        }

        self.answer_wording = preamble \
            + ans_texts[ans_variant] \
            + lengths_resolutions_part \
            + chunks_part

        setup_wording_format_of(self, w_prefix='answer_')
Пример #44
0
def test_setup_wording_format_of_03(ow2):
    """Checks if obj.wording is correctly setup."""
    setup_wording_format_of(ow2)
    assert ow2.nb3_volume_unit3 == '\\SI{11}{cm^{3}}'
Пример #45
0
    def __init__(self, build_data, **kwargs):
        """
        The two numbers in build_data are the factors of the product.

        The first number will be the possible divisor (i.e. questions will be:
        "... is divisible by nb1. (True or false?)").

        kwargs may contain a 'variant' parameter.
        It can contain these values:
        - 'random' (default), then it will randomly be replaced by 'true'
          or 'false'
        - 'true', then the answer will be true
        - 'false', then a non zero remainder will be added:
          result = nb1 × nb2 + remainder
           and the answer will be false

        :param build_data: a tuple of 2 numbers
        :type build_data: tuple
        """
        super().setup('minimal', **kwargs)
        super().setup('division', nb=build_data, order='divisor,quotient',
                      **kwargs)

        variant = kwargs.get('variant', 'random')
        variant2 = kwargs.get('variant2', 'default')
        if variant == 'random':
            variant = random.choice(['true', 'false'])
        self.n1 = self.divisor
        if variant == 'true':
            self.answer = _('True')
            self.n2 = self.dividend
            if (self.n1 == 4
                and variant2 == 'ensure_no_confusion_between_rules'):
                if Number(self.n2).digits_sum() % 4 == 0:
                    self.n2 += 100
        else:
            self.answer = _('False')
            remainder = random.randint(1, self.divisor - 1)
            correction = 0
            if variant2 == 'ensure_no_confusion_between_rules':
                if self.n1 == 3:
                    if ((self.dividend - 1) % 100) % 3 == 0:
                        remainder = -1
                    else:
                        remainder = 1
                elif self.n1 == 9:
                    remainder = 9 - (self.dividend % 100) % 9
                elif self.n1 == 4:
                    remainder = 2
                    mod4 = Number(self.dividend + remainder).digits_sum() % 4
                    if mod4 != 0:
                        if Number(self.dividend + remainder).digit(100) < 7:
                            correction = 100 * (4 - mod4)
                        else:
                            correction = -100 * mod4
            self.n2 = self.dividend + remainder + correction
        statement = _('{n2} is divisible by {n1}.')
        nl = r'\newline' if self.slideshow else ''
        self.wording = r'{} {} {}'.format(statement, nl,
                                          _('(True or false?)'))
        setup_wording_format_of(self)
        self.transduration = 21
Пример #46
0
def test_setup_wording_format_of_04(ow2):
    """Checks if obj.wording is correctly setup."""
    setup_wording_format_of(ow2)
    assert ow2.nb1_length_unit1.startswith('\\SI{8}{')
Пример #47
0
def test_setup_wording_format_of_02(ow2):
    """Checks if obj.wording is correctly setup."""
    setup_wording_format_of(ow2)
    assert hasattr(ow2, 'name')
Пример #48
0
    def __init__(self, numbers_to_use, picture='true', **options):
        super().setup("minimal", **options)
        if numbers_to_use[0] < 11:
            raise ValueError('numbers_to_use[0] == {} whereas it should be '
                             '>= 11'.format(str(numbers_to_use[0])))
        numbers_to_use = (numbers_to_use[0] / 10, ) + numbers_to_use[1:]
        super().setup("numbers",
                      nb=numbers_to_use,
                      shuffle_nbs=False,
                      **options)
        super().setup("length_units", **options)
        super().setup("intercept_theorem_figure", butterfly=True, **options)

        self.figure.setup_labels([True, False, True, True, False, True],
                                 segments_list=self.figure.small +
                                 self.figure.side)

        self.line1 = self.figure.small[1].length_name
        self.line2 = self.figure.side[1].length_name

        self.wording = _('The drawn figure is out of shape. {newline} '
                         'The lengths are given in {length_unit}. '
                         '{newline} {newline} '
                         'Prove that {line1} is parallel to {line2}.')
        setup_wording_format_of(self)

        self.ratio1 = shared.machine.write_math_style1(
            Equality([
                Quotient(('+', self.figure.small[0].length_name,
                          self.figure.side[0].length_name)),
                Quotient(('+', self.figure.small[0].length,
                          self.figure.side[0].length))
            ]).printed)

        self.ratio2 = shared.machine.write_math_style1(
            Equality([
                Quotient(('+', self.figure.small[2].length_name,
                          self.figure.side[2].length_name)),
                Quotient(('+', self.figure.small[2].length,
                          self.figure.side[2].length))
            ]).printed)

        self.crossproduct = shared.machine.write_math_style1(
            Equality([
                Quotient(('+',
                          Product([
                              Item(self.figure.small[0].length),
                              Item(self.figure.side[2].length)
                          ]), Item(self.figure.side[0].length))),
                Item(self.figure.small[2].length)
            ]).printed)

        self.equal_ratios = shared.machine.write_math_style1(
            self.figure.ratios_for_converse().into_str(
                as_a_quotients_equality=True))

        ans_variant = options.get('ans_variant', 'default')
        ans_texts = {
            'default':
            _('\\begin{tabular}{ll}'
              'We have: & '
              '{main_vertex_name} {belongs_to} {chunk0_length_name}'
              ' \\\\ '
              ' & '
              '{main_vertex_name} {belongs_to} {chunk1_length_name}'
              ' \end{tabular}'),
            'alternative2':
            _('{vertex1_name}, {main_vertex_name} and '
              '{point0_name} on one hand, '
              '{vertex2_name}, {main_vertex_name} and '
              '{point1_name} on the other hand,'
              'are aligned in the same order. ')
        }

        ratios = _('\\begin{multicols}{2} '
                   'On one hand: {ratio1} '
                   'and on the other hand: {ratio2} '
                   '\end{multicols} '
                   'ans as: {crossproduct} '
                   'then: {equal_ratios} {newline} ')

        conclusion = _('Hence by the converse of the intercept theorem, '
                       '{line1} is parallel to {line2}.')

        self.answer_wording = ans_texts[ans_variant] + ratios + conclusion
        setup_wording_format_of(self, w_prefix='answer_')