mathmaker
0.4(alpha)
|
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 ------------------------------------------