diff options
author | Timotej Lazar <timotej.lazar@araneo.org> | 2015-08-28 17:44:51 +0200 |
---|---|---|
committer | Timotej Lazar <timotej.lazar@araneo.org> | 2015-08-28 17:44:51 +0200 |
commit | 29892da19ae7c1b2777f48bce4674262d2a19cef (patch) | |
tree | fce7e6007b7d9d8b9a8b6a26649a80ad8c6d0183 | |
parent | ad7c5dbfea7730150f9e749349bee4e3db12af84 (diff) |
Add a hint service for Prolog
-rw-r--r-- | server/problems.py | 3 | ||||
-rw-r--r-- | server/prolog_session.py | 21 | ||||
-rw-r--r-- | server/user_session.py | 8 | ||||
-rw-r--r-- | wsgi_server.py | 16 |
4 files changed, 47 insertions, 1 deletions
diff --git a/server/problems.py b/server/problems.py index f54237d..fed9e77 100644 --- a/server/problems.py +++ b/server/problems.py @@ -36,6 +36,9 @@ def load_module(fullname): raise return mod +def load_language(language, tail_module): + return load_module('{0}.{1}'.format(language, tail_module)) + def load_problem(language, problem_group, problem, tail_module): return load_module('{0}.problems.{1}.{2}.{3}'.format(language, problem_group, problem, tail_module)) diff --git a/server/prolog_session.py b/server/prolog_session.py index ff44a56..d83d62d 100644 --- a/server/prolog_session.py +++ b/server/prolog_session.py @@ -88,6 +88,27 @@ class PrologSession(object): prolog.engine.destroy(self._engine_id) self._engine_id = None + def hint(self, user_id, problem_id, program): + language, problem_group, problem = Problem.identifier(problem_id) + + # If compilation fails just return compiler messages. + engine_id, output = prolog.engine.create(code=program) + if engine_id is not None: + prolog.engine.destroy(engine_id) + if 'error' in map(operator.itemgetter(0), output): + errors_msg = '\n'.join(['{}: {}'.format(m_type, m_text) for m_type, m_text in output]) + return [{'id': 'syntax_error', 'args': {'messages': errors_msg}}] + + # Otherwise try problem-specific hints. + problem_module = problems.load_problem(language, problem_group, problem, 'common') + if hasattr(problem_module, 'hint'): + hints = problem_module.hint(program) + if hints: + return hints + + # Finally return a generic "try thinking a bit" message. + return [{'id': 'no_hint'}] + def test(self, user_id, problem_id, program): language, problem_group, problem = Problem.identifier(problem_id) problem_module = problems.load_problem(language, problem_group, problem, 'common') diff --git a/server/user_session.py b/server/user_session.py index a463903..8b76e0a 100644 --- a/server/user_session.py +++ b/server/user_session.py @@ -66,6 +66,12 @@ class UserSession(object): def get_problem_data(self, language, problem_group, problem): mod = problems.load_problem(language, problem_group, problem, 'en') + mod_language = problems.load_language(language, 'en') + + # Get generic and problem-specific hints. + hint = dict(mod_language.hint) + hint.update(mod.hint) + conn = db.get_connection() try: cur = conn.cursor() @@ -76,7 +82,7 @@ class UserSession(object): result = { 'language': {'id': row[0], 'identifier': language, 'name': row[1]}, 'problem_group': {'id': row[2], 'identifier': problem_group, 'name': row[3]}, - 'problem': {'id': problem_id, 'identifier': problem, 'name': row[5], 'slug': mod.slug, 'description': mod.description, 'hint': mod.hint} + 'problem': {'id': problem_id, 'identifier': problem, 'name': row[5], 'slug': mod.slug, 'description': mod.description, 'hint': hint} } cur.execute("select content from solution where problem_id = %s and codeq_user_id = %s", (problem_id, self.uid)) row = cur.fetchone() diff --git a/wsgi_server.py b/wsgi_server.py index 1624772..50676b4 100644 --- a/wsgi_server.py +++ b/wsgi_server.py @@ -147,6 +147,19 @@ class Query(CodeqService): session.update_solution(problem_id, trace, program) return result +class Hint(CodeqService): + def process(self, js, session): + problem_id = js.get('problem_id') + program = js.get('program') + if problem_id is None: + return {'code': 1, 'message': 'Problem ID not given'} + if program is None: + return {'code': 2, 'message': 'No program specified'} + + prolog = session.get_prolog() + hints = prolog.hint(session.get_uid(), problem_id, program) + return {'code': 0, 'message': 'ok', 'hints': hints} + class Test(CodeqService): def process(self, js, session): problem_id = js.get('problem_id') @@ -186,6 +199,9 @@ api.add_route('/activity', activity) query = Query() api.add_route('/query', query) +hint = Hint() +api.add_route('/hint', hint) + test = Test() api.add_route('/test', test) |