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