summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTimotej Lazar <timotej.lazar@araneo.org>2015-08-28 17:44:51 +0200
committerTimotej Lazar <timotej.lazar@araneo.org>2015-08-28 17:44:51 +0200
commit29892da19ae7c1b2777f48bce4674262d2a19cef (patch)
treefce7e6007b7d9d8b9a8b6a26649a80ad8c6d0183
parentad7c5dbfea7730150f9e749349bee4e3db12af84 (diff)
Add a hint service for Prolog
-rw-r--r--server/problems.py3
-rw-r--r--server/prolog_session.py21
-rw-r--r--server/user_session.py8
-rw-r--r--wsgi_server.py16
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)