def generate_tree(data_to_compress): # stats first contains symbols and their weights, # then parent nodes and their weights as well, while the tree is built stats = get_weights_and_symbols(data_to_compress) stats = sorted(stats, key=lambda x: x["weight"]) # as long as we have more than one element to process, we'll grow the tree while len(stats) > 1: # let's create a parent node parent_node = {"left0": None, "right1": None, "weight": 0} # the 2 children are the first and second elements of the list parent_node["left0"] = pop_entry(stats) parent_node["right1"] = pop_entry(stats) # and the weight is the sum of both children's cumulative_weight = parent_node["left0"]["weight"] + parent_node[ "right1"]["weight"] parent_node["weight"] = cumulative_weight # let's add a new entry in the list for the recently created parent node entry = {"node": None, "weight": 0} entry["node"] = parent_node entry["weight"] = cumulative_weight stats.append(entry) # and re-sort the list stats = sorted(stats, key=lambda x: x["weight"]) # we just have one entry left - the root of the tree - let's return it. root_node = pop_entry(stats) return root_node
def generate_tree(data_to_compress): # stats first contains symbols and their weights, # then parent nodes and their weights as well, while the tree is built stats = get_weights_and_symbols(data_to_compress) stats = sorted(stats, key = lambda x:x["weight"]) # as long as we have more than one element to process, we'll grow the tree while len(stats) > 1: # let's create a parent node parent_node = {"left0": None, "right1": None, "weight": 0} # the 2 children are the first and second elements of the list parent_node["left0"] = pop_entry(stats) parent_node["right1"] = pop_entry(stats) # and the weight is the sum of both children's cumulative_weight = parent_node["left0"]["weight"] + parent_node["right1"]["weight"] parent_node["weight"] = cumulative_weight # let's add a new entry in the list for the recently created parent node entry = {"node": None, "weight": 0} entry["node"] = parent_node entry["weight"] = cumulative_weight stats.append(entry) # and re-sort the list stats = sorted(stats, key = lambda x:x["weight"]) # we just have one entry left - the root of the tree - let's return it. root_node = pop_entry(stats) return root_node
def encode(data_to_compress): stats = _encoding.get_weights_and_symbols(data_to_compress) stats = sorted(stats, key = lambda x:x["weight"], reverse = True) tree = generate_tree(stats) return tree
#Kabopan - Readable Algorithms. Public Domain, 2007-2009 from kbp.entro._encoding import generate_codes, get_weights_and_symbols assert generate_codes({'left0': {'symbol': 'a', 'weight': 1}, 'right1': {'symbol': 'b', 'weight': 1}, 'weight': 2}) == {'a': '0', 'b': '1'} assert get_weights_and_symbols("a") == [{"symbol":"a", "weight":1}] assert get_weights_and_symbols("abababbc") == [ \ {"symbol":"a", "weight":3}, {"symbol":"b", "weight":4}, {"symbol":"c", "weight":1}]
#Kabopan - Readable Algorithms. Public Domain, 2007-2009 from kbp.entro._encoding import generate_codes, get_weights_and_symbols assert generate_codes({ 'left0': { 'symbol': 'a', 'weight': 1 }, 'right1': { 'symbol': 'b', 'weight': 1 }, 'weight': 2 }) == { 'a': '0', 'b': '1' } assert get_weights_and_symbols("a") == [{"symbol": "a", "weight": 1}] assert get_weights_and_symbols("abababbc") == [ \ {"symbol":"a", "weight":3}, {"symbol":"b", "weight":4}, {"symbol":"c", "weight":1}]