Commit 5755325a by Александр

changed syntax to support e1,e2 in AX6 and add convert_to_p behavior

parent fa2cf6a4
from collections import OrderedDict
import json import json
import unittest import unittest
import itertools
def vsepr_parse_user_answer(user_input): def vsepr_parse_user_answer(user_input):
d = OrderedDict(json.loads(user_input)) return json.loads(user_input)
d['atoms'] = OrderedDict(sorted(d['atoms'].items()))
return d
def vsepr_build_correct_answer(geometry, atoms): def vsepr_build_correct_answer(geometry, atoms):
correct_answer = OrderedDict() return {'geometry': geometry, 'atoms': atoms}
correct_answer['geometry'] = geometry
correct_answer['atoms'] = OrderedDict(sorted(atoms.items()))
return correct_answer
def vsepr_grade(user_input, correct_answer, convert_to_perepherial=False): def vsepr_grade(user_input, correct_answer, convert_to_perepherial=False):
...@@ -22,6 +16,7 @@ def vsepr_grade(user_input, correct_answer, convert_to_perepherial=False): ...@@ -22,6 +16,7 @@ def vsepr_grade(user_input, correct_answer, convert_to_perepherial=False):
c0, a, e c0, a, e
c0, p c0, p
""" """
# import ipdb; ipdb.set_trace()
# print user_input, type(user_input) # print user_input, type(user_input)
# print correct_answer, type(correct_answer) # print correct_answer, type(correct_answer)
if user_input['geometry'] != correct_answer['geometry']: if user_input['geometry'] != correct_answer['geometry']:
...@@ -33,19 +28,45 @@ def vsepr_grade(user_input, correct_answer, convert_to_perepherial=False): ...@@ -33,19 +28,45 @@ def vsepr_grade(user_input, correct_answer, convert_to_perepherial=False):
if convert_to_perepherial: if convert_to_perepherial:
# convert user_input from (a,e,e1,e2) to (p) # convert user_input from (a,e,e1,e2) to (p)
# correct_answer must be set in (p) using this flag # correct_answer must be set in (p) using this flag
c0 = user_input['atoms'].pop('c0')
user_input['atoms'] = {'p' + str(i): v for i, v in enumerate(user_input['atoms'].values())} user_input['atoms'] = {'p' + str(i): v for i, v in enumerate(user_input['atoms'].values())}
user_input['atoms']['c0'] = c0
# special case for AX6
if 'e10' in correct_answer['atoms']: # need check e1x, e2x symmetry for AX6..
a_user = {}
a_correct = {}
for ea_position in ['a', 'e1', 'e2']: # collecting positions:
a_user[ea_position] = [v for k, v in user_input['atoms'].items() if k.startswith(ea_position)]
a_correct[ea_position] = [v for k, v in correct_answer['atoms'].items() if k.startswith(ea_position)]
correct = [sorted(a_correct['a'])] + [sorted(a_correct['e1'])] + [sorted(a_correct['e2'])]
for permutation in itertools.permutations(['a', 'e1', 'e2']):
if correct == [sorted(a_user[permutation[0]])] + [sorted(a_user[permutation[1]])] + [sorted(a_user[permutation[2]])]:
return True
return False
for ea_position in ['p', 'a', 'e', 'e1', 'e2']: else: # no need to checl e1x,e2x symmetry - convert them to ex
# collecting atoms: if 'e10' in user_input['atoms']: # e1x exists, it is AX6.. case
a_user = [v for k, v in user_input['atoms'].items() if k.startswith(ea_position)] e_index = 0
a_correct = [v for k, v in correct_answer['atoms'].items() if k.startswith(ea_position)] for k, v in user_input['atoms'].items():
# print a_user, a_correct if len(k) == 3: # e1x
if len(a_user) != len(a_correct): del user_input['atoms'][k]
return False user_input['atoms']['e' + str(e_index)] = v
if sorted(a_user) != sorted(a_correct): e_index += 1
return False
# common case
return True for ea_position in ['p', 'a', 'e']:
# collecting atoms:
a_user = [v for k, v in user_input['atoms'].items() if k.startswith(ea_position)]
a_correct = [v for k, v in correct_answer['atoms'].items() if k.startswith(ea_position)]
# print a_user, a_correct
if len(a_user) != len(a_correct):
return False
if sorted(a_user) != sorted(a_correct):
return False
return True
class Test_Grade(unittest.TestCase): class Test_Grade(unittest.TestCase):
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment