#!/usr/bin/env python
# See instructions at line 124 and fill in the functions at 60 and 82
import sys
import copy#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
# The delta debugger
def ddmin(s):#assert test(s) == “FAIL”
n = 2 # Initial granularity
while len(s) >= 2:start = 0
subset_length = len(s) / n
some_complement_is_failing = Falsewhile start < len(s):
complement = s[:start] + s[start + subset_length:]
if test(complement) == “FAIL”:
s = complement
n = max(n – 1, 2)
some_complement_is_failing = True
breakstart += subset_length
if not some_complement_is_failing:
if n == len(s):
break
n = min(n * 2, len(s))
return s
# 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# FILL IN FROM YOUR SOLUTION IN THE PREVIOUS EXERCISE
def trace_fetch_state(frame, event, arg):global the_line
global the_iteration
global the_stateline_number = frame.f_lineno
line_state = frame.f_locals
#print(line_number)
#print(line_state)
if event == ‘line’:if line_number == the_line:
the_iteration = the_iteration – 1
#print(the_iteration)
if the_iteration == 0:the_state = copy.deepcopy(line_state)
#print(the_state)
return Nonereturn trace_fetch_state
# Get the state at LINE/ITERATION
def get_state(input, line, iteration):global the_line
global the_iteration
global the_statethe_line = line
the_iteration = iterationsys.settrace(trace_fetch_state)
y = remove_html_markup(input)
sys.settrace(None)return the_state
# FILL IN FROM YOUR SOLUTION IN THE PREVIOUS EXERCISE
def trace_apply_diff(frame, event, arg):global the_line
global the_diff
global the_iterationline_number = frame.f_lineno
#print(line_number)if line_number == the_line:
the_iteration = the_iteration – 1
if the_iteration == 0:
frame.f_locals.update(the_diff)
the_line = None
return Nonereturn 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_iterationline = the_line
iteration = the_iterationthe_diff = diffs
sys.settrace(trace_apply_diff)
y = remove_html_markup(the_input)
sys.settrace(None)the_line = line
the_iteration = iterationif y.find(‘<‘) == -1:
return “PASS”
else:
return “FAIL”
html_fail = ‘”<b>foo</b>”‘
html_pass = “‘<b>foo</b>'”locations = [(8, 1), (14, 1), (14, 2), (14, 3), (23, 1)]
def auto_cause_chain(locations):
global html_fail, html_pass, the_input, the_line, the_iteration, the_diff
print “The program was started with”, repr(html_fail)prev_value = {}
prev_state = {}# Loop to get touch line and iteration from a particular locations
for (line, iteration) in locations:# Get the passing and the failing state
state_pass = get_state(html_pass, line, iteration)
state_fail = get_state(html_fail, line, iteration)if state_pass == None:
state_pass = {}
if state_fail == None:
state_fail = {}
diffs = []
# Compute the differences between the passing and failing runs
for key in state_fail.keys():if not state_pass.has_key(key) or state_pass[key] != state_fail[key]:
diffs.append((key, state_fail[key]))
# Minimize the failure-inducing set of differences
the_input = html_pass
the_line = line
the_iteration = iteration
Stop = False
if test(diffs) == “FAIL”:cause = ddmin(diffs)
print “Then, in Line ” + repr(line) + ” (iteration ” + repr(iteration) + “),”,
for key, value in cause:if (key not in prev_value or prev_value[key] != value):
print “Then”, key, “became”, repr(value)
prev_value[key] = valueif Stop:
break
print “Then the program failed.”
auto_cause_chain(locations)
# The output should look like this:
“””
The program was started with ‘”<b>foo</b>”‘
Then, in Line 8 (iteration 1), s became ‘”<b>foo</b>”‘
Then, in Line 14 (iteration 1), c became ‘”‘
Then, in Line 14 (iteration 2), quote became True
Then, in Line 14 (iteration 3), out became ‘<‘
Then, in Line 23 (iteration 1), out became ‘<b>foo</b>’
Then the program failed.
“””
