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 import os 00024 import gettext 00025 from optparse import OptionParser 00026 00027 from lib import * 00028 from lib.common import software 00029 import common 00030 import obj_test 00031 import lib_test 00032 import sheet 00033 import machine 00034 import time 00035 00036 AVAILABLE_UNITS = [ ("items", 00037 obj_test.calc_test.items_test), 00038 #("functional_items_test", 00039 # obj_test.calc_test.functional_items_test), 00040 ("values", 00041 obj_test.calc_test.values_test), 00042 ("products", 00043 obj_test.calc_test.products_test), 00044 ("monomials", 00045 obj_test.calc_test.monomials_test), 00046 ("product_reduction", 00047 obj_test.calc_test.product_reduction_test), 00048 ("sums", 00049 obj_test.calc_test.sums_test), 00050 ("sum_reduction", 00051 obj_test.calc_test.sum_reduction_test), 00052 ("quotients", 00053 obj_test.calc_test.quotients_test), 00054 ("fraction_simplification", 00055 obj_test.calc_test.fraction_simplification_test), 00056 ("fractions_products", 00057 obj_test.calc_test.fractions_products_test), 00058 ("fractions_quotients", 00059 obj_test.calc_test.fractions_quotients_test), 00060 ("fractions_sums", 00061 obj_test.calc_test.fractions_sums_test), 00062 ("equations", 00063 obj_test.equations_test), 00064 ("expansion_and_reduction", 00065 obj_test.calc_test.expansion_and_reduction_test), 00066 ("squareroots", 00067 obj_test.calc_test.squareroots_test), 00068 ("point", 00069 obj_test.geo_test.point_test), 00070 ("right_triangle", 00071 obj_test.geo_test.right_triangle_test), 00072 ("triangle", 00073 obj_test.geo_test.triangle_test), 00074 ("utils", 00075 lib_test.utils_test), 00076 ("table", 00077 obj_test.table_test), 00078 ("cross_product_equations", 00079 obj_test.cross_product_equations_test), 00080 ("table_UP", 00081 obj_test.table_uncomplete_proportional_test) # , 00082 # ("functional_items", 00083 # obj_test.calc_test.functional_items_test) 00084 ] 00085 00086 AVAILABLE_UNIT_NAMES = [AVAILABLE_UNITS[i][0] \ 00087 for i in xrange(len(AVAILABLE_UNITS))] 00088 00089 AVAILABLE_UNITS_LEXICON = {} 00090 for i in xrange(len(AVAILABLE_UNITS)): 00091 AVAILABLE_UNITS_LEXICON[AVAILABLE_UNIT_NAMES[i]] = AVAILABLE_UNITS[i][1] 00092 00093 00094 def short_test_run(lang): 00095 M = machine.LaTeX(lang, create_pic_file='no') 00096 for elt in sheet.AVAILABLE: 00097 M.write(str(sheet.AVAILABLE[elt][0](M))) 00098 00099 def long_test_run(n, lang): 00100 for i in xrange(n): 00101 short_test_run(lang) 00102 #time.sleep(2) 00103 00104 def fraction_simplification_coverage(n): 00105 number_of_failed = 0 00106 for i in xrange(int(n)): 00107 os.write(common.output, "\n" + str(i+1)) 00108 for j in xrange(int(n)): 00109 # test if the Fraction i over j is reduced the right way 00110 f = common.Fraction(('+', i+1, j+1)) 00111 if f.is_reducible(): 00112 go_on = True 00113 while go_on: 00114 g = f.simplified() 00115 if not g.is_reducible(): 00116 os.write(common.output, ".") 00117 go_on = False 00118 elif g.numerator.factor[0].raw_value == \ 00119 f.numerator.factor[0].raw_value \ 00120 and g.denominator.factor[0].raw_value == \ 00121 f.denominator.factor[0].raw_value: 00122 #___ 00123 os.write(common.err_output, 00124 "\nFAILED : " \ 00125 + str(i+1) + "/" + str(j+1) \ 00126 + " -------- Step " \ 00127 + str(g.numerator.factor[0].raw_value) \ 00128 + "/" \ 00129 + str(g.denominator.factor[0].raw_value) \ 00130 + "\n") 00131 go_on = False 00132 number_of_failed += 1 00133 00134 else: 00135 f = g 00136 # go_on is still True 00137 else: 00138 os.write(common.output, ".") 00139 00140 os.write(common.output, "\nNumber of failed : " + \ 00141 str(number_of_failed) + "\n") 00142 00143 00144 def main(): 00145 parser = OptionParser(usage="usage: %prog [options] arg", 00146 version="autotest for " + software.NAME + "\n" \ 00147 + software.NAME + " " + software.VERSION \ 00148 + "\nLicense : " + software.LICENSE \ 00149 + "\n" + software.COPYRIGHT + " " \ 00150 + software.AUTHOR) 00151 00152 parser.add_option("-l", "--language", 00153 action="store", 00154 dest="lang", 00155 default='en', 00156 metavar="LANGUAGE", 00157 help="will check if LANGUAGE is available and if yes," \ 00158 + " will produce the output in LANGUAGE.") 00159 00160 parser.add_option("-v", "--verbose", 00161 action="store_true", 00162 dest="verbose", 00163 default=False, 00164 help="will turn on verbose mode (more details will be" \ 00165 + " written to the output.)") 00166 00167 parser.add_option("-V", "--superverbose", 00168 action="store_true", 00169 dest="superverbose", 00170 default=False, 00171 help="will turn on superverbose mode (much more " \ 00172 + "details will be written to the output.)") 00173 00174 parser.add_option("--short-test-run", 00175 action="store_true", 00176 dest="short_test_run", 00177 default=False, 00178 help="will start a short test run (writes once each" \ 00179 + " of the available sheets on the std err " \ 00180 + "output) instead of a unit test.") 00181 00182 parser.add_option("--long-test-run", 00183 action="store", 00184 type="int", 00185 dest="long_test_run", 00186 default=0, 00187 help="will start a long test run (writes n times the" \ 00188 + " available sheets on the std err output) " \ 00189 + "instead of a unit test." \ 00190 + " This option will be ignored if " \ 00191 + "--short-test-run is specified.") 00192 00193 parser.add_option("-F", "--fraction-simplification-coverage", 00194 action="store", 00195 type="int", 00196 dest="fraction_simplification_coverage", 00197 metavar="N", 00198 default=0, 00199 help="will start a special test to check the " \ 00200 + "simplification of fractions. It will test " \ 00201 + "all fractions from 1/1 to N/N") 00202 00203 parser.add_option("-u", "--unit", 00204 action="append", 00205 type="string", 00206 dest="units", 00207 help="will test only the given unit, instead of all of" \ 00208 + "them (default behaviour). This option can be" \ 00209 + " repeated to test several units, for instance " \ 00210 + ": autotest-mathmaker -u item -u " \ 00211 + "product will check only these two units :" \ 00212 + " item_test and product_test") 00213 00214 parser.add_option("--units-list", 00215 action="store_true", 00216 dest="units_list", 00217 default=False, 00218 help="will write the list of available units and exit.") 00219 00220 (options, args) = parser.parse_args() 00221 00222 if options.verbose: 00223 common.verbose = True 00224 common.verbose_space = " " 00225 common.OK = "ok " 00226 common.FAILED = "FAILED :\n" 00227 common.MISSING = "MISSING : " 00228 00229 elif options.superverbose: 00230 common.verbose = True 00231 common.superverbose = True 00232 common.verbose_space = " " 00233 common.OK = "ok " 00234 common.FAILED = "FAILED ]\n" 00235 common.MISSING = "MISSING : " 00236 common.superverbose_opening_token = "[#" 00237 common.superverbose_closing_token = "] " 00238 00239 if options.lang == 'en': 00240 gettext.translation(software.NAME, 00241 common.localdir, 00242 ['en']).install() 00243 else: 00244 common.tested_language = options.lang 00245 language_test(options.lang) 00246 00247 if options.units_list: 00248 os.write(common.output, "List of available test units :\n") 00249 for u in AVAILABLE_UNITS: 00250 os.write(common.output, u[0] + "\n") 00251 00252 elif options.short_test_run: 00253 short_test_run(common.tested_language) 00254 00255 elif options.long_test_run != 0: 00256 long_test_run(options.long_test_run, common.tested_language) 00257 00258 elif options.fraction_simplification_coverage != 0: 00259 fraction_simplification_coverage(\ 00260 options.fraction_simplification_coverage) 00261 00262 else: 00263 tested_units = [] 00264 if options.units != None and len(options.units) != 0: 00265 for i in xrange(len(options.units)): 00266 if options.units[i] in AVAILABLE_UNIT_NAMES: 00267 tested_units.append(AVAILABLE_UNITS_LEXICON[\ 00268 options.units[i]]) 00269 else: 00270 os.write(common.output, 00271 "You requested to test the unit '" \ 00272 + options.units[i] \ 00273 + "' but it's not available. " \ 00274 + "Run autotest-mathmaker --units-list" \ 00275 + " for more information.\n") 00276 else: 00277 for u in AVAILABLE_UNITS: 00278 tested_units.append(u[1]) 00279 00280 for unit in tested_units: 00281 common.counter = 0 00282 common.superverbose_counter = 0 00283 unit.action() 00284 if common.verbose: 00285 os.write(common.output, "\n") 00286 00287 if not common.verbose: 00288 os.write(common.output, "\n") 00289 00290 os.write(common.output, 00291 "FAILED : " + str(common.failed_counter) \ 00292 + " MISSING : " + str(common.missing_counter) \ 00293 + "\nTotal OK : " \ 00294 + str(common.global_counter - \ 00295 common.missing_counter - \ 00296 common.failed_counter)\ 00297 + "/" + str(common.global_counter) + "\n")