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 lib.common.cst import * 00025 from Q_Structure import Q_Structure 00026 from core.base_calculus import * 00027 from core.calculus import * 00028 00029 # DON'T FORGET FOR THIS QUESTION TO ALSO DEFINE 00030 # THE INIT CALLER (JUST AFTER AVAILABLE_Q_KIND_VALUES) 00031 AVAILABLE_Q_KIND_VALUES = \ 00032 {'monom01_polyn1' : ['default'], # any of the 2 next 00033 'monom0_polyn1' : ['default'], # a×(bx + c) 00034 'monom1_polyn1' : ['default'], # ax×(bx + c) 00035 'polyn1_polyn1' : ['default'], # (ax + b)×(cx + d) 00036 'any_basic_expd' : ['default'], # any of the 3 prev. 00037 'sum_of_any_basic_expd' : ['default', 'easy', 'harder', 'with_a_binomial'], 00038 'sign_expansion' : ['default'], 00039 'sign_expansion_short_test' : ['default'], 00040 'numeric_sum_square' : ['default'], 00041 'numeric_difference_square' : ['default'], 00042 'numeric_squares_difference' : ['default'], 00043 'sum_square' : ['default'], # passed to an __init__() 00044 'difference_square' : ['default'], # idem 00045 'squares_difference' : ['default'], # idem 00046 'any_binomial' : ['default'] # idem (not really good ?) 00047 } 00048 00049 INIT_CALLER = \ 00050 {'monom01_polyn1' : Expandable, 00051 'monom0_polyn1' : Expandable, 00052 'monom1_polyn1' : Expandable, 00053 'polyn1_polyn1' : Expandable, 00054 'any_basic_expd' : Expandable, 00055 'sum_of_any_basic_expd' : Expandable, 00056 'sign_expansion' : Expandable, 00057 'sign_expansion_short_test' : Expandable, 00058 'numeric_sum_square' : BinomialIdentity, 00059 'numeric_difference_square' : BinomialIdentity, 00060 'numeric_squares_difference' : BinomialIdentity, 00061 'sum_square' : BinomialIdentity, 00062 'difference_square' : BinomialIdentity, 00063 'squares_difference' : BinomialIdentity, 00064 'any_binomial' : BinomialIdentity 00065 } 00066 00067 # ------------------------------------------------------------------------------ 00068 # -------------------------------------------------------------------------- 00069 # ------------------------------------------------------------------------------ 00070 ## 00071 # @class Q_AlgebraExpressionExpansion 00072 # @brief An object to expand (like 2(x-3), 4x(2-9x), (3+x)(x-1) or (x+1)² etc.) 00073 class Q_AlgebraExpressionExpansion(Q_Structure): 00074 00075 00076 00077 00078 00079 # -------------------------------------------------------------------------- 00080 ## 00081 # @brief Constructor 00082 # @param embedded_machine The machine to be used 00083 # @param **options Any options 00084 # @return One instance of question.Q_AlgebraExpressionExpansion 00085 def __init__(self, embedded_machine, q_kind='default_nothing', **options): 00086 self.derived = True 00087 00088 # The call to the mother class __init__() method will set the 00089 # fields matching optional arguments which are so far : 00090 # self.q_kind, self.q_subkind 00091 # plus self.machine, self.options (modified) 00092 Q_Structure.__init__(self, embedded_machine, 00093 q_kind, AVAILABLE_Q_KIND_VALUES, 00094 **options) 00095 # The purpose of this next line is to get the possibly modified 00096 # value of **options 00097 options = self.options 00098 00099 00100 init_caller = INIT_CALLER[q_kind] 00101 00102 self.expandable_objct = None 00103 00104 self.numeric_aux = None 00105 00106 if q_kind=='any_basic_expd': 00107 randomly_drawn = randomly.decimal_0_1() 00108 if randomly_drawn <= 0.25: 00109 self.expandable_objct = Expandable((RANDOMLY, 00110 'monom0_polyn1'), 00111 randomly_reversed=0.5) 00112 elif randomly_drawn <= 0.50: 00113 self.expandable_objct = Expandable((RANDOMLY, 00114 'monom1_polyn1'), 00115 randomly_reversed=0.5) 00116 else: 00117 self.expandable_objct = Expandable((RANDOMLY, 00118 'polyn1_polyn1')) 00119 00120 elif q_kind=='monom0_polyn1' or q_kind=='monom1_polyn1': 00121 self.expandable_objct = Expandable((RANDOMLY, 00122 q_kind), 00123 randomly_reversed=0.5) 00124 elif q_kind=='monom01_polyn1': 00125 self.expandable_objct = Expandable((RANDOMLY, 00126 randomly.pop(['monom0_polyn1', 00127 'monom1_polyn1'])), 00128 randomly_reversed=0.5) 00129 00130 elif q_kind=='polyn1_polyn1': 00131 self.expandable_objct = Expandable((RANDOMLY, 00132 'polyn1_polyn1')) 00133 00134 elif q_kind=='sum_of_any_basic_expd': 00135 if self.q_subkind == 'harder' \ 00136 or self.q_subkind == 'with_a_binomial': 00137 #___ 00138 choices = ['monom0_polyn1', 'monom1_polyn1'] 00139 00140 drawn_types = list() 00141 drawn_types.append(randomly.pop(choices)) 00142 00143 if self.q_subkind == 'with_a_binomial': 00144 drawn_types.append('any_binomial') 00145 else: 00146 drawn_types.append('minus_polyn1_polyn1') 00147 00148 aux_expd_list = list() 00149 00150 for t in drawn_types: 00151 if t == 'any_binomial': 00152 aux_expd_list.append(BinomialIdentity((RANDOMLY, 00153 'any'), 00154 **options)) 00155 else: 00156 aux_expd_list.append(Expandable((RANDOMLY, t))) 00157 00158 final_list = list() 00159 for i in range(len(aux_expd_list)): 00160 final_list.append(randomly.pop(aux_expd_list)) 00161 00162 self.expandable_objct = Sum(final_list) 00163 00164 elif self.q_subkind == 'easy': 00165 choices = ['monom0_polyn1', 'monom1_polyn1'] 00166 00167 aux_expd_list = list() 00168 aux_expd_list.append(Expandable((RANDOMLY, 00169 randomly.pop(choices) 00170 )) 00171 ) 00172 00173 if randomly.heads_or_tails(): 00174 aux_expd_list.append(Expandable((RANDOMLY, 'sign_exp'))) 00175 else: 00176 aux_expd_list.append(Monomial((RANDOMLY, 15, 00177 randomly.integer(0,2) 00178 )) 00179 ) 00180 00181 final_list = list() 00182 for i in range(len(aux_expd_list)): 00183 final_list.append(randomly.pop(aux_expd_list)) 00184 00185 self.expandable_objct = Sum(final_list) 00186 00187 else: 00188 choices = ['monom0_polyn1', 'monom0_polyn1', 00189 'monom1_polyn1', 'monom1_polyn1', 00190 'polyn1_polyn1', 00191 'minus_polyn1_polyn1'] 00192 00193 drawn_types = list() 00194 drawn_types.append(randomly.pop(choices)) 00195 drawn_types.append(randomly.pop(choices)) 00196 00197 aux_expd_list = list() 00198 00199 for element in drawn_types: 00200 aux_expd_list.append(Expandable((RANDOMLY, element))) 00201 00202 aux_expd_list.append(Monomial((RANDOMLY, 15, 2))) 00203 00204 final_list = list() 00205 for i in range(len(aux_expd_list)): 00206 final_list.append(randomly.pop(aux_expd_list)) 00207 00208 self.expandable_objct = Sum(final_list) 00209 00210 elif q_kind=='sign_expansion' or q_kind=='sign_expansion_short_test': 00211 #___ 00212 sign_exp_kind = 0 00213 00214 if 'sign_exp_kind' in options: 00215 sign_exp_kind = options['sign_exp_kind'] 00216 00217 if q_kind=='sign_expansion_short_test': 00218 sign_exp_kind = 1 00219 00220 if sign_exp_kind == 0: 00221 sign_exp_kind = randomly.integer(1, 5) 00222 00223 # Creation of the terms 00224 aux_terms_list = list() 00225 00226 aux_expd_1 = Expandable((Monomial((randomly.sign(), 1, 0)), 00227 Polynomial((RANDOMLY, 15, 2, 2)) 00228 )) 00229 00230 aux_expd_2 = Expandable((Monomial((randomly.sign(), 1, 0)), 00231 Polynomial((RANDOMLY, 15, 2, 2)) 00232 )) 00233 00234 aux_expd_3 = Expandable((Monomial((randomly.sign(), 1, 0)), 00235 Polynomial((RANDOMLY, 15, 2, 2)) 00236 )) 00237 00238 long_aux_expd = Expandable((Monomial((randomly.sign(), 1, 0)), 00239 Polynomial((RANDOMLY, 15, 2, 3)) 00240 )) 00241 00242 if q_kind=='sign_expansion_short_test': 00243 long_aux_expd = Expandable((Monomial(('-', 1, 0)), 00244 Polynomial((RANDOMLY, 15, 2, 3)) 00245 )) 00246 00247 aux_monomial = Monomial((RANDOMLY, 15, 2)) 00248 00249 # 1st kind : a Monomial and ± (long Polynomial) 00250 # (like in a short test) 00251 if sign_exp_kind == 1: 00252 aux_terms_list.append(long_aux_expd) 00253 aux_terms_list.append(aux_monomial) 00254 00255 # 2d kind : ± (x+3) ± (4x - 7) 00256 elif sign_exp_kind == 2: 00257 aux_terms_list.append(aux_expd_1) 00258 aux_terms_list.append(aux_expd_2) 00259 00260 # 3d kind : ± (x+3) ± (4x - 7) ± (x² - 5x) 00261 elif sign_exp_kind == 3: 00262 aux_terms_list.append(aux_expd_1) 00263 aux_terms_list.append(aux_expd_2) 00264 aux_terms_list.append(aux_expd_3) 00265 00266 # 4th kind : ± (x+3) ± (4x - 7) ± Monomial 00267 elif sign_exp_kind == 4: 00268 aux_terms_list.append(aux_expd_1) 00269 aux_terms_list.append(aux_expd_2) 00270 aux_terms_list.append(aux_monomial) 00271 00272 # 5th kind : ± (x+3) ± Monomial ± (long Polynomial) 00273 elif sign_exp_kind == 5: 00274 aux_terms_list.append(aux_expd_2) 00275 aux_terms_list.append(aux_monomial) 00276 aux_terms_list.append(long_aux_expd) 00277 00278 # add as many possibilities as wanted, 00279 # don't forget to increase the last number here : 00280 # sign_exp_kind = randomly.integer(1, 5) (what's a bit above) 00281 00282 # Now let's distribute the terms randomly 00283 final_terms_list = list() 00284 for i in range(len(aux_terms_list)): 00285 final_terms_list.append(randomly.pop(aux_terms_list)) 00286 00287 self.expandable_objct = Sum(final_terms_list) 00288 00289 elif q_kind == 'numeric_sum_square' \ 00290 or q_kind == 'numeric_difference_square' \ 00291 or q_kind == 'numeric_squares_difference': 00292 #___ 00293 self.expandable_objct = init_caller((options['couple'][0], 00294 options['couple'][1]), 00295 **options) 00296 if q_kind == 'numeric_sum_square' \ 00297 or q_kind == 'numeric_difference_square': 00298 #___ 00299 self.numeric_aux = Sum([options['couple'][0], 00300 options['couple'][1] 00301 ]).reduce_() 00302 self.numeric_aux.set_exponent(2) 00303 00304 else: # squares_difference's case 00305 aux1 = Sum([options['couple'][0], 00306 options['couple'][1] 00307 ]).reduce_() 00308 temp = options['couple'][1].clone() 00309 temp.set_sign('-') 00310 aux2 = Sum([options['couple'][0], 00311 temp 00312 ]).reduce_() 00313 self.numeric_aux = Product([aux1, aux2]) 00314 00315 else: 00316 if q_kind == 'any_binomial': 00317 q_kind = 'any' 00318 00319 self.expandable_objct = init_caller((RANDOMLY, q_kind), 00320 **options) 00321 00322 00323 00324 # Creation of the expression : 00325 number = 0 00326 if 'expression_number' in options \ 00327 and is_.a_natural_int(options['expression_number']): 00328 #___ 00329 number = options['expression_number'] 00330 self.expression = Expression(number, self.expandable_objct) 00331 if self.numeric_aux != None: 00332 self.numeric_aux = Expression(number, self.numeric_aux) 00333 00334 00335 00336 00337 00338 00339 # -------------------------------------------------------------------------- 00340 ## 00341 # @brief Returns the text of the question as a str 00342 def text_to_str(self): 00343 M = self.machine 00344 00345 result = "" 00346 00347 if self.q_kind == 'numeric_sum_square' \ 00348 or self.q_kind == 'numeric_difference_square' \ 00349 or self.q_kind == 'numeric_squares_difference': 00350 #___ 00351 result += M.write_math_style2(M.type_string(self.numeric_aux)) 00352 00353 else: 00354 result += M.write_math_style2(M.type_string(self.expression)) 00355 00356 result += M.write_new_line() 00357 00358 return result 00359 00360 00361 00362 00363 00364 00365 00366 # -------------------------------------------------------------------------- 00367 ## 00368 # @brief Returns the answer of the question as a str 00369 def answer_to_str(self): 00370 M = self.machine 00371 00372 result = "" 00373 00374 if self.q_kind == 'numeric_sum_square' \ 00375 or self.q_kind == 'numeric_difference_square' \ 00376 or self.q_kind == 'numeric_squares_difference': 00377 #___ 00378 result += M.write_math_style2(M.type_string(self.numeric_aux)) 00379 result += M.write_new_line() 00380 00381 result += M.write(self.expression.auto_expansion_and_reduction()) 00382 00383 return result 00384 00385 00386 00387 00388 00389