Skip to content
Permalink
master
Switch branches/tags

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
Go to file
 
 
Cannot retrieve contributors at this time
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1" />
<meta name="generator" content="pdoc 0.6.3" />
<title>Finanzexplorer_Institute API documentation</title>
<meta name="description" content="" />
<link href='https://cdnjs.cloudflare.com/ajax/libs/normalize/8.0.0/normalize.min.css' rel='stylesheet'>
<link href='https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/8.0.0/sanitize.min.css' rel='stylesheet'>
<link href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/github.min.css" rel="stylesheet">
<style>.flex{display:flex !important}body{line-height:1.5em}#content{padding:20px}#sidebar{padding:30px;overflow:hidden}.http-server-breadcrumbs{font-size:130%;margin:0 0 15px 0}#footer{font-size:.75em;padding:5px 30px;border-top:1px solid #ddd;text-align:right}#footer p{margin:0 0 0 1em;display:inline-block}#footer p:last-child{margin-right:30px}h1,h2,h3,h4,h5{font-weight:300}h1{font-size:2.5em;line-height:1.1em}h2{font-size:1.75em;margin:1em 0 .50em 0}h3{font-size:1.4em;margin:25px 0 10px 0}h4{margin:0;font-size:105%}a{color:#058;text-decoration:none;transition:color .3s ease-in-out}a:hover{color:#e82}.title code{font-weight:bold}h2[id^="header-"]{margin-top:2em}.ident{color:#900}pre code{background:#f8f8f8;font-size:.8em;line-height:1.4em}code{background:#f2f2f1;padding:1px 4px;overflow-wrap:break-word}h1 code{background:transparent}pre{background:#f8f8f8;border:0;border-top:1px solid #ccc;border-bottom:1px solid #ccc;margin:1em 0;padding:1ex}#http-server-module-list{display:flex;flex-flow:column}#http-server-module-list div{display:flex}#http-server-module-list dt{min-width:10%}#http-server-module-list p{margin-top:0}.toc ul,#index{list-style-type:none;margin:0;padding:0}#index code{background:transparent}#index h3{border-bottom:1px solid #ddd}#index ul{padding:0}#index h4{font-weight:bold}#index h4 + ul{margin-bottom:.6em}@media (min-width:200ex){#index .two-column{column-count:2}}@media (min-width:300ex){#index .two-column{column-count:3}}dl{margin-bottom:2em}dl dl:last-child{margin-bottom:4em}dd{margin:0 0 1em 3em}#header-classes + dl > dd{margin-bottom:3em}dd dd{margin-left:2em}dd p{margin:10px 0}.name{background:#eee;font-weight:bold;font-size:.85em;padding:5px 10px;display:inline-block;min-width:40%}.name:hover{background:#e0e0e0}.name > span:first-child{white-space:nowrap}.name.class > span:nth-child(2){margin-left:.4em}.inherited{color:#999;border-left:5px solid #eee;padding-left:1em}.inheritance em{font-style:normal;font-weight:bold}.desc h2{font-weight:400;font-size:1.25em}.desc h3{font-size:1em}.desc dt code{background:inherit}.source summary{color:#666;text-align:right;font-weight:400;font-size:.8em;text-transform:uppercase;cursor:pointer}.source pre{max-height:500px;overflow:auto;margin:0}.source pre code{font-size:12px;overflow:visible}.hlist{list-style:none}.hlist li{display:inline}.hlist li:after{content:',\2002'}.hlist li:last-child:after{content:none}.hlist .hlist{display:inline;padding-left:1em}img{max-width:100%}.admonition{padding:.1em .5em;margin-bottom:1em}.admonition-title{font-weight:bold}.admonition.note,.admonition.info,.admonition.important{background:#aef}.admonition.todo,.admonition.versionadded,.admonition.tip,.admonition.hint{background:#dfd}.admonition.warning,.admonition.versionchanged,.admonition.deprecated{background:#fd4}.admonition.error,.admonition.danger,.admonition.caution{background:lightpink}</style>
<style media="screen and (min-width: 700px)">@media screen and (min-width:700px){#sidebar{width:30%}#content{width:70%;max-width:100ch;padding:3em 4em;border-left:1px solid #ddd}pre code{font-size:1em}.item .name{font-size:1em}main{display:flex;flex-direction:row-reverse;justify-content:flex-end}.toc ul ul,#index ul{padding-left:1.5em}.toc > ul > li{margin-top:.5em}}</style>
<style media="print">@media print{#sidebar h1{page-break-before:always}.source{display:none}}@media print{*{background:transparent !important;color:#000 !important;box-shadow:none !important;text-shadow:none !important}a[href]:after{content:" (" attr(href) ")";font-size:90%}a[href][title]:after{content:none}abbr[title]:after{content:" (" attr(title) ")"}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100% !important}@page{margin:0.5cm}p,h2,h3{orphans:3;widows:3}h1,h2,h3,h4,h5,h6{page-break-after:avoid}}</style>
</head>
<body>
<main>
<article id="content">
<header>
<h1 class="title">Module <code>Finanzexplorer_Institute</code></h1>
</header>
<section id="section-intro">
<details class="source">
<summary>Source code</summary>
<pre><code class="python"># -*- coding: utf-8 -*-
# © Paul Schild 2019
import wx
import wx.grid
import os
import os.path
import Finanzexplorer_model as model
import copy
import json
import math
import csv
from collections import defaultdict, OrderedDict
from operator import itemgetter
from openpyxl import load_workbook
from matplotlib import use
use(&#39;WXAgg&#39;)
import matplotlib.pyplot as plt
from fpdf import FPDF
import datetime
&#39;&#39;&#39;
Eine Übersicht über alle wx.Python widgets findet sich unter folgendem Link:
https://wxpython.org/Phoenix/docs/html/gallery.html
&#39;&#39;&#39;
develope_mode = False
dev_function_stack = []
WHITE = &#34;#ffffff&#34; # für das Interface (wx.grid)
active_konzeptColor = &#34;#ffffff&#34; # active bedeutet, dieses Konzept ist angewählt
active_konzept = None
worksheets = [&#34;1954-1963&#34;, &#34;1964-1966&#34;, &#34;1967&#34;, &#34;1968-1972&#34;, &#34;1973-1986&#34;, &#34;1987-1997&#34;, &#34;1998-2002&#34;]
model.RECHNUNGSTYP = &#34;&#34; # siehe Finanzexplorer_model.py. Ursprünglich zur Unterscheidung von &#39;EA&#39; und &#39;VÜ&#39;
# EA = Einnahmen/Ausgabenrechnung; VÜ = Vermögensübersicht
# Mit den Instituten kam &#39;INST&#39; hinzu.
dct_cells = {}
found_cells = [] # für die Suchfunktion
class PDF(FPDF):
def header(self):
self.set_font(&#34;Times&#34;, &#34;B&#34;, 10)
# self.image(&#34;Icon.png&#34;, 10, 8, 8)
self.cell(80)
self.cell(30, 10, frame.GetTitle(), 0, 1, &#39;C&#39;)
self.ln(10)
def footer(self):
today = datetime.date.today()
self.set_y(-15)
self.set_font(&#34;Times&#34;, &#39;I&#39;, 8)
self.cell(0, 10, str(today), 0, 0, &#39;C&#39;)
self.set_y(-15)
link = self.add_link()
self.set_link(link, page=1)
self.cell(0, 10, &#34;top&#34;, 0, 0, &#39;R&#39;, link=link)
class Konzept:
def __init__(self, name, color):
self.rechnungstyp = model.RECHNUNGSTYP
self.name = name
self.color = color
self.cells = [] # not the real cell_objects, just the position as (row, col);
# Beim laden eines gespeicherten Konzepts werden diese Zellen in der Konzeptfarbe markiert
self.plots = defaultdict(list)
self.uncertain = []
class Cell:
def __init__(self, cellrow, cellcol, value):
self.row = cellrow
self.col = cellcol
self.value = value
self.color = WHITE
self.konzept = None
class ExcelCell:
def __init__(self, row=None, col=None, path=None, sheet=None, year=None, typ=None, category=None, betrag=None):
self.row = row
self.col = col
self.path = path
self.sheet = sheet
self.year = year
self.type = typ # z.B.: IST oder SOLL
self.category = category # z.B.: Gesamteinnahmen (noch str, besser FK)
# ab diesem Zeitpunkt sind die Werte in den Haushaltsplänen in TDM angegeben
if (self.year &gt; 1965 and self.type == &#34;IST&#34;) or (self.year &gt; 1966 and self.type == &#34;SOLL&#34;):
self.betrag = betrag
else:
self.betrag = betrag / 1000
# Die Einnahmen sind ab 1997/98 negativ aufgeführt. Dies hatten wir so in den Excel-Tabellen übernommen.
if ((self.year &gt; 1997 and self.type == &#34;IST&#34;) or (self.year &gt; 1998 and self.type == &#34;SOLL&#34;)) and self.row &lt; 25:
self.betrag = self.betrag * -1
if self.year &lt;= 1999:
self.inflationsbereinigt = self.betrag / dct_preisindices[self.year]
else:
# # noch Falsch. Was passiert mit den Werten, für die wir keinen Verbraucherpreisindex haben? (nach 1999)
# self.inflationsbereinigt = self.betrag
# # habe es nun in line_plot_inst() geändert. Inflationsbereinigt werden die Daten nach 1999 nicht angezeigt
pass
# Das erste Fenster, welches sich beim starten des Programms öffnet.
class DialogRechnungstypInit(wx.Dialog):
def __init__(self, parent, title):
super(DialogRechnungstypInit, self).__init__(parent, title=title, size=(280, 160))
# ---- Widgets erzeugen
self.panel = wx.Panel(self)
self.radiobox = wx.RadioBox(self.panel, -1, label=&#34;&#34;, # https://wxpython.org/Phoenix/docs/html/wx.RadioBox.html
choices=[&#34;Institutes&#34;,
&#34;Einnahmen-/Ausgabenrechnung (EA)&#34;,
&#34;Vermögensübersicht (VÜ)&#34;,
&#34;saved Concepts&#34;],
majorDimension=0,
style=wx.RA_SPECIFY_ROWS)
self.button = wx.Button(self.panel, -1, label=&#34;Okay&#34;)
# --- Widgets positionieren mit wx.BoxSizer (https://wxpython.org/Phoenix/docs/html/sizers_overview.html)
self.topsizer = wx.BoxSizer(wx.VERTICAL)
self.topsizer.AddSpacer(2)
self.topsizer.Add(self.radiobox, flag=wx.ALIGN_CENTER)
self.topsizer.AddSpacer(8)
self.topsizer.Add(self.button, flag=wx.ALIGN_CENTER)
self.panel.SetSizer(self.topsizer)
# --- Widgets an Functionen binden (Hier: wenn &#39;okay&#39;-Button gedrückt wird, wird self.start ausgeführt)
# --- https://wxpython.org/Phoenix/docs/html/events_overview.html
self.button.Bind(wx.EVT_BUTTON, self.start)
# Erst wenn dieses Fenster geschlossen wurde, kann mit Hauptfenster gearbeitet werden.
# Alternative zu Modal: .Show()
self.ShowModal()
def start(self, _):
tmp_rechnungstyp_id = self.radiobox.GetSelection()
if tmp_rechnungstyp_id == 0:
model.RECHNUNGSTYP = &#34;INST&#34;
frame.set_interface(_, &#34;INST&#34;)
self.Close()
elif tmp_rechnungstyp_id == 1:
model.RECHNUNGSTYP = &#34;EA&#34;
frame.set_interface(_, &#34;EA&#34;)
self.Close()
elif tmp_rechnungstyp_id == 2:
model.RECHNUNGSTYP = &#34;VÜ&#34;
frame.set_interface(_, &#34;VÜ&#34;)
self.Close()
elif tmp_rechnungstyp_id == 3:
if frame.load_konzepte_picker(_):
self.Close()
else:
pass
# Einstellungsfenster, welches sich öffnet, bevor die Grafen für die Gesamtrechnung angezeigt werden
class DialogGesamtPlotSettings(wx.Dialog):
def __init__(self, parent, title, lst):
super(DialogGesamtPlotSettings, self).__init__(parent, title=title, size=(250, 130))
self.parent = parent
self.panel = wx.Panel(self)
self.radiobutton_sum = wx.RadioButton(self.panel, -1, label=&#34;show Sum of institutes per file&#34;, style=wx.RB_GROUP)
self.radiobutton_inst = wx.RadioButton(self.panel, -1, label=&#34;show institutes seperate&#34;)
self.radiobutton_all = wx.RadioButton(self.panel, -1, label=&#34;show Sum and Institutes seperate&#34;)
self.btn = wx.Button(self.panel, -1, label=&#34;okay&#34;)
# --- Positionierung
self.sizer_top = wx.BoxSizer(wx.VERTICAL)
self.sizer_top.Add(self.radiobutton_sum)
self.sizer_top.Add(self.radiobutton_inst)
self.sizer_top.Add(self.radiobutton_all)
self.sizer_top.Add(self.btn)
self.panel.SetSizer(self.sizer_top)
self.btn.Bind(wx.EVT_BUTTON, self.create_plot)
def create_plot(self, _):
if self.radiobutton_sum.GetValue():
mode = 1
elif self.radiobutton_inst.GetValue():
mode = 2
else:
mode = 3
line_plot_gesamt(frame.new_get_konzept(), mode)
self.Close()
class DialogPlotSettings(wx.Dialog):
def __init__(self, parent, title):
super(DialogPlotSettings, self).__init__(parent, title=title, size=(250, 130))
self.parent = parent
self.panel = wx.Panel(self)
self.text01 = wx.StaticText(self.panel, -1, label=&#34;Ist- oder Sollwerte: &#34;)
self.choiceTyp = wx.Choice(self.panel, -1, choices=[&#34;IST&#34;, &#34;SOLL&#34;, &#34;IST &amp; SOLL&#34;], size=(100, 20))
self.text02 = wx.StaticText(self.panel, -1, label=&#34;Ein Diagramm pro.. &#34;)
self.choiceGrouping = wx.Choice(self.panel, -1, choices=[&#34;Institut&#34;, &#34;Konzept&#34;], size=(100, 20))
self.text03 = wx.StaticText(self.panel, -1, label=&#34;max Y-Wert: &#34;)
self.choiceYTicks = wx.Choice(self.panel, -1, choices=[&#34;auto&#34;, &#34;compareable&#34;], size=(100, 20))
self.checkbox_inflation = wx.CheckBox(self.panel, -1, label=&#34;Inflationsbereinigt&#34;)
self.btn = wx.Button(self.panel, -1, label=&#34;okay&#34;)
self.sizer_settings = wx.BoxSizer(wx.HORIZONTAL)
self.sizer_left = wx.BoxSizer(wx.VERTICAL)
self.sizer_right = wx.BoxSizer(wx.VERTICAL)
self.sizer_left.AddSpacer(4)
self.sizer_left.Add(self.text01)
self.sizer_left.AddSpacer(8)
self.sizer_left.Add(self.text02)
self.sizer_left.AddSpacer(8)
self.sizer_left.Add(self.text03)
self.sizer_left.AddSpacer(10)
self.sizer_left.Add(self.checkbox_inflation)
self.sizer_right.AddSpacer(4)
self.sizer_right.Add(self.choiceTyp)
self.sizer_right.AddSpacer(5)
self.sizer_right.Add(self.choiceGrouping)
self.sizer_right.AddSpacer(5)
self.sizer_right.Add(self.choiceYTicks)
self.sizer_right.AddSpacer(10)
self.sizer_right.Add(self.btn)
self.sizer_settings.Add(self.sizer_left, flag=wx.ALIGN_TOP)
self.sizer_settings.AddSpacer(5)
self.sizer_settings.Add(self.sizer_right, flag=wx.ALIGN_TOP)
self.sizer_settings.AddSpacer(5)
self.panel.SetSizer(self.sizer_settings)
self.btn.Bind(wx.EVT_BUTTON, self.create_plot)
def create_plot(self, _):
checkbox_inflation = 1 if self.checkbox_inflation.GetValue() else 0
# --- EndModal um einen Integer zurückzugeben. Damit ein Integer mehrere Informationen beinhalten kann,
# habe ich mit den Dezimalstellen gearbeitet.
# Erscheint mir nicht optimal und ist sicherlich eleganter zu lösen ;)
self.EndModal((self.choiceTyp.GetSelection()+1) * 10000 +
(self.choiceGrouping.GetSelection()+1) * 1000 +
(self.choiceYTicks.GetSelection()+1) * 100 +
(checkbox_inflation+1) * 10 +
9) # Prüfnummer (Damit kein Plot kommt, falls das Fenster geschlossen wird)
class DialogNewKonzept(wx.Dialog):
def __init__(self, parent, title):
super(DialogNewKonzept, self).__init__(parent, title=title, size=(200, 100))
self.parent = parent
self.panel = wx.Panel(self)
self.name_of_new_konzept = wx.TextCtrl(self.panel, -1, &#34;&#34;, size=(100, 23))
self.color_of_new_konzept = wx.ColourPickerCtrl(self.panel, -1, wx.RED)
self.btn = wx.Button(self.panel, -1, label=&#34;okay&#34;)
self.sizer_dialog = wx.BoxSizer(wx.VERTICAL)
self.sizer_dialog_konzept = wx.BoxSizer(wx.HORIZONTAL)
self.sizer_dialog_konzept.Add(self.name_of_new_konzept, flag=wx.ALIGN_CENTER)
self.sizer_dialog_konzept.AddSpacer(10)
self.sizer_dialog_konzept.Add(self.color_of_new_konzept, flag=wx.ALIGN_CENTER)
self.sizer_dialog.AddSpacer(5)
self.sizer_dialog.Add(self.sizer_dialog_konzept, flag=wx.ALIGN_CENTER)
self.sizer_dialog.AddSpacer(10)
self.sizer_dialog.Add(self.btn, flag=wx.ALIGN_CENTER)
self.panel.SetSizer(self.sizer_dialog)
self.btn.Bind(wx.EVT_BUTTON, self.create_new_konzept)
def create_new_konzept(self, _):
self.parent.add_new_konzept(self.name_of_new_konzept.Value, rgb_to_hex(self.color_of_new_konzept.GetColour()))
# rgb_to_hex() ist unten definiert. keine build-in Funktion von Python
self.Close()
class MyGrid(wx.grid.Grid): # &#39;Mouse vs. Python&#39; hat mir Anfangs sehr geholfen, um mit den Grids in wxPython umzugehen.
# http://www.blog.pythonlibrary.org/2010/04/04/wxpython-grid-tips-and-tricks/
def __init__(self, parent): # Durch die erste __init__ wird nichts mehr vom parent (wx.grid.Grid) geerbt..
&#34;&#34;&#34;Constructor&#34;&#34;&#34;
wx.grid.Grid.__init__(self, parent) # ..um dennoch zu erben, muss die parent.__init__ aufgerufen werden
self.parent = parent
self.CreateGrid(200, 58)
# self.SetRowSize(0, 60)
for i in range(58):
self.SetColSize(i, 240)
self.SetRowLabelSize(0)
self.SetMargins(0, 0)
self.this_row = 0
self.this_col = 0
self.GetGridWindow().Bind(wx.EVT_MOTION, self.on_mouse_over)
self.Show()
def on_mouse_over(self, event):
&#34;&#34;&#34;
Displays a tooltip over any cell in a certain column
&#34;&#34;&#34;
# This method was suggested by none other than Robin Dunn
# http://www.blog.pythonlibrary.org/2010/04/04/wxpython-grid-tips-and-tricks/
# https://alldunn.com/robin/
x, y = self.CalcUnscrolledPosition(event.GetX(), event.GetY())
coords = self.XYToCell(x, y)
try:
if model.RECHNUNGSTYP != &#34;INST&#34;:
msg = &#34;{} {}: {}&#34;.format(model.get_dct_cells()[(coords[0], coords[1])].value[0].bezeichnung,
model.get_dct_cells()[(coords[0], coords[1])].jahr,
model.get_dct_cells()[(coords[0], coords[1])].posten.geldbetrag)
event.GetEventObject().SetToolTip(msg)
else:
pass
except KeyError: # for empty cells
pass
except AttributeError: # for cells without oberkategorie
pass
def show_popup_menu(self, event):
self.this_row = event.GetRow()
self.this_col = event.GetCol()
if not hasattr(self, &#34;popupID1&#34;):
self.popupID1 = wx.NewId()
self.popupID2 = wx.NewId()
self.popupID3 = wx.NewId()
self.popupID4 = wx.NewId()
self.popupID5 = wx.NewId()
self.popupID6 = wx.NewId()
menu = wx.Menu()
item = wx.MenuItem(menu, self.popupID1, &#34;trigger Cell&#34;)
item_02 = wx.MenuItem(menu, self.popupID2, &#34;trigger category&#34;)
item_03 = wx.MenuItem(menu, self.popupID3, &#34;select whole category&#34;)
item_04 = wx.MenuItem(menu, self.popupID4, &#34;unselect whole Category&#34;)
item_uncertain_cat = wx.MenuItem(menu, self.popupID5, &#34;uncertain&#34;)
item_uncertain = wx.MenuItem(menu, self.popupID6, &#34;uncertain&#34;)
sub_menu = wx.Menu()
sub_menu.Append(item_02)
sub_menu.Append(item_03)
sub_menu.Append(item_04)
sub_menu.Append(item_uncertain_cat)
menu.Append(item)
menu.Append(wx.NewId(), &#34;Category&#34;, sub_menu)
menu.Append(item_uncertain)
self.PopupMenu(menu)
self.Bind(wx.EVT_MENU, self.select_cell, item)
self.Bind(wx.EVT_MENU, self.trigger_kategorie_from_popup, item_02)
self.Bind(wx.EVT_MENU, self.select_whole_category_from_popup, item_03)
self.Bind(wx.EVT_MENU, self.unselect_whole_category_from_popup, item_04)
self.Bind(wx.EVT_MENU, self.select_uncertain_from_popup, item_uncertain)
self.Bind(wx.EVT_MENU, self.select_uncertain_cat_from_popup, item_uncertain_cat)
menu.Destroy()
def trigger_kategorie_from_popup(self, _):
kat_id = self.get_cell(self.this_row, self.this_col).value[0].id
for c in model.get_dct_cells().values():
if c.value[0].id == kat_id:
if c.color != active_konzeptColor:
c.color = active_konzeptColor
c.konzept = active_konzept
if (c.row, c.col) not in self.parent.GetParent().konzepte[c.konzept.name].cells:
self.parent.GetParent().konzepte[c.konzept.name].cells.append((c.row, c.col))
else:
if c.color != WHITE:
self.parent.GetParent().konzepte[c.konzept.name].cells.remove((c.row, c.col))
c.color = WHITE
c.konzept = None
self.SetCellBackgroundColour(c.row, c.col, c.color)
self.ForceRefresh()
def select_whole_category_from_popup(self, _):
kat_id = self.get_cell(self.this_row, self.this_col).value[0].id
for c in model.get_dct_cells().values():
if c.value[0].id == kat_id:
c.color = active_konzeptColor
c.konzept = active_konzept
if (c.row, c.col) not in self.parent.GetParent().konzepte[c.konzept.name].cells:
self.parent.GetParent().konzepte[c.konzept.name].cells.append((c.row, c.col))
self.SetCellBackgroundColour(c.row, c.col, c.color)
self.ForceRefresh()
def unselect_whole_category_from_popup(self, _):
kat_id = self.get_cell(self.this_row, self.this_col).value[0].id
for c in model.get_dct_cells().values():
if c.value[0].id == kat_id:
self.SetCellBackgroundColour(c.row, c.col, WHITE)
c.konzept = None
self.ForceRefresh()
def select_uncertain_from_popup(self, _):
current_textcolor = frame.myGrid.GetCellTextColour(self.this_row, self.this_col)
if active_konzeptColor != &#34;#ffffff&#34; and active_konzeptColor != current_textcolor:
frame.myGrid.SetCellTextColour(self.this_row, self.this_col, active_konzeptColor)
active_konzept.uncertain.append((self.this_row, self.this_col))
else:
frame.myGrid.SetCellTextColour(self.this_row, self.this_col, &#34;#000000&#34;)
active_konzept.uncertain.remove((self.this_row, self.this_col))
self.ForceRefresh()
def select_uncertain_cat_from_popup(self, _):
current_cell = self.get_cell(self.this_row, self.this_col)
current_textcolor = frame.myGrid.GetCellTextColour(self.this_row, self.this_col)
for c in model.get_dct_cells().values():
if c.value[0].id == current_cell.value[0].id:
if active_konzeptColor != &#34;#ffffff&#34; and active_konzeptColor != current_textcolor:
frame.myGrid.SetCellTextColour(c.row, c.col, active_konzeptColor)
active_konzept.uncertain.append((c.row, c.col))
else:
frame.myGrid.SetCellTextColour(c.row, c.col, &#34;#000000&#34;)
if (c.row, c.col) in active_konzept.uncertain:
active_konzept.uncertain.remove((c.row, c.col))
self.ForceRefresh()
def set_cellvalue(self, cellpos, value):
cell_row, cell_col = cellpos
self.SetCellValue(cell_row, cell_col, value)
def select_cell(self, event):
if active_konzeptColor != &#34;#ffffff&#34;: # active_konzeptColor == &#34;#ffffff&#34; würde bedeuten,
# es ist kein Konzept ausgewählt. Mitlerweile wird beim erzeugen eines
# Konzept dieses auch direkt auf Aktiv gesetzt und macht diese Bedingung
# evtl überflüßig
try:
if model.RECHNUNGSTYP == &#34;INST&#34;:
c = dct_cells[(event.GetRow(), event.GetCol())] # c = Zelle, die von der Maus angewählt wurde
else:
c = model.get_dct_cells()[(self.this_row, self.this_col)]
if model.RECHNUNGSTYP == &#34;INST&#34; and c.row &lt; 9:
pass
else:
if c.color != &#34;#cccccc&#34;:
if c.color != active_konzeptColor:
c.color = active_konzeptColor
c.konzept = active_konzept
if (c.row, c.col) not in self.parent.GetParent().konzepte[c.konzept.name].cells:
self.parent.GetParent().konzepte[c.konzept.name].cells.append((c.row, c.col))
else:
if c.color != WHITE:
self.parent.GetParent().konzepte[c.konzept.name].cells.remove((c.row, c.col))
c.color = WHITE
c.konzept = None
self.SetCellBackgroundColour(c.row, c.col, c.color)
self.ForceRefresh()
self.parent.GetParent().tmpStoredKonzepte = None
else:
msg = &#34;Grey cells are just for orientation,\nthey are not selectable.&#34;
dlg = wx.MessageDialog(self, msg, &#39;Information&#39;, style=wx.OK | wx.ICON_INFORMATION | wx.CENTRE)
dlg.ShowModal()
except KeyError:
pass
else:
msg = &#34;Add or select a concept first.&#34;
dlg = wx.MessageDialog(self, msg, &#39;Information&#39;, style=wx.OK | wx.ICON_INFORMATION | wx.CENTRE)
dlg.ShowModal()
def trigger_kategorie(self, event):
if active_konzeptColor != &#34;#ffffff&#34;:
try:
current_cell = self.get_cell(event.GetRow(), event.GetCol())
kat_id = current_cell.value[0].id
for c in model.get_dct_cells().values():
if c.value[0].id == kat_id:
if c.color != active_konzeptColor:
c.color = active_konzeptColor
c.konzept = active_konzept
if (c.row, c.col) not in self.parent.GetParent().konzepte[c.konzept.name].cells:
self.parent.GetParent().konzepte[c.konzept.name].cells.append((c.row, c.col))
else:
if c.color != WHITE:
self.parent.GetParent().konzepte[c.konzept.name].cells.remove((c.row, c.col))
c.color = WHITE
c.konzept = None
self.SetCellBackgroundColour(c.row, c.col, c.color)
self.ForceRefresh()
except KeyError:
pass
else:
msg = &#34;Add or select a concept first.&#34;
dlg = wx.MessageDialog(self, msg, &#39;Information&#39;, style=wx.OK | wx.ICON_INFORMATION | wx.CENTRE)
dlg.ShowModal()
def reset_all_categories(self):
tmp_dct = dct_cells.values() if model.RECHNUNGSTYP == &#34;INST&#34; else model.get_dct_cells().values()
for c in tmp_dct:
if self.GetCellBackgroundColour(c.row, c.col) != &#34;#cccccc&#34;:
self.SetCellBackgroundColour(c.row, c.col, WHITE)
c.color = WHITE
c.konzept = None
frame.myGrid.SetCellTextColour(c.row, c.col, &#34;#000000&#34;)
self.ForceRefresh()
self.parent.GetParent().tmpStoredKonzepte = None
def delete_konzept_in_grid(self):
if model.RECHNUNGSTYP == &#34;INST&#34;:
for c in dct_cells.values():
if c.konzept == active_konzept:
self.SetCellBackgroundColour(c.row, c.col, WHITE)
c.konzept = None
c.color = WHITE
else:
for c in model.get_dct_cells().values():
if c.konzept == active_konzept:
self.SetCellBackgroundColour(c.row, c.col, WHITE)
c.konzept = None
c.color = WHITE
self.ForceRefresh()
self.parent.GetParent().tmpStoredKonzepte = None
def erase_grid(self):
for row in range(200):
for col in range(58):
self.SetCellBackgroundColour(row, col, WHITE)
self.set_cellvalue((row, col), &#34;&#34;)
def get_cell(self, row, col):
return model.get_dct_cells()[(row, col)]
class InstitutsForm(wx.Frame):
def __init__(self):
&#34;&#34;&#34;Constructor&#34;&#34;&#34;
wx.Frame.__init__(self,
parent=None,
title=&#34;Finanzexplorer&#34;,
size=(1000, 700))
self.p = wx.Panel(self, size=(300, 700))
self.button = wx.Button(self.p, -1, label=&#34;plot me&#34;)
self.search_control = wx.SearchCtrl(self.p, -1, value=&#34;&#34;, size=(240, 23))
self.search_control.ShowCancelButton(True)
self.btn_add = wx.Button(self.p, -1, label=&#34;add&#34;, size=(40, 20))
self.btn_delete = wx.Button(self.p, -1, label=&#34;delete&#34;, size=(60, 20))
self.btn_reset = wx.Button(self.p, -1, label=&#34;reset&#34;, size=(50, 20))
self.btn_save = wx.Button(self.p, -1, label=&#34;save&#34;, size=(51, 20))
self.btn_load = wx.Button(self.p, -1, label=&#34;load&#34;, size=(42, 20))
self.static_text = wx.StaticText(self.p, -1, &#34;Konzepte:&#34;)
self.p.infotext = wx.StaticText(self.p, -1, &#34;&#34;, size=(150, 23*4))
# # self.p.infotext, um über parent vom grid (panel = self.p) auf den infotext zugreifen zu können
self.list_ctrl_index = 0
self.konzept_listcontrol = wx.ListCtrl(self.p, size=(155, 100),
style=wx.LC_REPORT | wx.BORDER_SUNKEN | wx.LC_SINGLE_SEL)
self.konzept_listcontrol.InsertColumn(0, &#39;Konzeptname&#39;, width=150)
self.static_text_02 = wx.StaticText(self.p, -1, &#34;Institutes:&#34;)
self.checkbox_sum = wx.CheckBox(self.p, -1, label=&#34;Sum institutes&#34;)
self.institute = defaultdict(dict)
self.choices_files = [x for x in get_saves().keys()]
self.choices = []
self.checkbox = wx.CheckListBox(self.p, -1, size=(200, 1000),
choices=[], style=wx.LB_ALWAYS_SB)
self.checkbox.Bind(wx.EVT_CHECKLISTBOX, self.checked_item)
self.myGrid = MyGrid(self.p)
self.konzepte = {}
self.tmpStoredKonzepte = None
self.sizer_grid = wx.BoxSizer(wx.VERTICAL)
self.sizer_grid.Add(self.search_control)
self.sizer_grid.Add(self.myGrid, 1, wx.EXPAND)
self.sizer_info = wx.BoxSizer(wx.VERTICAL)
self.sizer_info.Add(self.p.infotext)
self.sizer_save = wx.BoxSizer(wx.HORIZONTAL)
self.sizer_save.Add(self.btn_load)
self.sizer_save.AddSpacer(60)
self.sizer_save.Add(self.btn_save)
# self.sizer_save.Add(self.filepicker)
self.sizer_konzeptbutton = wx.BoxSizer(wx.HORIZONTAL)
self.sizer_konzeptbutton.AddSpacer(1)
self.sizer_konzeptbutton.Add(self.btn_add)
self.sizer_konzeptbutton.AddSpacer(1)
self.sizer_konzeptbutton.Add(self.btn_delete)
self.sizer_konzeptbutton.AddSpacer(1)
self.sizer_konzeptbutton.Add(self.btn_reset)
self.sizer_konzeptbutton.AddSpacer(1)
self.sizer_instituts = wx.BoxSizer(wx.VERTICAL)
self.sizer_instituts.Add(self.checkbox)
self.sizer_controller = wx.BoxSizer(wx.VERTICAL)
self.sizer_controller.AddSpacer(5)
self.sizer_controller.Add(self.button)
self.sizer_controller.AddSpacer(5)
self.sizer_controller.Add(self.static_text)
self.sizer_controller.AddSpacer(5)
self.sizer_controller.Add(self.konzept_listcontrol)
self.sizer_controller.Add(self.sizer_konzeptbutton)
self.sizer_controller.AddSpacer(1)
self.sizer_controller.Add(self.sizer_save)
self.sizer_controller.AddSpacer(10)
self.sizer_controller.Add(self.sizer_info)
self.sizer_controller.Add(self.static_text_02)
self.sizer_controller.Add(self.checkbox_sum)
self.sizer_controller.Add(self.sizer_instituts)
self.topSizer = wx.BoxSizer(wx.HORIZONTAL)
self.topSizer.Add(self.sizer_controller)
self.topSizer.Add(self.sizer_grid)
self.p.SetSizer(self.topSizer)
self.btn_load.Bind(wx.EVT_BUTTON, self.load_konzepte_picker)
self.search_control.Bind(wx.EVT_SEARCHCTRL_SEARCH_BTN, self.find_category)
self.search_control.Bind(wx.EVT_SEARCHCTRL_CANCEL_BTN, self.unfind_category)
# --------- Menu Bar --------- #
self.menuBar()
self.Show()
def menuBar(self):
menuBar = wx.MenuBar()
fileButton = wx.Menu()
openMenu = wx.Menu()
openItem01 = openMenu.Append(-1, &#39;Institutsexplorer&#39;)
openItem02 = openMenu.Append(-1, &#39;Einnahmen-Ausgabenrechnung&#39;)
openItem03 = openMenu.Append(-1, &#39;Vermögensübersicht&#39;)
fileButton.Append(-1, &#39;Open ..&#39;, openMenu)
openInNewWindowItem = fileButton.Append(-1, &#39;Open new Window&#39;)
fileButton.AppendSeparator()
create_report = fileButton.Append(-1, &#34;create Report (PDF)&#34;)
fileButton.AppendSeparator()
exitItem = fileButton.Append(-1, &#39;Exit&#39;, &#39;status msg...&#39;)
menuBar.Append(fileButton, &#39;File&#39;)
runButton = wx.Menu()
self.plotItem = runButton.Append(-1, &#39;create Graphs&#39;)
menuBar.Append(runButton, &#39;Run&#39;)
helpButton = wx.Menu()
templateItem = helpButton.Append(-1, &#39;show Template&#39;)
developeItem = helpButton.Append(-1, &#39;develope mode&#39;)
menuBar.Append(helpButton, &#39;help&#39;)
self.SetMenuBar(menuBar)
self.Bind(wx.EVT_MENU, self.Quit, exitItem)
self.Bind(wx.EVT_MENU, lambda event: self.set_interface_alert(event, &#39;INST&#39;), openItem01)
self.Bind(wx.EVT_MENU, lambda event: self.set_interface_alert(event, &#39;EA&#39;), openItem02)
self.Bind(wx.EVT_MENU, lambda event: self.set_interface_alert(event, &#39;VÜ&#39;), openItem03)
self.Bind(wx.EVT_MENU, self.new_window, openInNewWindowItem)
self.Bind(wx.EVT_MENU, self.create_report, create_report)
self.Bind(wx.EVT_MENU, self.open_template, templateItem)
self.Bind(wx.EVT_MENU, self.develope_mode, developeItem)
def develope_mode(self, _):
&#34;&#34;&#34;
If develope_mode True, docstrings will be printed on console.
&#34;&#34;&#34;
global develope_mode
develope_mode = not develope_mode
def Quit(self, _):
self.Close()
def open_template(self, _):
&#34;&#34;&#34;
öffnet das Excel-Template, welches wir zum einen bei der Datenaufnahme aus den Haushaltsplänen
als Vorlage verwendet haben, zum anderen wurde anhand des Templates das Grid-Interface für die
Institute im Finanzexplorer erzeugt.
:param _: wx-event (not used)
&#34;&#34;&#34;
os.system(&#39;open Institute/Haushaltsbücher_MPI_Template.xlsx&amp;&#39;)
def new_window(self, _):
&#34;&#34;&#34;
Öffnet den Finanzexplorer erneut, um zum Beispiel parallel an der Einnahmen-/Ausgabenrechnung und
der Vermögensübersicht arbeiten zu können.
:param _: wx-event (not used)
&#34;&#34;&#34;
os.system(&#39;venv/bin/python Finanzexplorer_Institute.py&amp;&#39;)
def set_interface_alert(self, _, typ):
&#34;&#34;&#34;
Falls bereits ein Interface eines bestimmten Rechnungstyps geöffnet ist und nicht dem entspricht,
der gerade geöffnet werden soll, erscheint eine Warnung, dass noch ungespeicherte Konzepte verloren gehen.
:param _: wx-event (not used)
:param typ: Zur Unterscheidung von EA = Einnahmen-/Ausgabenrechnung, VÜ = Vermögensübersicht, INST = Institute
:return:
&#34;&#34;&#34;
if model.RECHNUNGSTYP == &#34;&#34;:
self.set_interface(_, typ)
elif model.RECHNUNGSTYP == typ:
pass
else:
msg = &#34;Unsaved changes will be discarded!\n\nDo you want to proceed?&#34;
dlg = wx.MessageDialog(self, msg, &#39;Warning&#39;, style=wx.YES_NO | wx.ICON_QUESTION | wx.CENTRE)
result = dlg.ShowModal()
if result == wx.ID_YES:
self.set_interface(_, typ)
else:
pass
def set_interface(self, _, typ):
&#34;&#34;&#34;
wxFrame wird nach dem &#39;richtigen&#39; Rechnungstyp ausgerichtet: wxWidgets werden neue Funktionen zugeteilt.
:param _: wx-event (not used)
:param typ: Zur Unterscheidung von EA = Einnahmen-/Ausgabenrechnung, VÜ = Vermögensübersicht, INST = Institute
:return:
&#34;&#34;&#34;
# erase old interface and data
fresh_new_start()
frame.reset_konzepte(_)
# set new interface and data
model.RECHNUNGSTYP = typ
if model.RECHNUNGSTYP == &#34;EA&#34;: # User-Interface for Einnahmen-/Ausgabenrechnung
model.superkategorien = [68, 92]
frame.SetTitle(&#34;Finanzexplorer - MPG Gesamt - Einnahmen-/ Ausgabenrechnung&#34;)
elif model.RECHNUNGSTYP == &#34;VÜ&#34;: # User-Interface for Vermögensübersicht
model.superkategorien = [1, 2]
frame.SetTitle(&#34;Finanzexplorer - MPG Gesamt - Vermögensübersicht&#34;)
# Superkategorien sind die &#39;Wurzeln&#39; des Schema-Baums in EA und VÜ.
# Also den Kategorien &#34;Einnahmen&#34;, &#34;Ausgaben&#34;, &#34;Aktiva&#34; und &#34;Passiva&#34;.
# Die Zahlen entsprechen den Kategorie-IDs in der Finanz-DB.
if model.RECHNUNGSTYP == &#34;INST&#34;:
frame.SetTitle(&#34;Finanzexplorer - MPG Institute&#34;)
self.checkbox_sum.SetLabel(&#34;Sum institutes&#34;)
self.set_institutes()
self.choices = [x for x in self.get_institutes().keys()]
self.choices.sort()
self.checkbox.Set(self.choices)
import_inst_template()
# Bindings for &#34;INST&#34;
self.button.Bind(wx.EVT_BUTTON, self.button_click)
self.myGrid.Bind(wx.grid.EVT_GRID_CELL_LEFT_DCLICK, self.myGrid.select_cell)
self.Bind(wx.EVT_MENU, self.button_click, self.plotItem)
self.checked_item(_=None)
self.sizer_controller.Show(self.checkbox_sum)
self.sizer_controller.Layout()
else: # for &#34;EA&#34; or &#34;VÜ&#34;
self.checkbox.Set([])
self.choices_files = [x for x in get_saves().keys()]
self.checkbox.Set(self.choices_files)
import_mpg_gesamt_data()
populate_cells()
self.static_text_02.SetLabel(&#34;Saved Conzepts:&#34;)
# Bindings for &#34;EA&#34; or &#34;VÜ&#34;
self.button.Bind(wx.EVT_BUTTON, self.button_click_gesamt)
self.myGrid.Bind(wx.grid.EVT_GRID_CELL_LEFT_DCLICK, self.myGrid.trigger_kategorie)
self.myGrid.Bind(wx.grid.EVT_GRID_CELL_RIGHT_CLICK, self.myGrid.show_popup_menu)
self.Bind(wx.EVT_MENU, self.button_click_gesamt, self.plotItem)
self.sizer_controller.Hide(self.checkbox_sum)
self.sizer_controller.Layout()
# Bindings for all types
self.btn_add.Bind(wx.EVT_BUTTON, self.add_konzept)
self.konzept_listcontrol.Bind(wx.EVT_LIST_ITEM_SELECTED, self.colour_picked)
self.konzept_listcontrol.Bind(wx.EVT_LIST_ITEM_DESELECTED, self.check_selection)
self.btn_reset.Bind(wx.EVT_BUTTON, self.reset_konzepte)
self.btn_delete.Bind(wx.EVT_BUTTON, self.delete_konzept)
self.btn_save.Bind(wx.EVT_BUTTON, self.save_konzepte)
def set_institutes(self):
&#34;&#34;&#34;
Liest die Namen und Pfade aller relevanten Excel-Dateien aus dem Ordner &#39;Institute&#39; ein und
speichert sie im dict self.institute unter dem Key des Institutsnamens. Nested dict &#39;path&#39; and &#39;file&#39;
:return:
&#34;&#34;&#34;
if develope_mode:
print(help(self.set_institutes))
for (dirpath, dirnames, filenames) in os.walk(&#34;../Finanzexplorer-Git-data/Institute&#34;):
filenames = [x for x in filenames
if &#34;Haushaltsb&#34; in x
and &#34;.xlsx&#34; in x
and &#34;Template&#34; not in x
and &#34;Haushaltsbücher_MPG_gesamt.xlsx&#34; not in x
and &#34;_All&#34; not in x]
for f in filenames:
if f.split(&#34;_&#34;)[1] == &#34;MPI&#34;:
name = f[21:len(f)-5].lower()
else:
name = f[17:len(f) - 5].lower()
name = name.capitalize()
self.institute[name][&#34;path&#34;] = os.path.join(dirpath, f)
self.institute[name][&#34;file&#34;] = f
def get_institutes(self):
return self.institute
# Damit die Anzahl der ausgewählten Institute angezeigt wird
def checked_item(self, _):
if model.RECHNUNGSTYP == &#34;INST&#34;:
if len(self.checkbox.GetCheckedItems()) != 0:
self.static_text_02.SetLabel(&#34;Institute ({} selected):&#34;.format(len(self.checkbox.GetCheckedItems())))
else:
self.static_text_02.SetLabel(&#34;Institute:&#34;)
self.tmpStoredKonzepte = None
def add_konzept(self, _):
DialogNewKonzept(self, &#34;new concept&#34;).ShowModal()
# Das Fenster &#39;DialogNewKonzept&#39; wird geöffnet. Name und Farbe des Konzepts können bestimmt werden
# .ShowModal(), damit an anderen Fenstern nicht gearbeitet werden kann, solange dieses geöffnet ist
# Die Alternative zu .ShowModal() wäre .Show()
def add_new_konzept(self, name, color):
self.konzept_listcontrol.InsertItem(self.list_ctrl_index, name)
self.konzept_listcontrol.SetItemTextColour(self.list_ctrl_index, color)
self.konzepte[name] = Konzept(name, color)
self.konzept_listcontrol.SetItemState(self.list_ctrl_index, wx.LIST_STATE_SELECTED, wx.LIST_STATE_SELECTED)
self.list_ctrl_index += 1
self.tmpStoredKonzepte = None
def check_selection(self, _):
global active_konzeptColor
global active_konzept
if self.konzept_listcontrol.GetSelectedItemCount() == 0: # Wenn kein Konzept angewählt ist ..
active_konzeptColor = &#34;#ffffff&#34;
active_konzept = None
def colour_picked(self, event):
global active_konzeptColor
global active_konzept
active_konzeptColor = self.konzept_listcontrol.GetItemTextColour(event.GetIndex())
active_konzept = self.konzepte[self.konzept_listcontrol.GetItem(event.GetIndex()).GetText()]
def reset_konzepte(self, _):
self.konzepte = {}
self.konzept_listcontrol.DeleteAllItems()
self.list_ctrl_index = 0
self.myGrid.reset_all_categories()
for item in self.checkbox.GetCheckedItems():
self.checkbox.Check(item, False)
self.checked_item(_=None)
self.tmpStoredKonzepte = None
def delete_konzept(self, _):
global active_konzept, active_konzeptColor
self.myGrid.delete_konzept_in_grid()
# delete dct-entry
self.tmpStoredKonzepte = None
try:
del self.konzepte[active_konzept.name]
except AttributeError:
pass
# delete listCtrl-entry
self.list_ctrl_index -= 1
try:
self.konzept_listcontrol.DeleteItem(self.konzept_listcontrol.GetFocusedItem())
except AssertionError:
pass
# set new active konzept to last one in list...
items_in_listctrl = self.konzept_listcontrol.GetItemCount()
if items_in_listctrl &gt; 0:
active_konzept = self.konzepte[self.konzept_listcontrol.GetItem(items_in_listctrl - 1).GetText()]
active_konzeptColor = active_konzept.color
self.konzept_listcontrol.SetItemState(self.list_ctrl_index - 1,
wx.LIST_STATE_SELECTED,
wx.LIST_STATE_SELECTED)
# ...or to &#34;None&#34;, if list is empty
else:
active_konzept = None
active_konzeptColor = WHITE
def get_inst_konzepte(self):
# print(get_inst_konzepte().__name__)
if self.tmpStoredKonzepte: # spart Zeit, da nicht erneut die Excel-Tabellen geöffnet werden müssen
all_konzept_data = self.tmpStoredKonzepte
else:
# get_selected_institutes
checked_institutes_paths = []
for x in self.checkbox.GetCheckedItems():
checked_institutes_paths.append((self.get_institutes()[self.choices[x]][&#34;path&#34;], self.choices[x]))
# get existing concepts
dct_xkonzepte = defaultdict(dict)
tmp_xkonzepte = defaultdict(list)
for c in dct_cells.values():
if c.konzept:
tmp_xkonzepte[(worksheets[c.col], c.konzept.name)].append(c.value)
for sheet_konzeptname, lst in tmp_xkonzepte.items():
dct_xkonzepte[sheet_konzeptname[0]][sheet_konzeptname[1]] = lst
# worksheets = [&#34;1954-1963&#34;, &#34;1964-1966&#34;, &#34;1967&#34;, &#34;1968-1972&#34;, &#34;1973-1986&#34;, &#34;1987-1997&#34;, &#34;1998-2002&#34;]
# c.col = Spalte im interface = index aus der Liste &#39;worksheets&#39;
# dct_xkonzepte{&#34;1954-1963&#34;: {Konzeptname:[list of selected cells per year]}}
# get data according to the selected institutes AND existing concepts
all_konzept_data = {}
for path in checked_institutes_paths:
konzept_data = defaultdict(list)
wb = load_workbook(path[0], data_only=True)
for sheet in worksheets:
try:
ws = wb[sheet] # exp. Worksheet &#34;1954-1963&#34;
# get data (sheet by sheet) for each concept and store it in a list (each konzept has one list)
for konzeptname, conceptcells_per_year in dct_xkonzepte[sheet].items():
for row in range(1, ws.max_row+1):
for v in conceptcells_per_year:
if ws.cell(row, 1).value == v:
# hier wird in die Excel gegangen und
# nach der ausgewählten Zelle aus dem Interface gesucht
for col in range(1, ws.max_column+1):
if ws.cell(3, col).value and ws.cell(row, col).value not in [&#34;&#34;, &#34; &#34;, None,
&#34;None&#34;, &#34;0&#34;, 0]:
if sheet == &#34;1998-2002&#34; and col &gt; 12: # €-Werte
pass
else:
konzept_data[konzeptname].append(
ExcelCell(row=row,
col=col,
path=path,
sheet=sheet,
year=int(ws.cell(3, col).value),
typ=ws.cell(2, col).value,
category=ws.cell(row, 1).value,
betrag=float(ws.cell(row, col).value)))
except KeyError:
print(&#34;{} doesn&#39;t has sheet {}&#34;.format(path[0], sheet))
except ValueError:
print(&#34;\nWrong entry: {}\nPath: {}\nSheet: {}\nRow, Column: {}, {}\n&#34;.format(wb[sheet].cell(row, col).value, path[0], sheet, row, col))
all_konzept_data[path[1]] = konzept_data
for key, inst in all_konzept_data.items():
for name, lst in inst.items(): # lst = list of ExcelCell objects
lst.sort(key=lambda z: z.year)
for obj in lst:
self.konzepte[name].plots[key].append((obj.year, obj.betrag, obj.type))
# -----------------------------------
# # Summe wird immer auch gespeichert. Ob sie genutzt wird entscheidet self.summe in der Klasse Konzepte
for key, inst in all_konzept_data.items():
for name, lst in inst.items(): # lst = list of ExcelCell objects; name = Konzeptname
for obj in lst:
tmp_is_in_list = False
for index, x in enumerate(self.konzepte[name].plots[&#34;SUMME&#34;]):
if x[0] == obj.year and x[2] == obj.type:
tmp_lst = list(x)
tmp_lst[1] += obj.betrag
self.konzepte[name].plots[&#34;SUMME&#34;][index] = tuple(tmp_lst)
tmp_is_in_list = True
if not tmp_is_in_list:
self.konzepte[name].plots[&#34;SUMME&#34;].append((obj.year, obj.betrag, obj.type))
# -----------------------------------
self.tmpStoredKonzepte = all_konzept_data
return all_konzept_data
def button_click(self, _):
if frame.checkbox_sum.GetValue():
data = self.get_inst_konzepte()
line_plot_inst(data, typ=&#34;IST&#34;, grouping_by=&#34;Institute&#34;, mode=&#34;auto&#34;, inflation=False)
else:
self.plot_settings()
def button_click_gesamt(self, _):
line_plot_gesamt_settings()
def new_get_konzept(self):
&#34;&#34;&#34;
Es werden alle Zellen der Obj Schemata durchgegangen und geschaut, welche Zellen zu einem Konzept gehören.
Diese Zellen mit Konzept werden in einem Dict unter dem Key des Konzepts
und der entsprechenden Jahreszahl gespeichert.
Besser: Nicht in den Cell-obj das Konzept speichern, sondern in den Konzepten die tatsächlichen Cell-obj.
So wäre es möglich, direkt anhand der Konzepte die richtigen Zellen anzusteuern und man muss nicht
alle Zellen (auch die ohne Konzept) durchsuchen. Beide Verbindungen (Cell -&gt; Konzept und Konzept -&gt; Cell)
gleichzeitig sind nicht möglich, da so eine schleife entstehen würde, die beim erzeugen eines json
zum Error führen würde (siehe save_konzepte()).
:return: dct_xkonzepte = &lt;dict&gt; {Konzeptname: &lt;list&gt; [(Jahr, Betrag), (Jahr, Betrag),..], Konzeptname:..}
&#34;&#34;&#34;
tmp_dct_xkonzepte = defaultdict(dict)
dct_xkonzepte = defaultdict(list)
for s in model.get_dct_schemata().values():
if s.typ == model.RECHNUNGSTYP:
for kon in self.konzepte.values():
tmp_dct_xkonzepte[kon.name][s.jahr] = None
for c in s.cells:
if c.konzept:
if tmp_dct_xkonzepte[c.konzept.name][s.jahr] is None:
tmp_dct_xkonzepte[c.konzept.name][s.jahr] = 0.00
if c.jahr &gt;= 2001:
tmp_dct_xkonzepte[c.konzept.name][s.jahr] += (c.posten.geldbetrag * 1.95583) # DM -&gt; €
else:
tmp_dct_xkonzepte[c.konzept.name][s.jahr] += c.posten.geldbetrag
for name, konzept in tmp_dct_xkonzepte.items():
for year, v_values in konzept.items():
dct_xkonzepte[name].append((year, v_values))
dct_xkonzepte[name].sort(key=lambda x: x[0])
self.konzepte[name].plots[&#34;MPG-Gesamt&#34;] = dct_xkonzepte[name]
return dct_xkonzepte
def plot_settings(self, xshow=True):
data = self.get_inst_konzepte()
return_code = str(DialogPlotSettings(self, title=&#34;plot settings&#34;).ShowModal())
if len(return_code) == 5: # Prüfnummer (Länge 5 bedeutet Fenster wurde nicht geschlossen)
typ = [&#34;IST&#34;, &#34;SOLL&#34;, &#34;IST &amp; SOLL&#34;][int(return_code[0]) - 1]
grouping_by = [&#34;Institute&#34;, &#34;Konzept&#34;][int(return_code[1]) - 1]
mode = [&#34;auto&#34;, &#34;compareable&#34;][int(return_code[2]) - 1]
inflation = [False, True][int(return_code[3]) - 1]
if not xshow:
image = line_plot_inst(data, typ, grouping_by=grouping_by, mode=mode, inflation=inflation, xshow=False)
return image
else:
line_plot_inst(data, typ, grouping_by=grouping_by, mode=mode, inflation=inflation, xshow=True)
else:
pass
def save_konzepte(self, _):
&#34;&#34;&#34;
Anhand der erstellten Konzepte wird ein defaul-filename erzeugt. In dieser Datei wird das dict frame.konzepte
als json gespeichert.
:param _: not used
:return: no return :/
&#34;&#34;&#34;
konzeptnames = []
for x in self.checkbox.GetCheckedItems():
konzeptnames.append(self.choices[x])
konzeptnames.append(&#34;_&#34;)
for k, v in self.konzepte.items():
konzeptnames.append(k)
konzeptnames.append(&#34;_&#34;)
str_konzeptnames = &#39;&#39;.join(konzeptnames)
str_konzeptnames = str_konzeptnames[:len(str_konzeptnames) - 1] # um den letzen Unterstrich zu löschen
str_konzeptnames = str_konzeptnames.replace(&#34;/&#34;, &#34;-&#34;) # um keinen subfolder zu erzeugen (Error)
new_filename = model.RECHNUNGSTYP + &#34;_&#34; + str_konzeptnames
filedlg = wx.FileDialog(self.p, &#34;Save Konzept&#34;, defaultFile=new_filename, style=wx.FD_SAVE)
filedlg.ShowModal()
filepath = filedlg.GetPath()
if filepath:
if model.RECHNUNGSTYP == &#34;INST&#34;:
self.get_inst_konzepte()
else:
self.new_get_konzept()
with open(filepath, &#34;w&#34;) as outfile:
json.dump(self.konzepte, outfile, default=lambda o: o.__dict__)
def load_konzepte_picker(self, _):
&#34;&#34;&#34;
Dialogfeld zum auswählen der zu ladenden Datei wird geöffnet.
:param _:
:return: Boolean = Datei wurde ausgewählt oder nicht.
&#34;&#34;&#34;
filedlg = wx.FileDialog(self.p, &#34;Load&#34;, style=wx.FD_OPEN | wx.FD_FILE_MUST_EXIST)
filedlg.ShowModal()
filepath = filedlg.GetPath()
if filepath:
self.load_konzept(_, filepath)
return True
else:
return False
def load_konzept(self, _, filepath):
&#34;&#34;&#34;
Das Json aus der Datei wird als Dictionary geladen und die Informationen verarpeitet,
sprich: Rechnungstyp gesetzt, richtige Interface laden, Zellen des Konzepts entsprechend eingefärbt und
Konzepte im FRame gespeichert.
:param _: not used
:param filepath: Pfad zur Datei
:return: no return :/
&#34;&#34;&#34;
global active_konzept, active_konzeptColor
with open(filepath) as infile:
dct_infile = json.load(infile)
checked_items = []
for k, v in dct_infile.items(): # k = Konzeptname, v = &lt;dict&gt; Kozept (Keys = Attr der Class Konzept)
if model.RECHNUNGSTYP == &#34;&#34;:
model.RECHNUNGSTYP = v[&#34;rechnungstyp&#34;]
self.set_interface(_=None, typ=v[&#34;rechnungstyp&#34;])
if v[&#34;rechnungstyp&#34;] == model.RECHNUNGSTYP:
self.add_new_konzept(k, v[&#34;color&#34;])
for cell_pos in v[&#34;cells&#34;]:
if model.RECHNUNGSTYP == &#34;INST&#34;:
c = dct_cells[(cell_pos[0], cell_pos[1])]
else:
c = model.get_dct_cells()[(cell_pos[0], cell_pos[1])]
if c.color != v[&#34;color&#34;]:
active_konzeptColor = v[&#34;color&#34;]
c.color = active_konzeptColor
active_konzept = self.konzepte[k]
c.konzept = active_konzept
if (cell_pos[0], cell_pos[1]) not in self.konzepte[k].cells:
self.konzepte[k].cells.append((cell_pos[0], cell_pos[1]))
self.myGrid.SetCellBackgroundColour(c.row, c.col, c.color)
if v[&#34;rechnungstyp&#34;] == &#34;INST&#34;:
for inst in v[&#34;plots&#34;].keys():
if inst != &#34;SUMME&#34;:
checked_items.append(inst.capitalize())
else:
self.checkbox_sum.SetValue(True)
if v[&#34;rechnungstyp&#34;] != &#34;Inst&#34;:
for cell_pos in v[&#34;uncertain&#34;]:
frame.myGrid.SetCellTextColour(cell_pos[0], cell_pos[1], v[&#34;color&#34;])
else:
msg = &#34;File &#39;{}&#39; is not of type &#39;{}&#39;\n\n&#34; \
&#34;Unsaved changes will be discarded!\n\n&#34; \
&#34;Do you want to proceed?&#34;.format(filepath.split(&#34;/&#34;)[-1], model.RECHNUNGSTYP)
dlg = wx.MessageDialog(self, msg, &#39;Warning&#39;, style=wx.YES_NO | wx.ICON_QUESTION | wx.CENTRE)
result = dlg.ShowModal()
if result == wx.ID_YES:
model.RECHNUNGSTYP = v[&#34;rechnungstyp&#34;]
self.set_interface(_, v[&#34;rechnungstyp&#34;])
self.add_new_konzept(k, v[&#34;color&#34;])
for cell_pos in v[&#34;cells&#34;]:
if model.RECHNUNGSTYP == &#34;INST&#34;:
c = dct_cells[(cell_pos[0], cell_pos[1])]
else:
c = model.get_dct_cells()[(cell_pos[0], cell_pos[1])]
if c.color != v[&#34;color&#34;]:
active_konzeptColor = v[&#34;color&#34;]
c.color = active_konzeptColor
active_konzept = self.konzepte[k]
c.konzept = active_konzept
if (cell_pos[0], cell_pos[1]) not in self.konzepte[k].cells:
self.konzepte[k].cells.append((cell_pos[0], cell_pos[1]))
self.myGrid.SetCellBackgroundColour(c.row, c.col, c.color)
if v[&#34;rechnungstyp&#34;] == &#34;INST&#34;:
for inst in v[&#34;plots&#34;].keys():
if inst != &#34;SUMME&#34;:
checked_items.append(inst.capitalize())
else:
break
self.checkbox.SetCheckedStrings(checked_items)
active_konzeptColor = &#34;#ffffff&#34;
self.checked_item(_=None)
self.myGrid.ForceRefresh()
def find_category(self, _):
&#34;&#34;&#34;
Es werden alle Zellen nach dem Suchbegriff durchsucht und bei Übereinstimmung hellblau eingefärbt. Zudem
werden diese Zellen in der Liste found_cells gespeichert.
Not case-sensitive. Falls erwünscht die .lower() herausnehmen.
Im Fall der Institute werden die ersten 8 Zeilen sowie graue Zellen nicht berücksichtigt.
:param _: not used
:return: no return :/
&#34;&#34;&#34;
self.unfind_category(_)
value = self.search_control.GetValue()
if model.RECHNUNGSTYP == &#34;INST&#34;:
for cell in dct_cells.values():
if value.lower() in cell.value.lower() and cell.row &gt; 8 and cell.color != &#34;#cccccc&#34;:
found_cells.append(cell)
self.myGrid.SetCellBackgroundColour(cell.row, cell.col, &#34;#d6ffff&#34;)
else:
for cell in model.get_dct_cells().values():
if value.lower() in cell.value[0].bezeichnung.lower():
found_cells.append(cell)
self.myGrid.SetCellBackgroundColour(cell.row, cell.col, &#34;#d6ffff&#34;)
self.myGrid.ForceRefresh()
def unfind_category(self, _):
&#34;&#34;&#34;
Zellen aus der Liste found_cells erhalten wieder ihre ursprüngliche Farbe (Farbe aus &lt;Cell-Obj&gt;.color).
:param _: not used
:return: no return :/
&#34;&#34;&#34;
global found_cells
for cell in found_cells:
self.myGrid.SetCellBackgroundColour(cell.row, cell.col, cell.color)
found_cells = []
self.myGrid.ForceRefresh()
def create_report(self, _, filename=&#34;Test&#34;):
&#34;&#34;&#34;
Erstellt eine PDF, zum einen mit dem Diagramm, zum anderen mit einer Jahresgenauen aufschlüsselung
der pro Konzept verwendeten Kategorien und ihrer Geldbeträge.
Zum erstellen eines Inhaltsverzeichnisses (&#39;toc&#39;) muss der letzte Prozess zweimal durchlaufen werden.
Die Seitenangaben müssen beim ersten durchlauf gespeichert werden, das sie beim zweiten Durchlauf beim erstellen
des Inhaltsverzeichnisses bereits auf der ersten Seite zum erstellen der Links gebraucht werden.
:param _: not used
:param filename: Dateiname (Bislang nur &#39;Test&#39;. Besser: &#39;Report_&lt;Konzeptnamen&gt;&#39; (siehe save_konzepte()))
:return: no return :/
&#34;&#34;&#34;
if model.RECHNUNGSTYP == &#34;INST&#34;:
image = self.plot_settings(xshow=False)
else:
image = line_plot_gesamt(frame.new_get_konzept(), mode=0, xshow=False)
myPDF = PDF()
report_konzepte = defaultdict(dict)
inhaltsverzeichnis = {}
for konzeptname, konzeptobjekt in frame.konzepte.items():
kategorien = []
sorted_lst_cells = sorted(konzeptobjekt.cells, key=itemgetter(1))
for konzeptcell in sorted_lst_cells:
if model.RECHNUNGSTYP == &#34;INST&#34;:
kategorien.append((dct_cells[konzeptcell].value, konzeptcell))
else:
kategorien.append((model.get_dct_cells()[konzeptcell].value, konzeptcell, model.get_dct_cells()[konzeptcell].posten))
if model.RECHNUNGSTYP == &#34;INST&#34;:
years = worksheets
else:
years = range(1948, 2006)
for i, sheet in enumerate(years):
xkategorien = []
for kat in kategorien:
if kat[1][1] == i:
if model.RECHNUNGSTYP == &#34;INST&#34;:
xkategorien.append(kat[0])
else:
if kat[0][0].spezifizierung:
xkategorien.append([kat[0][0].bezeichnung + &#34; (&#34; + kat[0][0].spezifizierung + &#34;): &#34;,
str(round(kat[2].geldbetrag, 2))])
else:
xkategorien.append([kat[0][0].bezeichnung + &#34;: &#34;, str(round(kat[2].geldbetrag, 2))])
for item in xkategorien:
for i, x in enumerate(item):
item[i] = x.replace(&#39;–&#39;, &#39;-&#39;)
item[i] = x.replace(&#34;\u0308&#34;, &#34;_&#34;)
report_konzepte[konzeptname][sheet] = xkategorien
for toc in [False, True]:
if toc:
myPDF = PDF()
myPDF.add_page()
myPDF.set_font(&#39;Times&#39;, &#39;B&#39;, 12)
myPDF.cell(w=200, h=12, txt=&#34;Inhaltsverzeichnis&#34;, ln=2)
myPDF.set_font(&#39;Times&#39;, size=10)
myPDF.cell(w=20, h=10, txt=&#34; - &#34;)
link = myPDF.add_link()
myPDF.set_link(link, page=2)
myPDF.cell(w=100, h=10, txt=&#34;Diagramm&#34;, link=link, ln=1)
for konzeptname, page in inhaltsverzeichnis.items():
myPDF.cell(w=20, h=10, txt=&#34; - &#34;)
link = myPDF.add_link()
myPDF.set_link(link, page=page + 1)
myPDF.cell(w=100, h=10, txt=konzeptname, link=link, ln=1)
myPDF.set_font(&#39;Times&#39;, size=10)
# Grafiken
myPDF.add_page()
if image:
myPDF.image(image, w=200, h=150)
for konzeptname, sheets in report_konzepte.items():
myPDF.add_page()
myPDF.set_font(&#39;Times&#39;, &#39;B&#39;, 12)
myPDF.cell(w=50, h=12, txt=&#34;&#34;, ln=1)
myPDF.cell(w=10, h=12, txt=&#34;&#34;)
myPDF.cell(w=160, h=12, txt=konzeptname)
myPDF.set_font(&#39;Times&#39;, size=8)
myPDF.cell(w=50, h=12, txt=&#34;DM&#34;, ln=1)
if not toc:
inhaltsverzeichnis[konzeptname] = myPDF.page_no()
for sheet, txt in sheets.items():
x, y = myPDF.get_x(), myPDF.get_y()
myPDF.line(x + 20, y, x + 185, y)
summe = 0
for i, x in enumerate(txt):
myPDF.cell(w=10, h=8, txt=&#34;&#34;)
if i == 0:
myPDF.cell(w=10, h=8, txt=str(sheet))
else:
myPDF.cell(w=10, h=8, txt=&#34;&#34;)
y = myPDF.get_y()
myPDF.multi_cell(w=140, h=8, txt=x[0])
new_line_y = myPDF.get_y()
if new_line_y - y &gt; 10: # Wenn Multi_cell mit den Kategoriennamen einen linebreak hatte..
myPDF.set_xy(x=175, y=y+7) # .. dann Cell mit Beträgen eine Zeile tiefer.
else:
myPDF.set_xy(x=175, y=y) # .. sonst auf selber höhe.
myPDF.multi_cell(w=50, h=8, txt=x[1])
myPDF.set_y(new_line_y)
summe += float(x[1])
if len(txt) &gt; 1:
x, y = myPDF.get_x(), myPDF.get_y()
myPDF.line(x + 165, y, x + 180, y)
myPDF.cell(w=10, h=8, txt=&#34;&#34;)
myPDF.cell(w=10, h=8, txt=&#34;&#34;)
myPDF.cell(w=145, h=8, txt=&#34;SUMME:&#34;)
myPDF.cell(w=50, h=8, txt=str(round(summe, 2)), ln=1)
if toc:
myPDF.output(&#34;../../../Reports/&#34; + filename + &#39;.pdf&#39;, &#39;F&#39;)
os.system(&#39;open Test.pdf&amp;&#39;)
myPDF.close()
def line_plot_inst(data, typ, grouping_by, mode, inflation, xshow=True):
ymin, ymax, steps = get_limits(data, typ)
fig = plt.figure()
plt.close()
if frame.checkbox_sum.GetValue():
ax = {}
for ex_institute in data.values(): # Bsp-Institut, um die Anzahl der Konzepte und Größe des Plot zu setzen
if len(frame.konzepte.keys()) &gt; 4:
for count, konzeptname in enumerate(ex_institute.keys()):
rows = len(ex_institute.keys()) / 2
rows = int(rows) + 1 if rows % 1 != 0 else int(rows)
if count &gt; rows - 1:
ax[konzeptname] = plt.subplot2grid((rows, 2), (count - rows, 1), rowspan=1, colspan=1)
else:
ax[konzeptname] = plt.subplot2grid((rows, 2), (count, 0), rowspan=1, colspan=1)
else:
count = 0
for konzeptname in ex_institute.keys():
ax[konzeptname] = plt.subplot2grid((len(ex_institute.keys()) * 10, 1),
(count, 0), rowspan=8, colspan=1)
count += 10
# dictionary mit den Werten 0 erzeugen
dct_konzepte = {}
for instname, konzepte in data.items():
for konzeptname, ex_cells in konzepte.items():
dct_konzepte[konzeptname] = {}
for x in range(1954, 2003):
dct_konzepte[konzeptname][x] = 0
# User fragen, ob der Plot Inflationsbereinigt sein soll oder nicht.
bool_inflation = False
msg = &#34;Do you want this plot adjusted for inflation?&#34;
dlg = wx.MessageDialog(None, msg, &#39;Inflation&#39;, style=wx.YES_NO | wx.CANCEL | wx.CENTRE)
result = dlg.ShowModal()
if result == wx.ID_YES:
bool_inflation = True
elif result == 5101:
return
else:
pass
# auf jeden dict-wert den aktuellen Betrag draufaddieren
dct_legend_set = defaultdict(set)
for instname, konzepte in data.items():
for konzeptname, ex_cells in konzepte.items():
for x in ex_cells:
if x.type == typ:
if bool_inflation and x.year &lt;= 1999:
dct_konzepte[konzeptname][x.year] += x.inflationsbereinigt
else:
dct_konzepte[konzeptname][x.year] += x.betrag
dct_legend_set[konzeptname].add(instname)
for konzeptname, year in dct_konzepte.items():
ax[konzeptname].plot(year.keys(), year.values(), color=frame.konzepte[konzeptname].color)
ax[konzeptname].grid(linewidth=&#39;0.2&#39;)
ax[konzeptname].ticklabel_format(style=&#34;plain&#34;)
for konzeptname, instnames in dct_legend_set.items():
tmp = [&#34; + &#34;.join(instnames), ]
ax[konzeptname].legend(tmp)
ax[konzeptname].set_title(konzeptname.upper(), pad=1)
# ------------------------------
else:
if grouping_by == &#34;Institute&#34;:
ax = {}
if len(frame.checkbox.GetCheckedItems()) &gt; 4:
for count, instname in enumerate(data.keys()):
rows = len(data.keys()) / 2
rows = int(rows) + 1 if rows % 1 != 0 else int(rows)
if count &gt; rows - 1:
ax[instname] = plt.subplot2grid((rows, 2), (count - rows, 1), rowspan=1, colspan=1)
else:
ax[instname] = plt.subplot2grid((rows, 2), (count, 0), rowspan=1, colspan=1)
else:
count = 0
for instname in data.keys():
ax[instname] = plt.subplot2grid((len(data.keys()) * 10, 1), (count, 0), rowspan=8, colspan=1)
count += 10
for instname, inst in data.items():
legend = []
for key, kon in inst.items():
color = frame.konzepte[key].color
if typ == &#34;IST &amp; SOLL&#34;:
if inflation:
ax[instname].plot([x.year for x in kon if x.type == &#34;IST&#34; and x.year &lt;= 1999],
[y.inflationsbereinigt for y in kon if y.type == &#34;IST&#34; and y.year &lt;= 1999],
color=color)
legend.append(key + &#34; (IST)&#34;)
ax[instname].plot([x.year for x in kon if x.type == &#34;SOLL&#34; and x.year &lt;= 1999],
[y.inflationsbereinigt for y in kon if y.type == &#34;SOLL&#34; and y.year &lt;= 1999],
color=&#34;#cccccc&#34;)
legend.append(key + &#34; (SOLL)&#34;)
else:
ax[instname].plot([x.year for x in kon if x.type == &#34;IST&#34;],
[y.betrag for y in kon if y.type == &#34;IST&#34;],
color=color)
legend.append(key + &#34; (IST)&#34;)
ax[instname].plot([x.year for x in kon if x.type == &#34;SOLL&#34;],
[y.betrag for y in kon if y.type == &#34;SOLL&#34;],
color=&#34;#cccccc&#34;)
legend.append(key + &#34; (SOLL)&#34;)
else:
if inflation:
ax[instname].plot([x.year for x in kon if x.type == typ and x.year &lt;= 1999],
[y.inflationsbereinigt for y in kon if y.type == typ and y.year &lt;= 1999],
color=color)
else:
ax[instname].plot([x.year for x in kon if x.type == typ],
[y.betrag for y in kon if y.type == typ],
color=color)
legend.append(key)
ax[instname].set_title(instname.upper(), pad=1)
ax[instname].ticklabel_format(style=&#34;plain&#34;)
ax[instname].set_xticks([x for x in range(1945, 2010, 5)])
ax[instname].grid(linewidth=&#39;0.2&#39;)
if mode == &#34;compareable&#34;:
ax[instname].set_yticks([y for y in range(ymin, ymax, steps)])
ax[instname].legend(legend)
elif grouping_by == &#34;Konzept&#34;:
ax = {}
legend = defaultdict(list)
for ex_institute in data.values(): # Bsp-Institut, um die Anzahl der Konzepte und Größe des Plot zu setzen
if len(frame.konzepte.keys()) &gt; 4:
for count, konzeptname in enumerate(ex_institute.keys()):
rows = len(ex_institute.keys()) / 2
rows = int(rows) + 1 if rows % 1 != 0 else int(rows)
if count &gt; rows - 1:
ax[konzeptname] = plt.subplot2grid((rows, 2), (count - rows, 1), rowspan=1, colspan=1)
else:
ax[konzeptname] = plt.subplot2grid((rows, 2), (count, 0), rowspan=1, colspan=1)
else:
count = 0
for konzeptname in ex_institute.keys():
ax[konzeptname] = plt.subplot2grid((len(ex_institute.keys()) * 10, 1),
(count, 0), rowspan=8, colspan=1)
count += 10
for instname, inst in data.items():
for key, kon in inst.items():
# color = frame.konzepte[key].color
if typ == &#34;IST &amp; SOLL&#34;:
if inflation:
ax[key].plot([x.year for x in kon if x.type == &#34;IST&#34; and x.year &lt;= 1999],
[y.inflationsbereinigt for y in kon if y.type == &#34;IST&#34; and y.year &lt;= 1999])
legend[key].append(instname + &#34; (IST)&#34;)
ax[key].plot([x.year for x in kon if x.type == &#34;SOLL&#34; and x.year &lt;= 1999],
[y.inflationsbereinigt for y in kon if y.type == &#34;SOLL&#34; and y.year &lt;= 1999],
color=&#34;#cccccc&#34;)
legend[key].append(instname + &#34; (SOLL)&#34;)
else:
ax[key].plot([x.year for x in kon if x.type == &#34;IST&#34;],
[y.betrag for y in kon if y.type == &#34;IST&#34;])
legend[key].append(instname + &#34; (IST)&#34;)
ax[key].plot([x.year for x in kon if x.type == &#34;SOLL&#34;],
[y.betrag for y in kon if y.type == &#34;SOLL&#34;],
color=&#34;#cccccc&#34;)
legend[key].append(instname + &#34; (SOLL)&#34;)
else:
if inflation:
ax[key].plot([x.year for x in kon if x.type == typ and x.year &lt;= 1999],
[y.inflationsbereinigt for y in kon if y.type == typ and y.year &lt;= 1999])
legend[key].append(instname)
else:
ax[key].plot([x.year for x in kon if x.type == typ],
[y.betrag for y in kon if y.type == typ])
legend[key].append(instname)
ax[key].set_title(key.upper(), pad=1)
ax[key].ticklabel_format(style=&#34;plain&#34;)
ax[key].set_xticks([x for x in range(1945, 2010, 5)])
ax[key].grid(linewidth=&#39;0.2&#39;)
if mode == &#34;compareable&#34;:
ax[key].set_yticks([y for y in range(ymin, ymax, steps)])
for key in legend.keys():
ax[key].legend(legend[key])
# --------------------------
if xshow:
plt.show()
else:
plt.savefig(&#39;testchart.png&#39;, format=&#39;png&#39;, dpi=fig.dpi * 2)
return &#39;testchart.png&#39;
def line_plot_gesamt_settings(xshow=True):
if len(frame.checkbox.GetCheckedItems()) != 0:
checked_saves_paths = []
for x in frame.checkbox.GetCheckedItems():
checked_saves_paths.append([x for x in get_saves().values()][x])
dlg = DialogGesamtPlotSettings(frame, &#34;plot Settings&#34;, checked_saves_paths).ShowModal()
else:
line_plot_gesamt(frame.new_get_konzept(), mode=0, xshow=xshow)
def line_plot_gesamt(dct_konzepte, mode, xshow=True):
&#34;&#34;&#34;
Ein Diagramm für die MPG-Gesamt wird erzeugt und je nach &#39;xshow&#39; gespeichert oder direkt angezeigt.
:param dct_konzepte: Kanzeptdaten als Dict gespeichert.
:param mode: Nur relevant, wenn bereits gespeicherte Konzepte, die nicht geladen wurden, geplottet werden sollen.
:param xshow: Bool. Die Funktion wird auch aufgerufen, wenn z.B. ein Report erstellt werden soll. in dem Fall soll
der Plot nicht angezeigt werden (False), sondern nur das Diagramm erzeugt und gespeichert werden (True).
:return:&#39;temp_chart.png&#39;, nur wenn xshow == False.
&#34;&#34;&#34;
legend = []
fig = plt.figure()
# User fragen, ob der Plot Inflationsbereinigt sein soll oder nicht.
bool_inflation = False
msg = &#34;Do you want this plot adjusted for inflation?&#34;
dlg = wx.MessageDialog(None, msg, &#39;Inflation&#39;, style=wx.YES_NO | wx.CANCEL | wx.CENTRE)
result = dlg.ShowModal()
if result == wx.ID_YES:
bool_inflation = True
elif result == 5101:
return
else:
pass
# um &#34;Nicht-Rechnungstypkonforme&#34; Konzepte zu plotten------------------------------
if len(frame.checkbox.GetCheckedItems()) != 0:
checked_institutes_paths = []
for x in frame.checkbox.GetCheckedItems():
checked_institutes_paths.append([x for x in get_saves().values()][x])
for path in checked_institutes_paths:
with open(path) as infile:
dct_infile = json.load(infile)
for konzeptname, konzept_obj in dct_infile.items():
if len(konzept_obj[&#34;plots&#34;].items()) == 1:
color = konzept_obj[&#34;color&#34;]
else:
color = None
if mode == 1 and konzept_obj[&#34;rechnungstyp&#34;] == &#34;INST&#34;:
# mode 1: Die Summe der einzelnen Institute in einer gespeicherten Datei wird angezeigt.
x = []
y = []
konzept_obj[&#34;plots&#34;][&#34;SUMME&#34;].sort(key=lambda x: x[0]) # nach Jahreszahlen (x[0]) sortieren
for data in konzept_obj[&#34;plots&#34;][&#34;SUMME&#34;]:
if len(data) &gt; 2:
if data[2] == &#34;IST&#34;:
if bool_inflation:
if data[0] &lt;= 1999:
x.append(data[0])
y.append(data[1] / dct_preisindices[data[0]])
else:
x.append(data[0])
y.append(data[1])
else:
if bool_inflation:
if data[0] &lt;= 1999:
x.append(data[0])
y.append(data[1] / dct_preisindices[data[0]])
else:
x.append(data[0])
y.append(data[1])
plt.plot(x, y, color=color)
if (konzept_obj[&#34;rechnungstyp&#34;] in [&#34;EA&#34;, &#34;VÜ&#34;] and model.RECHNUNGSTYP in [&#34;EA&#34;, &#34;VÜ&#34;]) or \
(konzept_obj[&#34;rechnungstyp&#34;] == &#34;INST&#34; and model.RECHNUNGSTYP == &#34;INST&#34;):
legend.append(konzeptname)
else:
legend.append(&#34;SUMME - &#34; + konzeptname)
elif mode == 2:
# mode2: Die einzelnen Institute aus den ausgewählten gespeicherten Dateien werden angezeigt.
for institute, values in konzept_obj[&#34;plots&#34;].items():
if institute != &#34;SUMME&#34;:
x = []
y = []
values.sort(key=lambda x: x[0]) # nach Jahreszahlen (x[0]) sortieren
for data in values:
if len(data) &gt; 2:
if data[2] == &#34;IST&#34;:
if bool_inflation:
if data[0] &lt;= 1999:
x.append(data[0])
y.append(data[1] / dct_preisindices[data[0]])
else:
x.append(data[0])
y.append(data[1])
else:
if bool_inflation:
if data[0] &lt;= 1999:
x.append(data[0])
y.append(data[1] / dct_preisindices[data[0]])
else:
x.append(data[0])
y.append(data[1])
plt.plot(x, y, color=color)
if (konzept_obj[&#34;rechnungstyp&#34;] in [&#34;EA&#34;, &#34;VÜ&#34;] and model.RECHNUNGSTYP in [&#34;EA&#34;, &#34;VÜ&#34;]) or \
(konzept_obj[&#34;rechnungstyp&#34;] == &#34;INST&#34; and model.RECHNUNGSTYP == &#34;INST&#34;):
legend.append(konzeptname)
else:
legend.append(institute + &#34; - &#34; + konzeptname)
elif mode == 3:
# mode 3: Summe und einzelne Institute werden angezeigt. Summe jeweils pro gespeicherte Datei!
for institute, values in konzept_obj[&#34;plots&#34;].items():
x = []
y = []
values.sort(key=lambda x: x[0]) # nach Jahreszahlen (x[0]) sortieren
for data in values:
if len(data) &gt; 2:
if data[2] == &#34;IST&#34;:
if bool_inflation:
if data[0] &lt;= 1999:
x.append(data[0])
y.append(data[1] / dct_preisindices[data[0]])
else:
x.append(data[0])
y.append(data[1])
else:
if bool_inflation:
if data[0] &lt;= 1999:
x.append(data[0])
y.append(data[1] / dct_preisindices[data[0]])
else:
x.append(data[0])
y.append(data[1])
plt.plot(x, y, color=color)
if (konzept_obj[&#34;rechnungstyp&#34;] in [&#34;EA&#34;, &#34;VÜ&#34;] and model.RECHNUNGSTYP in [&#34;EA&#34;, &#34;VÜ&#34;]) or \
(konzept_obj[&#34;rechnungstyp&#34;] == &#34;INST&#34; and model.RECHNUNGSTYP == &#34;INST&#34;):
legend.append(konzeptname)
else:
legend.append(institute + &#34; - &#34; + konzeptname)
# --------------------------------------------------------------------------------
for key, lst in dct_konzepte.items():
color = frame.konzepte[key].color
values = []
if bool_inflation:
for x in lst:
# prevent deviding a nonetype
if x[1] is None and x[0] &lt;= 1999:
values.append(None)
elif x[0] &lt;= 1999:
values.append(x[1] / dct_preisindices[x[0]] / 1000000)
plt.plot([x[0] for x in lst if x[0] &lt;= 1999], values, color=color)
else:
for x in lst:
values.append(x[1] / 1000000)
plt.plot([x[0] for x in lst], values, color=color)
plt.grid(linewidth=&#39;0.2&#39;)
legend.append(key)
plt.ticklabel_format(style=&#34;plain&#34;)
plt.xlim(1945, 2005)
bottom, top = plt.ylim()
plt.ylim(0, top)
plt.legend(legend)
plt.ylabel(&#34;Beträge in mio. DM&#34;)
plt.xlabel(&#34;Jahre&#34;)
if bool_inflation:
plt.title(&#34;Inflationsbereinigt&#34;)
else:
plt.title(&#34;Title&#34;)
if xshow:
plt.show()
else:
plt.savefig(&#39;testchart.png&#39;, format=&#39;png&#39;, dpi=fig.dpi * 2)
return &#39;temp_chart.png&#39;
def import_inst_template():
&#34;&#34;&#34;
Anhand des Excell-Templates wird für jedes relevante Arbeitsblatt (also nicht das Synthese-Blatt)
die erste Spalte eingelesen und im Grid des Interface eins zu eins übertragen. Jede Spalte im Grid repräsentiert
also ein Arbeitsblatt.
Sonderfall Arbeitsblatt &#34;1954-1963&#34;: In diesem Jahr tauchen die Einnahmen mehrmals auf. Die Zeilen sind verborgen,
aber es gibt einen sprung zwischen Zeile 13 und 54. Die Idee war damals mehrere Abteilungen (mit einzelnen
Haushaltsplänen) eines Instituts auch in einer Excelldatei zu speichern. Diese Idee wurde jedoch verworfen.
:return: no return :/
&#34;&#34;&#34;
wb = load_workbook(&#34;../Finanzexplorer-Git-data/Institute/Haushaltsbücher_MPI_Template.xlsx&#34;, data_only=True)
grid_col = 0
for s in range(len(wb.sheetnames)):
if wb.sheetnames[s] == &#34;1954-1963&#34;: # Sonderregel für dieses Sheet,
# da im Template die Einnahmen mehrmals auftauchen
wb.active = s
sheet = wb.active
frame.myGrid.SetColLabelValue(grid_col, sheet.title)
for row in range(1, 14):
if sheet.cell(row, 1).value:
this_cell = Cell(row, grid_col, sheet.cell(row, 1).value)
if sheet.cell(row, grid_col+1).fill.start_color.index == &#34;00000000&#34;:
frame.myGrid.SetCellBackgroundColour(row, grid_col, &#34;#cccccc&#34;)
this_cell.color = &#34;#cccccc&#34;
dct_cells[(row, grid_col)] = this_cell
frame.myGrid.set_cellvalue((row, grid_col), sheet.cell(row, 1).value)
for row in range(56, 200):
if sheet.cell(row, 1).value:
this_cell = Cell(row, grid_col, sheet.cell(row, 1).value)
if sheet.cell(row, grid_col+1).fill.start_color.index == &#34;00000000&#34;:
frame.myGrid.SetCellBackgroundColour(row, grid_col, &#34;#cccccc&#34;)
this_cell.color = &#34;#cccccc&#34;
dct_cells[(row, grid_col)] = this_cell
frame.myGrid.set_cellvalue((row, grid_col), sheet.cell(row, 1).value)
grid_col += 1
elif wb.sheetnames[s][0] == &#34;1&#34;:
wb.active = s
sheet = wb.active
frame.myGrid.SetColLabelValue(grid_col, sheet.title)
for row in range(1, 200):
if sheet.cell(row, 1).value:
this_cell = Cell(row, grid_col, sheet.cell(row, 1).value)
frame.myGrid.set_cellvalue((row, grid_col), sheet.cell(row, 1).value)
if sheet.cell(row, grid_col+1).fill.start_color.index == &#34;00000000&#34;:
frame.myGrid.SetCellBackgroundColour(row, grid_col, &#34;#cccccc&#34;)
this_cell.color = &#34;#cccccc&#34;
dct_cells[(row, grid_col)] = this_cell
grid_col += 1
frame.myGrid.ForceRefresh()
tmp_stack = []
def set_hierarchie(schema_id, oberkategorie_id):
&#34;&#34;&#34;
Jedes Schema bekommt eine Liste (&#39;kategorien_hierarchisch&#39;) mit Tuples bestehend aus 3 Werten: (1. Kategorie-Obj,
2. Folge von &#39;-&#39; zur Markierung der Hierarchie-Ebene, 3. Oberkategorie (Kategorie-Obj) von &lt;1. Kategorie-Obj&gt;).
Zunächst wird diese Funktion für jede einzelne Superkategorie als Parameter (oberkategorie_id) aufgerufen. Ausgehend
von diesen &#39;wanderd&#39; die Funktion rekursiv durch den gesamten Strukturbaum.
Superkategorien sind &#34;Einnahmen&#34;, &#34;Ausgaben&#34;, &#34;Aktiva&#34; und &#34;Passiva&#34;, also die oberste Hierarchie-Ebene.
:param schema_id: ID zum ansteuern des richigen Schemata aus Finanzexplorer_model.py
:param oberkategorie_id: ID der jeweiligen Oberkategorie.
:return: no return :/
&#34;&#34;&#34;
if oberkategorie_id in model.superkategorien:
model.get_dct_schemata()[schema_id].kategorien_hierarchisch.append(
(model.get_dct_kategorien()[oberkategorie_id],
len(tmp_stack) * &#34;-&#34;,
None))
tmp_stack.append(oberkategorie_id)
for kr in model.get_dct_schemata()[schema_id].KategorieRelationen:
if model.get_dct_kategorien()[kr.origin_id].id == oberkategorie_id:
model.get_dct_schemata()[schema_id].kategorien_hierarchisch.append(
(kr.target_kategorie,
len(tmp_stack) * &#34;-&#34;,
model.get_dct_kategorien()[kr.origin_id]))
set_hierarchie(schema_id, kr.target_id)
tmp_stack.pop()
def import_mpg_gesamt_data():
&#34;&#34;&#34;
Importiert die Daten aus den CSV-Dateien (aus der Finanz-DB):
Kategorien:
Posten: http://gmpg-intern.mpiwg-berlin.mpg.de:8888/explorer/525/
Kategorierelationen: http://gmpg-intern.mpiwg-berlin.mpg.de:8888/explorer/526/
Schemata:
Hierarchie der Kategorien innerhalb eines Schemas wird festgelegt.
:return: no return :/
&#34;&#34;&#34;
model.import_kategorien()
model.import_posten()
model.import_kategorierelations()
model.import_schemata()
for year in range(1948, 2006):
for schema in model.get_dct_schemata().values():
if schema.jahr == year:
for x in model.superkategorien:
set_hierarchie(schema.id, x)
new_schemata = []
last_schema = None
for year in range(1948, 2006):
has_schema = False
for schema in model.get_dct_schemata().values():
if schema.jahr == year:
last_schema = copy.copy(schema)
has_schema = True
if not has_schema and last_schema:
new_schema = copy.deepcopy(last_schema)
new_schema.id += 1000
new_schema.jahr = year
new_schemata.append(new_schema)
last_schema = new_schema
for new in new_schemata:
model.get_dct_schemata()[new.id] = new
def populate_cells():
&#34;&#34;&#34;
Zellen im Grid werden nach Vorlage der Hierarchie im Schema befüllt.
&#34;&#34;&#34;
col = -1
for year in range(1948, 2006):
for schema in model.get_dct_schemata().values():
if schema.jahr == year:
row = 0
col += 1
frame.myGrid.SetColLabelValue(col, str(schema.jahr))
for kategorie_in_Hierarchie in schema.kategorien_hierarchisch:
row += 1
temp = model.Cell(row, col, kategorie_in_Hierarchie, schema.jahr)
model.get_dct_cells()[(row, col)] = temp
model.get_dct_schemata()[schema.id].cells.add(temp)
for cell in model.get_dct_cells().values():
cell.calculate_zwischensumme()
frame.myGrid.set_cellvalue(cell.get_pos(), str(cell.value[1]) + cell.value[0].bezeichnung)
def fresh_new_start():
&#34;&#34;&#34;
Alles wird gelöscht, um neu beginnen zu können.
&#34;&#34;&#34;
global dct_cells
model.dct_Kategorien = {}
model.dct_Posten = {}
model.dct_categorierelations = OrderedDict()
model.dct_Schemata = OrderedDict()
model.dct_cells = {}
dct_cells = {}
frame.myGrid.erase_grid()
def get_saves():
&#34;&#34;&#34;
:return: saves_path = Liste von Pfaden zu den Dateien aus dem Ordner &#39;Saves&#39;
&#34;&#34;&#34;
saves_path = {}
for (dirpath, dirnames, filenames) in os.walk(&#34;../../../Saves&#34;):
filenames = [x for x in filenames]
for f in filenames:
filepath = os.path.join(dirpath, f)
try:
if &#34;rechnungstyp&#34; in open(filepath).read():
saves_path[f] = filepath
except UnicodeDecodeError:
pass
return saves_path
def rgb_to_hex(rgb):
&#34;&#34;&#34;
wandelt einen rgb-Farbcode in einen Hex-Farbcode um:
:param rgb: Drei Werte zwischen 0 und 255
:return: hex, z.B. &#34;#ffffff&#34;
&#34;&#34;&#34;
r, g, b = rgb[:3]
def clamp(x):
return max(0, min(x, 255))
return &#34;#{0:02x}{1:02x}{2:02x}&#34;.format(clamp(r), clamp(g), clamp(b))
def get_limits(data, typ):
&#34;&#34;&#34;
Beim erstellen von Diagrammen zu mehreren Instituten oder Konzepten kann man wählen,
ob die erstellten Diagramme die selbe Scalierung haben sollen. Um dies zu tun brauchen
wir das Minimum und Maximum der Grafen.
:param data:
:param typ: IST oder/und SOLL
:return: Minimum, Maximum, Steps
&#34;&#34;&#34;
tmp_min = 0
tmp_max = 0
for konzeptname, konzept in data.items():
for institute, values in konzept.items():
if typ == &#34;IST &amp; SOLL&#34;:
for z in values:
if z.betrag &gt; tmp_max:
tmp_max = z.betrag
if z.betrag &lt; tmp_min:
tmp_min = z.betrag
else:
for z in values:
if z.betrag &gt; tmp_max and z.type == typ:
tmp_max = z.betrag
if z.betrag &lt; tmp_min and z.type == typ:
tmp_min = z.betrag
tmp_min = int(tmp_min)
tmp_max = int(tmp_max)
tmp_range = tmp_max - tmp_min
tmp_steps = int(math.pow(10, int(math.log10(tmp_range))-1))
while tmp_min % tmp_steps:
tmp_min -= 1
while tmp_max % tmp_steps:
tmp_max += 1
tmp_steps *= 5
return tmp_min, tmp_max, tmp_steps
def get_inflation_indices():
&#34;&#34;&#34;
liest die Inflationsdaten aus der entsprechenden Excell-tabelle ein und gibt sie als Dictionary zurück
:return: Dictionary
&#34;&#34;&#34;
dct_preisindices = {}
wb = load_workbook(&#34;../Finanzexplorer-Git-data/verbraucherpreisindex-lange-reihen-xlsx-5611103.xlsx&#34;, data_only=True)
ws = wb[&#34;JD_Index&#34;]
for row in range(6, 49):
cell = ws.cell(row, 1).value
dct_preisindices[int(cell[:4])] = float(ws.cell(row, 6).value / 100)
for row in range(51, 60):
cell = ws.cell(row, 1).value
dct_preisindices[int(cell[:4])] = float(ws.cell(row, 6).value / 100)
return dct_preisindices
no_trace = [&#34;calculate_zwischensumme&#34;, &#34;set_cellvalue&#34;, &#34;set_hierarchie&#34;, &#34;__init__&#34;, &#34;on_mouse_over&#34;, &#34;&lt;lambda&gt;&#34;, &#34;&lt;listcomp&gt;&#34;, &#34;clamp&#34;]
def tracefunc(frame, event, arg, indent=[0]):
if &#34;Finanzexplorer_model&#34; in frame.f_code.co_filename or &#34;Finanzexplorer_Institute&#34; in frame.f_code.co_filename:
if frame.f_code.co_name not in no_trace and (&#34;get&#34; not in frame.f_code.co_name or frame.f_code.co_name == &#34;new_get_konzept&#34;):
if event == &#34;call&#34;:
dev_function_stack.append(frame.f_code.co_name)
indent[0] += 2
if develope_mode:
print(&#34;-&#34; * indent[0] + &#34;&gt; call function&#34;, frame.f_code.co_name + &#34; (&#34; + str(frame.f_lineno) + &#34;)&#34;)
elif event == &#34;return&#34;:
dev_function_stack.append(frame.f_code.co_name)
if develope_mode:
print(&#34;&lt;&#34; + &#34;-&#34; * indent[0], &#34;exit function&#34;, frame.f_code.co_name + &#34; (&#34; + str(frame.f_lineno) + &#34;)&#34;)
indent[0] -= 2
return tracefunc
import sys
sys.setprofile(tracefunc)
# create a directory &#39;Saves&#39; next to the Platypus-file ( hopefully ;) )
os.makedirs(&#34;../Saves&#34;, exist_ok=True)
app = wx.App(False)
frame = InstitutsForm()
init_frame = DialogRechnungstypInit(None, &#34;Start with ..&#34;)
init_frame.Destroy()
dct_preisindices = get_inflation_indices()
app.MainLoop()
if develope_mode:
with open(&#39;gephi_nodes.csv&#39;, mode=&#39;w&#39;) as csv_file:
csv_writer = csv.writer(csv_file, delimiter=&#39;,&#39;)
line_count = 0
csv_writer.writerow([&#39;Source&#39;,&#39;Target&#39;])
for i, x in enumerate(dev_function_stack[1:]):
csv_writer.writerow([str(dev_function_stack[i-1]), x])
print(&#34;Process finished with exit code 0&#34;)</code></pre>
</details>
</section>
<section>
</section>
<section>
</section>
<section>
<h2 class="section-title" id="header-functions">Functions</h2>
<dl>
<dt id="Finanzexplorer_Institute.fresh_new_start"><code class="name flex">
<span>def <span class="ident">fresh_new_start</span></span>(<span>)</span>
</code></dt>
<dd>
<section class="desc"><p>Alles wird gelöscht, um neu beginnen zu können.</p></section>
<details class="source">
<summary>Source code</summary>
<pre><code class="python">def fresh_new_start():
&#34;&#34;&#34;
Alles wird gelöscht, um neu beginnen zu können.
&#34;&#34;&#34;
global dct_cells
model.dct_Kategorien = {}
model.dct_Posten = {}
model.dct_categorierelations = OrderedDict()
model.dct_Schemata = OrderedDict()
model.dct_cells = {}
dct_cells = {}
frame.myGrid.erase_grid()</code></pre>
</details>
</dd>
<dt id="Finanzexplorer_Institute.get_inflation_indices"><code class="name flex">
<span>def <span class="ident">get_inflation_indices</span></span>(<span>)</span>
</code></dt>
<dd>
<section class="desc"><p>liest die Inflationsdaten aus der entsprechenden Excell-tabelle ein und gibt sie als Dictionary zurück
:return: Dictionary</p></section>
<details class="source">
<summary>Source code</summary>
<pre><code class="python">def get_inflation_indices():
&#34;&#34;&#34;
liest die Inflationsdaten aus der entsprechenden Excell-tabelle ein und gibt sie als Dictionary zurück
:return: Dictionary
&#34;&#34;&#34;
dct_preisindices = {}
wb = load_workbook(&#34;../Finanzexplorer-Git-data/verbraucherpreisindex-lange-reihen-xlsx-5611103.xlsx&#34;, data_only=True)
ws = wb[&#34;JD_Index&#34;]
for row in range(6, 49):
cell = ws.cell(row, 1).value
dct_preisindices[int(cell[:4])] = float(ws.cell(row, 6).value / 100)
for row in range(51, 60):
cell = ws.cell(row, 1).value
dct_preisindices[int(cell[:4])] = float(ws.cell(row, 6).value / 100)
return dct_preisindices</code></pre>
</details>
</dd>
<dt id="Finanzexplorer_Institute.get_limits"><code class="name flex">
<span>def <span class="ident">get_limits</span></span>(<span>data, typ)</span>
</code></dt>
<dd>
<section class="desc"><p>Beim erstellen von Diagrammen zu mehreren Instituten oder Konzepten kann man wählen,
ob die erstellten Diagramme die selbe Scalierung haben sollen. Um dies zu tun brauchen
wir das Minimum und Maximum der Grafen.</p>
<p>:param data:
:param typ: IST oder/und SOLL
:return: Minimum, Maximum, Steps</p></section>
<details class="source">
<summary>Source code</summary>
<pre><code class="python">def get_limits(data, typ):
&#34;&#34;&#34;
Beim erstellen von Diagrammen zu mehreren Instituten oder Konzepten kann man wählen,
ob die erstellten Diagramme die selbe Scalierung haben sollen. Um dies zu tun brauchen
wir das Minimum und Maximum der Grafen.
:param data:
:param typ: IST oder/und SOLL
:return: Minimum, Maximum, Steps
&#34;&#34;&#34;
tmp_min = 0
tmp_max = 0
for konzeptname, konzept in data.items():
for institute, values in konzept.items():
if typ == &#34;IST &amp; SOLL&#34;:
for z in values:
if z.betrag &gt; tmp_max:
tmp_max = z.betrag
if z.betrag &lt; tmp_min:
tmp_min = z.betrag
else:
for z in values:
if z.betrag &gt; tmp_max and z.type == typ:
tmp_max = z.betrag
if z.betrag &lt; tmp_min and z.type == typ:
tmp_min = z.betrag
tmp_min = int(tmp_min)
tmp_max = int(tmp_max)
tmp_range = tmp_max - tmp_min
tmp_steps = int(math.pow(10, int(math.log10(tmp_range))-1))
while tmp_min % tmp_steps:
tmp_min -= 1
while tmp_max % tmp_steps:
tmp_max += 1
tmp_steps *= 5
return tmp_min, tmp_max, tmp_steps</code></pre>
</details>
</dd>
<dt id="Finanzexplorer_Institute.get_saves"><code class="name flex">
<span>def <span class="ident">get_saves</span></span>(<span>)</span>
</code></dt>
<dd>
<section class="desc"><p>:return: saves_path = Liste von Pfaden zu den
Dateien aus dem Ordner 'Saves'</p></section>
<details class="source">
<summary>Source code</summary>
<pre><code class="python">def get_saves():
&#34;&#34;&#34;
:return: saves_path = Liste von Pfaden zu den Dateien aus dem Ordner &#39;Saves&#39;
&#34;&#34;&#34;
saves_path = {}
for (dirpath, dirnames, filenames) in os.walk(&#34;../../../Saves&#34;):
filenames = [x for x in filenames]
for f in filenames:
filepath = os.path.join(dirpath, f)
try:
if &#34;rechnungstyp&#34; in open(filepath).read():
saves_path[f] = filepath
except UnicodeDecodeError:
pass
return saves_path</code></pre>
</details>
</dd>
<dt id="Finanzexplorer_Institute.import_inst_template"><code class="name flex">
<span>def <span class="ident">import_inst_template</span></span>(<span>)</span>
</code></dt>
<dd>
<section class="desc"><p>Anhand des Excell-Templates wird für jedes relevante Arbeitsblatt (also nicht das Synthese-Blatt)
die erste Spalte eingelesen und im Grid des Interface eins zu eins übertragen. Jede Spalte im Grid repräsentiert
also ein Arbeitsblatt.</p>
<p>Sonderfall Arbeitsblatt "1954-1963": In diesem Jahr tauchen die Einnahmen mehrmals auf. Die Zeilen sind verborgen,
aber es gibt einen sprung zwischen Zeile 13 und 54. Die Idee war damals mehrere Abteilungen (mit einzelnen
Haushaltsplänen) eines Instituts auch in einer Excelldatei zu speichern. Diese Idee wurde jedoch verworfen.</p>
<p>:return: no return :/</p></section>
<details class="source">
<summary>Source code</summary>
<pre><code class="python">def import_inst_template():
&#34;&#34;&#34;
Anhand des Excell-Templates wird für jedes relevante Arbeitsblatt (also nicht das Synthese-Blatt)
die erste Spalte eingelesen und im Grid des Interface eins zu eins übertragen. Jede Spalte im Grid repräsentiert
also ein Arbeitsblatt.
Sonderfall Arbeitsblatt &#34;1954-1963&#34;: In diesem Jahr tauchen die Einnahmen mehrmals auf. Die Zeilen sind verborgen,
aber es gibt einen sprung zwischen Zeile 13 und 54. Die Idee war damals mehrere Abteilungen (mit einzelnen
Haushaltsplänen) eines Instituts auch in einer Excelldatei zu speichern. Diese Idee wurde jedoch verworfen.
:return: no return :/
&#34;&#34;&#34;
wb = load_workbook(&#34;../Finanzexplorer-Git-data/Institute/Haushaltsbücher_MPI_Template.xlsx&#34;, data_only=True)
grid_col = 0
for s in range(len(wb.sheetnames)):
if wb.sheetnames[s] == &#34;1954-1963&#34;: # Sonderregel für dieses Sheet,
# da im Template die Einnahmen mehrmals auftauchen
wb.active = s
sheet = wb.active
frame.myGrid.SetColLabelValue(grid_col, sheet.title)
for row in range(1, 14):
if sheet.cell(row, 1).value:
this_cell = Cell(row, grid_col, sheet.cell(row, 1).value)
if sheet.cell(row, grid_col+1).fill.start_color.index == &#34;00000000&#34;:
frame.myGrid.SetCellBackgroundColour(row, grid_col, &#34;#cccccc&#34;)
this_cell.color = &#34;#cccccc&#34;
dct_cells[(row, grid_col)] = this_cell
frame.myGrid.set_cellvalue((row, grid_col), sheet.cell(row, 1).value)
for row in range(56, 200):
if sheet.cell(row, 1).value:
this_cell = Cell(row, grid_col, sheet.cell(row, 1).value)
if sheet.cell(row, grid_col+1).fill.start_color.index == &#34;00000000&#34;:
frame.myGrid.SetCellBackgroundColour(row, grid_col, &#34;#cccccc&#34;)
this_cell.color = &#34;#cccccc&#34;
dct_cells[(row, grid_col)] = this_cell
frame.myGrid.set_cellvalue((row, grid_col), sheet.cell(row, 1).value)
grid_col += 1
elif wb.sheetnames[s][0] == &#34;1&#34;:
wb.active = s
sheet = wb.active
frame.myGrid.SetColLabelValue(grid_col, sheet.title)
for row in range(1, 200):
if sheet.cell(row, 1).value:
this_cell = Cell(row, grid_col, sheet.cell(row, 1).value)
frame.myGrid.set_cellvalue((row, grid_col), sheet.cell(row, 1).value)
if sheet.cell(row, grid_col+1).fill.start_color.index == &#34;00000000&#34;:
frame.myGrid.SetCellBackgroundColour(row, grid_col, &#34;#cccccc&#34;)
this_cell.color = &#34;#cccccc&#34;
dct_cells[(row, grid_col)] = this_cell
grid_col += 1
frame.myGrid.ForceRefresh()</code></pre>
</details>
</dd>
<dt id="Finanzexplorer_Institute.import_mpg_gesamt_data"><code class="name flex">
<span>def <span class="ident">import_mpg_gesamt_data</span></span>(<span>)</span>
</code></dt>
<dd>
<section class="desc"><p>Importiert die Daten aus den CSV-Dateien (aus der Finanz-DB):
Kategorien:
Posten: <a href="http://gmpg-intern.mpiwg-berlin.mpg.de:8888/explorer/525/">http://gmpg-intern.mpiwg-berlin.mpg.de:8888/explorer/525/</a>
Kategorierelationen: <a href="http://gmpg-intern.mpiwg-berlin.mpg.de:8888/explorer/526/">http://gmpg-intern.mpiwg-berlin.mpg.de:8888/explorer/526/</a>
Schemata:</p>
<p>Hierarchie der Kategorien innerhalb eines Schemas wird festgelegt.</p>
<p>:return: no return :/</p></section>
<details class="source">
<summary>Source code</summary>
<pre><code class="python">def import_mpg_gesamt_data():
&#34;&#34;&#34;
Importiert die Daten aus den CSV-Dateien (aus der Finanz-DB):
Kategorien:
Posten: http://gmpg-intern.mpiwg-berlin.mpg.de:8888/explorer/525/
Kategorierelationen: http://gmpg-intern.mpiwg-berlin.mpg.de:8888/explorer/526/
Schemata:
Hierarchie der Kategorien innerhalb eines Schemas wird festgelegt.
:return: no return :/
&#34;&#34;&#34;
model.import_kategorien()
model.import_posten()
model.import_kategorierelations()
model.import_schemata()
for year in range(1948, 2006):
for schema in model.get_dct_schemata().values():
if schema.jahr == year:
for x in model.superkategorien:
set_hierarchie(schema.id, x)
new_schemata = []
last_schema = None
for year in range(1948, 2006):
has_schema = False
for schema in model.get_dct_schemata().values():
if schema.jahr == year:
last_schema = copy.copy(schema)
has_schema = True
if not has_schema and last_schema:
new_schema = copy.deepcopy(last_schema)
new_schema.id += 1000
new_schema.jahr = year
new_schemata.append(new_schema)
last_schema = new_schema
for new in new_schemata:
model.get_dct_schemata()[new.id] = new</code></pre>
</details>
</dd>
<dt id="Finanzexplorer_Institute.line_plot_gesamt"><code class="name flex">
<span>def <span class="ident">line_plot_gesamt</span></span>(<span>dct_konzepte, mode, xshow=True)</span>
</code></dt>
<dd>
<section class="desc"><p>Ein Diagramm für die MPG-Gesamt wird erzeugt und je nach 'xshow' gespeichert oder direkt angezeigt.</p>
<p>:param dct_konzepte: Kanzeptdaten als Dict gespeichert.
:param mode: Nur relevant, wenn bereits gespeicherte Konzepte, die nicht geladen wurden, geplottet werden sollen.
:param xshow: Bool. Die Funktion wird auch aufgerufen, wenn z.B. ein Report erstellt werden soll. in dem Fall soll
der Plot nicht angezeigt werden (False), sondern nur das Diagramm erzeugt und gespeichert werden (True).
:return:'temp_chart.png', nur wenn xshow == False.</p></section>
<details class="source">
<summary>Source code</summary>
<pre><code class="python">def line_plot_gesamt(dct_konzepte, mode, xshow=True):
&#34;&#34;&#34;
Ein Diagramm für die MPG-Gesamt wird erzeugt und je nach &#39;xshow&#39; gespeichert oder direkt angezeigt.
:param dct_konzepte: Kanzeptdaten als Dict gespeichert.
:param mode: Nur relevant, wenn bereits gespeicherte Konzepte, die nicht geladen wurden, geplottet werden sollen.
:param xshow: Bool. Die Funktion wird auch aufgerufen, wenn z.B. ein Report erstellt werden soll. in dem Fall soll
der Plot nicht angezeigt werden (False), sondern nur das Diagramm erzeugt und gespeichert werden (True).
:return:&#39;temp_chart.png&#39;, nur wenn xshow == False.
&#34;&#34;&#34;
legend = []
fig = plt.figure()
# User fragen, ob der Plot Inflationsbereinigt sein soll oder nicht.
bool_inflation = False
msg = &#34;Do you want this plot adjusted for inflation?&#34;
dlg = wx.MessageDialog(None, msg, &#39;Inflation&#39;, style=wx.YES_NO | wx.CANCEL | wx.CENTRE)
result = dlg.ShowModal()
if result == wx.ID_YES:
bool_inflation = True
elif result == 5101:
return
else:
pass
# um &#34;Nicht-Rechnungstypkonforme&#34; Konzepte zu plotten------------------------------
if len(frame.checkbox.GetCheckedItems()) != 0:
checked_institutes_paths = []
for x in frame.checkbox.GetCheckedItems():
checked_institutes_paths.append([x for x in get_saves().values()][x])
for path in checked_institutes_paths:
with open(path) as infile:
dct_infile = json.load(infile)
for konzeptname, konzept_obj in dct_infile.items():
if len(konzept_obj[&#34;plots&#34;].items()) == 1:
color = konzept_obj[&#34;color&#34;]
else:
color = None
if mode == 1 and konzept_obj[&#34;rechnungstyp&#34;] == &#34;INST&#34;:
# mode 1: Die Summe der einzelnen Institute in einer gespeicherten Datei wird angezeigt.
x = []
y = []
konzept_obj[&#34;plots&#34;][&#34;SUMME&#34;].sort(key=lambda x: x[0]) # nach Jahreszahlen (x[0]) sortieren
for data in konzept_obj[&#34;plots&#34;][&#34;SUMME&#34;]:
if len(data) &gt; 2:
if data[2] == &#34;IST&#34;:
if bool_inflation:
if data[0] &lt;= 1999:
x.append(data[0])
y.append(data[1] / dct_preisindices[data[0]])
else:
x.append(data[0])
y.append(data[1])
else:
if bool_inflation:
if data[0] &lt;= 1999:
x.append(data[0])
y.append(data[1] / dct_preisindices[data[0]])
else:
x.append(data[0])
y.append(data[1])
plt.plot(x, y, color=color)
if (konzept_obj[&#34;rechnungstyp&#34;] in [&#34;EA&#34;, &#34;VÜ&#34;] and model.RECHNUNGSTYP in [&#34;EA&#34;, &#34;VÜ&#34;]) or \
(konzept_obj[&#34;rechnungstyp&#34;] == &#34;INST&#34; and model.RECHNUNGSTYP == &#34;INST&#34;):
legend.append(konzeptname)
else:
legend.append(&#34;SUMME - &#34; + konzeptname)
elif mode == 2:
# mode2: Die einzelnen Institute aus den ausgewählten gespeicherten Dateien werden angezeigt.
for institute, values in konzept_obj[&#34;plots&#34;].items():
if institute != &#34;SUMME&#34;:
x = []
y = []
values.sort(key=lambda x: x[0]) # nach Jahreszahlen (x[0]) sortieren
for data in values:
if len(data) &gt; 2:
if data[2] == &#34;IST&#34;:
if bool_inflation:
if data[0] &lt;= 1999:
x.append(data[0])
y.append(data[1] / dct_preisindices[data[0]])
else:
x.append(data[0])
y.append(data[1])
else:
if bool_inflation:
if data[0] &lt;= 1999:
x.append(data[0])
y.append(data[1] / dct_preisindices[data[0]])
else:
x.append(data[0])
y.append(data[1])
plt.plot(x, y, color=color)
if (konzept_obj[&#34;rechnungstyp&#34;] in [&#34;EA&#34;, &#34;VÜ&#34;] and model.RECHNUNGSTYP in [&#34;EA&#34;, &#34;VÜ&#34;]) or \
(konzept_obj[&#34;rechnungstyp&#34;] == &#34;INST&#34; and model.RECHNUNGSTYP == &#34;INST&#34;):
legend.append(konzeptname)
else:
legend.append(institute + &#34; - &#34; + konzeptname)
elif mode == 3:
# mode 3: Summe und einzelne Institute werden angezeigt. Summe jeweils pro gespeicherte Datei!
for institute, values in konzept_obj[&#34;plots&#34;].items():
x = []
y = []
values.sort(key=lambda x: x[0]) # nach Jahreszahlen (x[0]) sortieren
for data in values:
if len(data) &gt; 2:
if data[2] == &#34;IST&#34;:
if bool_inflation:
if data[0] &lt;= 1999:
x.append(data[0])
y.append(data[1] / dct_preisindices[data[0]])
else:
x.append(data[0])
y.append(data[1])
else:
if bool_inflation:
if data[0] &lt;= 1999:
x.append(data[0])
y.append(data[1] / dct_preisindices[data[0]])
else:
x.append(data[0])
y.append(data[1])
plt.plot(x, y, color=color)
if (konzept_obj[&#34;rechnungstyp&#34;] in [&#34;EA&#34;, &#34;VÜ&#34;] and model.RECHNUNGSTYP in [&#34;EA&#34;, &#34;VÜ&#34;]) or \
(konzept_obj[&#34;rechnungstyp&#34;] == &#34;INST&#34; and model.RECHNUNGSTYP == &#34;INST&#34;):
legend.append(konzeptname)
else:
legend.append(institute + &#34; - &#34; + konzeptname)
# --------------------------------------------------------------------------------
for key, lst in dct_konzepte.items():
color = frame.konzepte[key].color
values = []
if bool_inflation:
for x in lst:
# prevent deviding a nonetype
if x[1] is None and x[0] &lt;= 1999:
values.append(None)
elif x[0] &lt;= 1999:
values.append(x[1] / dct_preisindices[x[0]] / 1000000)
plt.plot([x[0] for x in lst if x[0] &lt;= 1999], values, color=color)
else:
for x in lst:
values.append(x[1] / 1000000)
plt.plot([x[0] for x in lst], values, color=color)
plt.grid(linewidth=&#39;0.2&#39;)
legend.append(key)
plt.ticklabel_format(style=&#34;plain&#34;)
plt.xlim(1945, 2005)
bottom, top = plt.ylim()
plt.ylim(0, top)
plt.legend(legend)
plt.ylabel(&#34;Beträge in mio. DM&#34;)
plt.xlabel(&#34;Jahre&#34;)
if bool_inflation:
plt.title(&#34;Inflationsbereinigt&#34;)
else:
plt.title(&#34;Title&#34;)
if xshow:
plt.show()
else:
plt.savefig(&#39;testchart.png&#39;, format=&#39;png&#39;, dpi=fig.dpi * 2)
return &#39;temp_chart.png&#39;</code></pre>
</details>
</dd>
<dt id="Finanzexplorer_Institute.line_plot_gesamt_settings"><code class="name flex">
<span>def <span class="ident">line_plot_gesamt_settings</span></span>(<span>xshow=True)</span>
</code></dt>
<dd>
<section class="desc"></section>
<details class="source">
<summary>Source code</summary>
<pre><code class="python">def line_plot_gesamt_settings(xshow=True):
if len(frame.checkbox.GetCheckedItems()) != 0:
checked_saves_paths = []
for x in frame.checkbox.GetCheckedItems():
checked_saves_paths.append([x for x in get_saves().values()][x])
dlg = DialogGesamtPlotSettings(frame, &#34;plot Settings&#34;, checked_saves_paths).ShowModal()
else:
line_plot_gesamt(frame.new_get_konzept(), mode=0, xshow=xshow)</code></pre>
</details>
</dd>
<dt id="Finanzexplorer_Institute.line_plot_inst"><code class="name flex">
<span>def <span class="ident">line_plot_inst</span></span>(<span>data, typ, grouping_by, mode, inflation, xshow=True)</span>
</code></dt>
<dd>
<section class="desc"></section>
<details class="source">
<summary>Source code</summary>
<pre><code class="python">def line_plot_inst(data, typ, grouping_by, mode, inflation, xshow=True):
ymin, ymax, steps = get_limits(data, typ)
fig = plt.figure()
plt.close()
if frame.checkbox_sum.GetValue():
ax = {}
for ex_institute in data.values(): # Bsp-Institut, um die Anzahl der Konzepte und Größe des Plot zu setzen
if len(frame.konzepte.keys()) &gt; 4:
for count, konzeptname in enumerate(ex_institute.keys()):
rows = len(ex_institute.keys()) / 2
rows = int(rows) + 1 if rows % 1 != 0 else int(rows)
if count &gt; rows - 1:
ax[konzeptname] = plt.subplot2grid((rows, 2), (count - rows, 1), rowspan=1, colspan=1)
else:
ax[konzeptname] = plt.subplot2grid((rows, 2), (count, 0), rowspan=1, colspan=1)
else:
count = 0
for konzeptname in ex_institute.keys():
ax[konzeptname] = plt.subplot2grid((len(ex_institute.keys()) * 10, 1),
(count, 0), rowspan=8, colspan=1)
count += 10
# dictionary mit den Werten 0 erzeugen
dct_konzepte = {}
for instname, konzepte in data.items():
for konzeptname, ex_cells in konzepte.items():
dct_konzepte[konzeptname] = {}
for x in range(1954, 2003):
dct_konzepte[konzeptname][x] = 0
# User fragen, ob der Plot Inflationsbereinigt sein soll oder nicht.
bool_inflation = False
msg = &#34;Do you want this plot adjusted for inflation?&#34;
dlg = wx.MessageDialog(None, msg, &#39;Inflation&#39;, style=wx.YES_NO | wx.CANCEL | wx.CENTRE)
result = dlg.ShowModal()
if result == wx.ID_YES:
bool_inflation = True
elif result == 5101:
return
else:
pass
# auf jeden dict-wert den aktuellen Betrag draufaddieren
dct_legend_set = defaultdict(set)
for instname, konzepte in data.items():
for konzeptname, ex_cells in konzepte.items():
for x in ex_cells:
if x.type == typ:
if bool_inflation and x.year &lt;= 1999:
dct_konzepte[konzeptname][x.year] += x.inflationsbereinigt
else:
dct_konzepte[konzeptname][x.year] += x.betrag
dct_legend_set[konzeptname].add(instname)
for konzeptname, year in dct_konzepte.items():
ax[konzeptname].plot(year.keys(), year.values(), color=frame.konzepte[konzeptname].color)
ax[konzeptname].grid(linewidth=&#39;0.2&#39;)
ax[konzeptname].ticklabel_format(style=&#34;plain&#34;)
for konzeptname, instnames in dct_legend_set.items():
tmp = [&#34; + &#34;.join(instnames), ]
ax[konzeptname].legend(tmp)
ax[konzeptname].set_title(konzeptname.upper(), pad=1)
# ------------------------------
else:
if grouping_by == &#34;Institute&#34;:
ax = {}
if len(frame.checkbox.GetCheckedItems()) &gt; 4:
for count, instname in enumerate(data.keys()):
rows = len(data.keys()) / 2
rows = int(rows) + 1 if rows % 1 != 0 else int(rows)
if count &gt; rows - 1:
ax[instname] = plt.subplot2grid((rows, 2), (count - rows, 1), rowspan=1, colspan=1)
else:
ax[instname] = plt.subplot2grid((rows, 2), (count, 0), rowspan=1, colspan=1)
else:
count = 0
for instname in data.keys():
ax[instname] = plt.subplot2grid((len(data.keys()) * 10, 1), (count, 0), rowspan=8, colspan=1)
count += 10
for instname, inst in data.items():
legend = []
for key, kon in inst.items():
color = frame.konzepte[key].color
if typ == &#34;IST &amp; SOLL&#34;:
if inflation:
ax[instname].plot([x.year for x in kon if x.type == &#34;IST&#34; and x.year &lt;= 1999],
[y.inflationsbereinigt for y in kon if y.type == &#34;IST&#34; and y.year &lt;= 1999],
color=color)
legend.append(key + &#34; (IST)&#34;)
ax[instname].plot([x.year for x in kon if x.type == &#34;SOLL&#34; and x.year &lt;= 1999],
[y.inflationsbereinigt for y in kon if y.type == &#34;SOLL&#34; and y.year &lt;= 1999],
color=&#34;#cccccc&#34;)
legend.append(key + &#34; (SOLL)&#34;)
else:
ax[instname].plot([x.year for x in kon if x.type == &#34;IST&#34;],
[y.betrag for y in kon if y.type == &#34;IST&#34;],
color=color)
legend.append(key + &#34; (IST)&#34;)
ax[instname].plot([x.year for x in kon if x.type == &#34;SOLL&#34;],
[y.betrag for y in kon if y.type == &#34;SOLL&#34;],
color=&#34;#cccccc&#34;)
legend.append(key + &#34; (SOLL)&#34;)
else:
if inflation:
ax[instname].plot([x.year for x in kon if x.type == typ and x.year &lt;= 1999],
[y.inflationsbereinigt for y in kon if y.type == typ and y.year &lt;= 1999],
color=color)
else:
ax[instname].plot([x.year for x in kon if x.type == typ],
[y.betrag for y in kon if y.type == typ],
color=color)
legend.append(key)
ax[instname].set_title(instname.upper(), pad=1)
ax[instname].ticklabel_format(style=&#34;plain&#34;)
ax[instname].set_xticks([x for x in range(1945, 2010, 5)])
ax[instname].grid(linewidth=&#39;0.2&#39;)
if mode == &#34;compareable&#34;:
ax[instname].set_yticks([y for y in range(ymin, ymax, steps)])
ax[instname].legend(legend)
elif grouping_by == &#34;Konzept&#34;:
ax = {}
legend = defaultdict(list)
for ex_institute in data.values(): # Bsp-Institut, um die Anzahl der Konzepte und Größe des Plot zu setzen
if len(frame.konzepte.keys()) &gt; 4:
for count, konzeptname in enumerate(ex_institute.keys()):
rows = len(ex_institute.keys()) / 2
rows = int(rows) + 1 if rows % 1 != 0 else int(rows)
if count &gt; rows - 1:
ax[konzeptname] = plt.subplot2grid((rows, 2), (count - rows, 1), rowspan=1, colspan=1)
else:
ax[konzeptname] = plt.subplot2grid((rows, 2), (count, 0), rowspan=1, colspan=1)
else:
count = 0
for konzeptname in ex_institute.keys():
ax[konzeptname] = plt.subplot2grid((len(ex_institute.keys()) * 10, 1),
(count, 0), rowspan=8, colspan=1)
count += 10
for instname, inst in data.items():
for key, kon in inst.items():
# color = frame.konzepte[key].color
if typ == &#34;IST &amp; SOLL&#34;:
if inflation:
ax[key].plot([x.year for x in kon if x.type == &#34;IST&#34; and x.year &lt;= 1999],
[y.inflationsbereinigt for y in kon if y.type == &#34;IST&#34; and y.year &lt;= 1999])
legend[key].append(instname + &#34; (IST)&#34;)
ax[key].plot([x.year for x in kon if x.type == &#34;SOLL&#34; and x.year &lt;= 1999],
[y.inflationsbereinigt for y in kon if y.type == &#34;SOLL&#34; and y.year &lt;= 1999],
color=&#34;#cccccc&#34;)
legend[key].append(instname + &#34; (SOLL)&#34;)
else:
ax[key].plot([x.year for x in kon if x.type == &#34;IST&#34;],
[y.betrag for y in kon if y.type == &#34;IST&#34;])
legend[key].append(instname + &#34; (IST)&#34;)
ax[key].plot([x.year for x in kon if x.type == &#34;SOLL&#34;],
[y.betrag for y in kon if y.type == &#34;SOLL&#34;],
color=&#34;#cccccc&#34;)
legend[key].append(instname + &#34; (SOLL)&#34;)
else:
if inflation:
ax[key].plot([x.year for x in kon if x.type == typ and x.year &lt;= 1999],
[y.inflationsbereinigt for y in kon if y.type == typ and y.year &lt;= 1999])
legend[key].append(instname)
else:
ax[key].plot([x.year for x in kon if x.type == typ],
[y.betrag for y in kon if y.type == typ])
legend[key].append(instname)
ax[key].set_title(key.upper(), pad=1)
ax[key].ticklabel_format(style=&#34;plain&#34;)
ax[key].set_xticks([x for x in range(1945, 2010, 5)])
ax[key].grid(linewidth=&#39;0.2&#39;)
if mode == &#34;compareable&#34;:
ax[key].set_yticks([y for y in range(ymin, ymax, steps)])
for key in legend.keys():
ax[key].legend(legend[key])
# --------------------------
if xshow:
plt.show()
else:
plt.savefig(&#39;testchart.png&#39;, format=&#39;png&#39;, dpi=fig.dpi * 2)
return &#39;testchart.png&#39;</code></pre>
</details>
</dd>
<dt id="Finanzexplorer_Institute.populate_cells"><code class="name flex">
<span>def <span class="ident">populate_cells</span></span>(<span>)</span>
</code></dt>
<dd>
<section class="desc"><p>Zellen im Grid werden nach Vorlage der Hierarchie im Schema befüllt.</p></section>
<details class="source">
<summary>Source code</summary>
<pre><code class="python">def populate_cells():
&#34;&#34;&#34;
Zellen im Grid werden nach Vorlage der Hierarchie im Schema befüllt.
&#34;&#34;&#34;
col = -1
for year in range(1948, 2006):
for schema in model.get_dct_schemata().values():
if schema.jahr == year:
row = 0
col += 1
frame.myGrid.SetColLabelValue(col, str(schema.jahr))
for kategorie_in_Hierarchie in schema.kategorien_hierarchisch:
row += 1
temp = model.Cell(row, col, kategorie_in_Hierarchie, schema.jahr)
model.get_dct_cells()[(row, col)] = temp
model.get_dct_schemata()[schema.id].cells.add(temp)
for cell in model.get_dct_cells().values():
cell.calculate_zwischensumme()
frame.myGrid.set_cellvalue(cell.get_pos(), str(cell.value[1]) + cell.value[0].bezeichnung)</code></pre>
</details>
</dd>
<dt id="Finanzexplorer_Institute.rgb_to_hex"><code class="name flex">
<span>def <span class="ident">rgb_to_hex</span></span>(<span>rgb)</span>
</code></dt>
<dd>
<section class="desc"><p>wandelt einen rgb-Farbcode in einen Hex-Farbcode um:</p>
<p>:param rgb: Drei Werte zwischen 0 und 255
:return: hex, z.B. "#ffffff"</p></section>
<details class="source">
<summary>Source code</summary>
<pre><code class="python">def rgb_to_hex(rgb):
&#34;&#34;&#34;
wandelt einen rgb-Farbcode in einen Hex-Farbcode um:
:param rgb: Drei Werte zwischen 0 und 255
:return: hex, z.B. &#34;#ffffff&#34;
&#34;&#34;&#34;
r, g, b = rgb[:3]
def clamp(x):
return max(0, min(x, 255))
return &#34;#{0:02x}{1:02x}{2:02x}&#34;.format(clamp(r), clamp(g), clamp(b))</code></pre>
</details>
</dd>
<dt id="Finanzexplorer_Institute.set_hierarchie"><code class="name flex">
<span>def <span class="ident">set_hierarchie</span></span>(<span>schema_id, oberkategorie_id)</span>
</code></dt>
<dd>
<section class="desc"><p>Jedes Schema bekommt eine Liste ('kategorien_hierarchisch') mit Tuples bestehend aus 3 Werten: (1. Kategorie-Obj,
2. Folge von '-' zur Markierung der Hierarchie-Ebene, 3. Oberkategorie (Kategorie-Obj) von &lt;1. Kategorie-Obj&gt;).</p>
<p>Zunächst wird diese Funktion für jede einzelne Superkategorie als Parameter (oberkategorie_id) aufgerufen. Ausgehend
von diesen 'wanderd' die Funktion rekursiv durch den gesamten Strukturbaum.</p>
<p>Superkategorien sind "Einnahmen", "Ausgaben", "Aktiva" und "Passiva", also die oberste Hierarchie-Ebene.</p>
<p>:param schema_id: ID zum ansteuern des richigen Schemata aus Finanzexplorer_model.py
:param oberkategorie_id: ID der jeweiligen Oberkategorie.
:return: no return :/</p></section>
<details class="source">
<summary>Source code</summary>
<pre><code class="python">def set_hierarchie(schema_id, oberkategorie_id):
&#34;&#34;&#34;
Jedes Schema bekommt eine Liste (&#39;kategorien_hierarchisch&#39;) mit Tuples bestehend aus 3 Werten: (1. Kategorie-Obj,
2. Folge von &#39;-&#39; zur Markierung der Hierarchie-Ebene, 3. Oberkategorie (Kategorie-Obj) von &lt;1. Kategorie-Obj&gt;).
Zunächst wird diese Funktion für jede einzelne Superkategorie als Parameter (oberkategorie_id) aufgerufen. Ausgehend
von diesen &#39;wanderd&#39; die Funktion rekursiv durch den gesamten Strukturbaum.
Superkategorien sind &#34;Einnahmen&#34;, &#34;Ausgaben&#34;, &#34;Aktiva&#34; und &#34;Passiva&#34;, also die oberste Hierarchie-Ebene.
:param schema_id: ID zum ansteuern des richigen Schemata aus Finanzexplorer_model.py
:param oberkategorie_id: ID der jeweiligen Oberkategorie.
:return: no return :/
&#34;&#34;&#34;
if oberkategorie_id in model.superkategorien:
model.get_dct_schemata()[schema_id].kategorien_hierarchisch.append(
(model.get_dct_kategorien()[oberkategorie_id],
len(tmp_stack) * &#34;-&#34;,
None))
tmp_stack.append(oberkategorie_id)
for kr in model.get_dct_schemata()[schema_id].KategorieRelationen:
if model.get_dct_kategorien()[kr.origin_id].id == oberkategorie_id:
model.get_dct_schemata()[schema_id].kategorien_hierarchisch.append(
(kr.target_kategorie,
len(tmp_stack) * &#34;-&#34;,
model.get_dct_kategorien()[kr.origin_id]))
set_hierarchie(schema_id, kr.target_id)
tmp_stack.pop()</code></pre>
</details>
</dd>
<dt id="Finanzexplorer_Institute.tracefunc"><code class="name flex">
<span>def <span class="ident">tracefunc</span></span>(<span>frame, event, arg, indent=[-2])</span>
</code></dt>
<dd>
<section class="desc"></section>
<details class="source">
<summary>Source code</summary>
<pre><code class="python">def tracefunc(frame, event, arg, indent=[0]):
if &#34;Finanzexplorer_model&#34; in frame.f_code.co_filename or &#34;Finanzexplorer_Institute&#34; in frame.f_code.co_filename:
if frame.f_code.co_name not in no_trace and (&#34;get&#34; not in frame.f_code.co_name or frame.f_code.co_name == &#34;new_get_konzept&#34;):
if event == &#34;call&#34;:
dev_function_stack.append(frame.f_code.co_name)
indent[0] += 2
if develope_mode:
print(&#34;-&#34; * indent[0] + &#34;&gt; call function&#34;, frame.f_code.co_name + &#34; (&#34; + str(frame.f_lineno) + &#34;)&#34;)
elif event == &#34;return&#34;:
dev_function_stack.append(frame.f_code.co_name)
if develope_mode:
print(&#34;&lt;&#34; + &#34;-&#34; * indent[0], &#34;exit function&#34;, frame.f_code.co_name + &#34; (&#34; + str(frame.f_lineno) + &#34;)&#34;)
indent[0] -= 2
return tracefunc</code></pre>
</details>
</dd>
</dl>
</section>
<section>
<h2 class="section-title" id="header-classes">Classes</h2>
<dl>
<dt id="Finanzexplorer_Institute.Cell"><code class="flex name class">
<span>class <span class="ident">Cell</span></span>
<span>(</span><span>cellrow, cellcol, value)</span>
</code></dt>
<dd>
<section class="desc"></section>
<details class="source">
<summary>Source code</summary>
<pre><code class="python">class Cell:
def __init__(self, cellrow, cellcol, value):
self.row = cellrow
self.col = cellcol
self.value = value
self.color = WHITE
self.konzept = None</code></pre>
</details>
</dd>
<dt id="Finanzexplorer_Institute.DialogGesamtPlotSettings"><code class="flex name class">
<span>class <span class="ident">DialogGesamtPlotSettings</span></span>
<span>(</span><span>parent, title, lst)</span>
</code></dt>
<dd>
<section class="desc"><p>Dialog()
Dialog(parent, id=ID_ANY, title=EmptyString, pos=DefaultPosition, size=DefaultSize, style=DEFAULT_DIALOG_STYLE, name=DialogNameStr)</p>
<p>A dialog box is a window with a title bar and sometimes a system menu,
which can be moved around the screen.</p></section>
<details class="source">
<summary>Source code</summary>
<pre><code class="python">class DialogGesamtPlotSettings(wx.Dialog):
def __init__(self, parent, title, lst):
super(DialogGesamtPlotSettings, self).__init__(parent, title=title, size=(250, 130))
self.parent = parent
self.panel = wx.Panel(self)
self.radiobutton_sum = wx.RadioButton(self.panel, -1, label=&#34;show Sum of institutes per file&#34;, style=wx.RB_GROUP)
self.radiobutton_inst = wx.RadioButton(self.panel, -1, label=&#34;show institutes seperate&#34;)
self.radiobutton_all = wx.RadioButton(self.panel, -1, label=&#34;show Sum and Institutes seperate&#34;)
self.btn = wx.Button(self.panel, -1, label=&#34;okay&#34;)
# --- Positionierung
self.sizer_top = wx.BoxSizer(wx.VERTICAL)
self.sizer_top.Add(self.radiobutton_sum)
self.sizer_top.Add(self.radiobutton_inst)
self.sizer_top.Add(self.radiobutton_all)
self.sizer_top.Add(self.btn)
self.panel.SetSizer(self.sizer_top)
self.btn.Bind(wx.EVT_BUTTON, self.create_plot)
def create_plot(self, _):
if self.radiobutton_sum.GetValue():
mode = 1
elif self.radiobutton_inst.GetValue():
mode = 2
else:
mode = 3
line_plot_gesamt(frame.new_get_konzept(), mode)
self.Close()</code></pre>
</details>
<h3>Ancestors</h3>
<ul class="hlist">
<li>wx._core.Dialog</li>
<li>wx._core.TopLevelWindow</li>
<li>wx._core.NonOwnedWindow</li>
<li>wx._core.Window</li>
<li>wx._core.WindowBase</li>
<li>wx._core.EvtHandler</li>
<li>wx._core.Object</li>
<li>wx._core.Trackable</li>
<li>sip.wrapper</li>
<li>sip.simplewrapper</li>
</ul>
<h3>Methods</h3>
<dl>
<dt id="Finanzexplorer_Institute.DialogGesamtPlotSettings.create_plot"><code class="name flex">
<span>def <span class="ident">create_plot</span></span>(<span>self, _)</span>
</code></dt>
<dd>
<section class="desc"></section>
<details class="source">
<summary>Source code</summary>
<pre><code class="python">def create_plot(self, _):
if self.radiobutton_sum.GetValue():
mode = 1
elif self.radiobutton_inst.GetValue():
mode = 2
else:
mode = 3
line_plot_gesamt(frame.new_get_konzept(), mode)
self.Close()</code></pre>
</details>
</dd>
</dl>
</dd>
<dt id="Finanzexplorer_Institute.DialogNewKonzept"><code class="flex name class">
<span>class <span class="ident">DialogNewKonzept</span></span>
<span>(</span><span>parent, title)</span>
</code></dt>
<dd>
<section class="desc"><p>Dialog()
Dialog(parent, id=ID_ANY, title=EmptyString, pos=DefaultPosition, size=DefaultSize, style=DEFAULT_DIALOG_STYLE, name=DialogNameStr)</p>
<p>A dialog box is a window with a title bar and sometimes a system menu,
which can be moved around the screen.</p></section>
<details class="source">
<summary>Source code</summary>
<pre><code class="python">class DialogNewKonzept(wx.Dialog):
def __init__(self, parent, title):
super(DialogNewKonzept, self).__init__(parent, title=title, size=(200, 100))
self.parent = parent
self.panel = wx.Panel(self)
self.name_of_new_konzept = wx.TextCtrl(self.panel, -1, &#34;&#34;, size=(100, 23))
self.color_of_new_konzept = wx.ColourPickerCtrl(self.panel, -1, wx.RED)
self.btn = wx.Button(self.panel, -1, label=&#34;okay&#34;)
self.sizer_dialog = wx.BoxSizer(wx.VERTICAL)
self.sizer_dialog_konzept = wx.BoxSizer(wx.HORIZONTAL)
self.sizer_dialog_konzept.Add(self.name_of_new_konzept, flag=wx.ALIGN_CENTER)
self.sizer_dialog_konzept.AddSpacer(10)
self.sizer_dialog_konzept.Add(self.color_of_new_konzept, flag=wx.ALIGN_CENTER)
self.sizer_dialog.AddSpacer(5)
self.sizer_dialog.Add(self.sizer_dialog_konzept, flag=wx.ALIGN_CENTER)
self.sizer_dialog.AddSpacer(10)
self.sizer_dialog.Add(self.btn, flag=wx.ALIGN_CENTER)
self.panel.SetSizer(self.sizer_dialog)
self.btn.Bind(wx.EVT_BUTTON, self.create_new_konzept)
def create_new_konzept(self, _):
self.parent.add_new_konzept(self.name_of_new_konzept.Value, rgb_to_hex(self.color_of_new_konzept.GetColour()))
# rgb_to_hex() ist unten definiert. keine build-in Funktion von Python
self.Close()</code></pre>
</details>
<h3>Ancestors</h3>
<ul class="hlist">
<li>wx._core.Dialog</li>
<li>wx._core.TopLevelWindow</li>
<li>wx._core.NonOwnedWindow</li>
<li>wx._core.Window</li>
<li>wx._core.WindowBase</li>
<li>wx._core.EvtHandler</li>
<li>wx._core.Object</li>
<li>wx._core.Trackable</li>
<li>sip.wrapper</li>
<li>sip.simplewrapper</li>
</ul>
<h3>Methods</h3>
<dl>
<dt id="Finanzexplorer_Institute.DialogNewKonzept.create_new_konzept"><code class="name flex">
<span>def <span class="ident">create_new_konzept</span></span>(<span>self, _)</span>
</code></dt>
<dd>
<section class="desc"></section>
<details class="source">
<summary>Source code</summary>
<pre><code class="python">def create_new_konzept(self, _):
self.parent.add_new_konzept(self.name_of_new_konzept.Value, rgb_to_hex(self.color_of_new_konzept.GetColour()))
# rgb_to_hex() ist unten definiert. keine build-in Funktion von Python
self.Close()</code></pre>
</details>
</dd>
</dl>
</dd>
<dt id="Finanzexplorer_Institute.DialogPlotSettings"><code class="flex name class">
<span>class <span class="ident">DialogPlotSettings</span></span>
<span>(</span><span>parent, title)</span>
</code></dt>
<dd>
<section class="desc"><p>Dialog()
Dialog(parent, id=ID_ANY, title=EmptyString, pos=DefaultPosition, size=DefaultSize, style=DEFAULT_DIALOG_STYLE, name=DialogNameStr)</p>
<p>A dialog box is a window with a title bar and sometimes a system menu,
which can be moved around the screen.</p></section>
<details class="source">
<summary>Source code</summary>
<pre><code class="python">class DialogPlotSettings(wx.Dialog):
def __init__(self, parent, title):
super(DialogPlotSettings, self).__init__(parent, title=title, size=(250, 130))
self.parent = parent
self.panel = wx.Panel(self)
self.text01 = wx.StaticText(self.panel, -1, label=&#34;Ist- oder Sollwerte: &#34;)
self.choiceTyp = wx.Choice(self.panel, -1, choices=[&#34;IST&#34;, &#34;SOLL&#34;, &#34;IST &amp; SOLL&#34;], size=(100, 20))
self.text02 = wx.StaticText(self.panel, -1, label=&#34;Ein Diagramm pro.. &#34;)
self.choiceGrouping = wx.Choice(self.panel, -1, choices=[&#34;Institut&#34;, &#34;Konzept&#34;], size=(100, 20))
self.text03 = wx.StaticText(self.panel, -1, label=&#34;max Y-Wert: &#34;)
self.choiceYTicks = wx.Choice(self.panel, -1, choices=[&#34;auto&#34;, &#34;compareable&#34;], size=(100, 20))
self.checkbox_inflation = wx.CheckBox(self.panel, -1, label=&#34;Inflationsbereinigt&#34;)
self.btn = wx.Button(self.panel, -1, label=&#34;okay&#34;)
self.sizer_settings = wx.BoxSizer(wx.HORIZONTAL)
self.sizer_left = wx.BoxSizer(wx.VERTICAL)
self.sizer_right = wx.BoxSizer(wx.VERTICAL)
self.sizer_left.AddSpacer(4)
self.sizer_left.Add(self.text01)
self.sizer_left.AddSpacer(8)
self.sizer_left.Add(self.text02)
self.sizer_left.AddSpacer(8)
self.sizer_left.Add(self.text03)
self.sizer_left.AddSpacer(10)
self.sizer_left.Add(self.checkbox_inflation)
self.sizer_right.AddSpacer(4)
self.sizer_right.Add(self.choiceTyp)
self.sizer_right.AddSpacer(5)
self.sizer_right.Add(self.choiceGrouping)
self.sizer_right.AddSpacer(5)
self.sizer_right.Add(self.choiceYTicks)
self.sizer_right.AddSpacer(10)
self.sizer_right.Add(self.btn)
self.sizer_settings.Add(self.sizer_left, flag=wx.ALIGN_TOP)
self.sizer_settings.AddSpacer(5)
self.sizer_settings.Add(self.sizer_right, flag=wx.ALIGN_TOP)
self.sizer_settings.AddSpacer(5)
self.panel.SetSizer(self.sizer_settings)
self.btn.Bind(wx.EVT_BUTTON, self.create_plot)
def create_plot(self, _):
checkbox_inflation = 1 if self.checkbox_inflation.GetValue() else 0
# --- EndModal um einen Integer zurückzugeben. Damit ein Integer mehrere Informationen beinhalten kann,
# habe ich mit den Dezimalstellen gearbeitet.
# Erscheint mir nicht optimal und ist sicherlich eleganter zu lösen ;)
self.EndModal((self.choiceTyp.GetSelection()+1) * 10000 +
(self.choiceGrouping.GetSelection()+1) * 1000 +
(self.choiceYTicks.GetSelection()+1) * 100 +
(checkbox_inflation+1) * 10 +
9) # Prüfnummer (Damit kein Plot kommt, falls das Fenster geschlossen wird)</code></pre>
</details>
<h3>Ancestors</h3>
<ul class="hlist">
<li>wx._core.Dialog</li>
<li>wx._core.TopLevelWindow</li>
<li>wx._core.NonOwnedWindow</li>
<li>wx._core.Window</li>
<li>wx._core.WindowBase</li>
<li>wx._core.EvtHandler</li>
<li>wx._core.Object</li>
<li>wx._core.Trackable</li>
<li>sip.wrapper</li>
<li>sip.simplewrapper</li>
</ul>
<h3>Methods</h3>
<dl>
<dt id="Finanzexplorer_Institute.DialogPlotSettings.create_plot"><code class="name flex">
<span>def <span class="ident">create_plot</span></span>(<span>self, _)</span>
</code></dt>
<dd>
<section class="desc"></section>
<details class="source">
<summary>Source code</summary>
<pre><code class="python">def create_plot(self, _):
checkbox_inflation = 1 if self.checkbox_inflation.GetValue() else 0
# --- EndModal um einen Integer zurückzugeben. Damit ein Integer mehrere Informationen beinhalten kann,
# habe ich mit den Dezimalstellen gearbeitet.
# Erscheint mir nicht optimal und ist sicherlich eleganter zu lösen ;)
self.EndModal((self.choiceTyp.GetSelection()+1) * 10000 +
(self.choiceGrouping.GetSelection()+1) * 1000 +
(self.choiceYTicks.GetSelection()+1) * 100 +
(checkbox_inflation+1) * 10 +
9) # Prüfnummer (Damit kein Plot kommt, falls das Fenster geschlossen wird)</code></pre>
</details>
</dd>
</dl>
</dd>
<dt id="Finanzexplorer_Institute.DialogRechnungstypInit"><code class="flex name class">
<span>class <span class="ident">DialogRechnungstypInit</span></span>
<span>(</span><span>parent, title)</span>
</code></dt>
<dd>
<section class="desc"><p>Dialog()
Dialog(parent, id=ID_ANY, title=EmptyString, pos=DefaultPosition, size=DefaultSize, style=DEFAULT_DIALOG_STYLE, name=DialogNameStr)</p>
<p>A dialog box is a window with a title bar and sometimes a system menu,
which can be moved around the screen.</p></section>
<details class="source">
<summary>Source code</summary>
<pre><code class="python">class DialogRechnungstypInit(wx.Dialog):
def __init__(self, parent, title):
super(DialogRechnungstypInit, self).__init__(parent, title=title, size=(280, 160))
# ---- Widgets erzeugen
self.panel = wx.Panel(self)
self.radiobox = wx.RadioBox(self.panel, -1, label=&#34;&#34;, # https://wxpython.org/Phoenix/docs/html/wx.RadioBox.html
choices=[&#34;Institutes&#34;,
&#34;Einnahmen-/Ausgabenrechnung (EA)&#34;,
&#34;Vermögensübersicht (VÜ)&#34;,
&#34;saved Concepts&#34;],
majorDimension=0,
style=wx.RA_SPECIFY_ROWS)
self.button = wx.Button(self.panel, -1, label=&#34;Okay&#34;)
# --- Widgets positionieren mit wx.BoxSizer (https://wxpython.org/Phoenix/docs/html/sizers_overview.html)
self.topsizer = wx.BoxSizer(wx.VERTICAL)
self.topsizer.AddSpacer(2)
self.topsizer.Add(self.radiobox, flag=wx.ALIGN_CENTER)
self.topsizer.AddSpacer(8)
self.topsizer.Add(self.button, flag=wx.ALIGN_CENTER)
self.panel.SetSizer(self.topsizer)
# --- Widgets an Functionen binden (Hier: wenn &#39;okay&#39;-Button gedrückt wird, wird self.start ausgeführt)
# --- https://wxpython.org/Phoenix/docs/html/events_overview.html
self.button.Bind(wx.EVT_BUTTON, self.start)
# Erst wenn dieses Fenster geschlossen wurde, kann mit Hauptfenster gearbeitet werden.
# Alternative zu Modal: .Show()
self.ShowModal()
def start(self, _):
tmp_rechnungstyp_id = self.radiobox.GetSelection()
if tmp_rechnungstyp_id == 0:
model.RECHNUNGSTYP = &#34;INST&#34;
frame.set_interface(_, &#34;INST&#34;)
self.Close()
elif tmp_rechnungstyp_id == 1:
model.RECHNUNGSTYP = &#34;EA&#34;
frame.set_interface(_, &#34;EA&#34;)
self.Close()
elif tmp_rechnungstyp_id == 2:
model.RECHNUNGSTYP = &#34;VÜ&#34;
frame.set_interface(_, &#34;VÜ&#34;)
self.Close()
elif tmp_rechnungstyp_id == 3:
if frame.load_konzepte_picker(_):
self.Close()
else:
pass</code></pre>
</details>
<h3>Ancestors</h3>
<ul class="hlist">
<li>wx._core.Dialog</li>
<li>wx._core.TopLevelWindow</li>
<li>wx._core.NonOwnedWindow</li>
<li>wx._core.Window</li>
<li>wx._core.WindowBase</li>
<li>wx._core.EvtHandler</li>
<li>wx._core.Object</li>
<li>wx._core.Trackable</li>
<li>sip.wrapper</li>
<li>sip.simplewrapper</li>
</ul>
<h3>Methods</h3>
<dl>
<dt id="Finanzexplorer_Institute.DialogRechnungstypInit.start"><code class="name flex">
<span>def <span class="ident">start</span></span>(<span>self, _)</span>
</code></dt>
<dd>
<section class="desc"></section>
<details class="source">
<summary>Source code</summary>
<pre><code class="python">def start(self, _):
tmp_rechnungstyp_id = self.radiobox.GetSelection()
if tmp_rechnungstyp_id == 0:
model.RECHNUNGSTYP = &#34;INST&#34;
frame.set_interface(_, &#34;INST&#34;)
self.Close()
elif tmp_rechnungstyp_id == 1:
model.RECHNUNGSTYP = &#34;EA&#34;
frame.set_interface(_, &#34;EA&#34;)
self.Close()
elif tmp_rechnungstyp_id == 2:
model.RECHNUNGSTYP = &#34;VÜ&#34;
frame.set_interface(_, &#34;VÜ&#34;)
self.Close()
elif tmp_rechnungstyp_id == 3:
if frame.load_konzepte_picker(_):
self.Close()
else:
pass</code></pre>
</details>
</dd>
</dl>
</dd>
<dt id="Finanzexplorer_Institute.ExcelCell"><code class="flex name class">
<span>class <span class="ident">ExcelCell</span></span>
<span>(</span><span>row=None, col=None, path=None, sheet=None, year=None, typ=None, category=None, betrag=None)</span>
</code></dt>
<dd>
<section class="desc"></section>
<details class="source">
<summary>Source code</summary>
<pre><code class="python">class ExcelCell:
def __init__(self, row=None, col=None, path=None, sheet=None, year=None, typ=None, category=None, betrag=None):
self.row = row
self.col = col
self.path = path
self.sheet = sheet
self.year = year
self.type = typ # z.B.: IST oder SOLL
self.category = category # z.B.: Gesamteinnahmen (noch str, besser FK)
# ab diesem Zeitpunkt sind die Werte in den Haushaltsplänen in TDM angegeben
if (self.year &gt; 1965 and self.type == &#34;IST&#34;) or (self.year &gt; 1966 and self.type == &#34;SOLL&#34;):
self.betrag = betrag
else:
self.betrag = betrag / 1000
# Die Einnahmen sind ab 1997/98 negativ aufgeführt. Dies hatten wir so in den Excel-Tabellen übernommen.
if ((self.year &gt; 1997 and self.type == &#34;IST&#34;) or (self.year &gt; 1998 and self.type == &#34;SOLL&#34;)) and self.row &lt; 25:
self.betrag = self.betrag * -1
if self.year &lt;= 1999:
self.inflationsbereinigt = self.betrag / dct_preisindices[self.year]
else:
# # noch Falsch. Was passiert mit den Werten, für die wir keinen Verbraucherpreisindex haben? (nach 1999)
# self.inflationsbereinigt = self.betrag
# # habe es nun in line_plot_inst() geändert. Inflationsbereinigt werden die Daten nach 1999 nicht angezeigt
pass</code></pre>
</details>
</dd>
<dt id="Finanzexplorer_Institute.InstitutsForm"><code class="flex name class">
<span>class <span class="ident">InstitutsForm</span></span>
</code></dt>
<dd>
<section class="desc"><p>Frame()
Frame(parent, id=ID_ANY, title=EmptyString, pos=DefaultPosition, size=DefaultSize, style=DEFAULT_FRAME_STYLE, name=FrameNameStr)</p>
<p>A frame is a window whose size and position can (usually) be changed
by the user.</p>
<p>Constructor</p></section>
<details class="source">
<summary>Source code</summary>
<pre><code class="python">class InstitutsForm(wx.Frame):
def __init__(self):
&#34;&#34;&#34;Constructor&#34;&#34;&#34;
wx.Frame.__init__(self,
parent=None,
title=&#34;Finanzexplorer&#34;,
size=(1000, 700))
self.p = wx.Panel(self, size=(300, 700))
self.button = wx.Button(self.p, -1, label=&#34;plot me&#34;)
self.search_control = wx.SearchCtrl(self.p, -1, value=&#34;&#34;, size=(240, 23))
self.search_control.ShowCancelButton(True)
self.btn_add = wx.Button(self.p, -1, label=&#34;add&#34;, size=(40, 20))
self.btn_delete = wx.Button(self.p, -1, label=&#34;delete&#34;, size=(60, 20))
self.btn_reset = wx.Button(self.p, -1, label=&#34;reset&#34;, size=(50, 20))
self.btn_save = wx.Button(self.p, -1, label=&#34;save&#34;, size=(51, 20))
self.btn_load = wx.Button(self.p, -1, label=&#34;load&#34;, size=(42, 20))
self.static_text = wx.StaticText(self.p, -1, &#34;Konzepte:&#34;)
self.p.infotext = wx.StaticText(self.p, -1, &#34;&#34;, size=(150, 23*4))
# # self.p.infotext, um über parent vom grid (panel = self.p) auf den infotext zugreifen zu können
self.list_ctrl_index = 0
self.konzept_listcontrol = wx.ListCtrl(self.p, size=(155, 100),
style=wx.LC_REPORT | wx.BORDER_SUNKEN | wx.LC_SINGLE_SEL)
self.konzept_listcontrol.InsertColumn(0, &#39;Konzeptname&#39;, width=150)
self.static_text_02 = wx.StaticText(self.p, -1, &#34;Institutes:&#34;)
self.checkbox_sum = wx.CheckBox(self.p, -1, label=&#34;Sum institutes&#34;)
self.institute = defaultdict(dict)
self.choices_files = [x for x in get_saves().keys()]
self.choices = []
self.checkbox = wx.CheckListBox(self.p, -1, size=(200, 1000),
choices=[], style=wx.LB_ALWAYS_SB)
self.checkbox.Bind(wx.EVT_CHECKLISTBOX, self.checked_item)
self.myGrid = MyGrid(self.p)
self.konzepte = {}
self.tmpStoredKonzepte = None
self.sizer_grid = wx.BoxSizer(wx.VERTICAL)
self.sizer_grid.Add(self.search_control)
self.sizer_grid.Add(self.myGrid, 1, wx.EXPAND)
self.sizer_info = wx.BoxSizer(wx.VERTICAL)
self.sizer_info.Add(self.p.infotext)
self.sizer_save = wx.BoxSizer(wx.HORIZONTAL)
self.sizer_save.Add(self.btn_load)
self.sizer_save.AddSpacer(60)
self.sizer_save.Add(self.btn_save)
# self.sizer_save.Add(self.filepicker)
self.sizer_konzeptbutton = wx.BoxSizer(wx.HORIZONTAL)
self.sizer_konzeptbutton.AddSpacer(1)
self.sizer_konzeptbutton.Add(self.btn_add)
self.sizer_konzeptbutton.AddSpacer(1)
self.sizer_konzeptbutton.Add(self.btn_delete)
self.sizer_konzeptbutton.AddSpacer(1)
self.sizer_konzeptbutton.Add(self.btn_reset)
self.sizer_konzeptbutton.AddSpacer(1)
self.sizer_instituts = wx.BoxSizer(wx.VERTICAL)
self.sizer_instituts.Add(self.checkbox)
self.sizer_controller = wx.BoxSizer(wx.VERTICAL)
self.sizer_controller.AddSpacer(5)
self.sizer_controller.Add(self.button)
self.sizer_controller.AddSpacer(5)
self.sizer_controller.Add(self.static_text)
self.sizer_controller.AddSpacer(5)
self.sizer_controller.Add(self.konzept_listcontrol)
self.sizer_controller.Add(self.sizer_konzeptbutton)
self.sizer_controller.AddSpacer(1)
self.sizer_controller.Add(self.sizer_save)
self.sizer_controller.AddSpacer(10)
self.sizer_controller.Add(self.sizer_info)
self.sizer_controller.Add(self.static_text_02)
self.sizer_controller.Add(self.checkbox_sum)
self.sizer_controller.Add(self.sizer_instituts)
self.topSizer = wx.BoxSizer(wx.HORIZONTAL)
self.topSizer.Add(self.sizer_controller)
self.topSizer.Add(self.sizer_grid)
self.p.SetSizer(self.topSizer)
self.btn_load.Bind(wx.EVT_BUTTON, self.load_konzepte_picker)
self.search_control.Bind(wx.EVT_SEARCHCTRL_SEARCH_BTN, self.find_category)
self.search_control.Bind(wx.EVT_SEARCHCTRL_CANCEL_BTN, self.unfind_category)
# --------- Menu Bar --------- #
self.menuBar()
self.Show()
def menuBar(self):
menuBar = wx.MenuBar()
fileButton = wx.Menu()
openMenu = wx.Menu()
openItem01 = openMenu.Append(-1, &#39;Institutsexplorer&#39;)
openItem02 = openMenu.Append(-1, &#39;Einnahmen-Ausgabenrechnung&#39;)
openItem03 = openMenu.Append(-1, &#39;Vermögensübersicht&#39;)
fileButton.Append(-1, &#39;Open ..&#39;, openMenu)
openInNewWindowItem = fileButton.Append(-1, &#39;Open new Window&#39;)
fileButton.AppendSeparator()
create_report = fileButton.Append(-1, &#34;create Report (PDF)&#34;)
fileButton.AppendSeparator()
exitItem = fileButton.Append(-1, &#39;Exit&#39;, &#39;status msg...&#39;)
menuBar.Append(fileButton, &#39;File&#39;)
runButton = wx.Menu()
self.plotItem = runButton.Append(-1, &#39;create Graphs&#39;)
menuBar.Append(runButton, &#39;Run&#39;)
helpButton = wx.Menu()
templateItem = helpButton.Append(-1, &#39;show Template&#39;)
developeItem = helpButton.Append(-1, &#39;develope mode&#39;)
menuBar.Append(helpButton, &#39;help&#39;)
self.SetMenuBar(menuBar)
self.Bind(wx.EVT_MENU, self.Quit, exitItem)
self.Bind(wx.EVT_MENU, lambda event: self.set_interface_alert(event, &#39;INST&#39;), openItem01)
self.Bind(wx.EVT_MENU, lambda event: self.set_interface_alert(event, &#39;EA&#39;), openItem02)
self.Bind(wx.EVT_MENU, lambda event: self.set_interface_alert(event, &#39;VÜ&#39;), openItem03)
self.Bind(wx.EVT_MENU, self.new_window, openInNewWindowItem)
self.Bind(wx.EVT_MENU, self.create_report, create_report)
self.Bind(wx.EVT_MENU, self.open_template, templateItem)
self.Bind(wx.EVT_MENU, self.develope_mode, developeItem)
def develope_mode(self, _):
&#34;&#34;&#34;
If develope_mode True, docstrings will be printed on console.
&#34;&#34;&#34;
global develope_mode
develope_mode = not develope_mode
def Quit(self, _):
self.Close()
def open_template(self, _):
&#34;&#34;&#34;
öffnet das Excel-Template, welches wir zum einen bei der Datenaufnahme aus den Haushaltsplänen
als Vorlage verwendet haben, zum anderen wurde anhand des Templates das Grid-Interface für die
Institute im Finanzexplorer erzeugt.
:param _: wx-event (not used)
&#34;&#34;&#34;
os.system(&#39;open Institute/Haushaltsbücher_MPI_Template.xlsx&amp;&#39;)
def new_window(self, _):
&#34;&#34;&#34;
Öffnet den Finanzexplorer erneut, um zum Beispiel parallel an der Einnahmen-/Ausgabenrechnung und
der Vermögensübersicht arbeiten zu können.
:param _: wx-event (not used)
&#34;&#34;&#34;
os.system(&#39;venv/bin/python Finanzexplorer_Institute.py&amp;&#39;)
def set_interface_alert(self, _, typ):
&#34;&#34;&#34;
Falls bereits ein Interface eines bestimmten Rechnungstyps geöffnet ist und nicht dem entspricht,
der gerade geöffnet werden soll, erscheint eine Warnung, dass noch ungespeicherte Konzepte verloren gehen.
:param _: wx-event (not used)
:param typ: Zur Unterscheidung von EA = Einnahmen-/Ausgabenrechnung, VÜ = Vermögensübersicht, INST = Institute
:return:
&#34;&#34;&#34;
if model.RECHNUNGSTYP == &#34;&#34;:
self.set_interface(_, typ)
elif model.RECHNUNGSTYP == typ:
pass
else:
msg = &#34;Unsaved changes will be discarded!\n\nDo you want to proceed?&#34;
dlg = wx.MessageDialog(self, msg, &#39;Warning&#39;, style=wx.YES_NO | wx.ICON_QUESTION | wx.CENTRE)
result = dlg.ShowModal()
if result == wx.ID_YES:
self.set_interface(_, typ)
else:
pass
def set_interface(self, _, typ):
&#34;&#34;&#34;
wxFrame wird nach dem &#39;richtigen&#39; Rechnungstyp ausgerichtet: wxWidgets werden neue Funktionen zugeteilt.
:param _: wx-event (not used)
:param typ: Zur Unterscheidung von EA = Einnahmen-/Ausgabenrechnung, VÜ = Vermögensübersicht, INST = Institute
:return:
&#34;&#34;&#34;
# erase old interface and data
fresh_new_start()
frame.reset_konzepte(_)
# set new interface and data
model.RECHNUNGSTYP = typ
if model.RECHNUNGSTYP == &#34;EA&#34;: # User-Interface for Einnahmen-/Ausgabenrechnung
model.superkategorien = [68, 92]
frame.SetTitle(&#34;Finanzexplorer - MPG Gesamt - Einnahmen-/ Ausgabenrechnung&#34;)
elif model.RECHNUNGSTYP == &#34;VÜ&#34;: # User-Interface for Vermögensübersicht
model.superkategorien = [1, 2]
frame.SetTitle(&#34;Finanzexplorer - MPG Gesamt - Vermögensübersicht&#34;)
# Superkategorien sind die &#39;Wurzeln&#39; des Schema-Baums in EA und VÜ.
# Also den Kategorien &#34;Einnahmen&#34;, &#34;Ausgaben&#34;, &#34;Aktiva&#34; und &#34;Passiva&#34;.
# Die Zahlen entsprechen den Kategorie-IDs in der Finanz-DB.
if model.RECHNUNGSTYP == &#34;INST&#34;:
frame.SetTitle(&#34;Finanzexplorer - MPG Institute&#34;)
self.checkbox_sum.SetLabel(&#34;Sum institutes&#34;)
self.set_institutes()
self.choices = [x for x in self.get_institutes().keys()]
self.choices.sort()
self.checkbox.Set(self.choices)
import_inst_template()
# Bindings for &#34;INST&#34;
self.button.Bind(wx.EVT_BUTTON, self.button_click)
self.myGrid.Bind(wx.grid.EVT_GRID_CELL_LEFT_DCLICK, self.myGrid.select_cell)
self.Bind(wx.EVT_MENU, self.button_click, self.plotItem)
self.checked_item(_=None)
self.sizer_controller.Show(self.checkbox_sum)
self.sizer_controller.Layout()
else: # for &#34;EA&#34; or &#34;VÜ&#34;
self.checkbox.Set([])
self.choices_files = [x for x in get_saves().keys()]
self.checkbox.Set(self.choices_files)
import_mpg_gesamt_data()
populate_cells()
self.static_text_02.SetLabel(&#34;Saved Conzepts:&#34;)
# Bindings for &#34;EA&#34; or &#34;VÜ&#34;
self.button.Bind(wx.EVT_BUTTON, self.button_click_gesamt)
self.myGrid.Bind(wx.grid.EVT_GRID_CELL_LEFT_DCLICK, self.myGrid.trigger_kategorie)
self.myGrid.Bind(wx.grid.EVT_GRID_CELL_RIGHT_CLICK, self.myGrid.show_popup_menu)
self.Bind(wx.EVT_MENU, self.button_click_gesamt, self.plotItem)
self.sizer_controller.Hide(self.checkbox_sum)
self.sizer_controller.Layout()
# Bindings for all types
self.btn_add.Bind(wx.EVT_BUTTON, self.add_konzept)
self.konzept_listcontrol.Bind(wx.EVT_LIST_ITEM_SELECTED, self.colour_picked)
self.konzept_listcontrol.Bind(wx.EVT_LIST_ITEM_DESELECTED, self.check_selection)
self.btn_reset.Bind(wx.EVT_BUTTON, self.reset_konzepte)
self.btn_delete.Bind(wx.EVT_BUTTON, self.delete_konzept)
self.btn_save.Bind(wx.EVT_BUTTON, self.save_konzepte)
def set_institutes(self):
&#34;&#34;&#34;
Liest die Namen und Pfade aller relevanten Excel-Dateien aus dem Ordner &#39;Institute&#39; ein und
speichert sie im dict self.institute unter dem Key des Institutsnamens. Nested dict &#39;path&#39; and &#39;file&#39;
:return:
&#34;&#34;&#34;
if develope_mode:
print(help(self.set_institutes))
for (dirpath, dirnames, filenames) in os.walk(&#34;../Finanzexplorer-Git-data/Institute&#34;):
filenames = [x for x in filenames
if &#34;Haushaltsb&#34; in x
and &#34;.xlsx&#34; in x
and &#34;Template&#34; not in x
and &#34;Haushaltsbücher_MPG_gesamt.xlsx&#34; not in x
and &#34;_All&#34; not in x]
for f in filenames:
if f.split(&#34;_&#34;)[1] == &#34;MPI&#34;:
name = f[21:len(f)-5].lower()
else:
name = f[17:len(f) - 5].lower()
name = name.capitalize()
self.institute[name][&#34;path&#34;] = os.path.join(dirpath, f)
self.institute[name][&#34;file&#34;] = f
def get_institutes(self):
return self.institute
# Damit die Anzahl der ausgewählten Institute angezeigt wird
def checked_item(self, _):
if model.RECHNUNGSTYP == &#34;INST&#34;:
if len(self.checkbox.GetCheckedItems()) != 0:
self.static_text_02.SetLabel(&#34;Institute ({} selected):&#34;.format(len(self.checkbox.GetCheckedItems())))
else:
self.static_text_02.SetLabel(&#34;Institute:&#34;)
self.tmpStoredKonzepte = None
def add_konzept(self, _):
DialogNewKonzept(self, &#34;new concept&#34;).ShowModal()
# Das Fenster &#39;DialogNewKonzept&#39; wird geöffnet. Name und Farbe des Konzepts können bestimmt werden
# .ShowModal(), damit an anderen Fenstern nicht gearbeitet werden kann, solange dieses geöffnet ist
# Die Alternative zu .ShowModal() wäre .Show()
def add_new_konzept(self, name, color):
self.konzept_listcontrol.InsertItem(self.list_ctrl_index, name)
self.konzept_listcontrol.SetItemTextColour(self.list_ctrl_index, color)
self.konzepte[name] = Konzept(name, color)
self.konzept_listcontrol.SetItemState(self.list_ctrl_index, wx.LIST_STATE_SELECTED, wx.LIST_STATE_SELECTED)
self.list_ctrl_index += 1
self.tmpStoredKonzepte = None
def check_selection(self, _):
global active_konzeptColor
global active_konzept
if self.konzept_listcontrol.GetSelectedItemCount() == 0: # Wenn kein Konzept angewählt ist ..
active_konzeptColor = &#34;#ffffff&#34;
active_konzept = None
def colour_picked(self, event):
global active_konzeptColor
global active_konzept
active_konzeptColor = self.konzept_listcontrol.GetItemTextColour(event.GetIndex())
active_konzept = self.konzepte[self.konzept_listcontrol.GetItem(event.GetIndex()).GetText()]
def reset_konzepte(self, _):
self.konzepte = {}
self.konzept_listcontrol.DeleteAllItems()
self.list_ctrl_index = 0
self.myGrid.reset_all_categories()
for item in self.checkbox.GetCheckedItems():
self.checkbox.Check(item, False)
self.checked_item(_=None)
self.tmpStoredKonzepte = None
def delete_konzept(self, _):
global active_konzept, active_konzeptColor
self.myGrid.delete_konzept_in_grid()
# delete dct-entry
self.tmpStoredKonzepte = None
try:
del self.konzepte[active_konzept.name]
except AttributeError:
pass
# delete listCtrl-entry
self.list_ctrl_index -= 1
try:
self.konzept_listcontrol.DeleteItem(self.konzept_listcontrol.GetFocusedItem())
except AssertionError:
pass
# set new active konzept to last one in list...
items_in_listctrl = self.konzept_listcontrol.GetItemCount()
if items_in_listctrl &gt; 0:
active_konzept = self.konzepte[self.konzept_listcontrol.GetItem(items_in_listctrl - 1).GetText()]
active_konzeptColor = active_konzept.color
self.konzept_listcontrol.SetItemState(self.list_ctrl_index - 1,
wx.LIST_STATE_SELECTED,
wx.LIST_STATE_SELECTED)
# ...or to &#34;None&#34;, if list is empty
else:
active_konzept = None
active_konzeptColor = WHITE
def get_inst_konzepte(self):
# print(get_inst_konzepte().__name__)
if self.tmpStoredKonzepte: # spart Zeit, da nicht erneut die Excel-Tabellen geöffnet werden müssen
all_konzept_data = self.tmpStoredKonzepte
else:
# get_selected_institutes
checked_institutes_paths = []
for x in self.checkbox.GetCheckedItems():
checked_institutes_paths.append((self.get_institutes()[self.choices[x]][&#34;path&#34;], self.choices[x]))
# get existing concepts
dct_xkonzepte = defaultdict(dict)
tmp_xkonzepte = defaultdict(list)
for c in dct_cells.values():
if c.konzept:
tmp_xkonzepte[(worksheets[c.col], c.konzept.name)].append(c.value)
for sheet_konzeptname, lst in tmp_xkonzepte.items():
dct_xkonzepte[sheet_konzeptname[0]][sheet_konzeptname[1]] = lst
# worksheets = [&#34;1954-1963&#34;, &#34;1964-1966&#34;, &#34;1967&#34;, &#34;1968-1972&#34;, &#34;1973-1986&#34;, &#34;1987-1997&#34;, &#34;1998-2002&#34;]
# c.col = Spalte im interface = index aus der Liste &#39;worksheets&#39;
# dct_xkonzepte{&#34;1954-1963&#34;: {Konzeptname:[list of selected cells per year]}}
# get data according to the selected institutes AND existing concepts
all_konzept_data = {}
for path in checked_institutes_paths:
konzept_data = defaultdict(list)
wb = load_workbook(path[0], data_only=True)
for sheet in worksheets:
try:
ws = wb[sheet] # exp. Worksheet &#34;1954-1963&#34;
# get data (sheet by sheet) for each concept and store it in a list (each konzept has one list)
for konzeptname, conceptcells_per_year in dct_xkonzepte[sheet].items():
for row in range(1, ws.max_row+1):
for v in conceptcells_per_year:
if ws.cell(row, 1).value == v:
# hier wird in die Excel gegangen und
# nach der ausgewählten Zelle aus dem Interface gesucht
for col in range(1, ws.max_column+1):
if ws.cell(3, col).value and ws.cell(row, col).value not in [&#34;&#34;, &#34; &#34;, None,
&#34;None&#34;, &#34;0&#34;, 0]:
if sheet == &#34;1998-2002&#34; and col &gt; 12: # €-Werte
pass
else:
konzept_data[konzeptname].append(
ExcelCell(row=row,
col=col,
path=path,
sheet=sheet,
year=int(ws.cell(3, col).value),
typ=ws.cell(2, col).value,
category=ws.cell(row, 1).value,
betrag=float(ws.cell(row, col).value)))
except KeyError:
print(&#34;{} doesn&#39;t has sheet {}&#34;.format(path[0], sheet))
except ValueError:
print(&#34;\nWrong entry: {}\nPath: {}\nSheet: {}\nRow, Column: {}, {}\n&#34;.format(wb[sheet].cell(row, col).value, path[0], sheet, row, col))
all_konzept_data[path[1]] = konzept_data
for key, inst in all_konzept_data.items():
for name, lst in inst.items(): # lst = list of ExcelCell objects
lst.sort(key=lambda z: z.year)
for obj in lst:
self.konzepte[name].plots[key].append((obj.year, obj.betrag, obj.type))
# -----------------------------------
# # Summe wird immer auch gespeichert. Ob sie genutzt wird entscheidet self.summe in der Klasse Konzepte
for key, inst in all_konzept_data.items():
for name, lst in inst.items(): # lst = list of ExcelCell objects; name = Konzeptname
for obj in lst:
tmp_is_in_list = False
for index, x in enumerate(self.konzepte[name].plots[&#34;SUMME&#34;]):
if x[0] == obj.year and x[2] == obj.type:
tmp_lst = list(x)
tmp_lst[1] += obj.betrag
self.konzepte[name].plots[&#34;SUMME&#34;][index] = tuple(tmp_lst)
tmp_is_in_list = True
if not tmp_is_in_list:
self.konzepte[name].plots[&#34;SUMME&#34;].append((obj.year, obj.betrag, obj.type))
# -----------------------------------
self.tmpStoredKonzepte = all_konzept_data
return all_konzept_data
def button_click(self, _):
if frame.checkbox_sum.GetValue():
data = self.get_inst_konzepte()
line_plot_inst(data, typ=&#34;IST&#34;, grouping_by=&#34;Institute&#34;, mode=&#34;auto&#34;, inflation=False)
else:
self.plot_settings()
def button_click_gesamt(self, _):
line_plot_gesamt_settings()
def new_get_konzept(self):
&#34;&#34;&#34;
Es werden alle Zellen der Obj Schemata durchgegangen und geschaut, welche Zellen zu einem Konzept gehören.
Diese Zellen mit Konzept werden in einem Dict unter dem Key des Konzepts
und der entsprechenden Jahreszahl gespeichert.
Besser: Nicht in den Cell-obj das Konzept speichern, sondern in den Konzepten die tatsächlichen Cell-obj.
So wäre es möglich, direkt anhand der Konzepte die richtigen Zellen anzusteuern und man muss nicht
alle Zellen (auch die ohne Konzept) durchsuchen. Beide Verbindungen (Cell -&gt; Konzept und Konzept -&gt; Cell)
gleichzeitig sind nicht möglich, da so eine schleife entstehen würde, die beim erzeugen eines json
zum Error führen würde (siehe save_konzepte()).
:return: dct_xkonzepte = &lt;dict&gt; {Konzeptname: &lt;list&gt; [(Jahr, Betrag), (Jahr, Betrag),..], Konzeptname:..}
&#34;&#34;&#34;
tmp_dct_xkonzepte = defaultdict(dict)
dct_xkonzepte = defaultdict(list)
for s in model.get_dct_schemata().values():
if s.typ == model.RECHNUNGSTYP:
for kon in self.konzepte.values():
tmp_dct_xkonzepte[kon.name][s.jahr] = None
for c in s.cells:
if c.konzept:
if tmp_dct_xkonzepte[c.konzept.name][s.jahr] is None:
tmp_dct_xkonzepte[c.konzept.name][s.jahr] = 0.00
if c.jahr &gt;= 2001:
tmp_dct_xkonzepte[c.konzept.name][s.jahr] += (c.posten.geldbetrag * 1.95583) # DM -&gt; €
else:
tmp_dct_xkonzepte[c.konzept.name][s.jahr] += c.posten.geldbetrag
for name, konzept in tmp_dct_xkonzepte.items():
for year, v_values in konzept.items():
dct_xkonzepte[name].append((year, v_values))
dct_xkonzepte[name].sort(key=lambda x: x[0])
self.konzepte[name].plots[&#34;MPG-Gesamt&#34;] = dct_xkonzepte[name]
return dct_xkonzepte
def plot_settings(self, xshow=True):
data = self.get_inst_konzepte()
return_code = str(DialogPlotSettings(self, title=&#34;plot settings&#34;).ShowModal())
if len(return_code) == 5: # Prüfnummer (Länge 5 bedeutet Fenster wurde nicht geschlossen)
typ = [&#34;IST&#34;, &#34;SOLL&#34;, &#34;IST &amp; SOLL&#34;][int(return_code[0]) - 1]
grouping_by = [&#34;Institute&#34;, &#34;Konzept&#34;][int(return_code[1]) - 1]
mode = [&#34;auto&#34;, &#34;compareable&#34;][int(return_code[2]) - 1]
inflation = [False, True][int(return_code[3]) - 1]
if not xshow:
image = line_plot_inst(data, typ, grouping_by=grouping_by, mode=mode, inflation=inflation, xshow=False)
return image
else:
line_plot_inst(data, typ, grouping_by=grouping_by, mode=mode, inflation=inflation, xshow=True)
else:
pass
def save_konzepte(self, _):
&#34;&#34;&#34;
Anhand der erstellten Konzepte wird ein defaul-filename erzeugt. In dieser Datei wird das dict frame.konzepte
als json gespeichert.
:param _: not used
:return: no return :/
&#34;&#34;&#34;
konzeptnames = []
for x in self.checkbox.GetCheckedItems():
konzeptnames.append(self.choices[x])
konzeptnames.append(&#34;_&#34;)
for k, v in self.konzepte.items():
konzeptnames.append(k)
konzeptnames.append(&#34;_&#34;)
str_konzeptnames = &#39;&#39;.join(konzeptnames)
str_konzeptnames = str_konzeptnames[:len(str_konzeptnames) - 1] # um den letzen Unterstrich zu löschen
str_konzeptnames = str_konzeptnames.replace(&#34;/&#34;, &#34;-&#34;) # um keinen subfolder zu erzeugen (Error)
new_filename = model.RECHNUNGSTYP + &#34;_&#34; + str_konzeptnames
filedlg = wx.FileDialog(self.p, &#34;Save Konzept&#34;, defaultFile=new_filename, style=wx.FD_SAVE)
filedlg.ShowModal()
filepath = filedlg.GetPath()
if filepath:
if model.RECHNUNGSTYP == &#34;INST&#34;:
self.get_inst_konzepte()
else:
self.new_get_konzept()
with open(filepath, &#34;w&#34;) as outfile:
json.dump(self.konzepte, outfile, default=lambda o: o.__dict__)
def load_konzepte_picker(self, _):
&#34;&#34;&#34;
Dialogfeld zum auswählen der zu ladenden Datei wird geöffnet.
:param _:
:return: Boolean = Datei wurde ausgewählt oder nicht.
&#34;&#34;&#34;
filedlg = wx.FileDialog(self.p, &#34;Load&#34;, style=wx.FD_OPEN | wx.FD_FILE_MUST_EXIST)
filedlg.ShowModal()
filepath = filedlg.GetPath()
if filepath:
self.load_konzept(_, filepath)
return True
else:
return False
def load_konzept(self, _, filepath):
&#34;&#34;&#34;
Das Json aus der Datei wird als Dictionary geladen und die Informationen verarpeitet,
sprich: Rechnungstyp gesetzt, richtige Interface laden, Zellen des Konzepts entsprechend eingefärbt und
Konzepte im FRame gespeichert.
:param _: not used
:param filepath: Pfad zur Datei
:return: no return :/
&#34;&#34;&#34;
global active_konzept, active_konzeptColor
with open(filepath) as infile:
dct_infile = json.load(infile)
checked_items = []
for k, v in dct_infile.items(): # k = Konzeptname, v = &lt;dict&gt; Kozept (Keys = Attr der Class Konzept)
if model.RECHNUNGSTYP == &#34;&#34;:
model.RECHNUNGSTYP = v[&#34;rechnungstyp&#34;]
self.set_interface(_=None, typ=v[&#34;rechnungstyp&#34;])
if v[&#34;rechnungstyp&#34;] == model.RECHNUNGSTYP:
self.add_new_konzept(k, v[&#34;color&#34;])
for cell_pos in v[&#34;cells&#34;]:
if model.RECHNUNGSTYP == &#34;INST&#34;:
c = dct_cells[(cell_pos[0], cell_pos[1])]
else:
c = model.get_dct_cells()[(cell_pos[0], cell_pos[1])]
if c.color != v[&#34;color&#34;]:
active_konzeptColor = v[&#34;color&#34;]
c.color = active_konzeptColor
active_konzept = self.konzepte[k]
c.konzept = active_konzept
if (cell_pos[0], cell_pos[1]) not in self.konzepte[k].cells:
self.konzepte[k].cells.append((cell_pos[0], cell_pos[1]))
self.myGrid.SetCellBackgroundColour(c.row, c.col, c.color)
if v[&#34;rechnungstyp&#34;] == &#34;INST&#34;:
for inst in v[&#34;plots&#34;].keys():
if inst != &#34;SUMME&#34;:
checked_items.append(inst.capitalize())
else:
self.checkbox_sum.SetValue(True)
if v[&#34;rechnungstyp&#34;] != &#34;Inst&#34;:
for cell_pos in v[&#34;uncertain&#34;]:
frame.myGrid.SetCellTextColour(cell_pos[0], cell_pos[1], v[&#34;color&#34;])
else:
msg = &#34;File &#39;{}&#39; is not of type &#39;{}&#39;\n\n&#34; \
&#34;Unsaved changes will be discarded!\n\n&#34; \
&#34;Do you want to proceed?&#34;.format(filepath.split(&#34;/&#34;)[-1], model.RECHNUNGSTYP)
dlg = wx.MessageDialog(self, msg, &#39;Warning&#39;, style=wx.YES_NO | wx.ICON_QUESTION | wx.CENTRE)
result = dlg.ShowModal()
if result == wx.ID_YES:
model.RECHNUNGSTYP = v[&#34;rechnungstyp&#34;]
self.set_interface(_, v[&#34;rechnungstyp&#34;])
self.add_new_konzept(k, v[&#34;color&#34;])
for cell_pos in v[&#34;cells&#34;]:
if model.RECHNUNGSTYP == &#34;INST&#34;:
c = dct_cells[(cell_pos[0], cell_pos[1])]
else:
c = model.get_dct_cells()[(cell_pos[0], cell_pos[1])]
if c.color != v[&#34;color&#34;]:
active_konzeptColor = v[&#34;color&#34;]
c.color = active_konzeptColor
active_konzept = self.konzepte[k]
c.konzept = active_konzept
if (cell_pos[0], cell_pos[1]) not in self.konzepte[k].cells:
self.konzepte[k].cells.append((cell_pos[0], cell_pos[1]))
self.myGrid.SetCellBackgroundColour(c.row, c.col, c.color)
if v[&#34;rechnungstyp&#34;] == &#34;INST&#34;:
for inst in v[&#34;plots&#34;].keys():
if inst != &#34;SUMME&#34;:
checked_items.append(inst.capitalize())
else:
break
self.checkbox.SetCheckedStrings(checked_items)
active_konzeptColor = &#34;#ffffff&#34;
self.checked_item(_=None)
self.myGrid.ForceRefresh()
def find_category(self, _):
&#34;&#34;&#34;
Es werden alle Zellen nach dem Suchbegriff durchsucht und bei Übereinstimmung hellblau eingefärbt. Zudem
werden diese Zellen in der Liste found_cells gespeichert.
Not case-sensitive. Falls erwünscht die .lower() herausnehmen.
Im Fall der Institute werden die ersten 8 Zeilen sowie graue Zellen nicht berücksichtigt.
:param _: not used
:return: no return :/
&#34;&#34;&#34;
self.unfind_category(_)
value = self.search_control.GetValue()
if model.RECHNUNGSTYP == &#34;INST&#34;:
for cell in dct_cells.values():
if value.lower() in cell.value.lower() and cell.row &gt; 8 and cell.color != &#34;#cccccc&#34;:
found_cells.append(cell)
self.myGrid.SetCellBackgroundColour(cell.row, cell.col, &#34;#d6ffff&#34;)
else:
for cell in model.get_dct_cells().values():
if value.lower() in cell.value[0].bezeichnung.lower():
found_cells.append(cell)
self.myGrid.SetCellBackgroundColour(cell.row, cell.col, &#34;#d6ffff&#34;)
self.myGrid.ForceRefresh()
def unfind_category(self, _):
&#34;&#34;&#34;
Zellen aus der Liste found_cells erhalten wieder ihre ursprüngliche Farbe (Farbe aus &lt;Cell-Obj&gt;.color).
:param _: not used
:return: no return :/
&#34;&#34;&#34;
global found_cells
for cell in found_cells:
self.myGrid.SetCellBackgroundColour(cell.row, cell.col, cell.color)
found_cells = []
self.myGrid.ForceRefresh()
def create_report(self, _, filename=&#34;Test&#34;):
&#34;&#34;&#34;
Erstellt eine PDF, zum einen mit dem Diagramm, zum anderen mit einer Jahresgenauen aufschlüsselung
der pro Konzept verwendeten Kategorien und ihrer Geldbeträge.
Zum erstellen eines Inhaltsverzeichnisses (&#39;toc&#39;) muss der letzte Prozess zweimal durchlaufen werden.
Die Seitenangaben müssen beim ersten durchlauf gespeichert werden, das sie beim zweiten Durchlauf beim erstellen
des Inhaltsverzeichnisses bereits auf der ersten Seite zum erstellen der Links gebraucht werden.
:param _: not used
:param filename: Dateiname (Bislang nur &#39;Test&#39;. Besser: &#39;Report_&lt;Konzeptnamen&gt;&#39; (siehe save_konzepte()))
:return: no return :/
&#34;&#34;&#34;
if model.RECHNUNGSTYP == &#34;INST&#34;:
image = self.plot_settings(xshow=False)
else:
image = line_plot_gesamt(frame.new_get_konzept(), mode=0, xshow=False)
myPDF = PDF()
report_konzepte = defaultdict(dict)
inhaltsverzeichnis = {}
for konzeptname, konzeptobjekt in frame.konzepte.items():
kategorien = []
sorted_lst_cells = sorted(konzeptobjekt.cells, key=itemgetter(1))
for konzeptcell in sorted_lst_cells:
if model.RECHNUNGSTYP == &#34;INST&#34;:
kategorien.append((dct_cells[konzeptcell].value, konzeptcell))
else:
kategorien.append((model.get_dct_cells()[konzeptcell].value, konzeptcell, model.get_dct_cells()[konzeptcell].posten))
if model.RECHNUNGSTYP == &#34;INST&#34;:
years = worksheets
else:
years = range(1948, 2006)
for i, sheet in enumerate(years):
xkategorien = []
for kat in kategorien:
if kat[1][1] == i:
if model.RECHNUNGSTYP == &#34;INST&#34;:
xkategorien.append(kat[0])
else:
if kat[0][0].spezifizierung:
xkategorien.append([kat[0][0].bezeichnung + &#34; (&#34; + kat[0][0].spezifizierung + &#34;): &#34;,
str(round(kat[2].geldbetrag, 2))])
else:
xkategorien.append([kat[0][0].bezeichnung + &#34;: &#34;, str(round(kat[2].geldbetrag, 2))])
for item in xkategorien:
for i, x in enumerate(item):
item[i] = x.replace(&#39;–&#39;, &#39;-&#39;)
item[i] = x.replace(&#34;\u0308&#34;, &#34;_&#34;)
report_konzepte[konzeptname][sheet] = xkategorien
for toc in [False, True]:
if toc:
myPDF = PDF()
myPDF.add_page()
myPDF.set_font(&#39;Times&#39;, &#39;B&#39;, 12)
myPDF.cell(w=200, h=12, txt=&#34;Inhaltsverzeichnis&#34;, ln=2)
myPDF.set_font(&#39;Times&#39;, size=10)
myPDF.cell(w=20, h=10, txt=&#34; - &#34;)
link = myPDF.add_link()
myPDF.set_link(link, page=2)
myPDF.cell(w=100, h=10, txt=&#34;Diagramm&#34;, link=link, ln=1)
for konzeptname, page in inhaltsverzeichnis.items():
myPDF.cell(w=20, h=10, txt=&#34; - &#34;)
link = myPDF.add_link()
myPDF.set_link(link, page=page + 1)
myPDF.cell(w=100, h=10, txt=konzeptname, link=link, ln=1)
myPDF.set_font(&#39;Times&#39;, size=10)
# Grafiken
myPDF.add_page()
if image:
myPDF.image(image, w=200, h=150)
for konzeptname, sheets in report_konzepte.items():
myPDF.add_page()
myPDF.set_font(&#39;Times&#39;, &#39;B&#39;, 12)
myPDF.cell(w=50, h=12, txt=&#34;&#34;, ln=1)
myPDF.cell(w=10, h=12, txt=&#34;&#34;)
myPDF.cell(w=160, h=12, txt=konzeptname)
myPDF.set_font(&#39;Times&#39;, size=8)
myPDF.cell(w=50, h=12, txt=&#34;DM&#34;, ln=1)
if not toc:
inhaltsverzeichnis[konzeptname] = myPDF.page_no()
for sheet, txt in sheets.items():
x, y = myPDF.get_x(), myPDF.get_y()
myPDF.line(x + 20, y, x + 185, y)
summe = 0
for i, x in enumerate(txt):
myPDF.cell(w=10, h=8, txt=&#34;&#34;)
if i == 0:
myPDF.cell(w=10, h=8, txt=str(sheet))
else:
myPDF.cell(w=10, h=8, txt=&#34;&#34;)
y = myPDF.get_y()
myPDF.multi_cell(w=140, h=8, txt=x[0])
new_line_y = myPDF.get_y()
if new_line_y - y &gt; 10: # Wenn Multi_cell mit den Kategoriennamen einen linebreak hatte..
myPDF.set_xy(x=175, y=y+7) # .. dann Cell mit Beträgen eine Zeile tiefer.
else:
myPDF.set_xy(x=175, y=y) # .. sonst auf selber höhe.
myPDF.multi_cell(w=50, h=8, txt=x[1])
myPDF.set_y(new_line_y)
summe += float(x[1])
if len(txt) &gt; 1:
x, y = myPDF.get_x(), myPDF.get_y()
myPDF.line(x + 165, y, x + 180, y)
myPDF.cell(w=10, h=8, txt=&#34;&#34;)
myPDF.cell(w=10, h=8, txt=&#34;&#34;)
myPDF.cell(w=145, h=8, txt=&#34;SUMME:&#34;)
myPDF.cell(w=50, h=8, txt=str(round(summe, 2)), ln=1)
if toc:
myPDF.output(&#34;../../../Reports/&#34; + filename + &#39;.pdf&#39;, &#39;F&#39;)
os.system(&#39;open Test.pdf&amp;&#39;)
myPDF.close()</code></pre>
</details>
<h3>Ancestors</h3>
<ul class="hlist">
<li>wx._core.Frame</li>
<li>wx._core.TopLevelWindow</li>
<li>wx._core.NonOwnedWindow</li>
<li>wx._core.Window</li>
<li>wx._core.WindowBase</li>
<li>wx._core.EvtHandler</li>
<li>wx._core.Object</li>
<li>wx._core.Trackable</li>
<li>sip.wrapper</li>
<li>sip.simplewrapper</li>
</ul>
<h3>Methods</h3>
<dl>
<dt id="Finanzexplorer_Institute.InstitutsForm.Quit"><code class="name flex">
<span>def <span class="ident">Quit</span></span>(<span>self, _)</span>
</code></dt>
<dd>
<section class="desc"></section>
<details class="source">
<summary>Source code</summary>
<pre><code class="python">def Quit(self, _):
self.Close()</code></pre>
</details>
</dd>
<dt id="Finanzexplorer_Institute.InstitutsForm.add_konzept"><code class="name flex">
<span>def <span class="ident">add_konzept</span></span>(<span>self, _)</span>
</code></dt>
<dd>
<section class="desc"></section>
<details class="source">
<summary>Source code</summary>
<pre><code class="python">def add_konzept(self, _):
DialogNewKonzept(self, &#34;new concept&#34;).ShowModal()</code></pre>
</details>
</dd>
<dt id="Finanzexplorer_Institute.InstitutsForm.add_new_konzept"><code class="name flex">
<span>def <span class="ident">add_new_konzept</span></span>(<span>self, name, color)</span>
</code></dt>
<dd>
<section class="desc"></section>
<details class="source">
<summary>Source code</summary>
<pre><code class="python">def add_new_konzept(self, name, color):
self.konzept_listcontrol.InsertItem(self.list_ctrl_index, name)
self.konzept_listcontrol.SetItemTextColour(self.list_ctrl_index, color)
self.konzepte[name] = Konzept(name, color)
self.konzept_listcontrol.SetItemState(self.list_ctrl_index, wx.LIST_STATE_SELECTED, wx.LIST_STATE_SELECTED)
self.list_ctrl_index += 1
self.tmpStoredKonzepte = None</code></pre>
</details>
</dd>
<dt id="Finanzexplorer_Institute.InstitutsForm.button_click"><code class="name flex">
<span>def <span class="ident">button_click</span></span>(<span>self, _)</span>
</code></dt>
<dd>
<section class="desc"></section>
<details class="source">
<summary>Source code</summary>
<pre><code class="python">def button_click(self, _):
if frame.checkbox_sum.GetValue():
data = self.get_inst_konzepte()
line_plot_inst(data, typ=&#34;IST&#34;, grouping_by=&#34;Institute&#34;, mode=&#34;auto&#34;, inflation=False)
else:
self.plot_settings()</code></pre>
</details>
</dd>
<dt id="Finanzexplorer_Institute.InstitutsForm.button_click_gesamt"><code class="name flex">
<span>def <span class="ident">button_click_gesamt</span></span>(<span>self, _)</span>
</code></dt>
<dd>
<section class="desc"></section>
<details class="source">
<summary>Source code</summary>
<pre><code class="python">def button_click_gesamt(self, _):
line_plot_gesamt_settings()</code></pre>
</details>
</dd>
<dt id="Finanzexplorer_Institute.InstitutsForm.check_selection"><code class="name flex">
<span>def <span class="ident">check_selection</span></span>(<span>self, _)</span>
</code></dt>
<dd>
<section class="desc"></section>
<details class="source">
<summary>Source code</summary>
<pre><code class="python">def check_selection(self, _):
global active_konzeptColor
global active_konzept
if self.konzept_listcontrol.GetSelectedItemCount() == 0: # Wenn kein Konzept angewählt ist ..
active_konzeptColor = &#34;#ffffff&#34;
active_konzept = None</code></pre>
</details>
</dd>
<dt id="Finanzexplorer_Institute.InstitutsForm.checked_item"><code class="name flex">
<span>def <span class="ident">checked_item</span></span>(<span>self, _)</span>
</code></dt>
<dd>
<section class="desc"></section>
<details class="source">
<summary>Source code</summary>
<pre><code class="python">def checked_item(self, _):
if model.RECHNUNGSTYP == &#34;INST&#34;:
if len(self.checkbox.GetCheckedItems()) != 0:
self.static_text_02.SetLabel(&#34;Institute ({} selected):&#34;.format(len(self.checkbox.GetCheckedItems())))
else:
self.static_text_02.SetLabel(&#34;Institute:&#34;)
self.tmpStoredKonzepte = None</code></pre>
</details>
</dd>
<dt id="Finanzexplorer_Institute.InstitutsForm.colour_picked"><code class="name flex">
<span>def <span class="ident">colour_picked</span></span>(<span>self, event)</span>
</code></dt>
<dd>
<section class="desc"></section>
<details class="source">
<summary>Source code</summary>
<pre><code class="python">def colour_picked(self, event):
global active_konzeptColor
global active_konzept
active_konzeptColor = self.konzept_listcontrol.GetItemTextColour(event.GetIndex())
active_konzept = self.konzepte[self.konzept_listcontrol.GetItem(event.GetIndex()).GetText()]</code></pre>
</details>
</dd>
<dt id="Finanzexplorer_Institute.InstitutsForm.create_report"><code class="name flex">
<span>def <span class="ident">create_report</span></span>(<span>self, _, filename='Test')</span>
</code></dt>
<dd>
<section class="desc"><p>Erstellt eine PDF, zum einen mit dem Diagramm, zum anderen mit einer Jahresgenauen aufschlüsselung
der pro Konzept verwendeten Kategorien und ihrer Geldbeträge.</p>
<p>Zum erstellen eines Inhaltsverzeichnisses ('toc') muss der letzte Prozess zweimal durchlaufen werden.
Die Seitenangaben müssen beim ersten durchlauf gespeichert werden, das sie beim zweiten Durchlauf beim erstellen
des Inhaltsverzeichnisses bereits auf der ersten Seite zum erstellen der Links gebraucht werden.</p>
<p>:param <em>: not used
:param filename: Dateiname (Bislang nur 'Test'. Besser: 'Report</em><Konzeptnamen>' (siehe save_konzepte()))
:return: no return :/</p></section>
<details class="source">
<summary>Source code</summary>
<pre><code class="python">def create_report(self, _, filename=&#34;Test&#34;):
&#34;&#34;&#34;
Erstellt eine PDF, zum einen mit dem Diagramm, zum anderen mit einer Jahresgenauen aufschlüsselung
der pro Konzept verwendeten Kategorien und ihrer Geldbeträge.
Zum erstellen eines Inhaltsverzeichnisses (&#39;toc&#39;) muss der letzte Prozess zweimal durchlaufen werden.
Die Seitenangaben müssen beim ersten durchlauf gespeichert werden, das sie beim zweiten Durchlauf beim erstellen
des Inhaltsverzeichnisses bereits auf der ersten Seite zum erstellen der Links gebraucht werden.
:param _: not used
:param filename: Dateiname (Bislang nur &#39;Test&#39;. Besser: &#39;Report_&lt;Konzeptnamen&gt;&#39; (siehe save_konzepte()))
:return: no return :/
&#34;&#34;&#34;
if model.RECHNUNGSTYP == &#34;INST&#34;:
image = self.plot_settings(xshow=False)
else:
image = line_plot_gesamt(frame.new_get_konzept(), mode=0, xshow=False)
myPDF = PDF()
report_konzepte = defaultdict(dict)
inhaltsverzeichnis = {}
for konzeptname, konzeptobjekt in frame.konzepte.items():
kategorien = []
sorted_lst_cells = sorted(konzeptobjekt.cells, key=itemgetter(1))
for konzeptcell in sorted_lst_cells:
if model.RECHNUNGSTYP == &#34;INST&#34;:
kategorien.append((dct_cells[konzeptcell].value, konzeptcell))
else:
kategorien.append((model.get_dct_cells()[konzeptcell].value, konzeptcell, model.get_dct_cells()[konzeptcell].posten))
if model.RECHNUNGSTYP == &#34;INST&#34;:
years = worksheets
else:
years = range(1948, 2006)
for i, sheet in enumerate(years):
xkategorien = []
for kat in kategorien:
if kat[1][1] == i:
if model.RECHNUNGSTYP == &#34;INST&#34;:
xkategorien.append(kat[0])
else:
if kat[0][0].spezifizierung:
xkategorien.append([kat[0][0].bezeichnung + &#34; (&#34; + kat[0][0].spezifizierung + &#34;): &#34;,
str(round(kat[2].geldbetrag, 2))])
else:
xkategorien.append([kat[0][0].bezeichnung + &#34;: &#34;, str(round(kat[2].geldbetrag, 2))])
for item in xkategorien:
for i, x in enumerate(item):
item[i] = x.replace(&#39;–&#39;, &#39;-&#39;)
item[i] = x.replace(&#34;\u0308&#34;, &#34;_&#34;)
report_konzepte[konzeptname][sheet] = xkategorien
for toc in [False, True]:
if toc:
myPDF = PDF()
myPDF.add_page()
myPDF.set_font(&#39;Times&#39;, &#39;B&#39;, 12)
myPDF.cell(w=200, h=12, txt=&#34;Inhaltsverzeichnis&#34;, ln=2)
myPDF.set_font(&#39;Times&#39;, size=10)
myPDF.cell(w=20, h=10, txt=&#34; - &#34;)
link = myPDF.add_link()
myPDF.set_link(link, page=2)
myPDF.cell(w=100, h=10, txt=&#34;Diagramm&#34;, link=link, ln=1)
for konzeptname, page in inhaltsverzeichnis.items():
myPDF.cell(w=20, h=10, txt=&#34; - &#34;)
link = myPDF.add_link()
myPDF.set_link(link, page=page + 1)
myPDF.cell(w=100, h=10, txt=konzeptname, link=link, ln=1)
myPDF.set_font(&#39;Times&#39;, size=10)
# Grafiken
myPDF.add_page()
if image:
myPDF.image(image, w=200, h=150)
for konzeptname, sheets in report_konzepte.items():
myPDF.add_page()
myPDF.set_font(&#39;Times&#39;, &#39;B&#39;, 12)
myPDF.cell(w=50, h=12, txt=&#34;&#34;, ln=1)
myPDF.cell(w=10, h=12, txt=&#34;&#34;)
myPDF.cell(w=160, h=12, txt=konzeptname)
myPDF.set_font(&#39;Times&#39;, size=8)
myPDF.cell(w=50, h=12, txt=&#34;DM&#34;, ln=1)
if not toc:
inhaltsverzeichnis[konzeptname] = myPDF.page_no()
for sheet, txt in sheets.items():
x, y = myPDF.get_x(), myPDF.get_y()
myPDF.line(x + 20, y, x + 185, y)
summe = 0
for i, x in enumerate(txt):
myPDF.cell(w=10, h=8, txt=&#34;&#34;)
if i == 0:
myPDF.cell(w=10, h=8, txt=str(sheet))
else:
myPDF.cell(w=10, h=8, txt=&#34;&#34;)
y = myPDF.get_y()
myPDF.multi_cell(w=140, h=8, txt=x[0])
new_line_y = myPDF.get_y()
if new_line_y - y &gt; 10: # Wenn Multi_cell mit den Kategoriennamen einen linebreak hatte..
myPDF.set_xy(x=175, y=y+7) # .. dann Cell mit Beträgen eine Zeile tiefer.
else:
myPDF.set_xy(x=175, y=y) # .. sonst auf selber höhe.
myPDF.multi_cell(w=50, h=8, txt=x[1])
myPDF.set_y(new_line_y)
summe += float(x[1])
if len(txt) &gt; 1:
x, y = myPDF.get_x(), myPDF.get_y()
myPDF.line(x + 165, y, x + 180, y)
myPDF.cell(w=10, h=8, txt=&#34;&#34;)
myPDF.cell(w=10, h=8, txt=&#34;&#34;)
myPDF.cell(w=145, h=8, txt=&#34;SUMME:&#34;)
myPDF.cell(w=50, h=8, txt=str(round(summe, 2)), ln=1)
if toc:
myPDF.output(&#34;../../../Reports/&#34; + filename + &#39;.pdf&#39;, &#39;F&#39;)
os.system(&#39;open Test.pdf&amp;&#39;)
myPDF.close()</code></pre>
</details>
</dd>
<dt id="Finanzexplorer_Institute.InstitutsForm.delete_konzept"><code class="name flex">
<span>def <span class="ident">delete_konzept</span></span>(<span>self, _)</span>
</code></dt>
<dd>
<section class="desc"></section>
<details class="source">
<summary>Source code</summary>
<pre><code class="python">def delete_konzept(self, _):
global active_konzept, active_konzeptColor
self.myGrid.delete_konzept_in_grid()
# delete dct-entry
self.tmpStoredKonzepte = None
try:
del self.konzepte[active_konzept.name]
except AttributeError:
pass
# delete listCtrl-entry
self.list_ctrl_index -= 1
try:
self.konzept_listcontrol.DeleteItem(self.konzept_listcontrol.GetFocusedItem())
except AssertionError:
pass
# set new active konzept to last one in list...
items_in_listctrl = self.konzept_listcontrol.GetItemCount()
if items_in_listctrl &gt; 0:
active_konzept = self.konzepte[self.konzept_listcontrol.GetItem(items_in_listctrl - 1).GetText()]
active_konzeptColor = active_konzept.color
self.konzept_listcontrol.SetItemState(self.list_ctrl_index - 1,
wx.LIST_STATE_SELECTED,
wx.LIST_STATE_SELECTED)
# ...or to &#34;None&#34;, if list is empty
else:
active_konzept = None
active_konzeptColor = WHITE</code></pre>
</details>
</dd>
<dt id="Finanzexplorer_Institute.InstitutsForm.develope_mode"><code class="name flex">
<span>def <span class="ident">develope_mode</span></span>(<span>self, _)</span>
</code></dt>
<dd>
<section class="desc"><p>If develope_mode True, docstrings will be printed on console.</p></section>
<details class="source">
<summary>Source code</summary>
<pre><code class="python">def develope_mode(self, _):
&#34;&#34;&#34;
If develope_mode True, docstrings will be printed on console.
&#34;&#34;&#34;
global develope_mode
develope_mode = not develope_mode</code></pre>
</details>
</dd>
<dt id="Finanzexplorer_Institute.InstitutsForm.find_category"><code class="name flex">
<span>def <span class="ident">find_category</span></span>(<span>self, _)</span>
</code></dt>
<dd>
<section class="desc"><p>Es werden alle Zellen nach dem Suchbegriff durchsucht und bei Übereinstimmung hellblau eingefärbt. Zudem
werden diese Zellen in der Liste found_cells gespeichert.
Not case-sensitive. Falls erwünscht die .lower() herausnehmen.
Im Fall der Institute werden die ersten 8 Zeilen sowie graue Zellen nicht berücksichtigt.</p>
<p>:param _: not used
:return: no return :/</p></section>
<details class="source">
<summary>Source code</summary>
<pre><code class="python">def find_category(self, _):
&#34;&#34;&#34;
Es werden alle Zellen nach dem Suchbegriff durchsucht und bei Übereinstimmung hellblau eingefärbt. Zudem
werden diese Zellen in der Liste found_cells gespeichert.
Not case-sensitive. Falls erwünscht die .lower() herausnehmen.
Im Fall der Institute werden die ersten 8 Zeilen sowie graue Zellen nicht berücksichtigt.
:param _: not used
:return: no return :/
&#34;&#34;&#34;
self.unfind_category(_)
value = self.search_control.GetValue()
if model.RECHNUNGSTYP == &#34;INST&#34;:
for cell in dct_cells.values():
if value.lower() in cell.value.lower() and cell.row &gt; 8 and cell.color != &#34;#cccccc&#34;:
found_cells.append(cell)
self.myGrid.SetCellBackgroundColour(cell.row, cell.col, &#34;#d6ffff&#34;)
else:
for cell in model.get_dct_cells().values():
if value.lower() in cell.value[0].bezeichnung.lower():
found_cells.append(cell)
self.myGrid.SetCellBackgroundColour(cell.row, cell.col, &#34;#d6ffff&#34;)
self.myGrid.ForceRefresh()</code></pre>
</details>
</dd>
<dt id="Finanzexplorer_Institute.InstitutsForm.get_inst_konzepte"><code class="name flex">
<span>def <span class="ident">get_inst_konzepte</span></span>(<span>self)</span>
</code></dt>
<dd>
<section class="desc"></section>
<details class="source">
<summary>Source code</summary>
<pre><code class="python">def get_inst_konzepte(self):
# print(get_inst_konzepte().__name__)
if self.tmpStoredKonzepte: # spart Zeit, da nicht erneut die Excel-Tabellen geöffnet werden müssen
all_konzept_data = self.tmpStoredKonzepte
else:
# get_selected_institutes
checked_institutes_paths = []
for x in self.checkbox.GetCheckedItems():
checked_institutes_paths.append((self.get_institutes()[self.choices[x]][&#34;path&#34;], self.choices[x]))
# get existing concepts
dct_xkonzepte = defaultdict(dict)
tmp_xkonzepte = defaultdict(list)
for c in dct_cells.values():
if c.konzept:
tmp_xkonzepte[(worksheets[c.col], c.konzept.name)].append(c.value)
for sheet_konzeptname, lst in tmp_xkonzepte.items():
dct_xkonzepte[sheet_konzeptname[0]][sheet_konzeptname[1]] = lst
# worksheets = [&#34;1954-1963&#34;, &#34;1964-1966&#34;, &#34;1967&#34;, &#34;1968-1972&#34;, &#34;1973-1986&#34;, &#34;1987-1997&#34;, &#34;1998-2002&#34;]
# c.col = Spalte im interface = index aus der Liste &#39;worksheets&#39;
# dct_xkonzepte{&#34;1954-1963&#34;: {Konzeptname:[list of selected cells per year]}}
# get data according to the selected institutes AND existing concepts
all_konzept_data = {}
for path in checked_institutes_paths:
konzept_data = defaultdict(list)
wb = load_workbook(path[0], data_only=True)
for sheet in worksheets:
try:
ws = wb[sheet] # exp. Worksheet &#34;1954-1963&#34;
# get data (sheet by sheet) for each concept and store it in a list (each konzept has one list)
for konzeptname, conceptcells_per_year in dct_xkonzepte[sheet].items():
for row in range(1, ws.max_row+1):
for v in conceptcells_per_year:
if ws.cell(row, 1).value == v:
# hier wird in die Excel gegangen und
# nach der ausgewählten Zelle aus dem Interface gesucht
for col in range(1, ws.max_column+1):
if ws.cell(3, col).value and ws.cell(row, col).value not in [&#34;&#34;, &#34; &#34;, None,
&#34;None&#34;, &#34;0&#34;, 0]:
if sheet == &#34;1998-2002&#34; and col &gt; 12: # €-Werte
pass
else:
konzept_data[konzeptname].append(
ExcelCell(row=row,
col=col,
path=path,
sheet=sheet,
year=int(ws.cell(3, col).value),
typ=ws.cell(2, col).value,
category=ws.cell(row, 1).value,
betrag=float(ws.cell(row, col).value)))
except KeyError:
print(&#34;{} doesn&#39;t has sheet {}&#34;.format(path[0], sheet))
except ValueError:
print(&#34;\nWrong entry: {}\nPath: {}\nSheet: {}\nRow, Column: {}, {}\n&#34;.format(wb[sheet].cell(row, col).value, path[0], sheet, row, col))
all_konzept_data[path[1]] = konzept_data
for key, inst in all_konzept_data.items():
for name, lst in inst.items(): # lst = list of ExcelCell objects
lst.sort(key=lambda z: z.year)
for obj in lst:
self.konzepte[name].plots[key].append((obj.year, obj.betrag, obj.type))
# -----------------------------------
# # Summe wird immer auch gespeichert. Ob sie genutzt wird entscheidet self.summe in der Klasse Konzepte
for key, inst in all_konzept_data.items():
for name, lst in inst.items(): # lst = list of ExcelCell objects; name = Konzeptname
for obj in lst:
tmp_is_in_list = False
for index, x in enumerate(self.konzepte[name].plots[&#34;SUMME&#34;]):
if x[0] == obj.year and x[2] == obj.type:
tmp_lst = list(x)
tmp_lst[1] += obj.betrag
self.konzepte[name].plots[&#34;SUMME&#34;][index] = tuple(tmp_lst)
tmp_is_in_list = True
if not tmp_is_in_list:
self.konzepte[name].plots[&#34;SUMME&#34;].append((obj.year, obj.betrag, obj.type))
# -----------------------------------
self.tmpStoredKonzepte = all_konzept_data
return all_konzept_data</code></pre>
</details>
</dd>
<dt id="Finanzexplorer_Institute.InstitutsForm.get_institutes"><code class="name flex">
<span>def <span class="ident">get_institutes</span></span>(<span>self)</span>
</code></dt>
<dd>
<section class="desc"></section>
<details class="source">
<summary>Source code</summary>
<pre><code class="python">def get_institutes(self):
return self.institute</code></pre>
</details>
</dd>
<dt id="Finanzexplorer_Institute.InstitutsForm.load_konzept"><code class="name flex">
<span>def <span class="ident">load_konzept</span></span>(<span>self, _, filepath)</span>
</code></dt>
<dd>
<section class="desc"><p>Das Json aus der Datei wird als Dictionary geladen und die Informationen verarpeitet,
sprich: Rechnungstyp gesetzt, richtige Interface laden, Zellen des Konzepts entsprechend eingefärbt und
Konzepte im FRame gespeichert.</p>
<p>:param _: not used
:param filepath: Pfad zur Datei
:return: no return :/</p></section>
<details class="source">
<summary>Source code</summary>
<pre><code class="python">def load_konzept(self, _, filepath):
&#34;&#34;&#34;
Das Json aus der Datei wird als Dictionary geladen und die Informationen verarpeitet,
sprich: Rechnungstyp gesetzt, richtige Interface laden, Zellen des Konzepts entsprechend eingefärbt und
Konzepte im FRame gespeichert.
:param _: not used
:param filepath: Pfad zur Datei
:return: no return :/
&#34;&#34;&#34;
global active_konzept, active_konzeptColor
with open(filepath) as infile:
dct_infile = json.load(infile)
checked_items = []
for k, v in dct_infile.items(): # k = Konzeptname, v = &lt;dict&gt; Kozept (Keys = Attr der Class Konzept)
if model.RECHNUNGSTYP == &#34;&#34;:
model.RECHNUNGSTYP = v[&#34;rechnungstyp&#34;]
self.set_interface(_=None, typ=v[&#34;rechnungstyp&#34;])
if v[&#34;rechnungstyp&#34;] == model.RECHNUNGSTYP:
self.add_new_konzept(k, v[&#34;color&#34;])
for cell_pos in v[&#34;cells&#34;]:
if model.RECHNUNGSTYP == &#34;INST&#34;:
c = dct_cells[(cell_pos[0], cell_pos[1])]
else:
c = model.get_dct_cells()[(cell_pos[0], cell_pos[1])]
if c.color != v[&#34;color&#34;]:
active_konzeptColor = v[&#34;color&#34;]
c.color = active_konzeptColor
active_konzept = self.konzepte[k]
c.konzept = active_konzept
if (cell_pos[0], cell_pos[1]) not in self.konzepte[k].cells:
self.konzepte[k].cells.append((cell_pos[0], cell_pos[1]))
self.myGrid.SetCellBackgroundColour(c.row, c.col, c.color)
if v[&#34;rechnungstyp&#34;] == &#34;INST&#34;:
for inst in v[&#34;plots&#34;].keys():
if inst != &#34;SUMME&#34;:
checked_items.append(inst.capitalize())
else:
self.checkbox_sum.SetValue(True)
if v[&#34;rechnungstyp&#34;] != &#34;Inst&#34;:
for cell_pos in v[&#34;uncertain&#34;]:
frame.myGrid.SetCellTextColour(cell_pos[0], cell_pos[1], v[&#34;color&#34;])
else:
msg = &#34;File &#39;{}&#39; is not of type &#39;{}&#39;\n\n&#34; \
&#34;Unsaved changes will be discarded!\n\n&#34; \
&#34;Do you want to proceed?&#34;.format(filepath.split(&#34;/&#34;)[-1], model.RECHNUNGSTYP)
dlg = wx.MessageDialog(self, msg, &#39;Warning&#39;, style=wx.YES_NO | wx.ICON_QUESTION | wx.CENTRE)
result = dlg.ShowModal()
if result == wx.ID_YES:
model.RECHNUNGSTYP = v[&#34;rechnungstyp&#34;]
self.set_interface(_, v[&#34;rechnungstyp&#34;])
self.add_new_konzept(k, v[&#34;color&#34;])
for cell_pos in v[&#34;cells&#34;]:
if model.RECHNUNGSTYP == &#34;INST&#34;:
c = dct_cells[(cell_pos[0], cell_pos[1])]
else:
c = model.get_dct_cells()[(cell_pos[0], cell_pos[1])]
if c.color != v[&#34;color&#34;]:
active_konzeptColor = v[&#34;color&#34;]
c.color = active_konzeptColor
active_konzept = self.konzepte[k]
c.konzept = active_konzept
if (cell_pos[0], cell_pos[1]) not in self.konzepte[k].cells:
self.konzepte[k].cells.append((cell_pos[0], cell_pos[1]))
self.myGrid.SetCellBackgroundColour(c.row, c.col, c.color)
if v[&#34;rechnungstyp&#34;] == &#34;INST&#34;:
for inst in v[&#34;plots&#34;].keys():
if inst != &#34;SUMME&#34;:
checked_items.append(inst.capitalize())
else:
break
self.checkbox.SetCheckedStrings(checked_items)
active_konzeptColor = &#34;#ffffff&#34;
self.checked_item(_=None)
self.myGrid.ForceRefresh()</code></pre>
</details>
</dd>
<dt id="Finanzexplorer_Institute.InstitutsForm.load_konzepte_picker"><code class="name flex">
<span>def <span class="ident">load_konzepte_picker</span></span>(<span>self, _)</span>
</code></dt>
<dd>
<section class="desc"><p>Dialogfeld zum auswählen der zu ladenden Datei wird geöffnet.</p>
<p>:param _:
:return: Boolean = Datei wurde ausgewählt oder nicht.</p></section>
<details class="source">
<summary>Source code</summary>
<pre><code class="python">def load_konzepte_picker(self, _):
&#34;&#34;&#34;
Dialogfeld zum auswählen der zu ladenden Datei wird geöffnet.
:param _:
:return: Boolean = Datei wurde ausgewählt oder nicht.
&#34;&#34;&#34;
filedlg = wx.FileDialog(self.p, &#34;Load&#34;, style=wx.FD_OPEN | wx.FD_FILE_MUST_EXIST)
filedlg.ShowModal()
filepath = filedlg.GetPath()
if filepath:
self.load_konzept(_, filepath)
return True
else:
return False</code></pre>
</details>
</dd>
<dt id="Finanzexplorer_Institute.InstitutsForm.menuBar"><code class="name flex">
<span>def <span class="ident">menuBar</span></span>(<span>self)</span>
</code></dt>
<dd>
<section class="desc"></section>
<details class="source">
<summary>Source code</summary>
<pre><code class="python">def menuBar(self):
menuBar = wx.MenuBar()
fileButton = wx.Menu()
openMenu = wx.Menu()
openItem01 = openMenu.Append(-1, &#39;Institutsexplorer&#39;)
openItem02 = openMenu.Append(-1, &#39;Einnahmen-Ausgabenrechnung&#39;)
openItem03 = openMenu.Append(-1, &#39;Vermögensübersicht&#39;)
fileButton.Append(-1, &#39;Open ..&#39;, openMenu)
openInNewWindowItem = fileButton.Append(-1, &#39;Open new Window&#39;)
fileButton.AppendSeparator()
create_report = fileButton.Append(-1, &#34;create Report (PDF)&#34;)
fileButton.AppendSeparator()
exitItem = fileButton.Append(-1, &#39;Exit&#39;, &#39;status msg...&#39;)
menuBar.Append(fileButton, &#39;File&#39;)
runButton = wx.Menu()
self.plotItem = runButton.Append(-1, &#39;create Graphs&#39;)
menuBar.Append(runButton, &#39;Run&#39;)
helpButton = wx.Menu()
templateItem = helpButton.Append(-1, &#39;show Template&#39;)
developeItem = helpButton.Append(-1, &#39;develope mode&#39;)
menuBar.Append(helpButton, &#39;help&#39;)
self.SetMenuBar(menuBar)
self.Bind(wx.EVT_MENU, self.Quit, exitItem)
self.Bind(wx.EVT_MENU, lambda event: self.set_interface_alert(event, &#39;INST&#39;), openItem01)
self.Bind(wx.EVT_MENU, lambda event: self.set_interface_alert(event, &#39;EA&#39;), openItem02)
self.Bind(wx.EVT_MENU, lambda event: self.set_interface_alert(event, &#39;VÜ&#39;), openItem03)
self.Bind(wx.EVT_MENU, self.new_window, openInNewWindowItem)
self.Bind(wx.EVT_MENU, self.create_report, create_report)
self.Bind(wx.EVT_MENU, self.open_template, templateItem)
self.Bind(wx.EVT_MENU, self.develope_mode, developeItem)</code></pre>
</details>
</dd>
<dt id="Finanzexplorer_Institute.InstitutsForm.new_get_konzept"><code class="name flex">
<span>def <span class="ident">new_get_konzept</span></span>(<span>self)</span>
</code></dt>
<dd>
<section class="desc"><p>Es werden alle Zellen der Obj Schemata durchgegangen und geschaut, welche Zellen zu einem Konzept gehören.
Diese Zellen mit Konzept werden in einem Dict unter dem Key des Konzepts
und der entsprechenden Jahreszahl gespeichert.</p>
<p>Besser: Nicht in den Cell-obj das Konzept speichern, sondern in den Konzepten die tatsächlichen Cell-obj.
So wäre es möglich, direkt anhand der Konzepte die richtigen Zellen anzusteuern und man muss nicht
alle Zellen (auch die ohne Konzept) durchsuchen. Beide Verbindungen (Cell -&gt; Konzept und Konzept -&gt; Cell)
gleichzeitig sind nicht möglich, da so eine schleife entstehen würde, die beim erzeugen eines json
zum Error führen würde (siehe save_konzepte()).</p>
<p>:return: dct_xkonzepte = <dict> {Konzeptname: <list> [(Jahr, Betrag), (Jahr, Betrag),..], Konzeptname:..}</p></section>
<details class="source">
<summary>Source code</summary>
<pre><code class="python">def new_get_konzept(self):
&#34;&#34;&#34;
Es werden alle Zellen der Obj Schemata durchgegangen und geschaut, welche Zellen zu einem Konzept gehören.
Diese Zellen mit Konzept werden in einem Dict unter dem Key des Konzepts
und der entsprechenden Jahreszahl gespeichert.
Besser: Nicht in den Cell-obj das Konzept speichern, sondern in den Konzepten die tatsächlichen Cell-obj.
So wäre es möglich, direkt anhand der Konzepte die richtigen Zellen anzusteuern und man muss nicht
alle Zellen (auch die ohne Konzept) durchsuchen. Beide Verbindungen (Cell -&gt; Konzept und Konzept -&gt; Cell)
gleichzeitig sind nicht möglich, da so eine schleife entstehen würde, die beim erzeugen eines json
zum Error führen würde (siehe save_konzepte()).
:return: dct_xkonzepte = &lt;dict&gt; {Konzeptname: &lt;list&gt; [(Jahr, Betrag), (Jahr, Betrag),..], Konzeptname:..}
&#34;&#34;&#34;
tmp_dct_xkonzepte = defaultdict(dict)
dct_xkonzepte = defaultdict(list)
for s in model.get_dct_schemata().values():
if s.typ == model.RECHNUNGSTYP:
for kon in self.konzepte.values():
tmp_dct_xkonzepte[kon.name][s.jahr] = None
for c in s.cells:
if c.konzept:
if tmp_dct_xkonzepte[c.konzept.name][s.jahr] is None:
tmp_dct_xkonzepte[c.konzept.name][s.jahr] = 0.00
if c.jahr &gt;= 2001:
tmp_dct_xkonzepte[c.konzept.name][s.jahr] += (c.posten.geldbetrag * 1.95583) # DM -&gt; €
else:
tmp_dct_xkonzepte[c.konzept.name][s.jahr] += c.posten.geldbetrag
for name, konzept in tmp_dct_xkonzepte.items():
for year, v_values in konzept.items():
dct_xkonzepte[name].append((year, v_values))
dct_xkonzepte[name].sort(key=lambda x: x[0])
self.konzepte[name].plots[&#34;MPG-Gesamt&#34;] = dct_xkonzepte[name]
return dct_xkonzepte</code></pre>
</details>
</dd>
<dt id="Finanzexplorer_Institute.InstitutsForm.new_window"><code class="name flex">
<span>def <span class="ident">new_window</span></span>(<span>self, _)</span>
</code></dt>
<dd>
<section class="desc"><p>Öffnet den Finanzexplorer erneut, um zum Beispiel parallel an der Einnahmen-/Ausgabenrechnung und
der Vermögensübersicht arbeiten zu können.</p>
<p>:param _: wx-event (not used)</p></section>
<details class="source">
<summary>Source code</summary>
<pre><code class="python">def new_window(self, _):
&#34;&#34;&#34;
Öffnet den Finanzexplorer erneut, um zum Beispiel parallel an der Einnahmen-/Ausgabenrechnung und
der Vermögensübersicht arbeiten zu können.
:param _: wx-event (not used)
&#34;&#34;&#34;
os.system(&#39;venv/bin/python Finanzexplorer_Institute.py&amp;&#39;)</code></pre>
</details>
</dd>
<dt id="Finanzexplorer_Institute.InstitutsForm.open_template"><code class="name flex">
<span>def <span class="ident">open_template</span></span>(<span>self, _)</span>
</code></dt>
<dd>
<section class="desc"><p>öffnet das Excel-Template, welches wir zum einen bei der Datenaufnahme aus den Haushaltsplänen
als Vorlage verwendet haben, zum anderen wurde anhand des Templates das Grid-Interface für die
Institute im Finanzexplorer erzeugt.</p>
<p>:param _: wx-event (not used)</p></section>
<details class="source">
<summary>Source code</summary>
<pre><code class="python">def open_template(self, _):
&#34;&#34;&#34;
öffnet das Excel-Template, welches wir zum einen bei der Datenaufnahme aus den Haushaltsplänen
als Vorlage verwendet haben, zum anderen wurde anhand des Templates das Grid-Interface für die
Institute im Finanzexplorer erzeugt.
:param _: wx-event (not used)
&#34;&#34;&#34;
os.system(&#39;open Institute/Haushaltsbücher_MPI_Template.xlsx&amp;&#39;)</code></pre>
</details>
</dd>
<dt id="Finanzexplorer_Institute.InstitutsForm.plot_settings"><code class="name flex">
<span>def <span class="ident">plot_settings</span></span>(<span>self, xshow=True)</span>
</code></dt>
<dd>
<section class="desc"></section>
<details class="source">
<summary>Source code</summary>
<pre><code class="python">def plot_settings(self, xshow=True):
data = self.get_inst_konzepte()
return_code = str(DialogPlotSettings(self, title=&#34;plot settings&#34;).ShowModal())
if len(return_code) == 5: # Prüfnummer (Länge 5 bedeutet Fenster wurde nicht geschlossen)
typ = [&#34;IST&#34;, &#34;SOLL&#34;, &#34;IST &amp; SOLL&#34;][int(return_code[0]) - 1]
grouping_by = [&#34;Institute&#34;, &#34;Konzept&#34;][int(return_code[1]) - 1]
mode = [&#34;auto&#34;, &#34;compareable&#34;][int(return_code[2]) - 1]
inflation = [False, True][int(return_code[3]) - 1]
if not xshow:
image = line_plot_inst(data, typ, grouping_by=grouping_by, mode=mode, inflation=inflation, xshow=False)
return image
else:
line_plot_inst(data, typ, grouping_by=grouping_by, mode=mode, inflation=inflation, xshow=True)
else:
pass</code></pre>
</details>
</dd>
<dt id="Finanzexplorer_Institute.InstitutsForm.reset_konzepte"><code class="name flex">
<span>def <span class="ident">reset_konzepte</span></span>(<span>self, _)</span>
</code></dt>
<dd>
<section class="desc"></section>
<details class="source">
<summary>Source code</summary>
<pre><code class="python">def reset_konzepte(self, _):
self.konzepte = {}
self.konzept_listcontrol.DeleteAllItems()
self.list_ctrl_index = 0
self.myGrid.reset_all_categories()
for item in self.checkbox.GetCheckedItems():
self.checkbox.Check(item, False)
self.checked_item(_=None)
self.tmpStoredKonzepte = None</code></pre>
</details>
</dd>
<dt id="Finanzexplorer_Institute.InstitutsForm.save_konzepte"><code class="name flex">
<span>def <span class="ident">save_konzepte</span></span>(<span>self, _)</span>
</code></dt>
<dd>
<section class="desc"><p>Anhand der erstellten Konzepte wird ein defaul-filename erzeugt. In dieser Datei wird das dict frame.konzepte
als json gespeichert.</p>
<p>:param _: not used
:return: no return :/</p></section>
<details class="source">
<summary>Source code</summary>
<pre><code class="python">def save_konzepte(self, _):
&#34;&#34;&#34;
Anhand der erstellten Konzepte wird ein defaul-filename erzeugt. In dieser Datei wird das dict frame.konzepte
als json gespeichert.
:param _: not used
:return: no return :/
&#34;&#34;&#34;
konzeptnames = []
for x in self.checkbox.GetCheckedItems():
konzeptnames.append(self.choices[x])
konzeptnames.append(&#34;_&#34;)
for k, v in self.konzepte.items():
konzeptnames.append(k)
konzeptnames.append(&#34;_&#34;)
str_konzeptnames = &#39;&#39;.join(konzeptnames)
str_konzeptnames = str_konzeptnames[:len(str_konzeptnames) - 1] # um den letzen Unterstrich zu löschen
str_konzeptnames = str_konzeptnames.replace(&#34;/&#34;, &#34;-&#34;) # um keinen subfolder zu erzeugen (Error)
new_filename = model.RECHNUNGSTYP + &#34;_&#34; + str_konzeptnames
filedlg = wx.FileDialog(self.p, &#34;Save Konzept&#34;, defaultFile=new_filename, style=wx.FD_SAVE)
filedlg.ShowModal()
filepath = filedlg.GetPath()
if filepath:
if model.RECHNUNGSTYP == &#34;INST&#34;:
self.get_inst_konzepte()
else:
self.new_get_konzept()
with open(filepath, &#34;w&#34;) as outfile:
json.dump(self.konzepte, outfile, default=lambda o: o.__dict__)</code></pre>
</details>
</dd>
<dt id="Finanzexplorer_Institute.InstitutsForm.set_institutes"><code class="name flex">
<span>def <span class="ident">set_institutes</span></span>(<span>self)</span>
</code></dt>
<dd>
<section class="desc"><p>Liest die Namen und Pfade aller relevanten Excel-Dateien aus dem Ordner 'Institute' ein und
speichert sie im dict self.institute unter dem Key des Institutsnamens. Nested dict 'path' and 'file'
:return:</p></section>
<details class="source">
<summary>Source code</summary>
<pre><code class="python">def set_institutes(self):
&#34;&#34;&#34;
Liest die Namen und Pfade aller relevanten Excel-Dateien aus dem Ordner &#39;Institute&#39; ein und
speichert sie im dict self.institute unter dem Key des Institutsnamens. Nested dict &#39;path&#39; and &#39;file&#39;
:return:
&#34;&#34;&#34;
if develope_mode:
print(help(self.set_institutes))
for (dirpath, dirnames, filenames) in os.walk(&#34;../Finanzexplorer-Git-data/Institute&#34;):
filenames = [x for x in filenames
if &#34;Haushaltsb&#34; in x
and &#34;.xlsx&#34; in x
and &#34;Template&#34; not in x
and &#34;Haushaltsbücher_MPG_gesamt.xlsx&#34; not in x
and &#34;_All&#34; not in x]
for f in filenames:
if f.split(&#34;_&#34;)[1] == &#34;MPI&#34;:
name = f[21:len(f)-5].lower()
else:
name = f[17:len(f) - 5].lower()
name = name.capitalize()
self.institute[name][&#34;path&#34;] = os.path.join(dirpath, f)
self.institute[name][&#34;file&#34;] = f</code></pre>
</details>
</dd>
<dt id="Finanzexplorer_Institute.InstitutsForm.set_interface"><code class="name flex">
<span>def <span class="ident">set_interface</span></span>(<span>self, _, typ)</span>
</code></dt>
<dd>
<section class="desc"><p>wxFrame wird nach dem 'richtigen' Rechnungstyp ausgerichtet: wxWidgets werden neue Funktionen zugeteilt.</p>
<p>:param _: wx-event (not used)
:param typ: Zur Unterscheidung von EA = Einnahmen-/Ausgabenrechnung, VÜ = Vermögensübersicht, INST = Institute
:return:</p></section>
<details class="source">
<summary>Source code</summary>
<pre><code class="python">def set_interface(self, _, typ):
&#34;&#34;&#34;
wxFrame wird nach dem &#39;richtigen&#39; Rechnungstyp ausgerichtet: wxWidgets werden neue Funktionen zugeteilt.
:param _: wx-event (not used)
:param typ: Zur Unterscheidung von EA = Einnahmen-/Ausgabenrechnung, VÜ = Vermögensübersicht, INST = Institute
:return:
&#34;&#34;&#34;
# erase old interface and data
fresh_new_start()
frame.reset_konzepte(_)
# set new interface and data
model.RECHNUNGSTYP = typ
if model.RECHNUNGSTYP == &#34;EA&#34;: # User-Interface for Einnahmen-/Ausgabenrechnung
model.superkategorien = [68, 92]
frame.SetTitle(&#34;Finanzexplorer - MPG Gesamt - Einnahmen-/ Ausgabenrechnung&#34;)
elif model.RECHNUNGSTYP == &#34;VÜ&#34;: # User-Interface for Vermögensübersicht
model.superkategorien = [1, 2]
frame.SetTitle(&#34;Finanzexplorer - MPG Gesamt - Vermögensübersicht&#34;)
# Superkategorien sind die &#39;Wurzeln&#39; des Schema-Baums in EA und VÜ.
# Also den Kategorien &#34;Einnahmen&#34;, &#34;Ausgaben&#34;, &#34;Aktiva&#34; und &#34;Passiva&#34;.
# Die Zahlen entsprechen den Kategorie-IDs in der Finanz-DB.
if model.RECHNUNGSTYP == &#34;INST&#34;:
frame.SetTitle(&#34;Finanzexplorer - MPG Institute&#34;)
self.checkbox_sum.SetLabel(&#34;Sum institutes&#34;)
self.set_institutes()
self.choices = [x for x in self.get_institutes().keys()]
self.choices.sort()
self.checkbox.Set(self.choices)
import_inst_template()
# Bindings for &#34;INST&#34;
self.button.Bind(wx.EVT_BUTTON, self.button_click)
self.myGrid.Bind(wx.grid.EVT_GRID_CELL_LEFT_DCLICK, self.myGrid.select_cell)
self.Bind(wx.EVT_MENU, self.button_click, self.plotItem)
self.checked_item(_=None)
self.sizer_controller.Show(self.checkbox_sum)
self.sizer_controller.Layout()
else: # for &#34;EA&#34; or &#34;VÜ&#34;
self.checkbox.Set([])
self.choices_files = [x for x in get_saves().keys()]
self.checkbox.Set(self.choices_files)
import_mpg_gesamt_data()
populate_cells()
self.static_text_02.SetLabel(&#34;Saved Conzepts:&#34;)
# Bindings for &#34;EA&#34; or &#34;VÜ&#34;
self.button.Bind(wx.EVT_BUTTON, self.button_click_gesamt)
self.myGrid.Bind(wx.grid.EVT_GRID_CELL_LEFT_DCLICK, self.myGrid.trigger_kategorie)
self.myGrid.Bind(wx.grid.EVT_GRID_CELL_RIGHT_CLICK, self.myGrid.show_popup_menu)
self.Bind(wx.EVT_MENU, self.button_click_gesamt, self.plotItem)
self.sizer_controller.Hide(self.checkbox_sum)
self.sizer_controller.Layout()
# Bindings for all types
self.btn_add.Bind(wx.EVT_BUTTON, self.add_konzept)
self.konzept_listcontrol.Bind(wx.EVT_LIST_ITEM_SELECTED, self.colour_picked)
self.konzept_listcontrol.Bind(wx.EVT_LIST_ITEM_DESELECTED, self.check_selection)
self.btn_reset.Bind(wx.EVT_BUTTON, self.reset_konzepte)
self.btn_delete.Bind(wx.EVT_BUTTON, self.delete_konzept)
self.btn_save.Bind(wx.EVT_BUTTON, self.save_konzepte)</code></pre>
</details>
</dd>
<dt id="Finanzexplorer_Institute.InstitutsForm.set_interface_alert"><code class="name flex">
<span>def <span class="ident">set_interface_alert</span></span>(<span>self, _, typ)</span>
</code></dt>
<dd>
<section class="desc"><p>Falls bereits ein Interface eines bestimmten Rechnungstyps geöffnet ist und nicht dem entspricht,
der gerade geöffnet werden soll, erscheint eine Warnung, dass noch ungespeicherte Konzepte verloren gehen.</p>
<p>:param _: wx-event (not used)
:param typ: Zur Unterscheidung von EA = Einnahmen-/Ausgabenrechnung, VÜ = Vermögensübersicht, INST = Institute
:return:</p></section>
<details class="source">
<summary>Source code</summary>
<pre><code class="python">def set_interface_alert(self, _, typ):
&#34;&#34;&#34;
Falls bereits ein Interface eines bestimmten Rechnungstyps geöffnet ist und nicht dem entspricht,
der gerade geöffnet werden soll, erscheint eine Warnung, dass noch ungespeicherte Konzepte verloren gehen.
:param _: wx-event (not used)
:param typ: Zur Unterscheidung von EA = Einnahmen-/Ausgabenrechnung, VÜ = Vermögensübersicht, INST = Institute
:return:
&#34;&#34;&#34;
if model.RECHNUNGSTYP == &#34;&#34;:
self.set_interface(_, typ)
elif model.RECHNUNGSTYP == typ:
pass
else:
msg = &#34;Unsaved changes will be discarded!\n\nDo you want to proceed?&#34;
dlg = wx.MessageDialog(self, msg, &#39;Warning&#39;, style=wx.YES_NO | wx.ICON_QUESTION | wx.CENTRE)
result = dlg.ShowModal()
if result == wx.ID_YES:
self.set_interface(_, typ)
else:
pass</code></pre>
</details>
</dd>
<dt id="Finanzexplorer_Institute.InstitutsForm.unfind_category"><code class="name flex">
<span>def <span class="ident">unfind_category</span></span>(<span>self, _)</span>
</code></dt>
<dd>
<section class="desc"><p>Zellen aus der Liste found_cells erhalten wieder ihre ursprüngliche Farbe (Farbe aus <Cell-Obj>.color).</p>
<p>:param _: not used
:return: no return :/</p></section>
<details class="source">
<summary>Source code</summary>
<pre><code class="python">def unfind_category(self, _):
&#34;&#34;&#34;
Zellen aus der Liste found_cells erhalten wieder ihre ursprüngliche Farbe (Farbe aus &lt;Cell-Obj&gt;.color).
:param _: not used
:return: no return :/
&#34;&#34;&#34;
global found_cells
for cell in found_cells:
self.myGrid.SetCellBackgroundColour(cell.row, cell.col, cell.color)
found_cells = []
self.myGrid.ForceRefresh()</code></pre>
</details>
</dd>
</dl>
</dd>
<dt id="Finanzexplorer_Institute.Konzept"><code class="flex name class">
<span>class <span class="ident">Konzept</span></span>
<span>(</span><span>name, color)</span>
</code></dt>
<dd>
<section class="desc"></section>
<details class="source">
<summary>Source code</summary>
<pre><code class="python">class Konzept:
def __init__(self, name, color):
self.rechnungstyp = model.RECHNUNGSTYP
self.name = name
self.color = color
self.cells = [] # not the real cell_objects, just the position as (row, col);
# Beim laden eines gespeicherten Konzepts werden diese Zellen in der Konzeptfarbe markiert
self.plots = defaultdict(list)
self.uncertain = []</code></pre>
</details>
</dd>
<dt id="Finanzexplorer_Institute.MyGrid"><code class="flex name class">
<span>class <span class="ident">MyGrid</span></span>
<span>(</span><span>parent)</span>
</code></dt>
<dd>
<section class="desc"><p>Grid()
Grid(parent, id=wx.ID_ANY, pos=wx.DefaultPosition, size=wx.DefaultSize, style=wx.WANTS_CHARS, name=GridNameStr)</p>
<p>wxGrid and its related classes are used for displaying and editing
tabular data.</p>
<p>Constructor</p></section>
<details class="source">
<summary>Source code</summary>
<pre><code class="python">class MyGrid(wx.grid.Grid): # &#39;Mouse vs. Python&#39; hat mir Anfangs sehr geholfen, um mit den Grids in wxPython umzugehen.
# http://www.blog.pythonlibrary.org/2010/04/04/wxpython-grid-tips-and-tricks/
def __init__(self, parent): # Durch die erste __init__ wird nichts mehr vom parent (wx.grid.Grid) geerbt..
&#34;&#34;&#34;Constructor&#34;&#34;&#34;
wx.grid.Grid.__init__(self, parent) # ..um dennoch zu erben, muss die parent.__init__ aufgerufen werden
self.parent = parent
self.CreateGrid(200, 58)
# self.SetRowSize(0, 60)
for i in range(58):
self.SetColSize(i, 240)
self.SetRowLabelSize(0)
self.SetMargins(0, 0)
self.this_row = 0
self.this_col = 0
self.GetGridWindow().Bind(wx.EVT_MOTION, self.on_mouse_over)
self.Show()
def on_mouse_over(self, event):
&#34;&#34;&#34;
Displays a tooltip over any cell in a certain column
&#34;&#34;&#34;
# This method was suggested by none other than Robin Dunn
# http://www.blog.pythonlibrary.org/2010/04/04/wxpython-grid-tips-and-tricks/
# https://alldunn.com/robin/
x, y = self.CalcUnscrolledPosition(event.GetX(), event.GetY())
coords = self.XYToCell(x, y)
try:
if model.RECHNUNGSTYP != &#34;INST&#34;:
msg = &#34;{} {}: {}&#34;.format(model.get_dct_cells()[(coords[0], coords[1])].value[0].bezeichnung,
model.get_dct_cells()[(coords[0], coords[1])].jahr,
model.get_dct_cells()[(coords[0], coords[1])].posten.geldbetrag)
event.GetEventObject().SetToolTip(msg)
else:
pass
except KeyError: # for empty cells
pass
except AttributeError: # for cells without oberkategorie
pass
def show_popup_menu(self, event):
self.this_row = event.GetRow()
self.this_col = event.GetCol()
if not hasattr(self, &#34;popupID1&#34;):
self.popupID1 = wx.NewId()
self.popupID2 = wx.NewId()
self.popupID3 = wx.NewId()
self.popupID4 = wx.NewId()
self.popupID5 = wx.NewId()
self.popupID6 = wx.NewId()
menu = wx.Menu()
item = wx.MenuItem(menu, self.popupID1, &#34;trigger Cell&#34;)
item_02 = wx.MenuItem(menu, self.popupID2, &#34;trigger category&#34;)
item_03 = wx.MenuItem(menu, self.popupID3, &#34;select whole category&#34;)
item_04 = wx.MenuItem(menu, self.popupID4, &#34;unselect whole Category&#34;)
item_uncertain_cat = wx.MenuItem(menu, self.popupID5, &#34;uncertain&#34;)
item_uncertain = wx.MenuItem(menu, self.popupID6, &#34;uncertain&#34;)
sub_menu = wx.Menu()
sub_menu.Append(item_02)
sub_menu.Append(item_03)
sub_menu.Append(item_04)
sub_menu.Append(item_uncertain_cat)
menu.Append(item)
menu.Append(wx.NewId(), &#34;Category&#34;, sub_menu)
menu.Append(item_uncertain)
self.PopupMenu(menu)
self.Bind(wx.EVT_MENU, self.select_cell, item)
self.Bind(wx.EVT_MENU, self.trigger_kategorie_from_popup, item_02)
self.Bind(wx.EVT_MENU, self.select_whole_category_from_popup, item_03)
self.Bind(wx.EVT_MENU, self.unselect_whole_category_from_popup, item_04)
self.Bind(wx.EVT_MENU, self.select_uncertain_from_popup, item_uncertain)
self.Bind(wx.EVT_MENU, self.select_uncertain_cat_from_popup, item_uncertain_cat)
menu.Destroy()
def trigger_kategorie_from_popup(self, _):
kat_id = self.get_cell(self.this_row, self.this_col).value[0].id
for c in model.get_dct_cells().values():
if c.value[0].id == kat_id:
if c.color != active_konzeptColor:
c.color = active_konzeptColor
c.konzept = active_konzept
if (c.row, c.col) not in self.parent.GetParent().konzepte[c.konzept.name].cells:
self.parent.GetParent().konzepte[c.konzept.name].cells.append((c.row, c.col))
else:
if c.color != WHITE:
self.parent.GetParent().konzepte[c.konzept.name].cells.remove((c.row, c.col))
c.color = WHITE
c.konzept = None
self.SetCellBackgroundColour(c.row, c.col, c.color)
self.ForceRefresh()
def select_whole_category_from_popup(self, _):
kat_id = self.get_cell(self.this_row, self.this_col).value[0].id
for c in model.get_dct_cells().values():
if c.value[0].id == kat_id:
c.color = active_konzeptColor
c.konzept = active_konzept
if (c.row, c.col) not in self.parent.GetParent().konzepte[c.konzept.name].cells:
self.parent.GetParent().konzepte[c.konzept.name].cells.append((c.row, c.col))
self.SetCellBackgroundColour(c.row, c.col, c.color)
self.ForceRefresh()
def unselect_whole_category_from_popup(self, _):
kat_id = self.get_cell(self.this_row, self.this_col).value[0].id
for c in model.get_dct_cells().values():
if c.value[0].id == kat_id:
self.SetCellBackgroundColour(c.row, c.col, WHITE)
c.konzept = None
self.ForceRefresh()
def select_uncertain_from_popup(self, _):
current_textcolor = frame.myGrid.GetCellTextColour(self.this_row, self.this_col)
if active_konzeptColor != &#34;#ffffff&#34; and active_konzeptColor != current_textcolor:
frame.myGrid.SetCellTextColour(self.this_row, self.this_col, active_konzeptColor)
active_konzept.uncertain.append((self.this_row, self.this_col))
else:
frame.myGrid.SetCellTextColour(self.this_row, self.this_col, &#34;#000000&#34;)
active_konzept.uncertain.remove((self.this_row, self.this_col))
self.ForceRefresh()
def select_uncertain_cat_from_popup(self, _):
current_cell = self.get_cell(self.this_row, self.this_col)
current_textcolor = frame.myGrid.GetCellTextColour(self.this_row, self.this_col)
for c in model.get_dct_cells().values():
if c.value[0].id == current_cell.value[0].id:
if active_konzeptColor != &#34;#ffffff&#34; and active_konzeptColor != current_textcolor:
frame.myGrid.SetCellTextColour(c.row, c.col, active_konzeptColor)
active_konzept.uncertain.append((c.row, c.col))
else:
frame.myGrid.SetCellTextColour(c.row, c.col, &#34;#000000&#34;)
if (c.row, c.col) in active_konzept.uncertain:
active_konzept.uncertain.remove((c.row, c.col))
self.ForceRefresh()
def set_cellvalue(self, cellpos, value):
cell_row, cell_col = cellpos
self.SetCellValue(cell_row, cell_col, value)
def select_cell(self, event):
if active_konzeptColor != &#34;#ffffff&#34;: # active_konzeptColor == &#34;#ffffff&#34; würde bedeuten,
# es ist kein Konzept ausgewählt. Mitlerweile wird beim erzeugen eines
# Konzept dieses auch direkt auf Aktiv gesetzt und macht diese Bedingung
# evtl überflüßig
try:
if model.RECHNUNGSTYP == &#34;INST&#34;:
c = dct_cells[(event.GetRow(), event.GetCol())] # c = Zelle, die von der Maus angewählt wurde
else:
c = model.get_dct_cells()[(self.this_row, self.this_col)]
if model.RECHNUNGSTYP == &#34;INST&#34; and c.row &lt; 9:
pass
else:
if c.color != &#34;#cccccc&#34;:
if c.color != active_konzeptColor:
c.color = active_konzeptColor
c.konzept = active_konzept
if (c.row, c.col) not in self.parent.GetParent().konzepte[c.konzept.name].cells:
self.parent.GetParent().konzepte[c.konzept.name].cells.append((c.row, c.col))
else:
if c.color != WHITE:
self.parent.GetParent().konzepte[c.konzept.name].cells.remove((c.row, c.col))
c.color = WHITE
c.konzept = None
self.SetCellBackgroundColour(c.row, c.col, c.color)
self.ForceRefresh()
self.parent.GetParent().tmpStoredKonzepte = None
else:
msg = &#34;Grey cells are just for orientation,\nthey are not selectable.&#34;
dlg = wx.MessageDialog(self, msg, &#39;Information&#39;, style=wx.OK | wx.ICON_INFORMATION | wx.CENTRE)
dlg.ShowModal()
except KeyError:
pass
else:
msg = &#34;Add or select a concept first.&#34;
dlg = wx.MessageDialog(self, msg, &#39;Information&#39;, style=wx.OK | wx.ICON_INFORMATION | wx.CENTRE)
dlg.ShowModal()
def trigger_kategorie(self, event):
if active_konzeptColor != &#34;#ffffff&#34;:
try:
current_cell = self.get_cell(event.GetRow(), event.GetCol())
kat_id = current_cell.value[0].id
for c in model.get_dct_cells().values():
if c.value[0].id == kat_id:
if c.color != active_konzeptColor:
c.color = active_konzeptColor
c.konzept = active_konzept
if (c.row, c.col) not in self.parent.GetParent().konzepte[c.konzept.name].cells:
self.parent.GetParent().konzepte[c.konzept.name].cells.append((c.row, c.col))
else:
if c.color != WHITE:
self.parent.GetParent().konzepte[c.konzept.name].cells.remove((c.row, c.col))
c.color = WHITE
c.konzept = None
self.SetCellBackgroundColour(c.row, c.col, c.color)
self.ForceRefresh()
except KeyError:
pass
else:
msg = &#34;Add or select a concept first.&#34;
dlg = wx.MessageDialog(self, msg, &#39;Information&#39;, style=wx.OK | wx.ICON_INFORMATION | wx.CENTRE)
dlg.ShowModal()
def reset_all_categories(self):
tmp_dct = dct_cells.values() if model.RECHNUNGSTYP == &#34;INST&#34; else model.get_dct_cells().values()
for c in tmp_dct:
if self.GetCellBackgroundColour(c.row, c.col) != &#34;#cccccc&#34;:
self.SetCellBackgroundColour(c.row, c.col, WHITE)
c.color = WHITE
c.konzept = None
frame.myGrid.SetCellTextColour(c.row, c.col, &#34;#000000&#34;)
self.ForceRefresh()
self.parent.GetParent().tmpStoredKonzepte = None
def delete_konzept_in_grid(self):
if model.RECHNUNGSTYP == &#34;INST&#34;:
for c in dct_cells.values():
if c.konzept == active_konzept:
self.SetCellBackgroundColour(c.row, c.col, WHITE)
c.konzept = None
c.color = WHITE
else:
for c in model.get_dct_cells().values():
if c.konzept == active_konzept:
self.SetCellBackgroundColour(c.row, c.col, WHITE)
c.konzept = None
c.color = WHITE
self.ForceRefresh()
self.parent.GetParent().tmpStoredKonzepte = None
def erase_grid(self):
for row in range(200):
for col in range(58):
self.SetCellBackgroundColour(row, col, WHITE)
self.set_cellvalue((row, col), &#34;&#34;)
def get_cell(self, row, col):
return model.get_dct_cells()[(row, col)]</code></pre>
</details>
<h3>Ancestors</h3>
<ul class="hlist">
<li>wx._grid.Grid</li>
<li>wx._core.ScrolledWindow</li>
<li>wx._core._ScrolledWindowBase</li>
<li>wx._core.Window</li>
<li>wx._core.WindowBase</li>
<li>wx._core.EvtHandler</li>
<li>wx._core.Object</li>
<li>wx._core.Trackable</li>
<li>sip.wrapper</li>
<li>sip.simplewrapper</li>
</ul>
<h3>Methods</h3>
<dl>
<dt id="Finanzexplorer_Institute.MyGrid.delete_konzept_in_grid"><code class="name flex">
<span>def <span class="ident">delete_konzept_in_grid</span></span>(<span>self)</span>
</code></dt>
<dd>
<section class="desc"></section>
<details class="source">
<summary>Source code</summary>
<pre><code class="python">def delete_konzept_in_grid(self):
if model.RECHNUNGSTYP == &#34;INST&#34;:
for c in dct_cells.values():
if c.konzept == active_konzept:
self.SetCellBackgroundColour(c.row, c.col, WHITE)
c.konzept = None
c.color = WHITE
else:
for c in model.get_dct_cells().values():
if c.konzept == active_konzept:
self.SetCellBackgroundColour(c.row, c.col, WHITE)
c.konzept = None
c.color = WHITE
self.ForceRefresh()
self.parent.GetParent().tmpStoredKonzepte = None</code></pre>
</details>
</dd>
<dt id="Finanzexplorer_Institute.MyGrid.erase_grid"><code class="name flex">
<span>def <span class="ident">erase_grid</span></span>(<span>self)</span>
</code></dt>
<dd>
<section class="desc"></section>
<details class="source">
<summary>Source code</summary>
<pre><code class="python">def erase_grid(self):
for row in range(200):
for col in range(58):
self.SetCellBackgroundColour(row, col, WHITE)
self.set_cellvalue((row, col), &#34;&#34;)</code></pre>
</details>
</dd>
<dt id="Finanzexplorer_Institute.MyGrid.get_cell"><code class="name flex">
<span>def <span class="ident">get_cell</span></span>(<span>self, row, col)</span>
</code></dt>
<dd>
<section class="desc"></section>
<details class="source">
<summary>Source code</summary>
<pre><code class="python">def get_cell(self, row, col):
return model.get_dct_cells()[(row, col)]</code></pre>
</details>
</dd>
<dt id="Finanzexplorer_Institute.MyGrid.on_mouse_over"><code class="name flex">
<span>def <span class="ident">on_mouse_over</span></span>(<span>self, event)</span>
</code></dt>
<dd>
<section class="desc"><p>Displays a tooltip over any cell in a certain column</p></section>
<details class="source">
<summary>Source code</summary>
<pre><code class="python">def on_mouse_over(self, event):
&#34;&#34;&#34;
Displays a tooltip over any cell in a certain column
&#34;&#34;&#34;
# This method was suggested by none other than Robin Dunn
# http://www.blog.pythonlibrary.org/2010/04/04/wxpython-grid-tips-and-tricks/
# https://alldunn.com/robin/
x, y = self.CalcUnscrolledPosition(event.GetX(), event.GetY())
coords = self.XYToCell(x, y)
try:
if model.RECHNUNGSTYP != &#34;INST&#34;:
msg = &#34;{} {}: {}&#34;.format(model.get_dct_cells()[(coords[0], coords[1])].value[0].bezeichnung,
model.get_dct_cells()[(coords[0], coords[1])].jahr,
model.get_dct_cells()[(coords[0], coords[1])].posten.geldbetrag)
event.GetEventObject().SetToolTip(msg)
else:
pass
except KeyError: # for empty cells
pass
except AttributeError: # for cells without oberkategorie
pass</code></pre>
</details>
</dd>
<dt id="Finanzexplorer_Institute.MyGrid.reset_all_categories"><code class="name flex">
<span>def <span class="ident">reset_all_categories</span></span>(<span>self)</span>
</code></dt>
<dd>
<section class="desc"></section>
<details class="source">
<summary>Source code</summary>
<pre><code class="python">def reset_all_categories(self):
tmp_dct = dct_cells.values() if model.RECHNUNGSTYP == &#34;INST&#34; else model.get_dct_cells().values()
for c in tmp_dct:
if self.GetCellBackgroundColour(c.row, c.col) != &#34;#cccccc&#34;:
self.SetCellBackgroundColour(c.row, c.col, WHITE)
c.color = WHITE
c.konzept = None
frame.myGrid.SetCellTextColour(c.row, c.col, &#34;#000000&#34;)
self.ForceRefresh()
self.parent.GetParent().tmpStoredKonzepte = None</code></pre>
</details>
</dd>
<dt id="Finanzexplorer_Institute.MyGrid.select_cell"><code class="name flex">
<span>def <span class="ident">select_cell</span></span>(<span>self, event)</span>
</code></dt>
<dd>
<section class="desc"></section>
<details class="source">
<summary>Source code</summary>
<pre><code class="python">def select_cell(self, event):
if active_konzeptColor != &#34;#ffffff&#34;: # active_konzeptColor == &#34;#ffffff&#34; würde bedeuten,
# es ist kein Konzept ausgewählt. Mitlerweile wird beim erzeugen eines
# Konzept dieses auch direkt auf Aktiv gesetzt und macht diese Bedingung
# evtl überflüßig
try:
if model.RECHNUNGSTYP == &#34;INST&#34;:
c = dct_cells[(event.GetRow(), event.GetCol())] # c = Zelle, die von der Maus angewählt wurde
else:
c = model.get_dct_cells()[(self.this_row, self.this_col)]
if model.RECHNUNGSTYP == &#34;INST&#34; and c.row &lt; 9:
pass
else:
if c.color != &#34;#cccccc&#34;:
if c.color != active_konzeptColor:
c.color = active_konzeptColor
c.konzept = active_konzept
if (c.row, c.col) not in self.parent.GetParent().konzepte[c.konzept.name].cells:
self.parent.GetParent().konzepte[c.konzept.name].cells.append((c.row, c.col))
else:
if c.color != WHITE:
self.parent.GetParent().konzepte[c.konzept.name].cells.remove((c.row, c.col))
c.color = WHITE
c.konzept = None
self.SetCellBackgroundColour(c.row, c.col, c.color)
self.ForceRefresh()
self.parent.GetParent().tmpStoredKonzepte = None
else:
msg = &#34;Grey cells are just for orientation,\nthey are not selectable.&#34;
dlg = wx.MessageDialog(self, msg, &#39;Information&#39;, style=wx.OK | wx.ICON_INFORMATION | wx.CENTRE)
dlg.ShowModal()
except KeyError:
pass
else:
msg = &#34;Add or select a concept first.&#34;
dlg = wx.MessageDialog(self, msg, &#39;Information&#39;, style=wx.OK | wx.ICON_INFORMATION | wx.CENTRE)
dlg.ShowModal()</code></pre>
</details>
</dd>
<dt id="Finanzexplorer_Institute.MyGrid.select_uncertain_cat_from_popup"><code class="name flex">
<span>def <span class="ident">select_uncertain_cat_from_popup</span></span>(<span>self, _)</span>
</code></dt>
<dd>
<section class="desc"></section>
<details class="source">
<summary>Source code</summary>
<pre><code class="python">def select_uncertain_cat_from_popup(self, _):
current_cell = self.get_cell(self.this_row, self.this_col)
current_textcolor = frame.myGrid.GetCellTextColour(self.this_row, self.this_col)
for c in model.get_dct_cells().values():
if c.value[0].id == current_cell.value[0].id:
if active_konzeptColor != &#34;#ffffff&#34; and active_konzeptColor != current_textcolor:
frame.myGrid.SetCellTextColour(c.row, c.col, active_konzeptColor)
active_konzept.uncertain.append((c.row, c.col))
else:
frame.myGrid.SetCellTextColour(c.row, c.col, &#34;#000000&#34;)
if (c.row, c.col) in active_konzept.uncertain:
active_konzept.uncertain.remove((c.row, c.col))
self.ForceRefresh()</code></pre>
</details>
</dd>
<dt id="Finanzexplorer_Institute.MyGrid.select_uncertain_from_popup"><code class="name flex">
<span>def <span class="ident">select_uncertain_from_popup</span></span>(<span>self, _)</span>
</code></dt>
<dd>
<section class="desc"></section>
<details class="source">
<summary>Source code</summary>
<pre><code class="python">def select_uncertain_from_popup(self, _):
current_textcolor = frame.myGrid.GetCellTextColour(self.this_row, self.this_col)
if active_konzeptColor != &#34;#ffffff&#34; and active_konzeptColor != current_textcolor:
frame.myGrid.SetCellTextColour(self.this_row, self.this_col, active_konzeptColor)
active_konzept.uncertain.append((self.this_row, self.this_col))
else:
frame.myGrid.SetCellTextColour(self.this_row, self.this_col, &#34;#000000&#34;)
active_konzept.uncertain.remove((self.this_row, self.this_col))
self.ForceRefresh()</code></pre>
</details>
</dd>
<dt id="Finanzexplorer_Institute.MyGrid.select_whole_category_from_popup"><code class="name flex">
<span>def <span class="ident">select_whole_category_from_popup</span></span>(<span>self, _)</span>
</code></dt>
<dd>
<section class="desc"></section>
<details class="source">
<summary>Source code</summary>
<pre><code class="python">def select_whole_category_from_popup(self, _):
kat_id = self.get_cell(self.this_row, self.this_col).value[0].id
for c in model.get_dct_cells().values():
if c.value[0].id == kat_id:
c.color = active_konzeptColor
c.konzept = active_konzept
if (c.row, c.col) not in self.parent.GetParent().konzepte[c.konzept.name].cells:
self.parent.GetParent().konzepte[c.konzept.name].cells.append((c.row, c.col))
self.SetCellBackgroundColour(c.row, c.col, c.color)
self.ForceRefresh()</code></pre>
</details>
</dd>
<dt id="Finanzexplorer_Institute.MyGrid.set_cellvalue"><code class="name flex">
<span>def <span class="ident">set_cellvalue</span></span>(<span>self, cellpos, value)</span>
</code></dt>
<dd>
<section class="desc"></section>
<details class="source">
<summary>Source code</summary>
<pre><code class="python">def set_cellvalue(self, cellpos, value):
cell_row, cell_col = cellpos
self.SetCellValue(cell_row, cell_col, value)</code></pre>
</details>
</dd>
<dt id="Finanzexplorer_Institute.MyGrid.show_popup_menu"><code class="name flex">
<span>def <span class="ident">show_popup_menu</span></span>(<span>self, event)</span>
</code></dt>
<dd>
<section class="desc"></section>
<details class="source">
<summary>Source code</summary>
<pre><code class="python">def show_popup_menu(self, event):
self.this_row = event.GetRow()
self.this_col = event.GetCol()
if not hasattr(self, &#34;popupID1&#34;):
self.popupID1 = wx.NewId()
self.popupID2 = wx.NewId()
self.popupID3 = wx.NewId()
self.popupID4 = wx.NewId()
self.popupID5 = wx.NewId()
self.popupID6 = wx.NewId()
menu = wx.Menu()
item = wx.MenuItem(menu, self.popupID1, &#34;trigger Cell&#34;)
item_02 = wx.MenuItem(menu, self.popupID2, &#34;trigger category&#34;)
item_03 = wx.MenuItem(menu, self.popupID3, &#34;select whole category&#34;)
item_04 = wx.MenuItem(menu, self.popupID4, &#34;unselect whole Category&#34;)
item_uncertain_cat = wx.MenuItem(menu, self.popupID5, &#34;uncertain&#34;)
item_uncertain = wx.MenuItem(menu, self.popupID6, &#34;uncertain&#34;)
sub_menu = wx.Menu()
sub_menu.Append(item_02)
sub_menu.Append(item_03)
sub_menu.Append(item_04)
sub_menu.Append(item_uncertain_cat)
menu.Append(item)
menu.Append(wx.NewId(), &#34;Category&#34;, sub_menu)
menu.Append(item_uncertain)
self.PopupMenu(menu)
self.Bind(wx.EVT_MENU, self.select_cell, item)
self.Bind(wx.EVT_MENU, self.trigger_kategorie_from_popup, item_02)
self.Bind(wx.EVT_MENU, self.select_whole_category_from_popup, item_03)
self.Bind(wx.EVT_MENU, self.unselect_whole_category_from_popup, item_04)
self.Bind(wx.EVT_MENU, self.select_uncertain_from_popup, item_uncertain)
self.Bind(wx.EVT_MENU, self.select_uncertain_cat_from_popup, item_uncertain_cat)
menu.Destroy()</code></pre>
</details>
</dd>
<dt id="Finanzexplorer_Institute.MyGrid.trigger_kategorie"><code class="name flex">
<span>def <span class="ident">trigger_kategorie</span></span>(<span>self, event)</span>
</code></dt>
<dd>
<section class="desc"></section>
<details class="source">
<summary>Source code</summary>
<pre><code class="python">def trigger_kategorie(self, event):
if active_konzeptColor != &#34;#ffffff&#34;:
try:
current_cell = self.get_cell(event.GetRow(), event.GetCol())
kat_id = current_cell.value[0].id
for c in model.get_dct_cells().values():
if c.value[0].id == kat_id:
if c.color != active_konzeptColor:
c.color = active_konzeptColor
c.konzept = active_konzept
if (c.row, c.col) not in self.parent.GetParent().konzepte[c.konzept.name].cells:
self.parent.GetParent().konzepte[c.konzept.name].cells.append((c.row, c.col))
else:
if c.color != WHITE:
self.parent.GetParent().konzepte[c.konzept.name].cells.remove((c.row, c.col))
c.color = WHITE
c.konzept = None
self.SetCellBackgroundColour(c.row, c.col, c.color)
self.ForceRefresh()
except KeyError:
pass
else:
msg = &#34;Add or select a concept first.&#34;
dlg = wx.MessageDialog(self, msg, &#39;Information&#39;, style=wx.OK | wx.ICON_INFORMATION | wx.CENTRE)
dlg.ShowModal()</code></pre>
</details>
</dd>
<dt id="Finanzexplorer_Institute.MyGrid.trigger_kategorie_from_popup"><code class="name flex">
<span>def <span class="ident">trigger_kategorie_from_popup</span></span>(<span>self, _)</span>
</code></dt>
<dd>
<section class="desc"></section>
<details class="source">
<summary>Source code</summary>
<pre><code class="python">def trigger_kategorie_from_popup(self, _):
kat_id = self.get_cell(self.this_row, self.this_col).value[0].id
for c in model.get_dct_cells().values():
if c.value[0].id == kat_id:
if c.color != active_konzeptColor:
c.color = active_konzeptColor
c.konzept = active_konzept
if (c.row, c.col) not in self.parent.GetParent().konzepte[c.konzept.name].cells:
self.parent.GetParent().konzepte[c.konzept.name].cells.append((c.row, c.col))
else:
if c.color != WHITE:
self.parent.GetParent().konzepte[c.konzept.name].cells.remove((c.row, c.col))
c.color = WHITE
c.konzept = None
self.SetCellBackgroundColour(c.row, c.col, c.color)
self.ForceRefresh()</code></pre>
</details>
</dd>
<dt id="Finanzexplorer_Institute.MyGrid.unselect_whole_category_from_popup"><code class="name flex">
<span>def <span class="ident">unselect_whole_category_from_popup</span></span>(<span>self, _)</span>
</code></dt>
<dd>
<section class="desc"></section>
<details class="source">
<summary>Source code</summary>
<pre><code class="python">def unselect_whole_category_from_popup(self, _):
kat_id = self.get_cell(self.this_row, self.this_col).value[0].id
for c in model.get_dct_cells().values():
if c.value[0].id == kat_id:
self.SetCellBackgroundColour(c.row, c.col, WHITE)
c.konzept = None
self.ForceRefresh()</code></pre>
</details>
</dd>
</dl>
</dd>
<dt id="Finanzexplorer_Institute.PDF"><code class="flex name class">
<span>class <span class="ident">PDF</span></span>
<span>(</span><span>orientation='P', unit='mm', format='A4')</span>
</code></dt>
<dd>
<section class="desc"><p>PDF Generation class</p></section>
<details class="source">
<summary>Source code</summary>
<pre><code class="python">class PDF(FPDF):
def header(self):
self.set_font(&#34;Times&#34;, &#34;B&#34;, 10)
# self.image(&#34;Icon.png&#34;, 10, 8, 8)
self.cell(80)
self.cell(30, 10, frame.GetTitle(), 0, 1, &#39;C&#39;)
self.ln(10)
def footer(self):
today = datetime.date.today()
self.set_y(-15)
self.set_font(&#34;Times&#34;, &#39;I&#39;, 8)
self.cell(0, 10, str(today), 0, 0, &#39;C&#39;)
self.set_y(-15)
link = self.add_link()
self.set_link(link, page=1)
self.cell(0, 10, &#34;top&#34;, 0, 0, &#39;R&#39;, link=link)</code></pre>
</details>
<h3>Ancestors</h3>
<ul class="hlist">
<li>fpdf.fpdf.FPDF</li>
</ul>
<h3>Methods</h3>
<dl>
<dt id="Finanzexplorer_Institute.PDF.footer"><code class="name flex">
<span>def <span class="ident">footer</span></span>(<span>self)</span>
</code></dt>
<dd>
<section class="desc"><p>Footer to be implemented in your own inherited class</p></section>
<details class="source">
<summary>Source code</summary>
<pre><code class="python">def footer(self):
today = datetime.date.today()
self.set_y(-15)
self.set_font(&#34;Times&#34;, &#39;I&#39;, 8)
self.cell(0, 10, str(today), 0, 0, &#39;C&#39;)
self.set_y(-15)
link = self.add_link()
self.set_link(link, page=1)
self.cell(0, 10, &#34;top&#34;, 0, 0, &#39;R&#39;, link=link)</code></pre>
</details>
</dd>
<dt id="Finanzexplorer_Institute.PDF.header"><code class="name flex">
<span>def <span class="ident">header</span></span>(<span>self)</span>
</code></dt>
<dd>
<section class="desc"><p>Header to be implemented in your own inherited class</p></section>
<details class="source">
<summary>Source code</summary>
<pre><code class="python">def header(self):
self.set_font(&#34;Times&#34;, &#34;B&#34;, 10)
# self.image(&#34;Icon.png&#34;, 10, 8, 8)
self.cell(80)
self.cell(30, 10, frame.GetTitle(), 0, 1, &#39;C&#39;)
self.ln(10)</code></pre>
</details>
</dd>
</dl>
</dd>
</dl>
</section>
</article>
<nav id="sidebar">
<h1>Index</h1>
<div class="toc">
<ul></ul>
</div>
<ul id="index">
<li><h3><a href="#header-functions">Functions</a></h3>
<ul class="">
<li><code><a title="Finanzexplorer_Institute.fresh_new_start" href="#Finanzexplorer_Institute.fresh_new_start">fresh_new_start</a></code></li>
<li><code><a title="Finanzexplorer_Institute.get_inflation_indices" href="#Finanzexplorer_Institute.get_inflation_indices">get_inflation_indices</a></code></li>
<li><code><a title="Finanzexplorer_Institute.get_limits" href="#Finanzexplorer_Institute.get_limits">get_limits</a></code></li>
<li><code><a title="Finanzexplorer_Institute.get_saves" href="#Finanzexplorer_Institute.get_saves">get_saves</a></code></li>
<li><code><a title="Finanzexplorer_Institute.import_inst_template" href="#Finanzexplorer_Institute.import_inst_template">import_inst_template</a></code></li>
<li><code><a title="Finanzexplorer_Institute.import_mpg_gesamt_data" href="#Finanzexplorer_Institute.import_mpg_gesamt_data">import_mpg_gesamt_data</a></code></li>
<li><code><a title="Finanzexplorer_Institute.line_plot_gesamt" href="#Finanzexplorer_Institute.line_plot_gesamt">line_plot_gesamt</a></code></li>
<li><code><a title="Finanzexplorer_Institute.line_plot_gesamt_settings" href="#Finanzexplorer_Institute.line_plot_gesamt_settings">line_plot_gesamt_settings</a></code></li>
<li><code><a title="Finanzexplorer_Institute.line_plot_inst" href="#Finanzexplorer_Institute.line_plot_inst">line_plot_inst</a></code></li>
<li><code><a title="Finanzexplorer_Institute.populate_cells" href="#Finanzexplorer_Institute.populate_cells">populate_cells</a></code></li>
<li><code><a title="Finanzexplorer_Institute.rgb_to_hex" href="#Finanzexplorer_Institute.rgb_to_hex">rgb_to_hex</a></code></li>
<li><code><a title="Finanzexplorer_Institute.set_hierarchie" href="#Finanzexplorer_Institute.set_hierarchie">set_hierarchie</a></code></li>
<li><code><a title="Finanzexplorer_Institute.tracefunc" href="#Finanzexplorer_Institute.tracefunc">tracefunc</a></code></li>
</ul>
</li>
<li><h3><a href="#header-classes">Classes</a></h3>
<ul>
<li>
<h4><code><a title="Finanzexplorer_Institute.Cell" href="#Finanzexplorer_Institute.Cell">Cell</a></code></h4>
</li>
<li>
<h4><code><a title="Finanzexplorer_Institute.DialogGesamtPlotSettings" href="#Finanzexplorer_Institute.DialogGesamtPlotSettings">DialogGesamtPlotSettings</a></code></h4>
<ul class="">
<li><code><a title="Finanzexplorer_Institute.DialogGesamtPlotSettings.create_plot" href="#Finanzexplorer_Institute.DialogGesamtPlotSettings.create_plot">create_plot</a></code></li>
</ul>
</li>
<li>
<h4><code><a title="Finanzexplorer_Institute.DialogNewKonzept" href="#Finanzexplorer_Institute.DialogNewKonzept">DialogNewKonzept</a></code></h4>
<ul class="">
<li><code><a title="Finanzexplorer_Institute.DialogNewKonzept.create_new_konzept" href="#Finanzexplorer_Institute.DialogNewKonzept.create_new_konzept">create_new_konzept</a></code></li>
</ul>
</li>
<li>
<h4><code><a title="Finanzexplorer_Institute.DialogPlotSettings" href="#Finanzexplorer_Institute.DialogPlotSettings">DialogPlotSettings</a></code></h4>
<ul class="">
<li><code><a title="Finanzexplorer_Institute.DialogPlotSettings.create_plot" href="#Finanzexplorer_Institute.DialogPlotSettings.create_plot">create_plot</a></code></li>
</ul>
</li>
<li>
<h4><code><a title="Finanzexplorer_Institute.DialogRechnungstypInit" href="#Finanzexplorer_Institute.DialogRechnungstypInit">DialogRechnungstypInit</a></code></h4>
<ul class="">
<li><code><a title="Finanzexplorer_Institute.DialogRechnungstypInit.start" href="#Finanzexplorer_Institute.DialogRechnungstypInit.start">start</a></code></li>
</ul>
</li>
<li>
<h4><code><a title="Finanzexplorer_Institute.ExcelCell" href="#Finanzexplorer_Institute.ExcelCell">ExcelCell</a></code></h4>
</li>
<li>
<h4><code><a title="Finanzexplorer_Institute.InstitutsForm" href="#Finanzexplorer_Institute.InstitutsForm">InstitutsForm</a></code></h4>
<ul class="">
<li><code><a title="Finanzexplorer_Institute.InstitutsForm.Quit" href="#Finanzexplorer_Institute.InstitutsForm.Quit">Quit</a></code></li>
<li><code><a title="Finanzexplorer_Institute.InstitutsForm.add_konzept" href="#Finanzexplorer_Institute.InstitutsForm.add_konzept">add_konzept</a></code></li>
<li><code><a title="Finanzexplorer_Institute.InstitutsForm.add_new_konzept" href="#Finanzexplorer_Institute.InstitutsForm.add_new_konzept">add_new_konzept</a></code></li>
<li><code><a title="Finanzexplorer_Institute.InstitutsForm.button_click" href="#Finanzexplorer_Institute.InstitutsForm.button_click">button_click</a></code></li>
<li><code><a title="Finanzexplorer_Institute.InstitutsForm.button_click_gesamt" href="#Finanzexplorer_Institute.InstitutsForm.button_click_gesamt">button_click_gesamt</a></code></li>
<li><code><a title="Finanzexplorer_Institute.InstitutsForm.check_selection" href="#Finanzexplorer_Institute.InstitutsForm.check_selection">check_selection</a></code></li>
<li><code><a title="Finanzexplorer_Institute.InstitutsForm.checked_item" href="#Finanzexplorer_Institute.InstitutsForm.checked_item">checked_item</a></code></li>
<li><code><a title="Finanzexplorer_Institute.InstitutsForm.colour_picked" href="#Finanzexplorer_Institute.InstitutsForm.colour_picked">colour_picked</a></code></li>
<li><code><a title="Finanzexplorer_Institute.InstitutsForm.create_report" href="#Finanzexplorer_Institute.InstitutsForm.create_report">create_report</a></code></li>
<li><code><a title="Finanzexplorer_Institute.InstitutsForm.delete_konzept" href="#Finanzexplorer_Institute.InstitutsForm.delete_konzept">delete_konzept</a></code></li>
<li><code><a title="Finanzexplorer_Institute.InstitutsForm.develope_mode" href="#Finanzexplorer_Institute.InstitutsForm.develope_mode">develope_mode</a></code></li>
<li><code><a title="Finanzexplorer_Institute.InstitutsForm.find_category" href="#Finanzexplorer_Institute.InstitutsForm.find_category">find_category</a></code></li>
<li><code><a title="Finanzexplorer_Institute.InstitutsForm.get_inst_konzepte" href="#Finanzexplorer_Institute.InstitutsForm.get_inst_konzepte">get_inst_konzepte</a></code></li>
<li><code><a title="Finanzexplorer_Institute.InstitutsForm.get_institutes" href="#Finanzexplorer_Institute.InstitutsForm.get_institutes">get_institutes</a></code></li>
<li><code><a title="Finanzexplorer_Institute.InstitutsForm.load_konzept" href="#Finanzexplorer_Institute.InstitutsForm.load_konzept">load_konzept</a></code></li>
<li><code><a title="Finanzexplorer_Institute.InstitutsForm.load_konzepte_picker" href="#Finanzexplorer_Institute.InstitutsForm.load_konzepte_picker">load_konzepte_picker</a></code></li>
<li><code><a title="Finanzexplorer_Institute.InstitutsForm.menuBar" href="#Finanzexplorer_Institute.InstitutsForm.menuBar">menuBar</a></code></li>
<li><code><a title="Finanzexplorer_Institute.InstitutsForm.new_get_konzept" href="#Finanzexplorer_Institute.InstitutsForm.new_get_konzept">new_get_konzept</a></code></li>
<li><code><a title="Finanzexplorer_Institute.InstitutsForm.new_window" href="#Finanzexplorer_Institute.InstitutsForm.new_window">new_window</a></code></li>
<li><code><a title="Finanzexplorer_Institute.InstitutsForm.open_template" href="#Finanzexplorer_Institute.InstitutsForm.open_template">open_template</a></code></li>
<li><code><a title="Finanzexplorer_Institute.InstitutsForm.plot_settings" href="#Finanzexplorer_Institute.InstitutsForm.plot_settings">plot_settings</a></code></li>
<li><code><a title="Finanzexplorer_Institute.InstitutsForm.reset_konzepte" href="#Finanzexplorer_Institute.InstitutsForm.reset_konzepte">reset_konzepte</a></code></li>
<li><code><a title="Finanzexplorer_Institute.InstitutsForm.save_konzepte" href="#Finanzexplorer_Institute.InstitutsForm.save_konzepte">save_konzepte</a></code></li>
<li><code><a title="Finanzexplorer_Institute.InstitutsForm.set_institutes" href="#Finanzexplorer_Institute.InstitutsForm.set_institutes">set_institutes</a></code></li>
<li><code><a title="Finanzexplorer_Institute.InstitutsForm.set_interface" href="#Finanzexplorer_Institute.InstitutsForm.set_interface">set_interface</a></code></li>
<li><code><a title="Finanzexplorer_Institute.InstitutsForm.set_interface_alert" href="#Finanzexplorer_Institute.InstitutsForm.set_interface_alert">set_interface_alert</a></code></li>
<li><code><a title="Finanzexplorer_Institute.InstitutsForm.unfind_category" href="#Finanzexplorer_Institute.InstitutsForm.unfind_category">unfind_category</a></code></li>
</ul>
</li>
<li>
<h4><code><a title="Finanzexplorer_Institute.Konzept" href="#Finanzexplorer_Institute.Konzept">Konzept</a></code></h4>
</li>
<li>
<h4><code><a title="Finanzexplorer_Institute.MyGrid" href="#Finanzexplorer_Institute.MyGrid">MyGrid</a></code></h4>
<ul class="">
<li><code><a title="Finanzexplorer_Institute.MyGrid.delete_konzept_in_grid" href="#Finanzexplorer_Institute.MyGrid.delete_konzept_in_grid">delete_konzept_in_grid</a></code></li>
<li><code><a title="Finanzexplorer_Institute.MyGrid.erase_grid" href="#Finanzexplorer_Institute.MyGrid.erase_grid">erase_grid</a></code></li>
<li><code><a title="Finanzexplorer_Institute.MyGrid.get_cell" href="#Finanzexplorer_Institute.MyGrid.get_cell">get_cell</a></code></li>
<li><code><a title="Finanzexplorer_Institute.MyGrid.on_mouse_over" href="#Finanzexplorer_Institute.MyGrid.on_mouse_over">on_mouse_over</a></code></li>
<li><code><a title="Finanzexplorer_Institute.MyGrid.reset_all_categories" href="#Finanzexplorer_Institute.MyGrid.reset_all_categories">reset_all_categories</a></code></li>
<li><code><a title="Finanzexplorer_Institute.MyGrid.select_cell" href="#Finanzexplorer_Institute.MyGrid.select_cell">select_cell</a></code></li>
<li><code><a title="Finanzexplorer_Institute.MyGrid.select_uncertain_cat_from_popup" href="#Finanzexplorer_Institute.MyGrid.select_uncertain_cat_from_popup">select_uncertain_cat_from_popup</a></code></li>
<li><code><a title="Finanzexplorer_Institute.MyGrid.select_uncertain_from_popup" href="#Finanzexplorer_Institute.MyGrid.select_uncertain_from_popup">select_uncertain_from_popup</a></code></li>
<li><code><a title="Finanzexplorer_Institute.MyGrid.select_whole_category_from_popup" href="#Finanzexplorer_Institute.MyGrid.select_whole_category_from_popup">select_whole_category_from_popup</a></code></li>
<li><code><a title="Finanzexplorer_Institute.MyGrid.set_cellvalue" href="#Finanzexplorer_Institute.MyGrid.set_cellvalue">set_cellvalue</a></code></li>
<li><code><a title="Finanzexplorer_Institute.MyGrid.show_popup_menu" href="#Finanzexplorer_Institute.MyGrid.show_popup_menu">show_popup_menu</a></code></li>
<li><code><a title="Finanzexplorer_Institute.MyGrid.trigger_kategorie" href="#Finanzexplorer_Institute.MyGrid.trigger_kategorie">trigger_kategorie</a></code></li>
<li><code><a title="Finanzexplorer_Institute.MyGrid.trigger_kategorie_from_popup" href="#Finanzexplorer_Institute.MyGrid.trigger_kategorie_from_popup">trigger_kategorie_from_popup</a></code></li>
<li><code><a title="Finanzexplorer_Institute.MyGrid.unselect_whole_category_from_popup" href="#Finanzexplorer_Institute.MyGrid.unselect_whole_category_from_popup">unselect_whole_category_from_popup</a></code></li>
</ul>
</li>
<li>
<h4><code><a title="Finanzexplorer_Institute.PDF" href="#Finanzexplorer_Institute.PDF">PDF</a></code></h4>
<ul class="">
<li><code><a title="Finanzexplorer_Institute.PDF.footer" href="#Finanzexplorer_Institute.PDF.footer">footer</a></code></li>
<li><code><a title="Finanzexplorer_Institute.PDF.header" href="#Finanzexplorer_Institute.PDF.header">header</a></code></li>
</ul>
</li>
</ul>
</li>
</ul>
</nav>
</main>
<footer id="footer">
<p>Generated by <a href="https://pdoc3.github.io/pdoc"><cite>pdoc</cite> 0.6.3</a>.</p>
</footer>
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/highlight.min.js"></script>
<script>hljs.initHighlightingOnLoad()</script>
</body>
</html>