Mercurial > ~astiob > upreckon > hgweb
view test-svn.py @ 40:af9c45708987
Cemented a decision previously being unsure about
The mere presense of the tasknames configuration variable now always makes problem names to be printed.
This is not new, but the old behaviour (only printing names if we test more than one problem), previously commented out, has now been removed altogether.
author | Oleg Oshmyan <chortos@inbox.lv> |
---|---|
date | Sun, 05 Dec 2010 14:34:24 +0100 |
parents | f90bd2d1a12b |
children |
line wrap: on
line source
#! /usr/bin/python # Copyright (c) 2009-2010 Chortos-2 <chortos@inbox.lv> import os, sys, shutil, time, subprocess, filecmp, optparse, signal, tempfile, tarfile, zipfile version = '1.21.0 ($$REV$$)' parser = optparse.OptionParser(version='test.py '+version, usage='usage: %prog [options] [problem names] [[path' + os.path.sep + 'to' + os.path.sep + ']solution-app] [test case numbers]\n\nTest case numbers can be specified in plain text or as a Python expression\nif there is only one positional argument.\n\nOnly problem names listed in testconf.py are recognized.') parser.add_option('-u', '--update', dest='update', action='store_true', default=False, help='check for an updated version of test.py') parser.add_option('-e', '--exclude', dest='exclude', action='append', help='test case number(s) to exclude, as a Python expression; multiple -e options can be supplied') parser.add_option('-c', '--cleanup', dest='clean', action='store_true', default=False, help='delete the copies of input/output files and exit') parser.add_option('-s', '--save-io', dest='erase', action='store_false', default=True, help='do not delete the copies of input/output files after the last test case; create copies of input files and store output in files even if the solution uses standard I/O; delete the stored input/output files if the solution uses standard I/O and the -c/--cleanup option is specified') parser.add_option('-m', '--copy-io', dest='copyonly', action='store_true', default=False, help='only create a copy of the input/output files of the last test case for manual testing; to delete them, use options -cs or -cm') parser.add_option('-x', '--auto-exit', dest='pause', action='store_false', default=True, help='do not wait for a key to be pressed when finished testing') parser.add_option('-p', '--python', action='store_true', default=False, help='always parse all positional arguments as a single Python expression (including the first argument even if it names an executable file)') parser.add_option('-t', '--detect-time', dest='autotime', action='store_true', default=False, help='spend a second detecting the most precise time measurement function') parser.add_option('-b', dest='builtin', action='store_true', default=False) options, args = parser.parse_args() parser.destroy() del parser if options.builtin: try: if args[0] == 'run': import resource maxmemory = int(args[1]) resource.setrlimit(resource.RLIMIT_AS, (maxmemory*1024**2, maxmemory*1024**2)) os.execv(args[2], args[2:]) else: sys.exit(2) except: sys.exit(2) def update(): import urllib latesttext = urllib.urlopen('http://chortos.selfip.net/~astiob/test.py/version.txt').read() latest = latesttext.split('.') installed = version.split('.') update = '' if latest[0] > installed[0]: update = 'major' elif latest[0] == installed[0]: if latest[1] > installed[1]: update = 'feature' elif latest[1] == installed[1]: if latest[2] > installed[2]: update = 'bug-fixing' elif latest[2] == installed[2]: print 'You are using the latest publicly available version of test.py.' return if update == '': print 'Your copy of test.py is newer than the publicly available version.' return print 'A ' + update + ' update to test.py is available. Downloading...' sys.stdout.flush() urllib.urlretrieve('http://chortos.selfip.net/~astiob/test.py/test.py', 'test.py') print 'Downloaded and installed. Now you are using test.py ' + latesttext + '.' if options.update: update() sys.exit() try: import resource memlimit = True def call(name): pid = os.fork() if not pid: resource.setrlimit(resource.RLIMIT_AS, (maxmemory*1024**2, maxmemory*1024**2)) os.execl(name) else: return pid except ImportError: memlimit = False globals1 = set(globals()) # Initialize some configuration variables with default values tasknames = (os.path.curdir,) maxtime = 0 tests = () dummies = () testsexcluded = () padwithzeroestolength = 0 taskweight = 100 pointmap = {} stdio = False dummyinname = '' dummyoutname = '' tester = '' maxexitcode = 0 def exectestconf_helper(name): if os.path.isfile('tests.tar'): f = tarfile.open('tests.tar') try: exec f.extractfile(name).read() in globals() f.close() return True except KeyError: f.close() if os.path.isfile('tests.zip'): f = zipfile.ZipFile('tests.zip') try: exec f.open(name, 'rU').read() in globals() f.close() return True except KeyError: f.close() if os.path.isfile('tests.tgz'): f = tarfile.open('tests.tgz') try: exec f.extractfile(name).read() in globals() f.close() return True except KeyError: f.close() if os.path.isfile('tests.tar.gz'): f = tarfile.open('tests.tar.gz') try: exec f.extractfile(name).read() in globals() f.close() return True except KeyError: f.close() if os.path.isfile('tests.tbz2'): f = tarfile.open('tests.tbz2') try: exec f.extractfile(name).read() in globals() f.close() return True except KeyError: f.close() if os.path.isfile('tests.tar.bz2'): f = tarfile.open('tests.tar.bz2') try: exec f.extractfile(name).read() in globals() f.close() return True except KeyError: f.close() return False try: execfile('testconf.py') except IOError, error: exc_info = sys.exc_info()[2] try: execfile(os.path.join('tests', 'testconf.py')) except IOError: if not exectestconf_helper('testconf.py'): raise IOError, (error.errno, 'The configuration file is missing', error.filename), exc_info del exc_info globals2 = set(globals()) globals2.remove('globals1') globals2 -= globals1 del globals1 shared = {} g = globals() for k in globals2: shared[k] = g[k] newtasknames = [] while len(args) and args[0] in tasknames: newtasknames.append(args[0]) del args[0] if len(newtasknames): tasknames = newtasknames scoresumoveralltasks = 0 scoremaxoveralltasks = 0 ntasks = 0 nfulltasks = 0 cwd = '' # At any time this is either '' or taskname if options.autotime: c = time.clock() time.sleep(1) c = time.clock() - c if int(c + .99999) == 1: clock = time.clock else: clock = time.time elif os.name == 'nt': clock = time.clock else: clock = time.time if options.copyonly: options.erase = False def existstestcase_helper(name): if os.path.isfile('tests.tar'): f = tarfile.open('tests.tar') try: f.getmember(name) f.close() return True except KeyError: f.close() if os.path.isfile('tests.zip'): f = zipfile.ZipFile('tests.zip') try: f.getinfo(name) f.close() return True except KeyError: f.close() if os.path.isfile('tests.tgz'): f = tarfile.open('tests.tgz') try: f.getmember(name) f.close() return True except KeyError: f.close() if os.path.isfile('tests.tar.gz'): f = tarfile.open('tests.tar.gz') try: f.getmember(name) f.close() return True except KeyError: f.close() if os.path.isfile('tests.tbz2'): f = tarfile.open('tests.tbz2') try: f.getmember(name) f.close() return True except KeyError: f.close() if os.path.isfile('tests.tar.bz2'): f = tarfile.open('tests.tar.bz2') try: f.getmember(name) f.close() return True except KeyError: f.close() return False def existstestcase(name): if os.path.isfile(os.path.join('tests', taskname, name)) or os.path.isfile(os.path.join('tests', name)): return True if cwd and (os.path.isfile(os.path.join(oldcwd, 'tests', cwd, name)) or os.path.isfile(os.path.join(oldcwd, 'tests', name))): return True if existstestcase_helper(os.path.join(taskname, name)) or existstestcase_helper(name): return True if cwd: os.chdir(oldcwd) if existstestcase_helper(os.path.join(cwd, name)) or existstestcase_helper(name): os.chdir(cwd) return True os.chdir(cwd) return False def opentestcase_helper(name): if os.path.isfile('tests.tar'): f = tarfile.open('tests.tar') try: c = f.extractfile(name) return c except KeyError: f.close() if os.path.isfile('tests.zip'): f = zipfile.ZipFile('tests.zip') try: c = f.open(name, 'rU') f.close() return c except KeyError: f.close() if os.path.isfile('tests.tgz'): f = tarfile.open('tests.tgz') try: c = f.extractfile(name) return c except KeyError: f.close() if os.path.isfile('tests.tar.gz'): f = tarfile.open('tests.tar.gz') try: c = f.extractfile(name) return c except KeyError: f.close() if os.path.isfile('tests.tbz2'): f = tarfile.open('tests.tbz2') try: c = f.extractfile(name) return c except KeyError: f.close() if os.path.isfile('tests.tar.bz2'): f = tarfile.open('tests.tar.bz2') try: c = f.extractfile(name) return c except KeyError: f.close() return None def opentestcase(name): if os.path.isfile(os.path.join('tests', taskname, name)): return open(os.path.join('tests', taskname, name), 'rU') elif os.path.isfile(os.path.join('tests', name)): return open(os.path.join('tests', name), 'rU') f = opentestcase_helper(os.path.join(taskname, name)) if not f: f = opentestcase_helper(name) if f: return f if cwd: if os.path.isfile(os.path.join(oldcwd, 'tests', cwd, name)): return open(os.path.join(oldcwd, 'tests', cwd, name), 'rU') elif os.path.isfile(os.path.join(oldcwd, 'tests', name)): return open(os.path.join(oldcwd, 'tests', name), 'rU') os.chdir(oldcwd) f = opentestcase_helper(os.path.join(cwd, name)) if not f: f = opentestcase_helper(name) os.chdir(cwd) if f: return f raise KeyError, 'The test-case-defining file \'' + name + '\' cannot be found' def copytestcase_helper(name, target): if os.path.isfile('tests.tar'): f = tarfile.open('tests.tar') try: m = f.getmember(name) m.name = target f.extract(m) f.close() return True except KeyError: f.close() if os.path.isfile('tests.zip'): if not os.path.isabs(target): f = zipfile.ZipFile('tests.zip') try: m = f.getinfo(name) m.filename = target f.extract(m) f.close() return True except KeyError: f.close() else: oldcwd = os.getcwdu() os.chdir('/') # FIXME: portability? f = zipfile.ZipFile(os.path.join(oldcwd, 'tests.zip')) try: m = f.getinfo(name) m.filename = os.path.relpath(target) f.extract(m) f.close() os.chdir(oldcwd) return True except KeyError: f.close() os.chdir(oldcwd) if os.path.isfile('tests.tgz'): f = tarfile.open('tests.tgz') try: m = f.getmember(name) m.name = target f.extract(m) f.close() return True except KeyError: f.close() if os.path.isfile('tests.tar.gz'): f = tarfile.open('tests.tar.gz') try: m = f.getmember(name) m.name = target f.extract(m) f.close() return True except KeyError: f.close() if os.path.isfile('tests.tbz2'): f = tarfile.open('tests.tbz2') try: m = f.getmember(name) m.name = target f.extract(m) f.close() return True except KeyError: f.close() if os.path.isfile('tests.tar.bz2'): f = tarfile.open('tests.tar.bz2') try: m = f.getmember(name) m.name = target f.extract(m) f.close() return True except KeyError: f.close() return False def copytestcase(name, target): if os.path.isfile(os.path.join('tests', taskname, name)): shutil.copyfile(os.path.join('tests', taskname, name), target) return elif os.path.isfile(os.path.join('tests', name)): shutil.copyfile(os.path.join('tests', name), target) return if copytestcase_helper(os.path.join(taskname, name), target) or copytestcase_helper(name, target): return if cwd: if os.path.isfile(os.path.join(oldcwd, 'tests', cwd, name)): shutil.copyfile(os.path.join(oldcwd, 'tests', cwd, name), target) return elif os.path.isfile(os.path.join(oldcwd, 'tests', name)): shutil.copyfile(os.path.join(oldcwd, 'tests', name), target) return os.chdir(oldcwd) if copytestcase_helper(os.path.join(cwd, name), target) or copytestcase_helper(name, target): os.chdir(cwd) return os.chdir(cwd) raise KeyError, 'The test-case-defining file \'' + name + '\' cannot be found' # Always chdir if the directory exists but use any existing config def chdir_and_exec_testconf(): global cwd cwd = '' if os.path.isdir(taskname): os.chdir(taskname) if taskname != os.path.curdir: cwd = taskname try: execfile('testconf.py', globals()) return except IOError: pass if not cwd: if os.path.isfile(os.path.join('tests', taskname, 'testconf.py')): execfile(os.path.join('tests', taskname, 'testconf.py'), globals()) return if os.path.isfile(os.path.join('tests', 'testconf.py')): execfile(os.path.join('tests', 'testconf.py'), globals()) return if exectestconf_helper(os.path.join(taskname, 'testconf.py')) or exectestconf_helper('testconf.py'): return if cwd: os.chdir(oldcwd) if os.path.isfile(os.path.join('tests', cwd, 'testconf.py')): execfile(os.path.join('tests', cwd, 'testconf.py'), globals()) os.chdir(cwd) return if os.path.isfile(os.path.join('tests', 'testconf.py')): execfile(os.path.join('tests', 'testconf.py'), globals()) os.chdir(cwd) return if exectestconf_helper(os.path.join(cwd, 'testconf.py')) or exectestconf_helper('testconf.py'): os.chdir(cwd) return if os.path.isfile('testconf.py'): execfile('testconf.py', globals()) os.chdir(cwd) return os.chdir(cwd) elif os.path.isfile('testconf.py'): execfile('testconf.py', globals()) return raise KeyError, 'The configuration file for task ' + taskname + ' is missing' try: name namedefined = True except Exception: namedefined = False for taskname in tasknames: if ntasks: print try: if len(tasknames) > 1: print taskname except Exception: if taskname != os.path.curdir or ntasks: print taskname try: del inname except NameError: pass try: del outname except NameError: pass try: del ansname except NameError: pass if not namedefined and taskname != os.path.curdir: name = os.path.join(os.path.curdir, taskname) for k in shared: g[k] = shared[k] oldcwd = os.getcwdu() chdir_and_exec_testconf() if options.clean: try: if not stdio or tester: if not tester: inname outname if tester: ansname except NameError, error: raise NameError, 'configuration ' + str(error).replace('name ', 'variable ', 1), sys.exc_info()[2] if not options.erase: try: inname = inname.replace('%', taskname) except NameError: inname = taskname + '.in' try: outname = outname.replace('%', taskname) except NameError: outname = taskname + '.out' try: ansname = ansname.replace('%', taskname) except NameError: ansname = taskname + '.ans' elif not stdio or tester or not options.erase: inname = inname.replace('%', taskname) outname = outname.replace('%', taskname) if tester: ansname = ansname.replace('%', taskname) if not stdio or tester or not options.erase: if os.path.exists(inname): os.remove(inname) if os.path.exists(outname): os.remove(outname) if (tester or not options.erase) and ansname: if os.path.exists(ansname): os.remove(ansname) continue try: name except NameError, error: if str(error).count('name') == 1: raise NameError, 'configuration ' + str(error), sys.exc_info()[2] else: raise NameError, 'configuration ' + str(error).replace('name ', 'variable ', 1), sys.exc_info()[2] try: if not stdio: inname outname testcaseinname if tester: outname if ansname: testcaseoutname else: testcaseoutname except NameError, error: raise NameError, 'configuration ' + str(error).replace('name ', 'variable ', 1), sys.exc_info()[2] if not options.erase: try: inname except NameError: inname = taskname + '.in' try: outname except NameError: outname = taskname + '.out' try: ansname except NameError: ansname = taskname + '.ans' if options.pause: try: pause except NameError, error: if os.name == 'posix': pause = 'read -s -n 1' print 'Configuration ' + str(error).replace('name ', 'variable ') + '; it was devised automatically but the choice might be incorrect, so test.py might exit immediately after the testing is completed.' elif os.name == 'nt': pause = 'pause' else: raise NameError, 'configuration ' + str(error).replace('name ', 'variable ') + ' and cannot be devised automatically', sys.exc_info()[2] if not dummyinname: dummyinname = testcaseinname if not dummyoutname and (not tester or ansname): dummyoutname = testcaseoutname dummyinname = dummyinname.replace('%', taskname) dummyoutname = dummyoutname.replace('%', taskname) testcaseinname = testcaseinname.replace('%', taskname) if not stdio or not options.erase: inname = inname.replace('%', taskname) outname = outname.replace('%', taskname) try: ansname = ansname.replace('%', taskname) except NameError: pass if tester: try: inname = inname.replace('%', taskname) except NameError: pass outname = outname.replace('%', taskname) if ansname: ansname = ansname.replace('%', taskname) testcaseoutname = testcaseoutname.replace('%', taskname) else: testcaseoutname = testcaseoutname.replace('%', taskname) if isinstance(padwithzeroestolength, tuple): padwithzeroestolength, paddummieswithzeroestolength = padwithzeroestolength else: paddummieswithzeroestolength = padwithzeroestolength if options.python: dummies = () s = ' '.join(args) tests = eval(s) try: tests.__iter__ except AttributeError: tests = (tests,) elif len(args): if os.path.exists(args[0]): name = args[0] del args[0] if len(args) > 1: dummies = () tests = args elif len(args): dummies = () s = args[0] if len(s) < padwithzeroestolength: s = s.zfill(padwithzeroestolength) if existstestcase(testcaseinname.replace('$', s)): tests = (s,) else: try: tests = eval(args[0]) try: tests.__iter__ except AttributeError: tests = (tests,) except Exception: tests = (s,) if options.exclude: testsexcluded = [] for i in options.exclude: v = eval(i) try: testsexcluded.extend(v) except TypeError: testsexcluded.append(v) # Windows doesn't like paths beginning with .\ and not ending with an extension name = os.path.normcase(name) if os.name == 'nt' and name.startswith('.\\'): name = name[2:] newpointmap = {} for i in pointmap: try: for j in i: newpointmap[j] = pointmap[i] except TypeError: newpointmap[i] = pointmap[i] pointmap = newpointmap if not tester: maxexitcode = 0 if maxtime > 0: strmaxtime = '/%.3f' % maxtime else: strmaxtime = '' padoutputtolength = 0 ntests = [] for j in dummies: try: j.__iter__ except AttributeError: j = (j,) ntests.append((j, True)) for i in j: s = str(i) if len(s) < paddummieswithzeroestolength: s = s.zfill(paddummieswithzeroestolength) s = 'sample ' + s if padoutputtolength < len(s): padoutputtolength = len(s) for j in tests: try: j.__iter__ except AttributeError: j = (j,) ntests.append((j, False)) for i in j: s = str(i) if len(s) < padwithzeroestolength: s = s.zfill(padwithzeroestolength) if padoutputtolength < len(s): padoutputtolength = len(s) tests = ntests score = maxpoints = ncorrect = ntotal = ncorrectvalued = nvalued = 0 if options.copyonly: j, isdummy = tests[-1] if isdummy: realinname = dummyinname realoutname = dummyoutname else: realinname = testcaseinname realoutname = testcaseoutname for i in j: if i in testsexcluded and not isdummy: continue s = str(i) if isdummy: if len(s) < paddummieswithzeroestolength: s = s.zfill(paddummieswithzeroestolength) else: if len(s) < padwithzeroestolength: s = s.zfill(padwithzeroestolength) copytestcase(realinname.replace('$', s), inname) if ansname: copytestcase(realoutname.replace('$', s), ansname) continue for j, isdummy in tests: ncorrectgrp = 0 ntotalgrp = 0 scoregrp = 0 maxpointsgrp = 0 if isdummy: realinname = dummyinname realoutname = dummyoutname else: realinname = testcaseinname realoutname = testcaseoutname for i in j: if i in testsexcluded and not isdummy: continue ntotalgrp += 1 s = str(i) if isdummy: npoints = 0 if len(s) < paddummieswithzeroestolength: s = s.zfill(paddummieswithzeroestolength) spref = 'sample ' else: npoints = pointmap.get(None, maxexitcode if maxexitcode and isinstance(maxexitcode, int) else 1) npoints = pointmap.get(i, npoints) maxpointsgrp += npoints if npoints: nvalued += 1 if len(s) < padwithzeroestolength: s = s.zfill(padwithzeroestolength) spref = '' print ' ' * (padoutputtolength - len(spref + s)) + spref + s + ':', sys.stdout.flush() outputdata = open(os.devnull, 'w') if stdio: f = tempfile.NamedTemporaryFile(delete=False) inputdatafname = f.name f.close() copytestcase(realinname.replace('$', s), inputdatafname) inputdata = open(inputdatafname, 'rU') if options.erase: tempoutput = tempfile.TemporaryFile('w+') else: tempoutput = open(outname, 'w+') try: proc = subprocess.Popen(name, stdin=inputdata, stdout=tempoutput, stderr=outputdata, universal_newlines=True) except OSError, error: raise OSError, 'The program to be tested cannot be launched: ' + str(error), sys.exc_info()[2] else: if os.path.exists(outname): os.remove(outname) copytestcase(realinname.replace('$', s), inname) try: proc = subprocess.Popen(name, stdin=outputdata, stdout=outputdata, stderr=outputdata, universal_newlines=True) except OSError, error: raise OSError, 'The program to be tested cannot be launched: ' + str(error), sys.exc_info()[2] cl = clock() if maxtime > 0: while 1: proc.poll() elapsed = clock() - cl if proc.returncode == None: if elapsed >= maxtime: print '%.3f%s s, 0/%d, time limit exceeded' % (elapsed, strmaxtime, npoints) sys.stdout.flush() while proc.returncode == None: try: proc.terminate() except OSError: pass except AttributeError: try: os.kill(proc.pid, signal.SIGTERM) except Exception: pass proc.poll() outputdata.close() if stdio: tempoutput.close() break else: print '%.3f%s s,' % (elapsed, strmaxtime), sys.stdout.flush() elapsed = 0 if stdio: tempoutput.seek(0) lines = tempoutput.readlines() tempoutput.close() break if elapsed >= maxtime: continue else: data = proc.communicate() elapsed = clock() - cl print '%.3f%s s,' % (elapsed, strmaxtime), sys.stdout.flush() if stdio: tempoutput.seek(0) lines = tempoutput.readlines() tempoutput.close() outputdata.close() if stdio: inputdata.close() try: os.unlink(inputdatafname) except Exception: pass if proc.returncode > 0: print '0/%d, non-zero return code %d' % (npoints, proc.returncode) sys.stdout.flush() elif proc.returncode < 0: print '0/%d, terminated by signal %d' % (npoints, -proc.returncode) sys.stdout.flush() else: if not tester: if stdio: outputdata = opentestcase(realoutname.replace('$', s)) r = 0 data = outputdata.read().splitlines(True) if len(lines) != len(data): r = 1 else: for i in zip(lines, data): if i[0] != i[1]: r = 1 break outputdata.close() else: try: inputdata = open(outname, 'rU') except IOError: print '0/%g, output file not created or not readable' % npoints sys.stdout.flush() r = None else: outputdata = opentestcase(realoutname.replace('$', s)) r = 0 lines = inputdata.readlines() data = outputdata.read().splitlines(True) if len(lines) != len(data): r = 1 else: for i in zip(lines, data): if i[0] != i[1]: r = 1 break inputdata.close() outputdata.close() else: if ansname: copytestcase(realoutname.replace('$', s), ansname) if stdio: try: copytestcase(realinname.replace('$', s), inname) except NameError: pass outputdata = open(outname, 'w') outputdata.writelines(lines) outputdata.close() try: proc = subprocess.Popen(tester, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, universal_newlines=True) except OSError, error: raise OSError, 'The tester application cannot be launched: ' + str(error), sys.exc_info()[2] data = proc.communicate() r = proc.returncode if tester and data[0]: data = ''.join((' (', data[0].strip(), ')')) else: data = '' if not maxexitcode and r or maxexitcode and not r: print '0/%g, wrong answer%s' % (npoints, data) sys.stdout.flush() elif not maxexitcode and r == 0 or maxexitcode and r >= maxexitcode: print '%g/%g, OK%s' % (npoints, npoints, data) sys.stdout.flush() scoregrp += npoints ncorrectgrp += 1 if npoints: ncorrectvalued += 1 elif maxexitcode and r != None: actualpoints = npoints*r/maxexitcode if not npoints*r%maxexitcode else float(npoints*r)/maxexitcode print '%g/%g, partly OK%s' % (actualpoints, npoints, data) sys.stdout.flush() scoregrp += actualpoints ncorrectgrp += 1 if npoints: ncorrectvalued += 1 if ntotalgrp: if ncorrectgrp < ntotalgrp: scoregrp = 0 if ntotalgrp > 1: print 'Group total: %d/%d tests; %g/%g points' % (ncorrectgrp, ntotalgrp, scoregrp, maxpointsgrp) sys.stdout.flush() ncorrect += ncorrectgrp ntotal += ntotalgrp score += scoregrp maxpoints += maxpointsgrp if options.erase: if not stdio or tester: if os.path.exists(inname): os.remove(inname) if os.path.exists(outname): os.remove(outname) if tester and ansname: if os.path.exists(ansname): os.remove(ansname) elif stdio: copytestcase(realinname.replace('$', s), inname) copytestcase(realoutname.replace('$', s), ansname) actualpoints = (score*taskweight/maxpoints if not score*taskweight%maxpoints else float(score*taskweight)/maxpoints) if maxpoints else 0 if nvalued != ntotal: print 'Grand total: %d/%d tests (%d/%d valued); %g/%g points; weighted score: %g/%g' % (ncorrect, ntotal, ncorrectvalued, nvalued, score, maxpoints, actualpoints, taskweight) else: print 'Grand total: %d/%d tests; %g/%g points; weighted score: %g/%g' % (ncorrect, ntotal, score, maxpoints, actualpoints, taskweight) scoresumoveralltasks += actualpoints scoremaxoveralltasks += taskweight ntasks += 1 nfulltasks += int((score == maxpoints) if maxpoints else (taskweight == 0)) os.chdir(oldcwd) if options.clean or options.copyonly: sys.exit() if ntasks != 1: print print 'Grand grand total: %g/%g weighted points; %d/%d problems solved fully' % (scoresumoveralltasks, scoremaxoveralltasks, nfulltasks, ntasks) if options.pause: print 'Press any key to exit... ', sys.stdout.flush() os.system(pause + ' >' + os.devnull)