-
Notifications
You must be signed in to change notification settings - Fork 0
/
P4-2.py
160 lines (135 loc) · 4.17 KB
/
P4-2.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
#!/usr/bin/env python
import sys
import copy
# See instructions at line 54
# The buggy program
def remove_html_markup(s):
tag = False
quote = False
out = ""
for c in s:
if c == '<' and not quote:
tag = True
elif c == '>' and not quote:
tag = False
elif c == '"' or c == "'" and tag:
quote = not quote
elif not tag:
out = out + c
return out
# We use these variables to communicate between callbacks and drivers
the_line = None
the_iteration = None
the_state = None
the_diff = None
the_input = None
the_previous_lineno = None ## I set it to sense iteration
the_hit_flag = True ## I set it to tag the hit of the pre-defined line and iteration
# FILL IN FROM YOUR SOLUTION IN THE PREVIOUS EXERCISE
def trace_fetch_state(frame, event, arg):
global the_line
global the_iteration
global the_state
# COPY YOUR CODE HERE
global the_previous_lineno
global the_hit_flag
if event == "call":
the_previous_lineno = None
the_hit_flag = True
if event == "line":
if the_iteration <= 1 and frame.f_lineno >= the_line and the_hit_flag:
the_state = copy.deepcopy(frame.f_locals)
the_hit_flag = False
if not the_previous_lineno:
the_previous_lineno = frame.f_lineno
elif frame.f_lineno < the_previous_lineno and the_hit_flag:
the_iteration -= 1
the_previous_lineno = frame.f_lineno
return trace_fetch_state
# This function allows you to get the state of the program
# at specified line and iteration and return it
def get_state(input, line, iteration):
global the_line
global the_iteration
global the_state
the_line = line
the_iteration = iteration
sys.settrace(trace_fetch_state)
y = remove_html_markup(input)
sys.settrace(None)
return the_state
# IMPLEMENT THIS !!!
# This function should trace the function until specified
# line and iteration, and then change the value of frame.f_locals
# to the supplied values in the_diff.
# It is crucial to use update() here. If you will set elements one by one,
# chances are that some changes will get lost.
# Please use the following syntax to be sure that it works correctly:
# frame.f_locals.update(the_diff)
def trace_apply_diff(frame, event, arg):
global the_line
global the_iteration
global the_diff
# YOUR CODE HERE
global the_previous_lineno
global the_hit_flag
if event == "call":
the_previous_lineno = None
the_hit_flag = True
if event == "line":
if the_iteration <= 1 and frame.f_lineno >= the_line and the_hit_flag:
frame.f_locals.update(the_diff)
the_hit_flag = False
if not the_previous_lineno:
the_previous_lineno = frame.f_lineno
elif frame.f_lineno < the_previous_lineno and the_hit_flag:
the_iteration -= 1
the_previous_lineno = frame.f_lineno
return trace_apply_diff
# Testing function: Call remove_html_output, stop at THE_LINE/THE_ITERATION,
# and apply the diffs in DIFFS at THE_LINE
def test(diffs):
global the_diff
global the_input
global the_line
global the_iteration
line = the_line
iteration = the_iteration
the_diff = diffs
sys.settrace(trace_apply_diff)
y = remove_html_markup(the_input)
sys.settrace(None)
the_line = line
the_iteration = iteration
if y.find('<') == -1:
return "PASS"
else:
return "FAIL"
html_fail = '"<b>foo</b>"'
html_pass = "'<b>foo</b>'"
def run_tests():
global the_input
global the_line
global the_iteration
the_input = '"<b>foo</b>"'
the_line = 8
the_iteration = 1
if not test([('s', html_pass)]) == "PASS":
print "The value 's' was not updated correctly."
print "Make sure that you use the update() function."
else:
print True
the_line = 10
the_iteration = 2
if not test([('quote', True)]) == "FAIL":
print "The value 'quote' was not updated correctly"
else:
print True
the_line = 16
the_iteration = 2
if not test([('tag', True), ('out', '<')]) == "FAIL":
print "Multiple values were not updated correctly"
else:
print True
print "Test results:"
run_tests()