summaryrefslogtreecommitdiff
path: root/kpov_judge/test_task.py
diff options
context:
space:
mode:
Diffstat (limited to 'kpov_judge/test_task.py')
-rwxr-xr-xkpov_judge/test_task.py246
1 files changed, 0 insertions, 246 deletions
diff --git a/kpov_judge/test_task.py b/kpov_judge/test_task.py
deleted file mode 100755
index 43aaf38..0000000
--- a/kpov_judge/test_task.py
+++ /dev/null
@@ -1,246 +0,0 @@
-#!/usr/bin/env python3
-
-import argparse
-import collections
-import getpass
-import inspect
-import io
-import json
-import locale
-import os
-import random
-import readline
-import sys
-import urllib.request
-
-import yaml
-import kpov_util
-
-locale.setlocale(locale.LC_ALL, ['C', 'utf8'])
-readline.set_completer_delims(readline.get_completer_delims().replace('/', ''))
-readline.parse_and_bind('tab: complete')
-
-TASK_URL = "file://" + os.getcwd() + '/tasks'
-PARAMS_FILE = os.path.expanduser("~/.kpov_params.yaml")
-DEFAULT_LANGUAGE = 'si'
-
-def print_header(title, spacing=1):
- print('\n'*spacing + '> {}'.format(title))
-
-# get the parameters for a task either from the user or from a file
-def get_params(params, params_meta, language=None):
- # prefill input() prompt with given text
- def rlinput(prompt, prefill=''):
- readline.set_startup_hook(lambda: readline.insert_text(prefill))
- try:
- return input(prompt)
- finally:
- readline.set_startup_hook()
-
- if language is None:
- language = params.get('language', DEFAULT_LANGUAGE)
-
- # print all non-writable parameters first, then prompt for writable ones
- for name, meta in sorted(params_meta.items(), key=lambda n: n[1].get('w', True)):
- description = meta.get('descriptions', {}).get(language, name)
- if name not in params:
- params[name] = None
- if meta.get('w', True):
- try:
- if meta.get('masked', False):
- s = getpass.getpass('{}: '.format(description))
- else:
- s = rlinput('{}: '.format(description), params.get(name, ''))
- if s:
- params[name] = s
- except EOFError:
- print()
- else:
- print('{}: {}'.format(name, params.get(name, '')))
- return params
-
-def add_meta_to_argparser(argparser, meta, defaults={}):
- language = defaults.get('language', DEFAULT_LANGUAGE)
- for k, v in meta.items():
- try:
- desc = v['descriptions'][language].encode("utf-8")
- except:
- desc = k
- argparser.add_argument('--'+k, nargs='?', type=str, help=desc,
- default=defaults.get(k, None))
-
-def load_params(filename):
- try:
- return yaml.load(open(filename))
- except:
- return {}
-
-def locate_task(params, argparser, quiet=False):
- # first the URL where all tasks are stored
- url_meta = {
- 'task_url': {'descriptions': {'si': 'URL z nalogami', 'en': 'Root URL for all tasks'}}
- }
- if 'task_url' not in params:
- params['task_url'] = TASK_URL
- add_meta_to_argparser(argparser, meta=url_meta, defaults=params)
- args, unknown_args = argparser.parse_known_args()
- params['task_url'] = args.task_url
- if not quiet:
- print_header('Task', spacing=0)
- params = get_params(params, url_meta)
-
- # and finally, the name of the task
- fetch_params_meta = collections.OrderedDict({'task_name': {'descriptions': {'si': 'Ime naloge', 'en': 'Task name'}}})
- add_meta_to_argparser(argparser, meta=fetch_params_meta, defaults=params)
- args, unknown_args = argparser.parse_known_args()
- # update params with the now known args
- for k, v in fetch_params_meta.items():
- params[k] = vars(args).get(k, params.get(k, None))
- if not quiet:
- params = get_params(params, fetch_params_meta)
- return params
-
-def http_auth(url, username, password):
- password_mgr = urllib.request.HTTPPasswordMgrWithDefaultRealm()
- password_mgr.add_password(None, url, username, password)
- handler = urllib.request.HTTPBasicAuthHandler(password_mgr)
- opener = urllib.request.build_opener(handler)
- urllib.request.install_opener(opener) # now all calls to urlopen use our opener
-
-def load_task(stream):
- # the stream should definitions for the functions task(…),
- # task_check and gen_params, and a dictionary params_meta
- d = {}
- exec(compile(source, 'task.py', 'exec'), globals(), d)
- return d['task'], d['task_check'], d['params_meta'], d['gen_params']
-
-
-if __name__ == '__main__':
- # get the parameters needed to get to the task, such as the URLs, the name of the task and optionally an ID from the student
- # start with the the parameters needed for the dialog gui to work
- argparser = argparse.ArgumentParser(conflict_handler='resolve',
- description='Test a KPOV Judge task.')
- argparser.add_argument('-h', '--help', action='store_true')
- argparser.add_argument('-q', '--quiet', action='store_true',
- help='disable prompts')
- argparser.add_argument('-g', '--generate_params', action='store_true',
- help='generate initial values for the task parameters')
- argparser.add_argument('-pf', '--params_file', nargs='?', default=PARAMS_FILE,
- help='a local file with saved param values')
- basic_args, unknown_args = argparser.parse_known_args()
-
- # get default parameters including language
- params = load_params(basic_args.params_file)
- argparser.add_argument('-l', '--language', nargs='?',
- default=params.get('language', DEFAULT_LANGUAGE),
- help='the language used')
- basic_args, unknown_args = argparser.parse_known_args()
- params['language'] = basic_args.language
-
- if basic_args.help:
- argparser.print_help()
- exit(0)
-
- # continue with the parameters needed to get the task
- params = locate_task(params, argparser, quiet=basic_args.quiet)
- # TODO: if the task name is missing or invalid, try to get a list of tasks
- # get task source and generate params if neccessarry
- try:
- task_url = params['task_url']
- task_name = params['task_name']
-
- source = urllib.request.urlopen("{task_url}/{task_name}/task.py".format(**params)).read()
- if not source:
- raise Exception('no such task: {}'.format(task_name))
- task, task_check, task_params_meta, gen_params = load_task(source)
- except Exception as e:
- print(e)
- with open(basic_args.params_file, 'w') as f:
- yaml.dump(params, f)
- exit(1)
-
- # get stored task parameters
- params['task_params'] = params.get('task_params', {})
- task_params = params['task_params'].setdefault(task_name, {})
- tokens = params.setdefault('tokens', {})
-
- # ensure we have a submission token
- if task_url.startswith('http'):
- n_tries = 3
- while n_tries > 0:
- try:
- if tokens.get(task_name):
- response = urllib.request.urlopen(
- '{task_url}/{task_name}/params.json'.format(**params),
- data=urllib.parse.urlencode({'token': tokens.get(task_name)}).encode())
- response = json.load(io.TextIOWrapper(response))
- if response:
- # got params
- task_params.update(response)
- break
- else:
- # did not get a token, try again with password
- del tokens[task_name]
- n_tries -= 1
-
- if not tokens.get(task_name):
- # get the student's ID and password
- # TODO clunky, should refactor all argument-getting stuff
- user_meta = collections.OrderedDict((
- ('username', {'descriptions': {'si': 'Uporabniško ime', 'en': 'Username'}}),
- ('password', {'descriptions': {'si': 'Geslo', 'en': 'Password'}, 'masked': True}),
- ))
- print_header('KPOV login')
- user_params = get_params(params, user_meta, params['language'])
-
- http_auth(task_url, user_params['username'], user_params['password'])
- response = urllib.request.urlopen('{task_url}/{task_name}/token.json'.format(**params))
- response = json.load(io.TextIOWrapper(response))
- if response:
- tokens[task_name] = response['token']
- params['username'] = user_params['username']
- except Exception as ex:
- print(ex)
-
- if basic_args.generate_params:
- #prejema lahko samo stringe in ne številk (potrebno je str(int)
- # print ("params before: {} {}".format(params, task_params))
- task_params.update(gen_params(params['username'], task_params_meta))
- # print ("params after: {} {}".format(params, task_params))
-
- task_argparser = argparse.ArgumentParser(parents=[argparser], conflict_handler='resolve', add_help=True)
- add_meta_to_argparser(task_argparser, task_params_meta, defaults=task_params)
- args = vars(task_argparser.parse_args())
- for k in task_params_meta:
- if args.get(k):
- task_params[k] = args[k]
- if not basic_args.quiet:
- print_header('Task parameters')
- task_params = get_params(task_params, task_params_meta, language=params['language'])
-
- public_params = {}
- for k in inspect.getargs(task.__code__)[0]:
- public_params[k] = task_params[k]
- params['task_params'][params['task_name']] = task_params
-
- # save parameters for the next run
- with open(basic_args.params_file, 'w') as f:
- yaml.dump(params, f)
-
- try:
- print_header('Results', spacing=0 if basic_args.quiet else 1)
- print('Running task... ', end='', flush=True)
- task_result = task(**public_params)
- print('checking task... ', end='', flush=True)
- task_params['token'] = tokens[task_name] # hack to avoid changing task_check signature
- score, hints = task_check(task_result, task_params)
- del task_params['token']
- print('done!')
- print('Score: {}'.format(score))
-
- print_header('Hints')
- for hint in hints:
- print(hint.strip())
- except Exception as e:
- import traceback
- traceback.print_exc()