Source code for mitschreiben.formatting

# -*- coding: utf-8 -*-

# mitschreiben
# ------------
# Python library supplying a tool to record values during calculations
# 
# Author:   sonntagsgesicht, based on a fork of Deutsche Postbank [pbrisk]
# Version:  0.3, copyright Wednesday, 18 September 2019
# Website:  https://github.com/sonntagsgesicht/mitschreiben
# License:  Apache License 2.0 (see LICENSE file)


from .table import Table
import os
import datetime


[docs]class DictTree(dict): """ A class to work with a dict whose keys are tuples as if this dict was a dictionary of dictionaries of dictionaries... When trying to look up a value with key (=tuple) and this tuple is partially contained in other keys (=tuples) than a DictTree with only those truncated keys is returned. """ def __getitem__(self, tpl): if not isinstance(tpl, tuple): tpl = (tpl,) if tpl in list(self.keys()): return super(DictTree, self).__getitem__(tpl) else: kvals = [(key[len(tpl):], value) for key, value in list(self.items()) if len(key) >= len(tpl) and key[0:len(tpl)] == tpl] if kvals: return DictTree(kvals) else: raise KeyError
[docs] def toplevel_tables(self, name): """Return tables from the two uppermost layers of the DictTree. One of them is a true table and the other is a collection of values""" len1_keys = [key for key in list(self.keys()) if len(key)==1] len2_keys = [key for key in list(self.keys()) if len(key)==2] pt = Table(name= name,) for k in len1_keys: pt.append('', k[0], self[k]) vt = Table(name=name) for k in len2_keys: vt.append(k[0], k[1], self[k]) return pt.sort(), vt.sort()
[docs] def to_tables(self): """Makes a table from each level within the DictTree and returns those tables stored in a new DictTree""" max_level = max(list(map(len, list(self.keys())))) tables = DictTree() for i in range(0, max_level): for key in sorted(list(set([k[0:i] for k in list(self.keys())]))): T = self[key] if isinstance(T, DictTree): key_str = "---".join(map(str, key)) a, b = T.toplevel_tables(key_str) if not a.is_empty() and i == 0: a.name = "Properties" tables[key+("table",)]= a.transpose() if not b.is_empty(): if b.rows_count == 1: b = b.transpose() tables[key+("table",)]= b return tables
[docs] def pretty_print(self): "this function prints an alphabetically sorted tree in a directory-like structure." def compare_keys(tpl_prev, tpl_next): equal_list = [x==y for x,y in zip(tpl_prev, tpl_next)] j = equal_list.index(False) return j, tpl_next[j:] keys = sorted(self.keys()) previous_key = None indent = 0 indentfactor = 1 for key in keys: rest_key = key if previous_key: indent, rest_key = compare_keys(previous_key, key) for i, value in enumerate(rest_key): print(("|"+" "*indentfactor)*(indent+i)+value \ + ((":" +" " * indentfactor + str(self[key]))if i == len(rest_key) - 1 else "")) previous_key = key
@staticmethod def _make_target_filename(filename, path): if path and not os.path.isdir(path): os.makedirs(path) if path: target_file_path = os.path.join(path, filename) else: target_file_path = filename return target_file_path
[docs] def as_tree_to_html(self, filename, path=None): """This function creates a html file that presents the dicttree in its tree structure.""" target_file_path = DictTree._make_target_filename(filename, path) def make_button(caption): return "<button class='accordion'>{}</button>".format(caption) def compare_keys(tpl_prev, tpl_next): equal_list = [x==y for x,y in zip(tpl_prev, tpl_next)] j = equal_list.index(False) return j, tpl_next[j:] keys = sorted(self.keys()) previous_key = None with open("htmldicttree.temp", "w") as tempfile: for key in keys: rest_key = key if previous_key: indent, rest_key = compare_keys(previous_key, key) previous_indent = len(previous_key)-1 if indent < previous_indent: tempfile.write("\n</div>" * abs(previous_indent - indent)) for i, value in enumerate(rest_key): if i == len(rest_key)-1: tempfile.write("\n<div class='panel-elem'>" + value +" : " + str(self[key]) + "</div>") else: tempfile.write("\n"+make_button(value)) tempfile.write("\n<div class='panel'>") previous_key = key abs_path = os.path.join(os.path.split(__file__)[0], 'html_basics', 'accordion.html') f = open(abs_path) s1, s2 = f.read().split("#SPLIT#") s1 = s1.replace('#TITLE', filename) f.close() with open('htmldicttree.temp') as temp: with open(target_file_path, 'w') as target_file: target_file.write(s1) for line in temp.readlines(): target_file.write(line) target_file.write(s2) os.remove('htmldicttree.temp')
[docs] def as_tables_to_html(self, filename, path=None): """This functions creates a html file presenting the tree in tables""" target_file_path = DictTree._make_target_filename(filename, path) tbs = self.to_tables() abs_path = os.path.join(os.path.split(__file__)[0],'html_basics','tables.html') f = open(abs_path) s1, s2 = f.read().split("#SPLIT#") s1 = s1.replace('#TITLE', filename) f.close() with open(target_file_path, "w") as f: f.write(s1) for tb in sorted(list(tbs.values()), key=lambda x: x.name): f.write("<table>\n") if tb.name == "": tb.name = "TOP" f.write("<tr><td>{}</td></tr>\n".format(tb.to_html())) f.write("</table>\n") f.write(s2)
[docs] def as_html_tree_table(self, filename, path=None): """This function creates a html file, that is structured like a tree, where the last two-level-deep branches are represented as tables""" tree = self.to_tables() target_file_path = DictTree._make_target_filename(filename, path) def make_button(caption): return "<button class='accordion'>{}</button>".format(caption) def compare_keys(tpl_prev, tpl_next): equal_list = [x==y for x,y in zip(tpl_prev, tpl_next)] j = equal_list.index(False) return j, tpl_next[j:] keys = sorted(list(tree.keys()), key=lambda x: x[:-1]) previous_key = None with open("htmldicttree.temp", "w") as tempfile: for key in keys: rest_key = key if previous_key: indent, rest_key = compare_keys(previous_key, key) previous_indent = len(previous_key)-1 if indent < previous_indent: tempfile.write("\n</div>" * abs(previous_indent - indent)) for i, value in enumerate(rest_key): if i == len(rest_key)-1 : tb = tree[key] tb.name = str(key[-1]) tempfile.write("\n<div class='panel-elem'>" + tb.to_html() + "</div>") else: tempfile.write("\n"+make_button(value)) tempfile.write("\n<div class='panel'>") previous_key = key abs_path = os.path.join(os.path.split(__file__)[0], 'html_basics', 'accordion_tables_combined.html') f = open(abs_path) s1, s2 = f.read().split("#SPLIT#") s1 = s1.replace("#TITLE", filename) f.close() with open('htmldicttree.temp') as temp: with open(target_file_path, 'w') as target_file: target_file.write(s1) for line in temp.readlines(): target_file.write(line) target_file.write(s2) os.remove('htmldicttree.temp')
[docs] def to_csv_files(self, path): "this function creates csv files for every table that can be made from the tree" def make_filename(tabname): timestamp = datetime.datetime.now().strftime("%Y%m%d") if len(tabname) > 200: tabname = tabname[:100]+"___"+reversed(reversed(tabname)[:100]) tabname = timestamp + "_" + tabname + ".csv" return tabname if path and not os.path.isdir(path): os.makedirs(path) for tb in list(self.to_tables().values()): filename = make_filename(tb.name) if path: target_file_path = os.path.join(path, filename) else: target_file_path = filename with open(target_file_path, "w") as f: f.write(tb.to_csv())