mathmaker
0.6(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 Q_Structure import Q_Structure 00025 00026 from core.base_calculus import * 00027 from core.calculus import * 00028 from lib.common.cst import * 00029 00030 AVAILABLE_Q_KIND_VALUES = {'level_01':['default', 00031 'ax + b', 00032 'ax² + b', 00033 'ax² + bx', 00034 'three_terms', 00035 'not_factorizable', 00036 'mixed', 00037 'mixed_factorizable'], 00038 00039 # C : common factor 00040 # F1 & F2 : the other factors 00041 # deg1 and deg2 represent polynoms 00042 # of 1st and 2d degree 00043 # F1 and F2 will be randomly exchanged at creation 00044 # of the expression, so a case like a×deg1 + a×deg2 00045 # contains also a×deg2 + a×deg1 00046 00047 # C × F1 ± C × F2 00048 00049 'level_02':['default', # synonym to type_123 00050 'type_123', # any of type_1, type_2, type_3 (a polynom as 00051 # common factor) 00052 'type_1', # any of type_1_* 00053 'type_1_ABC', # any of type 1 A, B and C cases 00054 'type_1_DEF', # any of type 1 D, E and F cases 00055 'type_1_GHI', # any of type 1 G, H and I cases 00056 'type_1_A', # any of A1 or A0 00057 'type_1_B', # any of B1 or B0 00058 'type_1_C', # synonym to C0 00059 'type_1_D', # any of D1 or D0 00060 'type_1_E', # . 00061 'type_1_F', # . 00062 'type_1_G', # . 00063 'type_1_H', # . 00064 'type_1_I', # . 00065 'type_1_0', # any of type_1_*0 cases 00066 'type_1_1', # any of type_1_*1 cases 00067 'type_1_A0', # a×deg1 + a×deg1' (deg* : at least 2 terms & a!=1) 00068 'type_1_B0', # a×deg2 + a×deg2' (deg* : at least 2 terms & a!=1) 00069 'type_1_C0', # a×deg1 + a×deg2 (deg* : at least 2 terms & a!=1) 00070 'type_1_D0', # ax×deg1 + ax×deg1' (deg* : at least 2 terms) 00071 'type_1_E0', # ax×deg2 + ax×deg2' (deg* : at least 2 terms) 00072 'type_1_F0', # ax×deg1 + ax×deg2 (deg* : at least 2 terms) 00073 'type_1_G0', # ax²×deg1 + ax²×deg1' (deg* : at least 2 terms) 00074 'type_1_H0', # ax²×deg2 + ax²×deg2' (deg* : at least 2 terms) 00075 'type_1_I0', # ax²×deg1 + ax²×deg2 (deg* : at least 2 terms) 00076 'type_1_A1', # a×deg1 + a×1 00077 'type_1_B1', # a×deg2 + a×1 00078 #'type_1_C1', # C1 has no sense 00079 'type_1_D1', # ax×deg1 + ax×1 00080 'type_1_E1', # ax×deg2 + ax×1 00081 #'type_1_F1', # F1 has no sense 00082 'type_1_G1', # ax²×deg1 + ax²×1 00083 'type_1_H1', # ax²×deg2 + ax²×1 00084 #'type_1_I1', # I1 has no sense 00085 00086 'type_2', # any of type_2_* 00087 'type_2_ABC', # any of type 2 A, B and C cases 00088 'type_2_DEF', # any of type 2 D, E and F cases 00089 'type_2_A', # any of A1 or A0 00090 'type_2_B', # any of B1 or B0 00091 'type_2_C', # synonym to C0 00092 'type_2_D', # any of D1 or D0 00093 'type_2_E', # . 00094 'type_2_F', # . 00095 'type_2_0', # any of type_2_*0 cases 00096 'type_2_1', # any of type_2_*1 cases 00097 'type_2_A0', # (ax+b)×deg1 + (ax+b)×deg1' 00098 'type_2_B0', # (ax+b)×deg2 + (ax+b)×deg2' 00099 'type_2_C0', # (ax+b)×deg1 + (ax+b)×deg2 00100 'type_2_D0', # (ax²+b)×deg1 + (ax²+b)×deg1' 00101 'type_2_E0', # (ax²+b)×deg2 + (ax²+b)×deg2' 00102 'type_2_F0', # (ax²+b)×deg1 + (ax²+b)×deg2 00103 'type_2_A1', # (ax+b)×deg1 + (ax+b)×1 00104 'type_2_B1', # (ax+b)×deg2 + (ax+b)×1 00105 #'type_2_C1', # C1 has no sense 00106 'type_2_D1', # (ax²+b)×deg1 + (ax²+b)×1 00107 'type_2_E1', # (ax²+b)×deg2 + (ax²+b)×1 00108 #'type_2_F1', # F1 has no sense 00109 00110 'type_3', # any of type_3_* 00111 'type_3_ABC', # any of type 3 A, B and C cases 00112 'type_3_A', # any of A1 or A0 00113 'type_3_B', # any of B1 or B0 00114 'type_3_C', # synonym to C0 00115 'type_3_0', # any of type_3_*0 cases 00116 'type_3_1' # any of type_3_*1 cases 00117 'type_3_A0', # (ax²+bx+c)×deg1 + (ax²+bx+c)×deg1' 00118 'type_3_B0', # (ax²+bx+c)×deg2 + (ax²+bx+c)×deg2' 00119 'type_3_C0', # (ax²+bx+c)×deg1 + (ax²+bx+c)×deg2 00120 'type_3_A1', # (ax²+bx+c)×deg1 + (ax²+bx+c)×1 00121 'type_3_B1', # (ax²+bx+c)×deg2 + (ax²+bx+c)×1 00122 #'type_3_C1' # C1 has no sense 00123 00124 'type_4_A0' # (ax+b)²×deg1 + (ax+b)×deg1' 00125 00126 ], 00127 00128 00129 # Here are the binomial identities 00130 00131 'level_03':['default', # synonym to 'any' 00132 'any', 00133 'any_mixed', # any but from the mixed types 00134 # (order of the terms is changed) 00135 'any_straight', # any but not from a mixed type 00136 'any_true', # any that can be factorized 00137 'any_fake', # any that cannot be factorized 00138 'any_true_straight', # any that can be factorized, not mixed 00139 'any_fake_straight', # any that cannot be factorized, not mixed 00140 'any_true_mixed', # any that can be factorized, mixed 00141 'any_fake_mixed', # any that cannot be factorized, mixed 00142 'sum_square', # (ax)² + 2abx + b² 00143 'sum_square_mixed', # like above but terms' order is changed 00144 'difference_square', # (ax)² - 2abx + b² 00145 'difference_square_mixed', # like above but terms' order is changed 00146 'squares_difference', # (ax)² - b² 00147 'squares_difference_mixed', # like above but terms' order is changed 00148 'fake_01', # 2×a×b doesn't match a² and b² (sum) 00149 'fake_01_mixed', # 2×a×b doesn't match a² and b² (sum, mixed) 00150 'fake_02', # 2×a×b doesn't match a² and b² (difference) 00151 'fake_02_mixed', # 2×a×b doesn't match a² and b² (difference, mixed) 00152 'fake_03', # (ax)² + b² 00153 'fake_03_mixed', # b² + (ax)² 00154 'fake_04_any', # any of fake_04 (signs don't match a binomial) 00155 'fake_04_any_straight', 00156 'fake_04_any_mixed', 00157 'fake_04_A', # (ax)² + 2abx - b² 00158 'fake_04_A_mixed', 00159 'fake_04_B', # -(ax)² + 2abx + b² 00160 'fake_04_B_mixed', 00161 'fake_04_C', # (ax)² - 2abx - b² 00162 'fake_04_C_mixed', 00163 'fake_04_D', # -(ax)² - 2abx + b² 00164 'fake_04_D_mixed' 00165 ] 00166 00167 00168 } 00169 00170 00171 00172 # ------------------------------------------------------------------------------ 00173 # -------------------------------------------------------------------------- 00174 # ------------------------------------------------------------------------------ 00175 ## 00176 # @class Q_Factorization 00177 # @brief Question related to the factorization of a literal expression 00178 class Q_Factorization(Q_Structure): 00179 00180 00181 00182 00183 00184 # -------------------------------------------------------------------------- 00185 ## 00186 # @brief Constructor. 00187 # @param embedded_machine The machine to be used 00188 # @param **options Any options 00189 # @return One instance of question.Q_Factorization 00190 def __init__(self, embedded_machine, q_kind='default_nothing', **options): 00191 self.derived = True 00192 00193 # The call to the mother class __init__() method will set the 00194 # fields matching optional arguments which are so far : 00195 # self.q_kind, self.q_subkind 00196 # plus self.machine, self.options (modified) 00197 Q_Structure.__init__(self, embedded_machine, 00198 q_kind, AVAILABLE_Q_KIND_VALUES, 00199 **options) 00200 # The purpose of this next line is to get the possibly modified 00201 # value of **options 00202 options = self.options 00203 q_subkind = self.q_subkind 00204 00205 # That's the number of the question, not of the expressions it might 00206 # contain ! 00207 self.number = "" 00208 00209 steps_method = None 00210 00211 if q_kind == 'level_01': 00212 steps_method = level_01 00213 00214 if q_subkind == 'mixed': 00215 q_subkind = randomly.pop(['default', 00216 'three_terms', 00217 'not_factorizable']) 00218 elif q_subkind == 'mixed_factorizable': 00219 q_subkind = randomly.pop(['default', 00220 'three_terms']) 00221 00222 #steps = level_01(subkind) 00223 00224 elif q_kind == 'level_02': 00225 steps_method = level_02 00226 00227 if q_subkind == 'default': 00228 q_subkind = 'type_123' 00229 00230 if q_subkind == 'type_123': 00231 q_subkind = randomly.pop(['type_1', 'type_2', 'type_3']) 00232 00233 if q_subkind == 'type_1': 00234 q_subkind = randomly.pop(['type_1_ABC', 00235 'type_1_DEF', 00236 'type_1_GHI']) 00237 00238 if q_subkind == 'type_1_ABC': 00239 q_subkind = randomly.pop(['type_1_A', 00240 'type_1_B', 00241 'type_1_C']) 00242 00243 if q_subkind == 'type_1_DEF': 00244 q_subkind = randomly.pop(['type_1_D', 00245 'type_1_E', 00246 'type_1_F']) 00247 00248 if q_subkind == 'type_1_GHI': 00249 q_subkind = randomly.pop(['type_1_G', 00250 'type_1_H', 00251 'type_1_I']) 00252 00253 if q_subkind == 'type_1_A': 00254 q_subkind = randomly.pop(['type_1_A0', 00255 'type_1_A1']) 00256 if q_subkind == 'type_1_B': 00257 q_subkind = randomly.pop(['type_1_B0', 00258 'type_1_B1']) 00259 if q_subkind == 'type_1_C': 00260 q_subkind = 'type_1_C0' 00261 00262 if q_subkind == 'type_1_D': 00263 q_subkind = randomly.pop(['type_1_D0', 00264 'type_1_D1']) 00265 if q_subkind == 'type_1_E': 00266 q_subkind = randomly.pop(['type_1_E0', 00267 'type_1_E1']) 00268 if q_subkind == 'type_1_F': 00269 q_subkind = 'type_1_F0' 00270 00271 if q_subkind == 'type_1_G': 00272 q_subkind = randomly.pop(['type_1_G0', 00273 'type_1_G1']) 00274 if q_subkind == 'type_1_H': 00275 q_subkind = randomly.pop(['type_1_H0', 00276 'type_1_H1']) 00277 if q_subkind == 'type_1_I': 00278 q_subkind = 'type_1_I0' 00279 00280 if q_subkind == 'type_1_0': 00281 q_subkind = randomly.pop(['type_1_A0', 00282 'type_1_B0', 00283 'type_1_C0', 00284 'type_1_D0', 00285 'type_1_E0', 00286 'type_1_F0', 00287 'type_1_G0', 00288 'type_1_H0', 00289 'type_1_I0']) 00290 00291 if q_subkind == 'type_1_1': 00292 q_subkind = randomly.pop(['type_1_A1', 00293 'type_1_B1', 00294 'type_1_D1', 00295 'type_1_E1', 00296 'type_1_G1', 00297 'type_1_H1']) 00298 00299 if q_subkind == 'type_2': 00300 q_subkind = randomly.pop(['type_2_ABC', 00301 'type_2_DEF']) 00302 00303 if q_subkind == 'type_2_ABC': 00304 q_subkind = randomly.pop(['type_2_A', 00305 'type_2_B', 00306 'type_2_C']) 00307 00308 if q_subkind == 'type_2_DEF': 00309 q_subkind = randomly.pop(['type_2_D', 00310 'type_2_E', 00311 'type_2_F']) 00312 00313 if q_subkind == 'type_2_A': 00314 q_subkind = randomly.pop(['type_2_A0', 00315 'type_2_A1']) 00316 if q_subkind == 'type_2_B': 00317 q_subkind = randomly.pop(['type_2_B0', 00318 'type_2_B1']) 00319 if q_subkind == 'type_2_C': 00320 q_subkind = 'type_2_C0' 00321 00322 if q_subkind == 'type_2_D': 00323 q_subkind = randomly.pop(['type_2_D0', 00324 'type_2_D1']) 00325 if q_subkind == 'type_2_E': 00326 q_subkind = randomly.pop(['type_2_E0', 00327 'type_2_E1']) 00328 if q_subkind == 'type_2_F': 00329 q_subkind = 'type_2_F0' 00330 00331 if q_subkind == 'type_2_0': 00332 q_subkind = randomly.pop(['type_2_A0', 00333 'type_2_B0', 00334 'type_2_C0', 00335 'type_2_D0', 00336 'type_2_E0', 00337 'type_2_F0']) 00338 00339 if q_subkind == 'type_2_1': 00340 q_subkind = randomly.pop(['type_2_A1', 00341 'type_2_B1', 00342 'type_2_D1', 00343 'type_2_E1']) 00344 00345 if q_subkind == 'type_3': 00346 q_subkind = 'type_3_ABC' 00347 00348 if q_subkind == 'type_3_ABC': 00349 q_subkind = randomly.pop(['type_3_A', 00350 'type_3_B', 00351 'type_3_C']) 00352 00353 if q_subkind == 'type_3_A': 00354 q_subkind = randomly.pop(['type_3_A0', 00355 'type_3_A1']) 00356 if q_subkind == 'type_3_B': 00357 q_subkind = randomly.pop(['type_3_B0', 00358 'type_3_B1']) 00359 if q_subkind == 'type_3_C': 00360 q_subkind = 'type_3_C0' 00361 00362 if q_subkind == 'type_3_0': 00363 q_subkind = randomly.pop(['type_3_A0', 00364 'type_3_B0', 00365 'type_3_C0']) 00366 00367 if q_subkind == 'type_3_1': 00368 q_subkind = randomly.pop(['type_3_A1', 00369 'type_3_B1']) 00370 00371 00372 00373 #steps = level_02(subkind, **options) 00374 00375 elif q_kind == 'level_03': 00376 steps_method = level_03 00377 options['markup'] = self.machine.markup 00378 00379 if q_subkind == 'any' or q_subkind == 'default': 00380 q_subkind = randomly.pop(['any_straight', 00381 'any_mixed']) 00382 00383 if q_subkind == 'any_straight': 00384 q_subkind = randomly.pop(['any_true_straight', 00385 'any_fake_straight']) 00386 00387 if q_subkind == 'any_mixed': 00388 q_subkind = randomly.pop(['any_true_mixed', 00389 'any_fake_mixed']) 00390 00391 if q_subkind == 'any_true': 00392 q_subkind = randomly.pop(['any_true_straight', 00393 'any_true_mixed']) 00394 00395 if q_subkind == 'any_fake': 00396 q_subkind = randomly.pop(['any_fake_straight', 00397 'any_fake_mixed']) 00398 00399 if q_subkind == 'any_true_straight': 00400 q_subkind = randomly.pop(['sum_square', 00401 'difference_square', 00402 'squares_difference']) 00403 00404 if q_subkind == 'any_fake_straight': 00405 q_subkind = randomly.pop(['fake_01', 00406 'fake_02', 00407 'fake_03', 00408 'fake_04_any_straight']) 00409 00410 if q_subkind == 'any_true_mixed': 00411 q_subkind = randomly.pop(['sum_square_mixed', 00412 'difference_square_mixed', 00413 'squares_difference_mixed']) 00414 00415 if q_subkind == 'any_fake_mixed': 00416 q_subkind = randomly.pop(['fake_01_mixed', 00417 'fake_02_mixed', 00418 'fake_03_mixed', 00419 'fake_04_any_mixed']) 00420 00421 if q_subkind == 'fake_04_any': 00422 q_subkind = randomly.pop(['fake_04_any_mixed', 00423 'fake_04_any_straight']) 00424 00425 if q_subkind == 'fake_04_any_mixed': 00426 q_subkind = randomly.pop(['fake_04_A_mixed', 00427 'fake_04_B_mixed', 00428 'fake_04_C_mixed', 00429 'fake_04_D_mixed']) 00430 00431 if q_subkind == 'fake_04_any_straight': 00432 q_subkind = randomly.pop(['fake_04_A', 00433 'fake_04_B', 00434 'fake_04_C', 00435 'fake_04_D']) 00436 00437 00438 00439 00440 steps = steps_method(q_subkind, **options) 00441 00442 00443 00444 00445 # Creation of the expression : 00446 number = 0 00447 if 'expression_number' in options \ 00448 and is_.a_natural_int(options['expression_number']): 00449 #___ 00450 number = options['expression_number'] 00451 self.expression = Expression(number, steps[0]) 00452 00453 # Putting the steps and the solution together : 00454 self.steps = [] 00455 00456 #for i in xrange(len(steps) - 1): 00457 # self.steps.append(Expression(number, 00458 # steps[i] 00459 # ) 00460 # ) 00461 # 00462 #solution = steps[len(steps) - 1] 00463 # 00464 #if isinstance(solution, Exponented): 00465 # self.steps.append(Expression(number, 00466 # solution 00467 # ) 00468 # ) 00469 #else: 00470 # self.steps.append(solution) 00471 00472 for i in range(len(steps)): 00473 if isinstance(steps[i], Exponented): 00474 self.steps.append(Expression(number, 00475 steps[i] 00476 ) 00477 ) 00478 else: 00479 self.steps.append(steps[i]) 00480 00481 00482 00483 00484 00485 # -------------------------------------------------------------------------- 00486 ## 00487 # @brief Returns the text of the question as a str 00488 def text_to_str(self): 00489 M = self.machine 00490 00491 result = M.write_math_style2(M.type_string(self.expression)) 00492 result += M.write_new_line() 00493 00494 return result 00495 00496 00497 00498 00499 00500 00501 # -------------------------------------------------------------------------- 00502 ## 00503 # @brief Returns the answer of the question as a str 00504 def answer_to_str(self): 00505 M = self.machine 00506 00507 result = "" 00508 00509 for i in range(len(self.steps)): 00510 if type(self.steps[i]) == str: 00511 result += M.write(self.steps[i]) 00512 else: 00513 result += M.write_math_style2(M.type_string(self.steps[i])) 00514 result += M.write_new_line() 00515 00516 return result 00517 00518 00519 00520 00521 00522 # -------------------------------------------------------------------------- 00523 ## 00524 # @brief Creates & returns the solution and the answer's steps. 00525 # @return steps (list containing the steps) 00526 def level_01(q_subkind, **options): 00527 if q_subkind == 'default' \ 00528 or q_subkind == 'three_terms' \ 00529 or q_subkind == 'ax + b' \ 00530 or q_subkind == 'ax² + b' \ 00531 or q_subkind == 'ax² + bx' : 00532 #___ 00533 # the idea is to build the final factorized result first and to 00534 # expand it to get the question (and the solution's steps 00535 # in the same time) 00536 00537 if q_subkind == 'default': 00538 common_factor = Monomial((RANDOMLY, 6, 1)) 00539 # In order to reduce the number of cases where x² appears, 00540 # let the common factor be of degree 0 most of the time. 00541 common_factor.set_degree(randomly.integer(0, 00542 1, 00543 weighted_table=[0.85, 00544 0.15]) 00545 ) 00546 00547 elif q_subkind == 'three_terms' \ 00548 or q_subkind == 'ax + b' \ 00549 or q_subkind == 'ax² + b': 00550 #___ 00551 common_factor = Monomial((RANDOMLY, 6, 0)) 00552 00553 elif q_subkind == 'ax² + bx': 00554 common_factor = Monomial((RANDOMLY, 6, 1)) 00555 common_factor.set_degree(1) 00556 00557 # to avoid having a situation like 1×(2x + 3) which isn't 00558 # factorizable : 00559 if common_factor.get_degree() == 0: 00560 common_factor.set_coeff(randomly.integer(2, 6)) 00561 00562 00563 # signs are randomly chosen ; the only case that is to be avoided 00564 # is all signs are negative (then it wouldn't factorize well... 00565 # I mean then the '-' should be factorized and not left in the final 00566 # result) 00567 signs_box = [['+', '+'], ['+', '-']] 00568 signs = randomly.pop(signs_box) 00569 00570 # this next test is to avoid -2x + 6 being factorized -2(x - 3) 00571 # which is not wrong but not "natural" to pupils 00572 # this test should be changed when a third term is being used. 00573 if signs == ['+', '-']: 00574 common_factor.set_sign('+') 00575 00576 coeff_1 = randomly.integer(2, 10) 00577 coeff_2 = randomly.coprime_to(coeff_1, [i + 1 for i in range(10)]) 00578 coeff_3 = None 00579 00580 if q_subkind == 'three_terms': 00581 coeff_3 = randomly.coprime_to(coeff_1 * coeff_2, 00582 [i + 1 for i in range(9)]) 00583 third_sign = randomly.sign() 00584 if third_sign == '-': 00585 common_factor.set_sign('+') 00586 00587 signs.append(third_sign) 00588 00589 lil_box = [] 00590 lil_box.append(Monomial(('+', 1, 0))) 00591 00592 if q_subkind == 'ax² + b': 00593 lil_box.append(Monomial(('+', 1, 2))) 00594 else: 00595 lil_box.append(Monomial(('+', 1, 1))) 00596 00597 if (common_factor.get_degree() == 0 \ 00598 and randomly.integer(1, 20) > 17 \ 00599 and q_subkind == 'default') \ 00600 or q_subkind == 'three_terms': 00601 #___ 00602 lil_box.append(Monomial(('+', 1, 2))) 00603 00604 first_term = randomly.pop(lil_box) 00605 second_term = randomly.pop(lil_box) 00606 third_term = None 00607 00608 00609 first_term.set_coeff(coeff_1) 00610 first_term.set_sign(randomly.pop(signs)) 00611 second_term.set_coeff(coeff_2) 00612 second_term.set_sign(randomly.pop(signs)) 00613 00614 if q_subkind == 'three_terms': 00615 third_term = randomly.pop(lil_box) 00616 third_term.set_coeff(coeff_3) 00617 third_term.set_sign(randomly.pop(signs)) 00618 if first_term.is_positive() and second_term.is_positive()\ 00619 and third_term.is_positive(): 00620 #___ 00621 common_factor.set_sign(randomly.sign()) 00622 00623 if not (q_subkind == 'three_terms'): 00624 if common_factor.get_degree() == 0 \ 00625 and first_term.get_degree() >= 1 \ 00626 and second_term.get_degree() >= 1: 00627 #___ 00628 if randomly.heads_or_tails(): 00629 first_term.set_degree(0) 00630 else: 00631 second_term.set_degree(0) 00632 00633 if q_subkind == 'three_terms': 00634 solution = Expandable((common_factor, 00635 Sum([first_term, 00636 second_term, 00637 third_term]))) 00638 00639 else: 00640 solution = Expandable((common_factor, 00641 Sum([first_term, 00642 second_term]))) 00643 00644 # now create the expanded step and the reduced step (which will 00645 # be given as a question) 00646 temp_steps = [] 00647 current_step = solution.clone() 00648 00649 while current_step != None: 00650 temp_steps.append(current_step) 00651 current_step = current_step.expand_and_reduce_next_step() 00652 00653 # now we put the steps in the right order 00654 steps = [] 00655 for i in range(len(temp_steps)): 00656 steps.append(temp_steps[len(temp_steps) - 1 - i]) 00657 00658 return steps 00659 00660 elif q_subkind == 'not_factorizable': 00661 signs_box = [['+', '+'], ['+', '-']] 00662 signs = randomly.pop(signs_box) 00663 00664 coeff_1 = randomly.integer(2, 10) 00665 coeff_2 = randomly.coprime_to(coeff_1, [i + 1 for i in range(10)]) 00666 00667 lil_box = [] 00668 lil_box.append(Monomial(('+', 1, 0))) 00669 lil_box.append(Monomial(('+', 1, 1))) 00670 lil_box.append(Monomial(('+', 1, 2))) 00671 00672 first_term = randomly.pop(lil_box) 00673 second_term = randomly.pop(lil_box) 00674 00675 first_term.set_coeff(coeff_1) 00676 first_term.set_sign(randomly.pop(signs)) 00677 00678 second_term.set_coeff(coeff_2) 00679 second_term.set_sign(randomly.pop(signs)) 00680 00681 if first_term.get_degree() >= 1 \ 00682 and second_term.get_degree() >= 1: 00683 #___ 00684 if randomly.heads_or_tails(): 00685 first_term.set_degree(0) 00686 else: 00687 second_term.set_degree(0) 00688 00689 steps = [] 00690 solution = \ 00691 _("So far, we don't know if this expression can be factorized.") 00692 steps.append(Sum([first_term, second_term])) 00693 steps.append(solution) 00694 00695 return steps 00696 00697 00698 00699 00700 00701 # -------------------------------------------------------------------------- 00702 ## 00703 # @brief Creates & returns the solution and the answer's steps. 00704 # @return steps (list containing the steps) 00705 def level_02(q_subkind, **options): 00706 00707 max_coeff = 20 00708 00709 if 'max_coeff' in options and is_.an_integer(options['max_coeff']): 00710 max_coeff = options['max_coeff'] 00711 00712 attribute_a_minus_sign = 'randomly' 00713 00714 if 'minus_sign' in options \ 00715 and (options['minus_sign'] == 'yes' \ 00716 or options['minus_sign'] == 'OK'): 00717 #___ 00718 attribute_a_minus_sign = 'yes' 00719 00720 elif 'minus_sign' in options \ 00721 and (options['minus_sign'] == 'no'): 00722 #___ 00723 attribute_a_minus_sign = 'no' 00724 00725 # Creation of the objects 00726 00727 # The three Monomials : ax², bx and c 00728 # Maybe we don't need to keep the integer values... 00729 a_val = randomly.integer(1, max_coeff) 00730 b_val = randomly.integer(1, max_coeff) 00731 c_val = randomly.integer(1, max_coeff) 00732 00733 if q_subkind == 'type_1_A0' \ 00734 or q_subkind == 'type_1_B0' \ 00735 or q_subkind == 'type_1_C0' \ 00736 or q_subkind == 'type_1_A1' \ 00737 or q_subkind == 'type_1_B1' \ 00738 or q_subkind == 'type_1_C1': 00739 #___ 00740 c_val = randomly.integer(2, max_coeff) 00741 00742 ax2 = Monomial((randomly.sign(), a_val, 2)) 00743 bx = Monomial((randomly.sign(), b_val, 1)) 00744 c = Monomial((randomly.sign(), c_val, 0)) 00745 00746 # deg1 : mx + p 00747 # and we need two of them 00748 deg1 = [] 00749 for i in range(2): 00750 deg1_mx = Monomial((randomly.sign(), 00751 randomly.integer(1, max_coeff), 00752 1)) 00753 deg1_p = None 00754 00755 if q_subkind == 'type_1_A0' \ 00756 or q_subkind == 'type_1_B0' \ 00757 or q_subkind == 'type_1_C0' \ 00758 or q_subkind == 'type_1_D0' \ 00759 or q_subkind == 'type_1_E0' \ 00760 or q_subkind == 'type_1_F0' \ 00761 or q_subkind == 'type_1_G0' \ 00762 or q_subkind == 'type_1_H0' \ 00763 or q_subkind == 'type_1_I0' \ 00764 or q_subkind == 'type_1_A1' \ 00765 or q_subkind == 'type_1_B1' \ 00766 or q_subkind == 'type_1_D1' \ 00767 or q_subkind == 'type_1_E1' \ 00768 or q_subkind == 'type_1_G1' \ 00769 or q_subkind == 'type_1_H1' \ 00770 or q_subkind == 'type_4_A0' : 00771 #___ 00772 deg1_p = Monomial((randomly.sign(), 00773 randomly.integer(1, max_coeff), 00774 0)) 00775 else: 00776 deg1_p = Monomial((randomly.sign(), 00777 randomly.integer(0, max_coeff), 00778 0)) 00779 00780 if not deg1_p.is_null(): 00781 lil_box = [deg1_mx, deg1_p] 00782 deg1.append(Polynomial([randomly.pop(lil_box), 00783 randomly.pop(lil_box)])) 00784 00785 else: 00786 deg1.append(deg1_mx) 00787 00788 00789 # deg2 : mx² + px + r 00790 # and we also need two of them 00791 deg2 = [] 00792 for i in range(2): 00793 deg2_mx2 = Monomial((randomly.sign(), 00794 randomly.integer(1, max_coeff), 00795 2)) 00796 00797 deg2_px = None 00798 deg2_r = None 00799 00800 if q_subkind == 'type_1_A0' \ 00801 or q_subkind == 'type_1_B0' \ 00802 or q_subkind == 'type_1_C0' \ 00803 or q_subkind == 'type_1_D0' \ 00804 or q_subkind == 'type_1_E0' \ 00805 or q_subkind == 'type_1_F0' \ 00806 or q_subkind == 'type_1_G0' \ 00807 or q_subkind == 'type_1_H0' \ 00808 or q_subkind == 'type_1_I0' \ 00809 or q_subkind == 'type_1_A1' \ 00810 or q_subkind == 'type_1_B1' \ 00811 or q_subkind == 'type_1_D1' \ 00812 or q_subkind == 'type_1_E1' \ 00813 or q_subkind == 'type_1_G1' \ 00814 or q_subkind == 'type_1_H1': 00815 #___ 00816 if randomly.heads_or_tails(): 00817 deg2_px = Monomial((randomly.sign(), 00818 randomly.integer(1, max_coeff), 00819 1)) 00820 deg2_r = Monomial((randomly.sign(), 00821 randomly.integer(0, max_coeff), 00822 0)) 00823 else: 00824 deg2_px = Monomial((randomly.sign(), 00825 randomly.integer(0, max_coeff), 00826 1)) 00827 deg2_r = Monomial((randomly.sign(), 00828 randomly.integer(1, max_coeff), 00829 0)) 00830 else: 00831 deg2_px = Monomial((randomly.sign(), 00832 randomly.integer(0, max_coeff), 00833 1)) 00834 deg2_r = Monomial((randomly.sign(), 00835 randomly.integer(0, max_coeff), 00836 0)) 00837 00838 lil_box = [deg2_mx2] 00839 00840 if not deg2_px.is_null(): 00841 lil_box.append(deg2_px) 00842 if not deg2_r.is_null(): 00843 lil_box.append(deg2_r) 00844 00845 monomials_list_for_deg2 = [] 00846 for i in range(len(lil_box)): 00847 monomials_list_for_deg2.append(randomly.pop(lil_box)) 00848 00849 deg2.append(Polynomial(monomials_list_for_deg2)) 00850 00851 00852 # Let's attribute the common factor C according to the required type 00853 # (NB : expression ± C×F1 ± C×F2) 00854 C = None 00855 00856 if q_subkind == 'type_1_A0' \ 00857 or q_subkind == 'type_1_B0' \ 00858 or q_subkind == 'type_1_C0' \ 00859 or q_subkind == 'type_1_A1' \ 00860 or q_subkind == 'type_1_B1': 00861 #___ 00862 C = c 00863 00864 elif q_subkind == 'type_1_D0' \ 00865 or q_subkind == 'type_1_E0' \ 00866 or q_subkind == 'type_1_F0' \ 00867 or q_subkind == 'type_1_D1' \ 00868 or q_subkind == 'type_1_E1': 00869 #___ 00870 C = bx 00871 00872 elif q_subkind == 'type_1_G0' \ 00873 or q_subkind == 'type_1_H0' \ 00874 or q_subkind == 'type_1_I0' \ 00875 or q_subkind == 'type_1_G1' \ 00876 or q_subkind == 'type_1_H1': 00877 #___ 00878 C = ax2 00879 00880 elif q_subkind == 'type_2_A0' \ 00881 or q_subkind == 'type_2_B0' \ 00882 or q_subkind == 'type_2_C0' \ 00883 or q_subkind == 'type_2_A1' \ 00884 or q_subkind == 'type_2_B1' \ 00885 or q_subkind == 'type_4_A0' : 00886 #___ 00887 C = Polynomial([bx, c]) 00888 00889 elif q_subkind == 'type_2_D0' \ 00890 or q_subkind == 'type_2_E0' \ 00891 or q_subkind == 'type_2_F0' \ 00892 or q_subkind == 'type_2_D1' \ 00893 or q_subkind == 'type_2_E1': 00894 #___ 00895 C = Polynomial([ax2, c]) 00896 00897 elif q_subkind == 'type_3_A0' \ 00898 or q_subkind == 'type_3_B0' \ 00899 or q_subkind == 'type_3_C0' \ 00900 or q_subkind == 'type_3_A1' \ 00901 or q_subkind == 'type_3_B1': 00902 #___ 00903 C = Polynomial([ax2, bx, c]) 00904 00905 # Let's attribute F1 and F2 according to the required type 00906 # (NB : expression ± C×F1 ± C×F2) 00907 F1 = None 00908 F2 = None 00909 00910 if q_subkind == 'type_1_A0' \ 00911 or q_subkind == 'type_1_A1' \ 00912 or q_subkind == 'type_1_D0' \ 00913 or q_subkind == 'type_1_D1' \ 00914 or q_subkind == 'type_1_G0' \ 00915 or q_subkind == 'type_1_G1' \ 00916 or q_subkind == 'type_2_A0' \ 00917 or q_subkind == 'type_2_A1' \ 00918 or q_subkind == 'type_2_D0' \ 00919 or q_subkind == 'type_2_D1' \ 00920 or q_subkind == 'type_3_A0' \ 00921 or q_subkind == 'type_3_A1': 00922 #___ 00923 F1 = deg1[0] 00924 F2 = deg1[1] 00925 00926 elif q_subkind == 'type_1_B0' \ 00927 or q_subkind == 'type_1_B1' \ 00928 or q_subkind == 'type_1_E0' \ 00929 or q_subkind == 'type_1_E1' \ 00930 or q_subkind == 'type_1_H0' \ 00931 or q_subkind == 'type_1_H1' \ 00932 or q_subkind == 'type_2_B0' \ 00933 or q_subkind == 'type_2_B1' \ 00934 or q_subkind == 'type_2_E0' \ 00935 or q_subkind == 'type_2_E1' \ 00936 or q_subkind == 'type_3_B0' \ 00937 or q_subkind == 'type_3_B1': 00938 #___ 00939 F1 = deg2[0] 00940 F2 = deg2[1] 00941 00942 elif q_subkind == 'type_1_C0' \ 00943 or q_subkind == 'type_1_F0' \ 00944 or q_subkind == 'type_1_I0' \ 00945 or q_subkind == 'type_2_C0' \ 00946 or q_subkind == 'type_2_F0' \ 00947 or q_subkind == 'type_3_C0': 00948 #___ 00949 F1 = deg1[0] 00950 F2 = deg2[0] 00951 00952 # The special case type_4_A0 : (ax+b)² + (ax+b)×deg1' 00953 # aka C² + C×F1 00954 elif q_subkind == 'type_4_A0': 00955 F1 = C.clone() 00956 F2 = deg1[0] 00957 00958 # Let's put a "1" somewhere in the type_*_*1 00959 if q_subkind == 'type_1_A1' \ 00960 or q_subkind == 'type_1_D1' \ 00961 or q_subkind == 'type_1_G1' \ 00962 or q_subkind == 'type_2_A1' \ 00963 or q_subkind == 'type_2_D1' \ 00964 or q_subkind == 'type_3_A1' \ 00965 or q_subkind == 'type_1_B1' \ 00966 or q_subkind == 'type_1_E1' \ 00967 or q_subkind == 'type_1_H1' \ 00968 or q_subkind == 'type_2_B1' \ 00969 or q_subkind == 'type_2_E1' \ 00970 or q_subkind == 'type_3_B1': 00971 #___ 00972 if randomly.heads_or_tails(): 00973 F1 = Item(1) 00974 else: 00975 F2 = Item(1) 00976 00977 00978 00979 # Let's possibly attribute a minus_sign 00980 # (NB : expression ± C×F1 ± C×F2) 00981 minus_sign = None # this will contain the name of the factor having 00982 # a supplementary minus sign in such cases : 00983 # C×F1 - C×F2 00984 # - C×F1 + C×F2 00985 00986 # in all the following cases, it doesn't bring anything to attribute 00987 # a minus sign 00988 if ((q_subkind == 'type_1_A0' \ 00989 or q_subkind == 'type_1_B0' \ 00990 or q_subkind == 'type_1_C0' \ 00991 or q_subkind == 'type_1_A1' \ 00992 or q_subkind == 'type_1_B1') \ 00993 and c_val < 0) \ 00994 or \ 00995 ((q_subkind == 'type_1_D0' \ 00996 or q_subkind == 'type_1_E0' \ 00997 or q_subkind == 'type_1_F0' \ 00998 or q_subkind == 'type_1_D1' \ 00999 or q_subkind == 'type_1_E1') \ 01000 and b_val < 0) \ 01001 or \ 01002 ((q_subkind == 'type_1_G0' \ 01003 or q_subkind == 'type_1_H0' \ 01004 or q_subkind == 'type_1_I0' \ 01005 or q_subkind == 'type_1_G1' \ 01006 or q_subkind == 'type_1_H1') \ 01007 and a_val < 0) : 01008 #___ 01009 pass # here we let minus_sign equal to None 01010 01011 # otherwise, let's attribute one randomly, 01012 # depending on attribute_a_minus_sign 01013 else: 01014 if attribute_a_minus_sign == 'randomly' \ 01015 or attribute_a_minus_sign == 'yes': 01016 #___ 01017 if attribute_a_minus_sign == 'yes' \ 01018 or randomly.heads_or_tails(): 01019 #___ 01020 if randomly.heads_or_tails(): 01021 minus_sign = "F1" 01022 else: 01023 minus_sign = "F2" 01024 else: 01025 pass # here we let minus_sign equal to None 01026 01027 01028 # Now let's build the expression ! 01029 expression = None 01030 01031 box_product1 = [C, F1] 01032 box_product2 = [C, F2] 01033 01034 if q_subkind == 'type_4_A0': 01035 CF1 = Product([C]) 01036 CF1.set_exponent(Value(2)) 01037 else: 01038 CF1 = Product([randomly.pop(box_product1), 01039 randomly.pop(box_product1)]) 01040 01041 CF2 = Product([randomly.pop(box_product2), 01042 randomly.pop(box_product2)]) 01043 01044 if minus_sign == "F1": 01045 if len(F1) >= 2: 01046 CF1 = Expandable((Item(-1), CF1)) 01047 else: 01048 CF1 = Product([Item(-1), CF1]) 01049 01050 elif minus_sign == "F2": 01051 if len(F2) >= 2: 01052 CF2 = Expandable((Item(-1), CF2)) 01053 else: 01054 CF2 = Product([Item(-1), CF2]) 01055 01056 expression = Sum([CF1, CF2]) 01057 01058 # Now let's build the factorization steps ! 01059 steps = [] 01060 steps.append(expression) 01061 01062 F1F2_sum = None 01063 01064 if minus_sign is None: 01065 F1F2_sum = Sum([F1, F2]) 01066 01067 elif minus_sign == "F1": 01068 if len(F1) >= 2: 01069 F1F2_sum = Sum([Expandable((Item(-1), F1)), F2]) 01070 else: 01071 F1F2_sum = Sum([Product([Item(-1), F1]), F2]) 01072 01073 elif minus_sign == "F2": 01074 if len(F2) >= 2: 01075 F1F2_sum = Sum([F1, Expandable((Item(-1), F2))]) 01076 else: 01077 F1F2_sum = Sum([F1, Product([Item(-1), F2])]) 01078 01079 temp = Product([C, F1F2_sum]) 01080 temp.set_compact_display(False) 01081 steps.append(temp) 01082 01083 F1F2_sum = F1F2_sum.expand_and_reduce_next_step() 01084 01085 while F1F2_sum != None: 01086 steps.append(Product([C, F1F2_sum])) 01087 F1F2_sum = F1F2_sum.expand_and_reduce_next_step() 01088 01089 # This doesn't fit the need, because too much Products are 01090 # wrongly recognized as reducible ! 01091 if steps[len(steps) - 1].is_reducible(): 01092 steps.append(steps[len(steps) - 1].reduce_()) 01093 01094 return steps 01095 01096 01097 01098 # -------------------------------------------------------------------------- 01099 ## 01100 # @brief Creates & returns the solution and the answer's steps. 01101 # @return steps (list containing the steps) 01102 def level_03(q_subkind, **options): 01103 01104 a = randomly.integer(1, 10) 01105 b = randomly.integer(1, 10) 01106 01107 steps = [] 01108 01109 if q_subkind == 'sum_square' or q_subkind == 'sum_square_mixed' \ 01110 or q_subkind == 'difference_square' \ 01111 or q_subkind == 'difference_square_mixed': 01112 #___ 01113 first_term = Monomial(('+', 01114 Item(('+', a, 2)).evaluate(), 01115 2)) 01116 01117 second_term = Monomial(('+', 01118 Item(('+', Product([2, a, b])\ 01119 .evaluate(), 1))\ 01120 .evaluate(), 01121 1)) 01122 01123 third_term = Monomial(('+', Item(('+', b, 2)).evaluate(), 0)) 01124 01125 if q_subkind == 'difference_square' \ 01126 or q_subkind == 'difference_square_mixed': 01127 #___ 01128 second_term.set_sign('-') 01129 01130 if q_subkind == 'sum_square_mixed' \ 01131 or q_subkind == 'difference_square_mixed': 01132 #___ 01133 ordered_expression = Polynomial([first_term, 01134 second_term, 01135 third_term]) 01136 01137 [first_term, second_term, third_term] = randomly.mix([first_term, 01138 second_term, 01139 third_term]) 01140 01141 01142 steps.append(Polynomial([first_term, second_term, third_term])) 01143 01144 if q_subkind == 'sum_square_mixed' \ 01145 or q_subkind == 'difference_square_mixed': 01146 #___ 01147 steps.append(ordered_expression) 01148 01149 sq_a_monom = Monomial(('+', a, 1)) 01150 sq_b_monom = Monomial(('+', b, 0)) 01151 01152 let_a_eq = Equality([Item('a'), 01153 sq_a_monom 01154 ]) 01155 01156 let_b_eq = Equality([Item('b'), 01157 sq_b_monom 01158 ]) 01159 01160 steps.append(_("Let") + " " \ 01161 + let_a_eq.into_str(force_expression_markers='yes') \ 01162 + " " + _("and") + " " \ 01163 + let_b_eq.into_str(force_expression_markers='yes')) 01164 01165 sq_a_monom.set_exponent(2) 01166 sq_b_monom.set_exponent(2) 01167 01168 a_square_eq = Equality([Item(('+', 'a', 2)), 01169 sq_a_monom, 01170 sq_a_monom.reduce_() 01171 ]) 01172 01173 b_square_eq = Equality([Item(('+', 'b', 2)), 01174 sq_b_monom, 01175 sq_b_monom.reduce_() 01176 ]) 01177 01178 steps.append(_("then") + " " \ 01179 + a_square_eq.into_str(force_expression_markers='yes')) 01180 01181 steps.append(_("and") + " " \ 01182 + b_square_eq.into_str(force_expression_markers='yes')) 01183 01184 two_times_a_times_b_numeric = Product([Item(2), 01185 Monomial(('+', a, 1)), 01186 Item(b)]) 01187 01188 two_times_a_times_b_reduced = two_times_a_times_b_numeric.reduce_() 01189 01190 two_times_a_times_b_eq = Equality([Product([Item(2), 01191 Item('a'), 01192 Item('b')]), 01193 two_times_a_times_b_numeric, 01194 two_times_a_times_b_reduced 01195 ]) 01196 01197 steps.append(_("and") + " " \ 01198 + two_times_a_times_b_eq.into_str( 01199 force_expression_markers='yes') 01200 ) 01201 01202 steps.append(_("So it is possible to factorize :")) 01203 01204 if q_subkind == 'difference_square' \ 01205 or q_subkind == 'difference_square_mixed': 01206 #___ 01207 b = -b 01208 01209 factorized_expression = Sum([Monomial(('+', a, 1)), Item(b)]) 01210 factorized_expression.set_exponent(2) 01211 01212 steps.append(factorized_expression) 01213 01214 01215 01216 elif q_subkind == 'squares_difference' \ 01217 or q_subkind == 'squares_difference_mixed': 01218 #___ 01219 # To have some (ax)² - b² but also sometimes b² - (ax)² : 01220 degrees = [2, 0, 1, 0] 01221 01222 if randomly.integer(1, 10) >= 8: 01223 degrees = [0, 2, 0, 1] 01224 01225 first_term = Monomial(('+', 01226 Item(('+', a, 2)).evaluate(), 01227 degrees[0])) 01228 01229 second_term = Monomial(('-', 01230 Item(('+', b, 2)).evaluate(), 01231 degrees[1])) 01232 01233 sq_first_term = Monomial(('+', 01234 Item(('+', a, 1)).evaluate(), 01235 degrees[2])) 01236 01237 sq_second_term = Monomial(('-', 01238 Item(('+', b, 1)).evaluate(), 01239 degrees[3])) 01240 01241 # The 'mixed' cases are : -b² + (ax)² and -(ax)² + b² 01242 if q_subkind == 'squares_difference_mixed': 01243 [first_term, second_term] = randomly.mix([first_term, 01244 second_term]) 01245 [sq_first_term, sq_second_term] = randomly.mix([sq_first_term, 01246 sq_second_term]) 01247 01248 01249 positive_sq_first = sq_first_term.clone() 01250 positive_sq_first.set_sign('+') 01251 positive_sq_second = sq_second_term.clone() 01252 positive_sq_second.set_sign('+') 01253 01254 01255 steps.append(Polynomial([first_term, second_term])) 01256 01257 first_inter = None 01258 second_inter = None 01259 01260 if sq_second_term.is_negative(): 01261 first_inter = positive_sq_first.clone() 01262 first_inter.set_exponent(2) 01263 temp_second_inter = positive_sq_second.clone() 01264 temp_second_inter.set_exponent(2) 01265 second_inter = Product([-1, temp_second_inter]) 01266 else: 01267 temp_first_inter = positive_sq_first.clone() 01268 temp_first_inter.set_exponent(2) 01269 first_inter = Product([-1, temp_first_inter]) 01270 second_inter = positive_sq_second.clone() 01271 second_inter.set_exponent(2) 01272 01273 01274 steps.append(Sum([first_inter, second_inter])) 01275 01276 if q_subkind == 'squares_difference_mixed': 01277 steps.append(Sum([second_inter, first_inter])) 01278 01279 steps.append(_("So, this expression can be factorized :")) 01280 01281 sum1 = None 01282 sum2 = None 01283 01284 if sq_second_term.is_negative(): 01285 sum1 = Sum([sq_first_term, sq_second_term]) 01286 sq_second_term.set_sign('+') 01287 sum2 = Sum([sq_first_term, sq_second_term]) 01288 01289 else: 01290 sum1 = Sum([sq_second_term, sq_first_term]) 01291 sq_first_term.set_sign('+') 01292 sum2 = Sum([sq_second_term, sq_first_term]) 01293 01294 lil_box = [sum1, sum2] 01295 01296 steps.append(Product([randomly.pop(lil_box), 01297 randomly.pop(lil_box) 01298 ]) 01299 ) 01300 01301 elif q_subkind == 'fake_01' or q_subkind == 'fake_01_mixed' \ 01302 or q_subkind == 'fake_02' or q_subkind == 'fake_02_mixed' \ 01303 or q_subkind == 'fake_03' or q_subkind == 'fake_03_mixed' \ 01304 or q_subkind == 'fake_04_A' or q_subkind == 'fake_04_A_mixed' \ 01305 or q_subkind == 'fake_04_B' or q_subkind == 'fake_04_B_mixed' \ 01306 or q_subkind == 'fake_04_C' or q_subkind == 'fake_04_C_mixed' \ 01307 or q_subkind == 'fake_04_D' or q_subkind == 'fake_04_D_mixed': 01308 #___ 01309 01310 straight_cases = ['fake_01', 'fake_02', 'fake_03', 01311 'fake_04_A', 'fake_04_B', 'fake_04_C', 'fake_04_D'] 01312 mixed_cases = ['fake_01_mixed', 'fake_02_mixed', 'fake_03_mixed', 01313 'fake_04_A_mixed', 'fake_04_B_mixed', 01314 'fake_04_C_mixed', 'fake_04_D_mixed'] 01315 01316 match_pb_cases = ['fake_01', 'fake_02', 01317 'fake_01_mixed', 'fake_02_mixed'] 01318 01319 sign_pb_cases = ['fake_03', 'fake_03_mixed', 01320 'fake_04_A', 'fake_04_B', 'fake_04_C', 'fake_04_D', 01321 'fake_04_A_mixed', 'fake_04_B_mixed', 01322 'fake_04_C_mixed', 'fake_04_D_mixed'] 01323 01324 ax = Monomial(('+', a, 1)) 01325 01326 b_ = Monomial(('+', b, 0)) 01327 01328 ax_2 = ax.clone() 01329 ax_2.set_exponent(2) 01330 01331 a2x2 = Monomial(('+', a*a, 2)) 01332 01333 b_2 = Monomial(('+', b, 0)) 01334 b_2.set_exponent(2) 01335 01336 b2 = Monomial(('+', b*b, 0)) 01337 01338 two_ax_b = Product([Item(2), 01339 Monomial(('+', a, 1)), 01340 Item(b)]) 01341 01342 twoabx = Monomial(('+', 2*a*b, 1)) 01343 01344 fake_twoabx = Monomial(('+', a*b, 1)) 01345 01346 if randomly.integer(1, 10) >= 8: 01347 fake_twoabx = Monomial(('+', 01348 2*a*b \ 01349 + randomly.pop([-1, 1])\ 01350 *randomly.integer(1, 5), 01351 1)) 01352 01353 first_term = None 01354 second_term = None 01355 third_term = None 01356 01357 ordered_expression = None 01358 mixed_expression = None 01359 01360 if q_subkind == 'fake_03' or q_subkind == 'fake_03_mixed': 01361 first_term = a2x2.clone() 01362 second_term = b2.clone() 01363 ordered_expression = Polynomial([first_term, second_term]) 01364 mixed_expression = Polynomial([second_term, first_term]) 01365 01366 else: 01367 first_term = a2x2.clone() 01368 third_term = b2.clone() 01369 01370 if q_subkind == 'fake_01' or q_subkind == 'fake_01_mixed'\ 01371 or q_subkind == 'fake_02' or q_subkind == 'fake_02_mixed': 01372 #___ 01373 second_term = fake_twoabx.clone() 01374 01375 else: 01376 second_term = twoabx.clone() 01377 01378 if q_subkind == 'fake_02' or q_subkind == 'fake_02_mixed': 01379 second_term.set_sign('-') 01380 01381 elif q_subkind == 'fake_04_A' or q_subkind == 'fake_04_A_mixed': 01382 third_term.set_sign('-') 01383 01384 elif q_subkind == 'fake_04_B' or q_subkind == 'fake_04_B_mixed': 01385 first_term.set_sign('-') 01386 01387 elif q_subkind == 'fake_04_C' or q_subkind == 'fake_04_C_mixed': 01388 second_term.set_sign('-') 01389 third_term.set_sign('-') 01390 01391 elif q_subkind == 'fake_04_D' or q_subkind == 'fake_04_D_mixed': 01392 first_term.set_sign('-') 01393 second_term.set_sign('-') 01394 01395 ordered_expression = Polynomial([first_term, 01396 second_term, 01397 third_term]) 01398 01399 mixed_expression = Polynomial(randomly.mix([first_term, 01400 second_term, 01401 third_term])) 01402 01403 01404 if q_subkind in straight_cases: 01405 steps.append(ordered_expression) 01406 01407 elif q_subkind == 'fake_03_mixed': 01408 steps.append(mixed_expression) 01409 01410 else: 01411 steps.append(mixed_expression) 01412 steps.append(ordered_expression) 01413 01414 01415 01416 if q_subkind in match_pb_cases: 01417 let_a_eq = Equality([Item('a'), 01418 ax 01419 ]) 01420 01421 let_b_eq = Equality([Item('b'), 01422 b_ 01423 ]) 01424 01425 steps.append(_("Let") + " " \ 01426 + let_a_eq.into_str(force_expression_markers='yes')\ 01427 + " " + _("and") + " " \ 01428 + let_b_eq.into_str(force_expression_markers='yes')) 01429 01430 01431 a_square_eq = Equality([Item(('+', 'a', 2)), 01432 ax_2, 01433 a2x2 01434 ]) 01435 01436 b_square_eq = Equality([Item(('+', 'b', 2)), 01437 b_2, 01438 b2 01439 ]) 01440 01441 steps.append(_("then") + " " \ 01442 + a_square_eq.into_str(force_expression_markers='yes')) 01443 01444 01445 steps.append(_("and") + " " \ 01446 + b_square_eq.into_str(force_expression_markers='yes')) 01447 01448 01449 two_times_a_times_b_eq = Equality([Product([Item(2), 01450 Item('a'), 01451 Item('b')]), 01452 two_ax_b, 01453 twoabx, 01454 fake_twoabx 01455 ], 01456 equal_signs=['=', '=', 'neq']) 01457 01458 steps.append(_("but") + " " \ 01459 + two_times_a_times_b_eq.into_str( 01460 force_expression_markers='yes') 01461 ) 01462 01463 steps.append(_("So it does not match a binomial identity.")) 01464 steps.append(_("This expression cannot be factorized.")) 01465 01466 01467 elif q_subkind in sign_pb_cases: 01468 steps.append(_("Because of the signs,")) 01469 steps.append(_("it does not match a binomial identity.")) 01470 steps.append(_("This expression cannot be factorized.")) 01471 01472 01473 01474 return steps 01475 01476 01477 01478 01479 01480 01481