Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save tuananhlai/edf948122c98006d2fd5b9f9eb5c5ac3 to your computer and use it in GitHub Desktop.
Save tuananhlai/edf948122c98006d2fd5b9f9eb5c5ac3 to your computer and use it in GitHub Desktop.
# This program is meant to use to calculate SBFL ranking metric
# Example usage:
# - Passing values directly through command line arguments:
# python3 fault-localization.py -f 1 --tf 1 -p 4 --tp 5 --fo ochiai
# - Passing filepath and formula:
# python3 fault-localization.py values.txt --fo tarantula
import sys
from math import sqrt
def wong3(f: int, tf: int, p: int, tp: int) -> int:
h = 0
if (p <= 2):
h = p
elif (p <= 10):
h = 2 + 0.1 * (p - 2)
else:
h = 2.8 + 0.001 * (p - 10)
return f - h
formula = {
"tarantula": lambda f, tf, p, tp: (f/tf)/(f/tf + p/tp),
"ochiai": lambda f, tf, p, tp: f/sqrt(tf * (f + p)),
"op2": lambda f, tf, p, tp: f - (p / (tp + 1)),
"barinel": lambda f, tf, p, tp: (1 - (p/(p + f))),
"jaccard": lambda f, tf, p, tp: (f/(tf + p)),
"wong1": lambda f, tf, p, tp: f,
"wong2": lambda f, tf, p, tp: f - p,
"wong3": wong3,
"m2": lambda f, tf, p, tp: f / (f + (tp - p) + 2 * (tf - f + p))
}
class FaultLocalization:
def __init__(self, args) -> None:
self.args = args
self.current_index = 0
self.failed = None
self.total_failed = None
self.passed = None
self.total_passed = None
self.formula = None
self.file_path = None
def __str__(self) -> str:
return str(self.failed) + " " + str(self.passed) + " " + str(self.file_path)
def parse(self):
argv = len(self.args)
while(self.current_index < argv):
self.parseOption(self.args[self.current_index])
self.current_index += 1
def parseOption(self, option):
if (option == "-f"):
self.current_index += 1
self.failed = int(self.args[self.current_index])
assert(self.failed >= 0)
elif (option == "--tf"):
self.current_index += 1
self.total_failed = int(self.args[self.current_index])
elif (option == "-p"):
self.current_index += 1
self.passed = int(self.args[self.current_index])
elif (option == "--tp"):
self.current_index += 1
self.total_passed = int(self.args[self.current_index])
elif (option == "--fo"):
self.current_index += 1
self.formula = formula[self.args[self.current_index]]
else:
self.file_path = self.args[self.current_index]
def calculate(self) -> float:
self.parse()
if self.file_path:
return self.calculateAll()
return self.formula(self.failed, self.total_failed, self.passed, self.total_passed)
def calculateAll(self):
values = open(self.file_path, 'r').read().split('\n')
results = []
for index, val in enumerate(values):
failed, total_failed, passed, total_passed = val.split()
value = self.formula(int(failed), int(total_failed), int(passed), int(total_passed))
results.append((index + 1, value))
print(sorted(results, key=lambda x: x[1], reverse=True))
if __name__ == "__main__":
fl = FaultLocalization(sys.argv[1:])
print(fl.calculate())
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment