mathmaker  0.6(alpha)
mamk_misc/doc/mathmaker4doxygen/sheet/exercise/X_Factorization.py
00001 # -*- coding: utf-8 -*-
00002 
00003 # Mathmaker creates automatically maths exercises sheets
00004 # with their answers
00005 # Copyright 2006-2014 Nicolas Hainaux <nico_h@users.sourceforge.net>
00006 
00007 # This file is part of Mathmaker.
00008 
00009 # Mathmaker is free software; you can redistribute it and/or modify
00010 # it under the terms of the GNU General Public License as published by
00011 # the Free Software Foundation; either version 3 of the License, or
00012 # any later version.
00013 
00014 # Mathmaker is distributed in the hope that it will be useful,
00015 # but WITHOUT ANY WARRANTY; without even the implied warranty of
00016 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017 # GNU General Public License for more details.
00018 
00019 # You should have received a copy of the GNU General Public License
00020 # along with Mathmaker; if not, write to the Free Software
00021 # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
00022 
00023 from lib import *
00024 from X_Structure import X_Structure
00025 import question
00026 #from core import *
00027 from core.calculus import *
00028 from lib.common import alphabet
00029 
00030 # Here the list of available values for the parameter x_kind='' and the
00031 # matching self.x_subkind values
00032 # Note : the bypass value allows to give the value of *x_subkind* directly to
00033 # the matching question Constructor, bypassing the action of the present class
00034 AVAILABLE_X_KIND_VALUES = \
00035     {'short_test' : ['medium_level', 'hard_level'],
00036      'mini_test' : ['two_factorizations'],
00037      'preformatted' : ['level_01_easy', 'level_02_easy',
00038                        'level_02_intermediate', 'level_03_sum_squares',
00039                        'level_03_difference_squares',
00040                        'level_03_squares_differences',
00041                        'level_03_some_not_factorizable',
00042                        'level_03_all_kinds'],
00043      'bypass' : ['level_01']
00044     }
00045 
00046 X_LAYOUT_UNIT = "cm"
00047 ALT_DEFAULT_LAYOUT = { 'exc' : [ None,                    'all'
00048                                ],
00049                        'ans' : [ [2,         9, 9],       (1, 1,
00050                                                            1, 1),
00051                                  None,                    1
00052                                ]
00053                      }
00054 # ----------------------  lines_nb    col_widths   questions
00055 X_LAYOUTS = {'default' :
00056               { 'exc' : [ None,                    'all'
00057                         ],
00058                 'ans' : [ [1,         6, 6, 6],    (1, 1, 1)
00059                         ]
00060               },
00061 
00062              ('short_test', 'hard_level') :
00063               { 'exc' : [ None,                    'all'
00064                         ],
00065                 'ans' : [ [4,         9, 9],       (1, 1,
00066                                                     1, 1,
00067                                                     1, 1,
00068                                                     1, 1)
00069                         ]
00070               },
00071 
00072              ('mini_test', 'two_factorizations') :
00073               { 'exc' : [ None,                    'all'
00074                         ],
00075                 'ans' : [ None,                    'all'
00076                         ]
00077               },
00078 
00079              ('preformatted', 'level_01_easy') :
00080               { 'exc' : [ None,                    'all'
00081                         ],
00082                 'ans' : [ ['?',         6, 6, 6],  'all'
00083                         ]
00084               },
00085 
00086              ('preformatted', 'level_02_easy') : ALT_DEFAULT_LAYOUT,
00087 
00088              ('preformatted', 'level_02_intermediate') : ALT_DEFAULT_LAYOUT,
00089 
00090              ('preformatted', 'level_03_some_not_factorizable') :
00091               { 'exc' : [ None,                    'all'
00092                         ],
00093                 'ans' : [ ['?',         6, 6, 6],  'all'
00094                         ]
00095               },
00096 
00097              ('bypass', 'level_01') :
00098               { 'exc' : [ None,                    'all'
00099                         ],
00100                 'ans' : [ ['?',         9,9],      'all'
00101                         ]
00102               }
00103 
00104 
00105             }
00106 
00107 # ------------------------------------------------------------------------------
00108 # --------------------------------------------------------------------------
00109 # ------------------------------------------------------------------------------
00110 ##
00111 # @class X_Factorization
00112 # @brief Factorization exercises.
00113 class X_Factorization(X_Structure):
00114 
00115 
00116 
00117 
00118 
00119     # --------------------------------------------------------------------------
00120     ##
00121     #   @brief Constructor.
00122     #   @param embedded_machine The machine that will be used to write output.
00123     #   @param **options Options detailed below :
00124     #          - start_number=<integer>
00125     #                         (should be >= 1)
00126     #          - number_of_questions=<integer>
00127     #            /!\ only useful if you use x_kind and not preformatted
00128     #                         (should be >= 1)
00129     #          - x_kind=<string>
00130     #                         ...
00131     #                         ...
00132     #          - preformatted=<string>
00133     #            /!\ preformatted is useless with short_test
00134     #            /!\ number_of_questions is useless with preformatted
00135     #            /!\ if you use it with the x_kind option, ensure there's a
00136     #                preformatted possibility with this option
00137     #                         'yes'
00138     #                         'OK'
00139     #                         any other value will be understood as 'no'
00140     #          - short_test=<string>
00141     #            /!\ the x_kind option above can't be used along this option
00142     #            use subtype if you need to make different short_test exercises
00143     #                         'yes'
00144     #                         'OK'
00145     #                         any other value will be understood as 'no'
00146     #          - subtype=<string>
00147     #                         ...
00148     #                         ...
00149     #   @todo Complete the description of the possible options !
00150     #   @return One instance of exercise.Factorization
00151     def __init__(self, embedded_machine, x_kind='default_nothing', **options):
00152         self.derived = True
00153         X_Structure.__init__(self, embedded_machine,
00154                              x_kind, AVAILABLE_X_KIND_VALUES, X_LAYOUTS,
00155                              X_LAYOUT_UNIT, **options)
00156         # The purpose of this next line is to get the possibly modified
00157         # value of **options
00158         options = self.options
00159 
00160         # BEGINING OF THE ZONE TO REWRITE -------------------------------------
00161 
00162         default_question = question.Q_Factorization
00163 
00164         # TEXTS OF THE EXERCISE
00165         self.text = {'exc' : _("Factorise : "),
00166                      'ans'   : ""
00167                     }
00168 
00169         # alternate texts section
00170         if self.x_kind == 'level_02_easy' \
00171            or self.x_kind == 'level_02_intermediate':
00172             self.text = {'exc' : _("Factorise :"),
00173                          'ans' : ""
00174                         }
00175 
00176         elif self.x_kind == 'level_03_some_not_factorizable' \
00177             or (self.x_kind == 'mini_test' \
00178                 and self.x_subkind == 'two_factorizations'):
00179         #___
00180             self.text = {'exc' : _("Factorise, if possible :"),
00181                          'ans' : ""
00182                         }
00183 
00184         # SHORT TEST & OTHER PREFORMATTED EXERCISES
00185         if self.x_kind == 'short_test':
00186             if self.x_subkind == 'easy_level':
00187                 # NOTE : the algebra (easy) short test uses directly one
00188                 # question and passes its arguments (x_kind...) directly
00189                 # to question.Factorization() (see below, at the end)
00190                 pass
00191 
00192             elif self.x_subkind == 'medium_level':
00193                 lil_box = []
00194 
00195                 lil_box.append(default_question(
00196                                    self.machine,
00197                                    q_kind='level_01',
00198                                    q_subkind='ax² + bx',
00199                                    expression_number=0))
00200 
00201                 if randomly.heads_or_tails():
00202                     lil_box.append(default_question(
00203                                        self.machine,
00204                                        q_kind='level_01',
00205                                        q_subkind='ax² + b',
00206                                        expression_number=0))
00207                 else:
00208                     lil_box.append(default_question(
00209                                        self.machine,
00210                                        q_kind='level_01',
00211                                        q_subkind='ax + b',
00212                                        expression_number=0))
00213 
00214                 lil_box.append(default_question(
00215                                    self.machine,
00216                                    q_kind='level_01',
00217                                    q_subkind='not_factorizable',
00218                                    expression_number=0))
00219 
00220                 for i in range(len(lil_box)):
00221                         q = randomly.pop(lil_box)
00222                         q.expression.set_name(alphabet.UPPERCASE[i])
00223                         for expression in q.steps:
00224                             expression.set_name(alphabet.UPPERCASE[i])
00225                         self.questions_list.append(q)
00226 
00227             elif self.x_subkind == 'hard_level':
00228                 lil_box = []
00229 
00230                 l03_kinds = ['sum_square_mixed',
00231                              'difference_square_mixed',
00232                              randomly.pop(
00233                                         ['squares_difference',
00234                                          'squares_difference_mixed'
00235                                          ]),
00236                              randomly.pop(
00237                                         ['fake_01',
00238                                          'fake_01_mixed',
00239                                          'fake_02',
00240                                          'fake_02_mixed',
00241                                          'fake_03',
00242                                          'fake_03_mixed'
00243                                          ]),
00244                              'fake_04_any_mixed'
00245                              ]
00246 
00247 
00248                 for n in range(len(l03_kinds)):
00249                     lil_box.append(default_question(
00250                                    self.machine,
00251                                    q_kind='level_03',
00252                                    q_subkind=l03_kinds[n],
00253                                    expression_number=n+1))
00254 
00255 
00256                 l02_kinds = [('type_2_A1', 'no'),
00257                              ('type_2_A0', 'yes'),
00258                              ('type_4_A0', 'no')]
00259 
00260                 for n in range(len(l02_kinds)):
00261                     lil_box.append(default_question(
00262                                    self.machine,
00263                                    q_kind='level_02',
00264                                    q_subkind=l02_kinds[n][0],
00265                                    max_coeff=10,
00266                                    minus_sign=l02_kinds[n][1],
00267                                    expression_number=n+len(l03_kinds)+1)
00268                                    )
00269 
00270                 for i in range(len(lil_box)):
00271                     q = randomly.pop(lil_box)
00272                     q.expression.set_name(alphabet.UPPERCASE[i])
00273                     for expression in q.steps:
00274                         if isinstance(expression, Expression):
00275                             expression.set_name(alphabet.UPPERCASE[i])
00276                     self.questions_list.append(q)
00277 
00278         elif self.x_kind == 'mini_test':
00279             if self.x_subkind == 'two_factorizations':
00280                 lil_box = []
00281 
00282                 lil_box.append(default_question(self.machine,
00283                             q_kind='level_03',
00284                             q_subkind=randomly.pop(['any_fake',
00285                                                     'any_true'],
00286                                                     weighted_table=[0.2,
00287                                                                     0.8]
00288                                                   ),
00289                             expression_number=1))
00290 
00291                 l02_kinds = [('type_2_A1', 'no'),
00292                              ('type_2_A0', 'yes'),
00293                              ('type_4_A0', 'no')]
00294 
00295                 n = randomly.pop([0, 1, 2])
00296 
00297                 lil_box.append(default_question(
00298                                    self.machine,
00299                                    q_kind='level_02',
00300                                    q_subkind=l02_kinds[n][0],
00301                                    max_coeff=10,
00302                                    minus_sign=l02_kinds[n][1],
00303                                    expression_number=2)
00304                                    )
00305 
00306                 for i in range(len(lil_box)):
00307                     q = randomly.pop(lil_box)
00308                     q.expression.set_name(\
00309                                     alphabet.UPPERCASE[i + self.start_number])
00310                     for expression in q.steps:
00311                         if isinstance(expression, Expression):
00312                             expression.set_name(\
00313                                     alphabet.UPPERCASE[i + self.start_number])
00314                     self.questions_list.append(q)
00315 
00316 
00317         elif self.x_kind == 'preformatted':
00318             if self.x_subkind == 'level_01_easy':
00319                 # n is the number of questions still left to do
00320                 n = 10
00321                 lil_box = []
00322 
00323                 lil_box.append(default_question(
00324                                self.machine,
00325                                q_kind='level_01',
00326                                q_subkind='ax² + bx',
00327                                expression_number=10-n))
00328 
00329                 n -= 1
00330 
00331                 if randomly.heads_or_tails():
00332                     lil_box.append(default_question(
00333                                    self.machine,
00334                                    q_kind='level_01',
00335                                    q_subkind='ax² + bx',
00336                                    expression_number=10-n))
00337 
00338                     n -= 1
00339 
00340                 lil_box.append(default_question(
00341                                self.machine,
00342                                q_kind='level_01',
00343                                q_subkind='ax² + b',
00344                                expression_number=10-n))
00345 
00346                 n -= 1
00347 
00348                 if randomly.heads_or_tails():
00349                     lil_box.append(default_question(
00350                                    self.machine,
00351                                    q_kind='level_01',
00352                                    q_subkind='ax² + b',
00353                                    expression_number=10-n))
00354 
00355                     n -= 1
00356 
00357                 if randomly.heads_or_tails():
00358                     lil_box.append(default_question(
00359                                    self.machine,
00360                                    q_kind='level_01',
00361                                    q_subkind='ax² + b',
00362                                    expression_number=10-n))
00363 
00364                     n -= 1
00365 
00366                 for i in range(n):
00367                     lil_box.append(default_question(
00368                                    self.machine,
00369                                    q_kind='level_01',
00370                                    q_subkind='ax + b',
00371                                    expression_number=n-i)
00372                                   )
00373 
00374                 for i in range(len(lil_box)):
00375                     q = randomly.pop(lil_box)
00376                     q.expression.set_name(alphabet.UPPERCASE[i])
00377                     for expression in q.steps:
00378                         expression.set_name(alphabet.UPPERCASE[i])
00379                     self.questions_list.append(q)
00380 
00381 
00382 
00383             elif self.x_subkind == 'level_02_easy':
00384                 subkinds = ['type_1_A0',
00385                             'type_1_D0',
00386                             'type_1_G0']
00387 
00388                 n1 = len(subkinds)
00389 
00390                 for i in range(n1):
00391                     self.questions_list.append(default_question(
00392                                                self.machine,
00393                                                q_kind='level_02',
00394                                                q_subkind=randomly.pop(subkinds),
00395                                                minus_sign='no',
00396                                                expression_number=i)
00397                                               )
00398 
00399                 subkinds = ['type_2_A0',
00400                             'type_2_D0']
00401 
00402                 n2 = len(subkinds)
00403 
00404                 for i in range(n2):
00405                     self.questions_list.append(default_question(
00406                                                self.machine,
00407                                                q_kind='level_02',
00408                                                q_subkind=randomly.pop(subkinds),
00409                                                minus_sign='no',
00410                                                expression_number=i+n1)
00411                                               )
00412 
00413             elif self.x_subkind == 'level_02_intermediate':
00414                 subkinds = ['type_1_D',
00415                             'type_1_G0',
00416                             'type_1_1']
00417 
00418                 n1 = len(subkinds)
00419 
00420                 for i in range(n1):
00421                     self.questions_list.append(default_question(
00422                                                self.machine,
00423                                                q_kind='level_02',
00424                                                q_subkind=randomly.pop(subkinds),
00425                                                minus_sign='no',
00426                                                expression_number=i)
00427                                               )
00428 
00429                 subkinds = randomly.pop([['type_2_A0', 'type_2_D1'],
00430                                          ['type_2_A1', 'type_2_D0']])
00431 
00432                 n2 = len(subkinds)
00433 
00434                 for i in range(n2):
00435                     self.questions_list.append(default_question(
00436                                                self.machine,
00437                                                q_kind='level_02',
00438                                                q_subkind=randomly.pop(subkinds),
00439                                                minus_sign='no',
00440                                                expression_number=i+n1)
00441                                               )
00442 
00443             elif self.x_subkind == 'level_03_sum_squares':
00444                 lil_box = []
00445 
00446                 for n in range(2):
00447                     lil_box.append(default_question(
00448                                    self.machine,
00449                                    q_kind='level_03',
00450                                    q_subkind='sum_square',
00451                                    expression_number=n+1))
00452 
00453                 lil_box.append(default_question(
00454                                    self.machine,
00455                                    q_kind='level_03',
00456                                    q_subkind='sum_square_mixed',
00457                                    expression_number=n+1))
00458 
00459                 for i in range(len(lil_box)):
00460                     q = lil_box[i]
00461                     q.expression.set_name(alphabet.UPPERCASE[i])
00462                     for expression in q.steps:
00463                         if isinstance(expression, Expression):
00464                             expression.set_name(alphabet.UPPERCASE[i])
00465                     self.questions_list.append(q)
00466 
00467             elif self.x_subkind == 'level_03_difference_squares':
00468                 lil_box = []
00469 
00470                 for n in range(2):
00471                     lil_box.append(default_question(
00472                                    self.machine,
00473                                    q_kind='level_03',
00474                                    q_subkind='difference_square',
00475                                    expression_number=n+1))
00476 
00477                 lil_box.append(default_question(
00478                                    self.machine,
00479                                    q_kind='level_03',
00480                                    subkind ='difference_square_mixed',
00481                                    expression_number=n+1))
00482 
00483                 for i in range(len(lil_box)):
00484                     q = lil_box[i]
00485                     q.expression.set_name(alphabet.UPPERCASE[i])
00486                     for expression in q.steps:
00487                         if isinstance(expression, Expression):
00488                             expression.set_name(alphabet.UPPERCASE[i])
00489                     self.questions_list.append(q)
00490 
00491 
00492 
00493             elif self.x_subkind == 'level_03_squares_differences':
00494                 lil_box = []
00495 
00496                 for n in range(2):
00497                     lil_box.append(default_question(
00498                                    self.machine,
00499                                    q_kind='level_03',
00500                                    q_subkind='squares_difference',
00501                                    expression_number=n+1))
00502 
00503                 lil_box.append(default_question(
00504                                    self.machine,
00505                                    q_kind='level_03',
00506                                    q_subkind='squares_difference_mixed',
00507                                    expression_number=n+1))
00508 
00509                 for i in range(len(lil_box)):
00510                     q = lil_box[i]
00511                     q.expression.set_name(alphabet.UPPERCASE[i])
00512                     for expression in q.steps:
00513                         if isinstance(expression, Expression):
00514                             expression.set_name(alphabet.UPPERCASE[i])
00515                     self.questions_list.append(q)
00516 
00517 
00518 
00519             elif self.x_subkind == 'level_03_some_not_factorizable':
00520                 lil_box = []
00521 
00522                 q1 = default_question(self.machine,
00523                                       q_kind='level_03',
00524                                       q_subkind='any_true_mixed',
00525                                       expression_number=1)
00526 
00527                 q2 = default_question(self.machine,
00528                                       q_kind='level_03',
00529                                       q_subkind='any_fake_straight',
00530                                       expression_number=2)
00531 
00532                 q1q2 = [q1, q2]
00533 
00534                 lil_box.append(randomly.pop(q1q2))
00535                 lil_box.append(randomly.pop(q1q2))
00536 
00537                 for n in range(3):
00538                     lil_box.append(default_question(self.machine,
00539                                                     q_kind='level_03',
00540                                                     q_subkind='any_true',
00541                                                     expression_number=n+3))
00542 
00543                 for n in range(2):
00544                     lil_box.append(default_question(self.machine,
00545                                                     q_kind='level_03',
00546                                                     q_subkind='any_fake',
00547                                                     expression_number=n+5))
00548 
00549                 for n in range(2):
00550                     lil_box.append(default_question(self.machine,
00551                                                     q_kind='level_03',
00552                                                     q_subkind='any',
00553                                                     expression_number=n+7))
00554 
00555 
00556 
00557                 for i in range(len(lil_box)):
00558                     q = lil_box[i]
00559                     q.expression.set_name(alphabet.UPPERCASE[i])
00560                     for expression in q.steps:
00561                         if isinstance(expression, Expression):
00562                             expression.set_name(alphabet.UPPERCASE[i])
00563                     self.questions_list.append(q)
00564 
00565 
00566 
00567             elif self.x_subkind == 'level_03_all_kinds':
00568                 all_kinds = ['sum_square',
00569                              'sum_square_mixed',
00570                              'difference_square',
00571                              'difference_square_mixed',
00572                              'squares_difference',
00573                              'squares_difference_mixed',
00574                              'fake_01',
00575                              'fake_01_mixed',
00576                              'fake_02',
00577                              'fake_02_mixed',
00578                              'fake_03',
00579                              'fake_03_mixed',
00580                              'fake_04_A',
00581                              'fake_04_A_mixed',
00582                              'fake_04_B',
00583                              'fake_04_B_mixed',
00584                              'fake_04_C',
00585                              'fake_04_C_mixed',
00586                              'fake_04_D',
00587                              'fake_04_D_mixed'
00588                              ]
00589 
00590                 lil_box = []
00591 
00592                 for n in range(len(all_kinds)):
00593                     lil_box.append(default_question(
00594                                    self.machine,
00595                                    q_kind='level_03',
00596                                    q_subkind=all_kinds[n],
00597                                    expression_number=n+1))
00598 
00599                 for i in range(len(lil_box)):
00600                     q = lil_box[i]
00601                     q.expression.set_name(alphabet.UPPERCASE[i])
00602                     for expression in q.steps:
00603                         if isinstance(expression, Expression):
00604                             expression.set_name(alphabet.UPPERCASE[i])
00605                     self.questions_list.append(q)
00606 
00607 
00608 
00609         # OTHER EXERCISES (BY_PASS OPTION)
00610         else:
00611             for i in range(self.q_nb):
00612                 self.questions_list.append(
00613                              default_question(self.machine,
00614                                         expression_number=i+self.start_number,
00615                                         q_kind = self.x_subkind,
00616                                         **options)
00617                                           )
00618 
00619 
00620     # --------------------------------------------------------------------------
00621     ##
00622     #   @brief Writes the answers of the questions to the output.
00623     #def write_answer(self):
00624     #    M = self.machine
00625     #    max_per_page = 12
00626     #    i_count = 0
00627     #    j = 0
00628     #    tabular_format = [3, "p{6 cm} p{6 cm} p{6 cm}"]
00629 
00630     #    if 'short_test' in self.options \
00631     #         and (self.options['short_test'] == 'hard_level'):
00632     #    #___
00633     #        tabular_format = [2, "p{9 cm} p{9 cm}"]
00634 
00635     #    M.write_tabular_begins(tabular_format[1])
00636     #    for i in xrange(len(self.questions_list)):
00637     #        j += 1
00638     #        i_count += 1
00639     #        self.questions_list[i].write_answer()
00640     #        if j < tabular_format[0]:
00641     #            M.write_separator_tabular_columns()
00642     #        if j == tabular_format[0] and i_count < max_per_page - 1:
00643     #            M.write_separator_tabular_lines()
00644     #            j = 0
00645 
00646     #        if i_count == max_per_page - 1:
00647     #            i_count = 0
00648     #            j = 0
00649     #            M.write_tabular_ends()
00650     #            M.write_tabular_begins(tabular_format[1])
00651             #M.write_new_line()
00652 
00653     #    M.write_tabular_ends()
00654 
00655         #M.write_new_line()
00656 
00657 
00658 
00659 
00660 
00661 
00662         # END OF THE ZONE TO REWRITE ------------------------------------------