#!/usr/bin/python3 '''Report the datastructures from best performers to worst for a given area of comparison''' import re #mport sys import glob #mport pprint import functools #mport collections def return_javascript_code(): ''' Output the required javascript for drilling down to greater levels of detail. Derived from http://www.gnostice.com/nl_article.asp?id=208&t=Interactive_Tree_Control_Using_An_HTML_List_and_JavaScript ''' # BTW, this dislikes it when you close your
  • 's with
  • 's # This xml tag makes chrome and perhaps others have problems # string = ''' Python Dictionary Results Table ''' return string def get_last_line(file_): '''Get the last line of file_''' last = None for line in file_: last = line return last @functools.total_ordering class Number_Pattern_Key(object): '''Store a number pattern key''' # pylint: disable=too-few-public-methods def __init__(self, number_pattern): self.number_pattern = number_pattern def __hash__(self): return hash(self.number_pattern) def __str__(self): return self.number_pattern __repr__ = __str__ def cmp(self, other): '''Compare two number pattern keys''' if self.number_pattern < other.number_pattern: return -1 elif self.number_pattern > other.number_pattern: return 1 else: return 0 def __lt__(self, other): if self.cmp(other) == -1: return True else: return False def __eq__(self, other): if self.cmp(other) == 0: return True else: return False @functools.total_ordering class Size_Key(object): '''Store a size key''' # pylint: disable=too-few-public-methods def __init__(self, size): self.size = size def __hash__(self): return hash(self.size) def __str__(self): return str(self.size) __repr__ = __str__ def cmp(self, other): '''Compare two size keys in order''' if self.size < other.size: return -1 elif self.size > other.size: return 1 else: return 0 def __lt__(self, other): if self.cmp(other) == -1: return True else: return False def __eq__(self, other): if self.cmp(other) == 0: return True else: return False @functools.total_ordering class Interpreter_Key(object): '''A class to hold an interpreter key''' # pylint: disable=too-few-public-methods def __init__(self, interpreter): self.interpreter = interpreter def __hash__(self): return hash(self.interpreter) def __str__(self): return str(self.interpreter) __repr__ = __str__ def cmp(self, other): '''Compare two interpreter names''' if self.interpreter < other.interpreter: return -1 elif self.interpreter > other.interpreter: return 1 else: return 0 def __lt__(self, other): if self.cmp(other) == -1: return True else: return False def __eq__(self, other): if self.cmp(other) == 0: return True else: return False @functools.total_ordering class Tree_Type_Key(object): '''Store a tree type key''' # pylint: disable=too-few-public-methods def __init__(self, tree_type): self.tree_type = tree_type def __hash__(self): return hash(self.tree_type) def __str__(self): return str(self.tree_type) __repr__ = __str__ def cmp(self, other): '''Compare two Tree_Type_keys''' if self.tree_type < other.tree_type: return -1 elif self.tree_type > other.tree_type: return 1 else: return 0 def __lt__(self, other): if self.cmp(other) == -1: return True else: return False def __eq__(self, other): if self.cmp(other) == 0: return True else: return False @functools.total_ordering class Performer(object): '''Class for holding a description of a top performing datastructure''' # pylint: disable=too-few-public-methods,too-many-return-statements def __init__(self, size, tree_type, duration, standard_deviation): self.size = int(size.size) self.tree_type = tree_type self.duration = float(duration) self.standard_deviation = float(standard_deviation) def cmp(self, other): '''Compare two Top_Performer's''' # Compare size in reverse if self.size < other.size: return 1 elif self.size > other.size: return -1 else: # Compare duration forward if self.duration < other.duration: return -1 elif self.duration > other.duration: return 1 #else: # if self.tree_type < other.tree_type: # return -1 # elif self.tree_type > other.tree_type: # return 1 # else: # return 0 else: return 0 def __lt__(self, other): if self.cmp(other) == -1: return True else: return False def __eq__(self, other): if self.cmp(other) == 0: return True else: return False def gen_performers(dict_): '''Generate the top performers''' for size_key in dict_: tree_type_dict = dict_[size_key] for tree_type_key in tree_type_dict: mean = tree_type_dict[tree_type_key][0] standard_deviation = tree_type_dict[tree_type_key][1] yield Performer(size_key, tree_type_key, mean, standard_deviation) def main(): # pylint: disable=too-many-locals '''Main function''' dict_ = {} for filename in glob.glob('*.dat'): fixed_red_black = filename.replace('red-black', 'red_black') fields = fixed_red_black.split('-') interpreter = '-'.join(fields[:2]) number_pattern = fields[2] # tree_type = re.sub(r'\.dat$', '', '-'.join(fields[5:7])) tree_type = re.sub(r'\.dat$', '', fields[3]) with open(filename, 'r') as file_: last_line = get_last_line(file_) size, duration, standard_deviation = last_line.split() size = int(size) duration = round(float(duration), 1) standard_deviation = round(float(standard_deviation), 3) number_pattern_key = Number_Pattern_Key(number_pattern) size_key = Size_Key(size) interpreter_key = Interpreter_Key(interpreter) tree_type_key = Tree_Type_Key(tree_type) if number_pattern_key not in dict_: dict_[number_pattern_key] = {} if interpreter_key not in dict_[number_pattern_key]: dict_[number_pattern_key][interpreter_key] = {} if size_key not in dict_[number_pattern_key][interpreter_key]: dict_[number_pattern_key][interpreter_key][size_key] = {} if tree_type_key not in dict_[number_pattern_key][interpreter_key][size_key]: dict_[number_pattern_key][interpreter_key][size_key][tree_type_key] = (duration, standard_deviation) num_top_performers = 20 print(return_javascript_code()) print('') print('') print('') main()