diff options
author | Martin Možina <martin.mozina@fri.uni-lj.si> | 2016-09-27 16:36:15 +0200 |
---|---|---|
committer | Martin Možina <martin.mozina@fri.uni-lj.si> | 2016-09-27 16:36:15 +0200 |
commit | 3f7538d784b24aa5305a228491efa4b68537a80f (patch) | |
tree | abbe0968308d48857570f74718d839f003fc402b /monkey | |
parent | 2013b5b59f2400ac3d4bf218a7ec5b1174f812d7 (diff) | |
parent | 28116fd8278bb3b8832f4f5b22c68bd7978c8efd (diff) |
Merge branch 'master' of ssh://212.235.189.51:22122/codeq-server
Diffstat (limited to 'monkey')
-rw-r--r-- | monkey/__init__.py | 2 | ||||
-rw-r--r-- | monkey/edits.py | 59 | ||||
-rwxr-xr-x | monkey/test.py | 5 |
3 files changed, 36 insertions, 30 deletions
diff --git a/monkey/__init__.py b/monkey/__init__.py index 5408061..42e0691 100644 --- a/monkey/__init__.py +++ b/monkey/__init__.py @@ -147,7 +147,7 @@ def fix_hints(code, steps): for h1, h2 in product(hints, hints): if h1 is h2 or h2['start'] <= h1['start']: continue - if h1['id'] == h2['id'] == 'monkey_insert' and h2['start'] - h1['start'] < 3: + if h1['id'] == h2['id'] == 'monkey_insert' and h2['start'] - h1['start'] < 5: hints.remove(h1) hints.remove(h2) hints.append({'id': 'monkey_change', 'start': h1['start'], 'end': h2['end']-1}) diff --git a/monkey/edits.py b/monkey/edits.py index 0f3a3e4..461f16b 100644 --- a/monkey/edits.py +++ b/monkey/edits.py @@ -31,7 +31,7 @@ def get_edits_from_trace(trace, test, id): def add_edit(path, start, end, tree): if start == end: return - if len(end) > 2*len(start): + if len(end) > 3*len(start): return edits[(path, start, end)].add(id) @@ -62,30 +62,42 @@ def get_edits_from_trace(trace, test, id): passed, total = test(code) correct = passed == total submissions.add((code, correct)) + + # Add edits for fragments we started tracking in submissions + # that passed fewer tests. + for start_tree, start_tokens, path, n_tests, pos_start, pos_end in open_edits: + if passed <= n_tests: + continue + end_tokens = tokenize(code[pos_start:pos_end]) + names = {} + start_normal = rename_vars_list(start_tokens, names) + end_normal = rename_vars_list(end_tokens, names) + norm_tree = rename_vars_ast(start_tree, names) + add_edit(path, tuple(start_normal), tuple(end_normal), norm_tree) if correct: # Ignore actions after the first correct version. done = True break - tree = prolog_parse(code) - if tree and tree.leaves() and tree != prev_tree: - for terminals, path in interesting_ranges(tree): - pos_start = terminals[0].pos - pos_end = terminals[-1].pos + len(terminals[-1].val) - # If there is an open edit with the same range, don't add a new one. - found = False - for e_start_tree, e_start_tokens, e_path, e_pos_start, e_pos_end in open_edits: - if e_pos_start == pos_start and e_pos_end == pos_end: - found = True - break - if not found: - #print('OPENING {}'.format(terminals)) - open_edits.append([tree, terminals, path, pos_start, pos_end]) - prev_tree = tree + tree = prolog_parse(code) + if tree and tree.leaves() and tree != prev_tree: + for terminals, path in interesting_ranges(tree): + pos_start = terminals[0].pos + pos_end = terminals[-1].pos + len(terminals[-1].val) + # If there is an open edit with the same range, don't + # add a new one. + found = False + for e_start_tree, e_start_tokens, e_path, n_tests, e_pos_start, e_pos_end in open_edits: + if e_pos_start == pos_start and e_pos_end == pos_end: + found = True + break + if not found: + open_edits.append([tree, terminals, path, passed, pos_start, pos_end]) + prev_tree = tree if action.type in {'insert', 'remove'}: new_open_edits = [] - for start_tree, start_tokens, path, pos_start, pos_end in open_edits: + for start_tree, start_tokens, path, n_tests, pos_start, pos_end in open_edits: new_pos_start, new_pos_end = pos_start, pos_end if action.type == 'remove': if action.offset < pos_end: @@ -102,6 +114,8 @@ def get_edits_from_trace(trace, test, id): new_pos_end += 1 elif action.offset == pos_end: if (prev_action is None or + (start_tokens[0].pos == pos_start and + start_tokens[-1].pos + len(start_tokens[-1].val) == pos_end) or prev_action.type == 'insert' and prev_action.offset == action.offset-1 or prev_action.type == 'remove' and prev_action.offset == action.offset): orig_next = None @@ -112,19 +126,10 @@ def get_edits_from_trace(trace, test, id): if not (orig_next and orig_next.val[0] == action.text): new_pos_end += 1 if new_pos_start != new_pos_end: - new_open_edits.append([start_tree, start_tokens, path, new_pos_start, new_pos_end]) + new_open_edits.append([start_tree, start_tokens, path, n_tests, new_pos_start, new_pos_end]) open_edits = new_open_edits prev_action = action - if done: - for start_tree, start_tokens, path, pos_start, pos_end in open_edits: - end_tokens = tokenize(code[pos_start:pos_end]) - names = {} - start_normal = rename_vars_list(start_tokens, names) - end_normal = rename_vars_list(end_tokens, names) - norm_tree = rename_vars_ast(start_tree, names) - add_edit(path, tuple(start_normal), tuple(end_normal), norm_tree) - return edits, submissions, queries def get_edits_from_solutions(solutions, test): diff --git a/monkey/test.py b/monkey/test.py index 9267782..b88942b 100755 --- a/monkey/test.py +++ b/monkey/test.py @@ -145,8 +145,9 @@ elif sys.argv[2] == 'info': # Print all observed edits and their costs. elif sys.argv[3] == 'edits': for (path, before, after), (cost, uids) in sorted(edits.items(), key=lambda x: x[1]): - print(' {:.4f}\t{} → {}'.format(cost, stringify(before) if before else 'ε', - stringify(after) if after else 'ε')) + print(' {:.4f}\t{}: {} → {}'.format(cost, '▹'.join(path), + stringify(before) if before else 'ε', + stringify(after) if after else 'ε')) # Print all student queries and their counts. elif sys.argv[3] == 'queries': |