Package: mitschreiben
Python projectmitschreibenmitschreiben (german for ‘to take notes’) helps recording values during
calculations for later evaluation, e.g. check if the right objects or
values were used or to present the results in structure of tablesIt provides a class called Record which is basically used for everything. It grants access to record object, it is used
for the recording and it is a context manager used to trigger whether to record or not.Example UsageIn the firstRecord(key = value)orRecord(dictionary)is placed where one wants to
record a value. The decoratorPrefixprovided by this class is used
to define a key extension under which the recorded value will be stored in theRecord. The Prefixes get stacked, so when there is a successive
function call to another function which is prefixed those Prefixes are
concatenated.frommitschreibenimportRecorddefmagical_stuff_happens(baz,barz):return"That's","great"classFoo():@Record.Prefix()defbar(self,baz,barz)some_value1,some_value2=self.do_something(baz,barz)Record(a_key=some_value1,another_key=some_value2)returnsome_value1,some_value2@Record.Prefix()defdo_something(self,baz,barz):a_dict={'again_a_key':baz,'so_creative':barz}Record(a_dict)returnmagical_stuff_happens(baz,barz)def__repr__(self):return"Foo({})".format(id(self))Now, sinceRecordis a contextmanager, the recording will only
happen in such a context. Thewith-statement activates the recording and returns the current scopes record object
for convenient access. Another thing is, that record level is increased by this statement, leading to record objects
that are only available in that scope. When leaving thewiththe outer scopes’s record will be extend by the inner
one, by prepending the outer records current prefix stack to each key of the inner one.withRecord()asrec:foo=Foo()foo.do_something("baz","barz")foo.bar("baz","barz")printrec.entriesThe entries are a dict whose keys are tuples which are the stacked Prefixes. In this way it is possible to determine which method on which object was called, what then led
to successive calls, where in the end a value is recorded. The example above has the following output.{('Foo(42403656).do_something','again_a_key'):'baz',('Foo(42403656).bar','Foo(42403656).do_something','again_a_key'):'baz',('Foo(42403656).do_something','so_creative'):'barz',('Foo(42403656).bar','a_key'):"That's",('Foo(42403656).bar','another_key'):'great',('Foo(42403656).bar','Foo(42403656).do_something','so_creative'):'barz'}Formatting the outputThe Record can be represented in different formats. The base to this is atree of dictionaries,
implemented by the classDictTreeinmitschreiben.formatting. For the two base outputs however, one
does not need to actually instantiate aDictTreeyourself. The respective methods areBoth of these methods produce tables of the output. The idea is that, that certain calculations are made with different
objects, leading to the same keywords. So one obtains a table with row keys (object names) and column keys (the keywords
used to record a value). As the name of the former methods suggests, it produces this tables and writes them as single
.csv files intoPath, whereas the latter construct a html document in which one can navigate through the tree structure
and see the tables at those positions where they would be placed in the tree. Those tables would look similar to<divclass='panel-elem'><table><trclass='headrow'><thcolspan='5'>table</th></tr><trclass='bodyrow'><th></th><th>a_key</th><th>again_a_key</th><th>another_key</th><th>so_creative</th></tr><trclass='bodyrow'><th>Foo(42403656).bar</th><td>That's</td><td>None</td><td>great</td><td>None</td></tr><trclass='bodyrow'><th>Foo(42403656).do_something</th><td>None</td><td>baz</td><td>None</td><td>barz</td></tr></table></div><divclass='panel'><divclass='panel-elem'><table><trclass='headrow'><thcolspan='2'>table</th></tr><trclass='bodyrow'><th></th><th>Foo(42403656).do_something</th></tr><trclass='bodyrow'><th>again_a_key</th><td>baz</td></tr><trclass='bodyrow'><th>so_creative</th><td>barz</td></tr></table></div>Another way would be to work with theDictTreedirectly.frommitschreiben.formattingimportDictTreeDT=DictTree(rec.entries)tables=DT.make_tables()fortintables:printt.pretty_string()printThis results in the following output. The first table represents the top
level of the record, whereas the other tabels are named byobject.function.Values |  a_key | again_a_key | another_key | so_creative
         Foo(42403656).bar | That's |        None |       great |        None
Foo(42403656).do_something |   None |         baz |        None |        barz

Foo(42403656).bar
                    Values | again_a_key | so_creative
Foo(42403656).do_something |         baz |        barz