Source code for mathmaker.lib.document.content.geometry.intercept_theorem_butterfly

# -*- coding: utf-8 -*-

# Mathmaker creates automatically maths exercises sheets
# with their answers
# Copyright 2006-2017 Nicolas Hainaux <nh.techn@gmail.com>

# This file is part of Mathmaker.

# Mathmaker is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# any later version.

# Mathmaker is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.

# You should have received a copy of the GNU General Public License
# along with Mathmaker; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA

import random

from mathmaker.lib import shared
from mathmaker.lib.tools.wording import setup_wording_format_of
from mathmaker.lib.core.root_calculus import Value
from mathmaker.lib.core.base_calculus import Item
from mathmaker.lib.document.content import component

ALL_LENGTHS_TO_CALCULATE = ['oneside', 'twosides']


[docs]class sub_object(component.structure): def __init__(self, build_data, picture='true', **options): super().setup("minimal", **options) if build_data[0] < 11: raise ValueError('build_data[0] == {} whereas it should be ' '>= 11'.format(str(build_data[0]))) build_data = (build_data[0] / 10, ) + build_data[1:] super().setup("numbers", nb=build_data, 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 ValueError('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 ValueError('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 ValueError('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()) self.ratios_substituted = shared.machine.write_math_style1( self.figure.ratios_equalities_substituted().into_str()) 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_')
[docs] def q(self, **options): return shared.machine.write_layout( (1, 2), [10, 10], [self.wording.format(**self.wording_format), shared.machine.insert_picture(self.figure, scale=0.7, top_aligned_in_a_tabular=True)])
[docs] def a(self, **options): return self.answer_wording.format(**self.answer_wording_format)
# TODO: create the "js" answer (for interactive pdf) # def js_a(self, **kwargs): # return [self......jsprinted]