summaryrefslogtreecommitdiff
path: root/monkey
diff options
context:
space:
mode:
authorMartin Možina <martin.mozina@fri.uni-lj.si>2016-09-27 16:36:15 +0200
committerMartin Možina <martin.mozina@fri.uni-lj.si>2016-09-27 16:36:15 +0200
commit3f7538d784b24aa5305a228491efa4b68537a80f (patch)
treeabbe0968308d48857570f74718d839f003fc402b /monkey
parent2013b5b59f2400ac3d4bf218a7ec5b1174f812d7 (diff)
parent28116fd8278bb3b8832f4f5b22c68bd7978c8efd (diff)
Merge branch 'master' of ssh://212.235.189.51:22122/codeq-server
Diffstat (limited to 'monkey')
-rw-r--r--monkey/__init__.py2
-rw-r--r--monkey/edits.py59
-rwxr-xr-xmonkey/test.py5
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':