In [1]:
from IPython.display import display, Markdown as md, HTML as html, FileLink
import math
import time
import json
import zipfile

import locale
locale.setlocale(locale.LC_ALL, 'de_DE.utf-8')

from joblib import Parallel, delayed
import functools

try:
    import pandas as pd
    import ipywidgets as widgets
    from ipywidgets import interact, interactive, interactive_output, interact_manual
    import numpy as np
    import matplotlib.pylab as plt
    import scipy
    from sklearn.preprocessing import minmax_scale
    import plotly.express as px
    from plotly.subplots import make_subplots
    import plotly.graph_objects as go

except Exception as e:
    !pip install pandas ipywidgets matplotlib plotly pandas-bokeh scipy scikit-learn
    import pandas as pd
    import ipywidgets as widgets
    from ipywidgets import interact, interactive, interactive_output, interact_manual
    import numpy as np
    import matplotlib.pylab as plt
    import scipy
    from sklearn.preprocessing import minmax_scale
    import plotly.express as ps
    from plotly.subplots import make_subplots
    import plotly.graph_objects as go
    
#pd.options.plotting.backend = "plotly"
In [2]:
#display(md("# Input"))
from IPython.display import display, HTML
display(HTML("<style>:root { --jp-widgets-inline-width: 21.5rem !important; }</style>"))

pd.options.display.float_format = '{:.2f}'.format
pd.options.mode.copy_on_write = True
In [3]:
v = [50,80,120,160,200,230,250,300]
L = range(10,110,10)
n_Z = sorted(set([19,30,38,42,45,47,48] + list(range(10,410,10))))
achsanzahl = range(10,110,10)
F_R = range(12,31,1)
F_0 = [x * 9.81 / 2 * 0.4 for x in F_R]

#F_0 = range(10,210,10)

delta_T_Stopfen = 5

delta_k_SI = [0.2, 0.5]
schienen_typen = ["UIC 60", "S 54", "S 49"]

_s_max = 75

s_zul = [15,15,13,11,9,9,7,7] # [mm]
abnutzung_zul = [18,18,17,14,10,10,10,10] # [mm]
iter = 4

delta_V_Schleifen = 0.1
V_z0 = 0.16

inspektionsinterval = [18, 18, 12, 6, 3, 3, 3, 3]

schwellen_typen = ["B07 2600", "B70 2600", "B70 2400"]

liste_ohne_WaO = ["Zug auf Schotter 0.2", "Zug auf Schotter 0.5", "Zug auf Fester Fahrbahn"]
In [4]:
handle_color = 'blue'
description_width = '12rem'

w_n_Z = widgets.SelectionSlider(
    value=50,
    description='Züge/d:',
    style={'description_width': description_width},
    options=n_Z,
    continuous_update=False,
)
w_achsanzahl = widgets.SelectionSlider(
    value=40,
    description='Achsanzahl:',
    style={'description_width': description_width},
    options=achsanzahl,
    continuous_update=False,
)
w_v = widgets.SelectionSlider(
    description="v [km/h]",
    style={'description_width': description_width},
    value=300,
    options = v,
    continuous_update=False,
)
w_v.style.handle_color = handle_color
w_F_0 = widgets.SelectionSlider(
    description="F_0 [kN]",
    style={'description_width': description_width},
    #value=70, 
    options=F_0,
    continuous_update=False,
    disabled=True
)
w_F_0.style.handle_color = handle_color

w_K_A_Schotter = widgets.BoundedIntText(
    value=220,
    min=10,
    max=2000,
    step=5,
    description='K_A_Schotter [€/m]:',
    style={'description_width': description_width},
    disabled=False,
    continuous_update=False,
)
w_K_A_Stopfen = widgets.BoundedIntText(
    value=30,
    min=10,
    max=2000,
    step=5,
    description='K_A_Stopfen [€/m]:',
    style={'description_width': description_width},
    disabled=False,
    continuous_update=False,
)
w_K_Stopfen = widgets.BoundedIntText(
    value=20,
    min=10,
    max=2000,
    step=5,
    description='K_Stopfen [€/m]:',
    style={'description_width': description_width},
    disabled=False,
    continuous_update=False,
)
w_K_A_Reinigung = widgets.BoundedIntText(
    value=170,
    min=10,
    max=2000,
    step=5,
    description='K_A_Reinigung [€/m]:',
    style={'description_width': description_width},
    disabled=False,
    continuous_update=False,
)

w_L_FF = widgets.IntSlider(
    description="L_FF [a]:",
    style={'description_width': description_width},
    value=40,
    min=5,
    max=100,
    step=5,
    continuous_update=False,
)
w_L_FF.style.handle_color = handle_color

w_K_A_FF = widgets.BoundedIntText(
    value=1125,
    min=10,
    max=2000,
    step=5,
    description='K_A_FF [€/m]:',
    style={'description_width': description_width},
    disabled=False,
    continuous_update=False,
)
w_L_WaO = widgets.IntSlider(
    description="L_WaO [a]:",
    style={'description_width': description_width},
    value=40,
    min=5,
    max=100,
    step=5,
    continuous_update=False,
)
w_L_WaO.style.handle_color = handle_color

w_K_A_WaO = widgets.BoundedIntText(
    value=850,
    min=10,
    max=2000,
    step=5,
    description='K_A_WaO [m]:',
    style={'description_width': description_width},
    disabled=False,
    continuous_update=False,
)
w_K_RB_Schotter = widgets.BoundedIntText(
    value=34,
    min=0,
    max=2000,
    step=1,
    description='K_RB_Schotter [€/Rückbau]:',
    style={'description_width': description_width},
    disabled=False,
    continuous_update=False,
)
w_K_RB_FF = widgets.BoundedIntText(
    value=151,
    min=0,
    max=2000,
    step=1,
    description='K_RB_FF [€/Rückbau]:',
    style={'description_width': description_width},
    disabled=False,
    continuous_update=False,
)
w_K_RB_WaO = widgets.BoundedIntText(
    value=57,
    min=0,
    max=2000,
    step=1,
    description='K_RB_WaO [€/Rückbau]:',
    style={'description_width': description_width},
    disabled=False,
    continuous_update=False,
)

w_K_A_Schiene_UIC = widgets.BoundedIntText(
    value=136,
    min=0,
    max=500,
    step=1,
    description='K_A_Schiene UIC 60 [€/m]:',
    style={'description_width': description_width},
    disabled=False,
    continuous_update=False,
)
w_K_A_Schiene_S54 = widgets.Text(
    description="K_A_Schiene S54 [€/m]:",
    style={'description_width': description_width},
    value="{0:.2f}".format(w_K_A_Schiene_UIC.value*54/60),
    disabled=True,
    continuous_update=False,
)
w_K_A_Schiene_S49 = widgets.Text(
    description="K_A_Schiene S49 [€/m]:",
    style={'description_width': description_width},
    value="{0:.2f}".format(w_K_A_Schiene_UIC.value*49/60),
    disabled=True,
    continuous_update=False,
)

def handle_change_schiene(change):
    w_K_A_Schiene_S54.value = "{0:.2f}".format(change.new*54/60)
    w_K_A_Schiene_S49.value = "{0:.2f}".format(change.new*49/60)

w_K_A_Schiene_UIC.observe(handle_change_schiene, names='value')

w_K_A_Schleifen = widgets.BoundedIntText(
    value=10,
    min=0,
    max=500,
    step=1,
    description='K_A_Schleifen [€/m]:',
    style={'description_width': description_width},
    disabled=False,
    continuous_update=False,
)

w_K_A_Schwelle_B07_2600 = widgets.BoundedIntText(
    value=120,
    min=0,
    max=300,
    step=1,
    description='K_A_Schwelle B07 2600 [€/m]:',
    style={'description_width': description_width},
    disabled=False,
    continuous_update=False,
)
w_K_A_Schwelle_B70_2400 = widgets.Text(
    description="K_A_Schwelle B70 2400 [€/m]:",
    style={'description_width': description_width},
    value="{0:.2f}".format(270*w_K_A_Schwelle_B07_2600.value/345),
    disabled=True,
    continuous_update=False,
)
w_K_A_Schwelle_B70_2600 = widgets.Text(
    description="K_A_Schwelle B70 2600 [€/m]:",
    style={'description_width': description_width},
    value="{0:.2f}".format(300*w_K_A_Schwelle_B07_2600.value/345),
    disabled=True,
    continuous_update=False,
)

def handle_change_schwelle(change):
    w_K_A_Schwelle_B70_2400.value = "{0:.2f}".format(270*change.new/345)
    w_K_A_Schwelle_B70_2600.value = "{0:.2f}".format(300*change.new/345)

w_K_A_Schwelle_B07_2600.observe(handle_change_schwelle, names='value')


w_L_Schwelle = widgets.IntSlider(
    description="L_Schwelle [a]:",
    style={'description_width': description_width},
    value=40,
    min=5,
    max=100,
    step=5,
    continuous_update=False,
)
w_L_Schwelle.style.handle_color = handle_color

w_K_Inspektion = widgets.BoundedIntText(
    value=1,
    min=0,
    max=500,
    step=1,
    description='K_A_Inspektion [€/m]:',
    style={'description_width': description_width},
    disabled=False,
    continuous_update=False,
)
w_K_BE_low = widgets.BoundedFloatText(
    value=7.5,
    min=0,
    max=200,
    step=0.5,
    description='w_K_BE_low [%]:',
    style={'description_width': description_width},
    disabled=False,
    continuous_update=False,
)
w_K_BE_mid = widgets.BoundedIntText(
    value=100,
    min=0,
    max=200,
    step=1,
    description='w_K_BE_mid [%]:',
    style={'description_width': description_width},
    disabled=False,
    continuous_update=False,
)
w_K_BE_high = widgets.BoundedIntText(
    value=33,
    min=0,
    max=200,
    step=1,
    description='w_K_BE_high [%]:',
    style={'description_width': description_width},
    disabled=False,
    continuous_update=False,
)

# not used
w_L = widgets.IntSlider(
    description="Laufzeit [a]",
    style={'description_width': description_width},
    value=50,
    min=10,
    max=100,
    step=10,
    continuous_update=False,
)
w_L.style.handle_color = handle_color

w_s = widgets.IntSlider(
    description="Strecke [km]",
    style={'description_width': description_width},
    value=10,
    min=1,
    max=1000,
    step=1,
    continuous_update=False,
)
w_s.style.handle_color = handle_color

w_stopfen = widgets.IntSlider(
    description="Stopfen",
    style={'description_width': description_width},
    value=5,
    min=1,
    max=20,
    step=1,
    continuous_update=False,
)
w_s.style.handle_color = handle_color

w_normalized = widgets.Checkbox(
    value=False,
    description='Normalized',
    disabled=False,
    indent=False
)
w_table = widgets.Checkbox(
    value=False,
    description='Show table',
    disabled=False,
    indent=False
)

w_show_WaO = widgets.Checkbox(
    value=True,
    description='Zeige WaO',
    disabled=False,
    indent=False
)

w_higher_BE = widgets.Checkbox(
    value=True,
    description='Nicht optimierte Unterbrechungen',
    disabled=False,
    indent=False
)

w_F_R = widgets.IntSlider(
    description="F_R [t]",
    style={'description_width': description_width},
    value=18,
    min=1,
    max=30,
    step=1,
    continuous_update=False,
)

controls_fixed = {
    '_n_Z': w_n_Z,
    '_achsanzahl': w_achsanzahl,
    #'_F_0': w_F_0,
    '_v': w_v,
    '_stopfen': w_stopfen,
    '_normalized': w_normalized,
    '_table': w_table,
    '_show_WaO': w_show_WaO,
    '_F_R': w_F_R,
}
controls_individual = {
    '_L': w_L,
    '_s': w_s,
    '_stopfen': w_stopfen,
    '_K_A_Schotter': w_K_A_Schotter,
    '_K_A_Stopfen': w_K_A_Stopfen,
    '_K_Stopfen': w_K_Stopfen,
    '_K_A_Reinigung': w_K_A_Reinigung,
    '_L_FF': w_L_FF,
    '_L_WaO': w_L_WaO,
    '_K_A_FF': w_K_A_FF,
    '_K_A_WaO': w_K_A_WaO,
    '_K_RB_Schotter': w_K_RB_Schotter,
    '_K_RB_FF': w_K_RB_FF,
    '_K_RB_WaO': w_K_RB_WaO,
    '_K_A_Schiene_UIC': w_K_A_Schiene_UIC,
    '_K_A_Schleifen': w_K_A_Schleifen,
    '_K_A_Schwelle_B07_2600': w_K_A_Schwelle_B07_2600,
    '_L_Schwelle': w_L_Schwelle,
    '_K_Inspektion': w_K_Inspektion,
    '_K_BE_low': w_K_BE_low,
    '_K_BE_mid': w_K_BE_mid,
    '_K_BE_high': w_K_BE_high,
    '_higher_BE': w_higher_BE,
}

def output_zwischenergebnisse(**values):
    global delta_k_SI, s_zul, delta_T_Stopfen
    
    _v = values["_v"]
    
    _F_0 = values["_F_R"] * 9.81 * 0.4 / 2
    #_F_0 = values["_F_0"]
    
    _masse_1_zug = ( _F_0 / 9.81 ) / 0.4 * 2 * values["_achsanzahl"]
    _zuege_pro_jahr = values["_n_Z"] * 365
    _B_j = _masse_1_zug * _zuege_pro_jahr / 1000000
    _ltd = _B_j * 1000000 / 365
    _F_dyn = _F_0 * (1 + pow((_v / 300), 2))
    _k_SI_0 =0.01 * 0.25 * pow((_F_dyn / 100), 4)*(1+pow((_v/160), 2))
    
    _stopfgang_i = range(0,values["_stopfen"])
    _reinigung_j = [item for item in _stopfgang_i for i in range(3)]
    _reinigung_ii = 3
    
    _v_index = [i for i,x in enumerate(v) if x == _v][0]
    _s_zul = s_zul[_v_index]
    
    for _delta_k_SI in delta_k_SI:
        _tmp_v = []
        for i in _stopfgang_i:
            
            #_k_SI_0 = 0.025 * pow((_F_dyn / 100), 4) # [1/Mt]
            
            _setzungsintensitaetskonstante = (1 + _stopfgang_i[i] * _delta_k_SI) - (2/3) *  _reinigung_j[i] * _reinigung_ii * _delta_k_SI
            _k_SI_i = _k_SI_0 * _setzungsintensitaetskonstante
            #_s_zul = s_zul[_v_index]
            ## LN 
            #_stopfintervall_delta_b = -(1/_k_SI_i)*math.log(1-(_s_zul/16)) if _s_zul < 16 else 1000 # [Mt]
            _stopfintervall_delta_b = -(1/_k_SI_i)*math.log(1-(_s_zul/(0.25*_s_max)))
            _instandhaltungsintervall_delta_T = _stopfintervall_delta_b / _B_j
            _instandhaltungsintervall_delte_T_min = min(delta_T_Stopfen, _instandhaltungsintervall_delta_T)
            _tmp_v.append([
                "Zug auf Schotter {}".format(_delta_k_SI),
                _stopfgang_i[i],
                _reinigung_j[i],
                _reinigung_ii,
                _v,
                values["_n_Z"],
                _zuege_pro_jahr,
                _B_j,
                _F_dyn,
                _k_SI_0,
                _setzungsintensitaetskonstante,
                _k_SI_i,
                _s_zul,
                _stopfintervall_delta_b,
                _instandhaltungsintervall_delta_T,
                _instandhaltungsintervall_delte_T_min,
            ])
        # sumup _tmp_v
        if _delta_k_SI == 0.2:
            L_Schotter_2 = sum([_x[-1] for _x in _tmp_v])
        else:
            L_Schotter_5 = sum([_x[-1] for _x in _tmp_v])
    
    boxes = []
    
    def p_rev(y):
        m = -2.0258903908369246
        c = 115.26486604656881
        return math.exp((y-c)/m)
    
    #  _F_dyn vs. values["_F_0"] 
    _calc_L_WaO =  p_rev( _F_dyn ) /  ( values["_n_Z"] * values["_achsanzahl"] * 365 )
    
    boxes.append(widgets.HBox([
        #widgets.Text(description="Züge/h:",style={'description_width': description_width}, value="{0:.2f}".format(values["_n_Z"]/24), disabled=True),
        widgets.Text(description="L_Schotter_2 [a]:",style={'description_width': description_width}, value="{0:.2f}".format(L_Schotter_2), disabled=True),
        widgets.Text(description="L_Schotter_5 [a]:",style={'description_width': description_width}, value="{0:.2f}".format(L_Schotter_5), disabled=True),
        widgets.Text(description="delta_T_Stopfen [a]:",style={'description_width': description_width}, value="{}".format(delta_T_Stopfen), disabled=True),
        widgets.Text(description="L_DFF304 IVES [a]",style={'description_width': description_width}, value="{0:.2f}".format(_calc_L_WaO), disabled=True),
        #widgets.Text(description="k_SI_0 [1/Mt]:",style={'description_width': description_width}, value="{0:.5f}".format(_k_SI_0), disabled=True)
    ]))
    boxes.append(widgets.HBox([
        widgets.Text(description="Maße Zug [t]:",style={'description_width': description_width}, value="{0:.2f}".format(_masse_1_zug), disabled=True),
        widgets.Text(description="B_j [Mt/a]:",style={'description_width': description_width}, value="{0:.2f}".format(_B_j), disabled=True),
        widgets.Text(description="B_d [t/d]:",style={'description_width': description_width}, value="{0:.2f}".format(_ltd), disabled=True),
        
    ]))
    boxes.append(widgets.HBox([
        widgets.Text(description="F_0 [kN]:",style={'description_width': description_width}, value="{0:.2f}".format(_F_0), disabled=True),
        widgets.Text(description="F_dyn [kN]:",style={'description_width': description_width}, value="{0:.2f}".format(_F_dyn), disabled=True),
    ]))
    for b in boxes:
        b.layout.min_height = "40px"
    
    display(widgets.VBox(boxes))

o_zwischenergebnisse = widgets.interactive_output(output_zwischenergebnisse, controls_fixed)

boxes1 = []
boxes2 = []
boxes1.append(widgets.HBox([o_zwischenergebnisse]))
boxes1.append(widgets.HBox([ w_F_R, w_v, w_n_Z, w_achsanzahl])) #w_F_0
#boxes1.append(widgets.HBox([w_show_WaO, ]))

boxes2.append(widgets.HBox([w_K_A_Schotter, w_K_A_Stopfen, w_K_Stopfen, w_K_A_Reinigung]))
boxes2.append(widgets.HBox([w_L_FF, w_K_A_FF, w_L_WaO, w_K_A_WaO]))
boxes2.append(widgets.HBox([w_K_RB_Schotter, w_K_RB_FF, w_K_RB_WaO, w_K_Inspektion]))
boxes2.append(widgets.HBox([w_K_A_Schiene_UIC, w_K_A_Schiene_S54, w_K_A_Schiene_S49, w_K_A_Schleifen]))
boxes2.append(widgets.HBox([w_K_A_Schwelle_B07_2600, w_K_A_Schwelle_B70_2600, w_K_A_Schwelle_B70_2400, w_L_Schwelle]))
boxes2.append(widgets.HBox([w_stopfen, w_K_BE_low, w_K_BE_mid, w_K_BE_high, ])) # w_normalized, w_table]))
#boxes2.append(widgets.HBox([w_L, w_s, ])) # w_normalized, w_table]))
boxes2.append(widgets.HBox([w_higher_BE, w_show_WaO, widgets.Text(description="s_max [mm]:",style={'description_width': description_width}, value="{}".format(_s_max), disabled=True)]))

for b in boxes1 + boxes2:
    b.layout.min_height = "40px"

display(html("<hr/>"))
display(widgets.VBox(boxes2))
display(html("<hr/>"))
display(widgets.VBox(boxes1))
display(html("<hr/>"))

VBox(children=(HBox(children=(BoundedIntText(value=220, description='K_A_Schotter [€/m]:', max=2000, min=10, s…

VBox(children=(HBox(children=(Output(),), layout=Layout(min_height='40px')), HBox(children=(IntSlider(value=18…

In [5]:
df_Schotter = None
df_FF = None
df_WaO = None
df_Schiene = None
df_Schwelle = None
df_Inspektion = None
df = pd.DataFrame()

def update_dataframe(**values):
    global df, df_Schotter, df_FF, df_WaO, df_Schiene, df_Schwelle, df_Inspektion
    
    global output1
    global delta_k_SI, s_zul

    global _k_A_Schwelle_optim, _k_A_Schiene_optim, _tmp_Schwelle, _tmp_Schiene, _k_A_Schwelle_optim_1, _k_A_Schwelle_optim_2,_k_A_Schwelle_optim_3,_k_A_Schiene_optim_1,_k_A_Schiene_optim_2,_k_A_Schiene_optim_3

    start = time.time()

    with output1:
        output1.clear_output()
        display(HTML('<span style="color:red;">Berechne...</span>'))
        
    # Inspektion
    _k_Inspektion_optim = {}
    _tmp = []
    for _v_index, _v in enumerate(v):
        _k_Inspektion = values["_K_Inspektion"]/(inspektionsinterval[_v_index]/12)
        _tmp.append([
            _v,
            inspektionsinterval[_v_index],
            inspektionsinterval[_v_index]/12,
            _k_Inspektion
        ])
        _k_Inspektion_optim[_v] = _k_Inspektion
        
    df_Inspektion = pd.DataFrame(_tmp, columns=[
        'v [km/h]',
        'Inspektionsintervall [Monate]',
        'Inspektionsintervall [a]',
        'Inspektionskosten gesamt [€/m*a]'
    ])       

    debug = False
    _start = time.time()
    # Schiene
    _k_A_Schwelle_optim = {}
    _k_A_Schiene_optim = {}
    
    _tmp_Schwelle = []
    _tmp_Schiene = []
    for _L in [values["_L"]]: #L:
        for _v_index, _v in enumerate(v):
            _k_A_Schwelle_optim_1 = _k_A_Schwelle_optim.setdefault(_v, {})
            _k_A_Schiene_optim_1 = _k_A_Schiene_optim.setdefault(_v, {})
            for _n_Z in n_Z:
                _k_A_Schwelle_optim_2 = _k_A_Schwelle_optim_1.setdefault(_n_Z, {})
                _k_A_Schiene_optim_2 = _k_A_Schiene_optim_1.setdefault(_n_Z, {})
                for _F_0 in F_0:
                    _k_A_Schwelle_optim_3 = _k_A_Schwelle_optim_2.setdefault(_F_0, {})
                    _k_A_Schiene_optim_3 = _k_A_Schiene_optim_2.setdefault(_F_0, {})
                    for _achsanzahl in achsanzahl:
                        _k_A_Schwelle_optim_4 = _k_A_Schwelle_optim_3.setdefault(_achsanzahl, {})
                        _k_A_Schiene_optim_4 = _k_A_Schiene_optim_3.setdefault(_achsanzahl, {})
                        
                        _masse_1_zug = ( _F_0 / 9.81 ) / 0.4 * 2 * _achsanzahl
                        _zuege_pro_jahr = _n_Z * 365
                        _B_j = _masse_1_zug * _zuege_pro_jahr / 1000000
                        _ltd = _B_j * 1000000 / 365
                        _F_R = _F_0 / 9.81 / 0.4 * 2
                        _F_dyn = _F_0 * (1 + pow((_v / 300), 2))

                        # Schwelle
                        for _schwelle_typ_index, _schwelle_typ in enumerate(schwellen_typen):
                            # B70_2600
                            if _schwelle_typ_index == 1:
                                if _v > 120:
                                    continue
                            # B70_2400
                            if _schwelle_typ_index == 2:
                                if _v > 120 or _ltd > 30000:
                                    continue
                            
                            _lebensdauer = values["_L_Schwelle"]

                            _anzahl_erneuerung = math.ceil(_L / _lebensdauer)

                            if _schwelle_typ_index == 0:
                                _k_E = values["_K_A_Schwelle_B07_2600"] / _lebensdauer
                            elif _schwelle_typ_index == 1:
                                _k_E = 270*values["_K_A_Schwelle_B07_2600"] / 345 / _lebensdauer
                            else:
                                _k_E = 300*values["_K_A_Schwelle_B07_2600"] / 345 / _lebensdauer

                            _tmp_Schwelle.append([
                                "Schwelle " + _schwelle_typ,
                                _L,
                                _anzahl_erneuerung,
                                _v,
                                _achsanzahl,
                                _n_Z,
                                _zuege_pro_jahr,
                                _B_j,
                                _ltd,
                                _F_R,
                                _F_0,
                                _F_dyn,
                                _lebensdauer,
                                _k_E,
                                _k_E,
                            ])
                            _k_A_Schwelle_optim_4['Schwellentyp'] = "Schwelle " + _schwelle_typ
                            _k_A_Schwelle_optim_4['k_ges [€/m*a]'] = _k_E
                        
                        # Schiene
                        for _schienen_typ_index, _schienen_typ in enumerate(schienen_typen):
                            # S 54
                            if _schienen_typ_index == 1:
                                if _v > 160 or (_ltd > 30000 and _v > 120):
                                    continue
                            # S 49
                            if _schienen_typ_index == 2:
                                if _v > 120 or _ltd > 30000:
                                    continue
                            
                            _delta_B_Schleifen = 10 * pow(( 100 / _F_dyn), 4)
                            _delta_T_Schleifen = _delta_B_Schleifen / _B_j
                            _abnutzung_zul = abnutzung_zul[_v_index]

                            _verschleissrate_rollkontakt = delta_V_Schleifen / _delta_B_Schleifen
                            _gesamtverschleiss_mmmt = V_z0 + _verschleissrate_rollkontakt
                            _gesamtverschleiss_mma = _B_j * _gesamtverschleiss_mmmt
                            _lebensdauer = _abnutzung_zul / _gesamtverschleiss_mma

                            _anzahl_erneuerung = math.ceil(_L / _lebensdauer)

                            if _schienen_typ_index == 0:
                                _k_E = values["_K_A_Schiene_UIC"] / _lebensdauer
                            elif _schienen_typ_index == 1:
                                _k_E = values["_K_A_Schiene_UIC"] * 54 / 60 / _lebensdauer
                            else:
                                _k_E = values["_K_A_Schiene_UIC"] * 49 / 60 / _lebensdauer

                            _k_Schleifen = values["_K_A_Schleifen"] / _delta_T_Schleifen
                            _tmp_Schiene.append([
                                "Schiene " + _schienen_typ,
                                _L,
                                _anzahl_erneuerung,
                                _v,
                                _achsanzahl,
                                _n_Z,
                                _zuege_pro_jahr,
                                _B_j,
                                _ltd,
                                _F_R,
                                _F_0,
                                _F_dyn,
                                _delta_B_Schleifen,
                                _delta_T_Schleifen,
                                _abnutzung_zul,
                                _verschleissrate_rollkontakt,
                                _gesamtverschleiss_mmmt,
                                _gesamtverschleiss_mma,
                                _lebensdauer,
                                _k_E,
                                _k_Schleifen,
                                _k_E + _k_Schleifen,
                            ])
                            _k_A_Schiene_optim_4['Schienentyp'] = "Schiene " + _schienen_typ
                            _k_A_Schiene_optim_4['delta_T_Schleifen [a]'] = _delta_T_Schleifen
                            _k_A_Schiene_optim_4['Schleifkosten [€/m*a]'] = _k_Schleifen
                            _k_A_Schiene_optim_4['k_ges [€/m*a]'] = _k_E + _k_Schleifen
    
    _end = time.time()
    if debug: print(_end-_start)
    
    #Parallel(n_jobs=1)(delayed(loop1)(i) for i in [values["_L"]])
    
    _start = time.time()
    df_Schwelle = pd.DataFrame(_tmp_Schwelle, columns=[
        'Schwellentyp',
        'Laufzeit',
        'Installationen',
        'v [km/h]',
        'Achsanzahl',
        'n_Z [Züge/a]',
        'Züge/a',
        'B_j [Mt/a]',
        'Last [t/d]',
        'F_R [t]',
        'F_0 [kN]',
        'F_dyn [kN]',
        'Lebensdauer [a]',
        'Erneuerungskosten k_E [€/m*a]',
        'k_ges [€/m*a]'
    ])
    
    df_Schiene = pd.DataFrame(_tmp_Schiene, columns=[
        'Schienentyp',
        'Laufzeit',
        'Installationen',
        'v [km/h]',
        'Achsanzahl',
        'n_Z [Züge/a]',
        'Züge/a',
        'B_j [Mt/a]',
        'Last [t/d]',
        'F_R [t]',
        'F_0 [kN]',
        'F_dyn [kN]',
        'delta_B_Schleifen [Mt]',
        'delta_T_Schleifen [a]',
        'zul. Abnutzung [mm]',
        'Verschleißrate Rollkontakt',
        'Gesamtverschleiß [mm/Mt]',
        'Gesamtverschleiß [mm/a]',
        'Lebensdauer [a]',
        'Erneuerungskosten k_E [€/m*a]',
        'Schleifkosten [€/m*a]',
        'k_ges [€/m*a]'
    ])
    
    #print(df_Schiene.loc[
    #    (df_Schiene["v [km/h]"] == 250) & 
    #    (df_Schiene["Achsanzahl"] == 60) & 
    #    (df_Schiene["n_Z [Züge/a]"] == 70) & 
    #    (df_Schiene["F_0 [kN]"] == 70)].head())
    _end = time.time()
    if debug: print(_end-_start)

    _start = time.time()
    _tmp_schotter = []
    _tmp = []
    for _L in [values["_L"]]: #L:
        for _v_index, _v in enumerate(v):
            for _n_Z in n_Z:
                for _F_0 in F_0:
                    for _achsanzahl in achsanzahl:
                        _masse_1_zug = ( _F_0 / 9.81 ) / 0.4 * 2 * _achsanzahl
                        _zuege_pro_jahr = _n_Z * 365
                        _B_j = _masse_1_zug * _zuege_pro_jahr / 1000000
                        _ltd = _B_j * 1000000 / 365
                        _F_R = _F_0 / 9.81 / 0.4 * 2
                        _F_dyn = _F_0 * (1 + pow((_v / 300), 2))
                        
                        # Schotter
                        _k_SI_0 =0.01 * 0.25 * pow((_F_dyn / 100), 4)*(1+pow((_v/160), 2))

                        _stopfgang_i = range(0,values["_stopfen"])
                        _reinigung_j = [item for item in _stopfgang_i for i in range(3)]
                        _reinigung_ii = 3
                        
                        for _delta_k_SI in delta_k_SI:
                            _tmp_v = []
                            for i in _stopfgang_i:
                                
                                _setzungsintensitaetskonstante = (1 + _stopfgang_i[i] * _delta_k_SI) - (2/3) *  _reinigung_j[i] * _reinigung_ii * _delta_k_SI
                                _k_SI_i = _k_SI_0 * _setzungsintensitaetskonstante
                                _s_zul = s_zul[_v_index]
                                ## LN 
                                _stopfintervall_delta_b = -(1/_k_SI_i)*math.log(1-(_s_zul/(0.25*_s_max))) # [Mt]
                                _instandhaltungsintervall_delta_T = _stopfintervall_delta_b / _B_j
                                _instandhaltungsintervall_delte_T_min = min(delta_T_Stopfen, _instandhaltungsintervall_delta_T)

                                _tmp_v.append([
                                    "Zug auf Schotter {}".format(_delta_k_SI),
                                    _L,
                                    _stopfgang_i[i],
                                    _reinigung_j[i],
                                    _reinigung_ii,
                                    _v,
                                    _achsanzahl,
                                    _n_Z,
                                    _zuege_pro_jahr,
                                    _B_j,
                                    _ltd,
                                    _F_R,
                                    _F_0,
                                    _F_dyn,
                                    _k_SI_0,
                                    _setzungsintensitaetskonstante,
                                    _k_SI_i,
                                    _s_zul,
                                    _stopfintervall_delta_b,
                                    _instandhaltungsintervall_delta_T,
                                    _instandhaltungsintervall_delte_T_min,
                                ])
                                _tmp_schotter.append([
                                    "Zug auf Schotter {}".format(_delta_k_SI),
                                    _L,
                                    _stopfgang_i[i],
                                    _reinigung_j[i],
                                    _reinigung_ii,
                                    _v,
                                    _achsanzahl,
                                    _n_Z,
                                    _zuege_pro_jahr,
                                    _B_j,
                                    _ltd,
                                    _F_R,
                                    _F_0,
                                    _F_dyn,
                                    _k_SI_0,
                                    _setzungsintensitaetskonstante,
                                    _k_SI_i,
                                    _s_zul,
                                    _stopfintervall_delta_b,
                                    _instandhaltungsintervall_delta_T,
                                    _instandhaltungsintervall_delte_T_min,
                                ])
                            # sumup _tmp_v
                            #for i in range(0,iter+1):
                            _lebensdauer = sum([_x[-1] for _x in _tmp_v])
                            _anzahl_erneuerung = math.ceil(_L / _lebensdauer)
                            _k_E = (values["_K_A_Schotter"] + values["_K_A_Stopfen"]) / _lebensdauer
                            _k_E += values["_K_Stopfen"] * values["_stopfen"] / _lebensdauer
                            _k_E += values["_K_A_Reinigung"] * math.ceil(values["_stopfen"] / 3) / _lebensdauer
                            _k_RB = values["_K_RB_Schotter"] / _lebensdauer
                            _k_Oberbau = _k_E + _k_RB
                            _k_Schwelle = _k_A_Schwelle_optim[_v][_n_Z][_F_0][_achsanzahl]["k_ges [€/m*a]"]
                            _k_Schiene = _k_A_Schiene_optim[_v][_n_Z][_F_0][_achsanzahl]["k_ges [€/m*a]"]
                            _k_Inspektion = _k_Inspektion_optim[_v]
                            
                            _k_Instandhaltung = _k_A_Schiene_optim[_v][_n_Z][_F_0][_achsanzahl]["Schleifkosten [€/m*a]"] \
                                + _k_Inspektion_optim[_v] + values["_K_Stopfen"] * values["_stopfen"] / _lebensdauer \
                                + values["_K_A_Reinigung"] * math.ceil(values["_stopfen"] / 3) / _lebensdauer
                            
                            _k_ges = _k_Schwelle + _k_Oberbau + _k_Schiene + _k_Inspektion

                            if values["_higher_BE"]:
                                _unterbrechungen = 1 / _k_A_Schiene_optim[_v][_n_Z][_F_0][_achsanzahl]["delta_T_Schleifen [a]"] + 1 / _instandhaltungsintervall_delte_T_min
                            else:
                                _unterbrechungen = 1 / _k_A_Schiene_optim[_v][_n_Z][_F_0][_achsanzahl]["delta_T_Schleifen [a]"] 
                            
                            if _ltd > 30000:
                                _k_BE = _k_ges * values["_K_BE_high"] / 100 * _unterbrechungen
                            elif _ltd > 10000:
                                _k_BE = _k_Instandhaltung * values["_K_BE_mid"] / 100 * _unterbrechungen
                            else:
                                _k_BE = _k_Instandhaltung * values["_K_BE_low"] / 100 * _unterbrechungen
                            
                            if _delta_k_SI == 0.5:
                                _k_Oberbau += 0.01
                            
                            _tmp.append([
                                _tmp_v[0][0],
                                _L,
                                _anzahl_erneuerung,
                                _v,
                                _achsanzahl,
                                _n_Z,
                                _zuege_pro_jahr,
                                _B_j,
                                _ltd,
                                _F_R,
                                _F_0,
                                _F_dyn,
                                _lebensdauer,
                                _k_E,
                                _k_RB,
                                _k_Oberbau,
                                _k_Schwelle,
                                _k_Schiene,
                                _k_Inspektion,
                                _k_Instandhaltung,
                                _k_BE,
                                _k_ges,
                                _k_ges + _k_BE,
                            ])

                        # FF
                        _lebensdauer = values["_L_FF"]
                        _anzahl_erneuerung = math.ceil(_L / _lebensdauer)
                        _k_E = values["_K_A_FF"] * 1.33 / _lebensdauer
                        _k_RB = values["_K_RB_FF"] * 1.33 / _lebensdauer
                        _k_Oberbau = _k_E + _k_RB
                        
                        _k_Schiene = _k_A_Schiene_optim[_v][_n_Z][_F_0][_achsanzahl]["k_ges [€/m*a]"]
                        _k_Inspektion = _k_Inspektion_optim[_v]
                        
                        _k_Instandhaltung = _k_A_Schiene_optim[_v][_n_Z][_F_0][_achsanzahl]["Schleifkosten [€/m*a]"] + _k_Inspektion_optim[_v]
                        
                        _k_ges = _k_E + _k_RB + _k_Schiene + _k_Inspektion

                        if _ltd > 30000:
                            _k_BE = _k_ges * values["_K_BE_high"] / 100 / _k_A_Schiene_optim[_v][_n_Z][_F_0][_achsanzahl]["delta_T_Schleifen [a]"] #/ _lebensdauer
                        elif _ltd > 10000:
                            _k_BE = _k_Instandhaltung * values["_K_BE_mid"] / 100  / _k_A_Schiene_optim[_v][_n_Z][_F_0][_achsanzahl]["delta_T_Schleifen [a]"]#/ _lebensdauer
                        else:
                            _k_BE = _k_Instandhaltung * values["_K_BE_low"] / 100  / _k_A_Schiene_optim[_v][_n_Z][_F_0][_achsanzahl]["delta_T_Schleifen [a]"]#/ _lebensdauer
                        
                        _tmp.append([
                            "Zug auf Fester Fahrbahn",
                            _L,
                            _anzahl_erneuerung,
                            _v,
                            _achsanzahl,
                            _n_Z,
                            _zuege_pro_jahr,
                            _B_j,
                            _ltd,
                            _F_R,
                            _F_0,
                            _F_dyn,
                            _lebensdauer,
                            _k_E,
                            _k_RB,
                            _k_Oberbau,
                            0.0,
                            _k_Schiene,
                            _k_Inspektion,
                            _k_Instandhaltung,
                            _k_BE,
                            _k_ges,
                            _k_ges + _k_BE,
                        ])

                        # WaO
                        _lebensdauer = values["_L_WaO"]
                        _anzahl_erneuerung = math.ceil(_L / _lebensdauer)
                        _k_E = values["_K_A_WaO"] * 1.33 / _lebensdauer
                        _k_RB = values["_K_RB_WaO"] * 1.33 / _lebensdauer
                        _k_Oberbau = _k_E + _k_RB
                        _k_Schiene = _k_A_Schiene_optim[_v][_n_Z][_F_0][_achsanzahl]["k_ges [€/m*a]"]
                        _k_Inspektion = _k_Inspektion_optim[_v]
                        
                        _k_Instandhaltung = _k_A_Schiene_optim[_v][_n_Z][_F_0][_achsanzahl]["Schleifkosten [€/m*a]"] + _k_Inspektion_optim[_v]
                        
                        _k_ges = _k_E + _k_RB + _k_Schiene + _k_Inspektion

                        if _ltd > 30000:
                            _k_BE = _k_ges * values["_K_BE_high"] / 100  / _k_A_Schiene_optim[_v][_n_Z][_F_0][_achsanzahl]["delta_T_Schleifen [a]"]#/ _lebensdauer
                        elif _ltd > 10000:
                            _k_BE = _k_Instandhaltung * values["_K_BE_mid"] / 100  / _k_A_Schiene_optim[_v][_n_Z][_F_0][_achsanzahl]["delta_T_Schleifen [a]"]#/ _lebensdauer
                        else:
                            _k_BE = _k_Instandhaltung * values["_K_BE_low"] / 100  / _k_A_Schiene_optim[_v][_n_Z][_F_0][_achsanzahl]["delta_T_Schleifen [a]"]#/ _lebensdauer
                        
                        _tmp.append([
                            "Zug auf WaO",
                            _L,
                            _anzahl_erneuerung,
                            _v,
                            _achsanzahl,
                            _n_Z,
                            _zuege_pro_jahr,
                            _B_j,
                            _ltd,
                            _F_R,
                            _F_0,
                            _F_dyn,
                            _lebensdauer,
                            _k_E,
                            _k_RB,
                            _k_Oberbau,
                            0.0,
                            _k_Schiene,
                            _k_Inspektion,
                            _k_Instandhaltung,
                            _k_BE,
                            _k_ges,
                            _k_ges + _k_BE,
                        ])
    _end = time.time()
    if debug: print(_end-_start)

    _start = time.time()
    df_Schotter = pd.DataFrame(_tmp_schotter, columns=[
        'Zugtyp',
        'Laufzeit',
        'stopfgang_i',
        'stopfgang_j',
        'reinigung_ii',
        'v [km/h]',
        'Achsanzahl',
        'n_Z [Züge/a]',
        'Züge/a',
        'B_j [Mt/a]',
        'Last [t/d]',
        'F_R [t]',
        'F_0 [kN]',
        'F_dyn [kN]',
        '_k_SI_0',
        '_setzungsintensitaetskonstante',
        '_k_SI_i',
        '_s_zul',
        '_stopfintervall_delta_b',
        '_instandhaltungsintervall_delta_T',
        '_instandhaltungsintervall_delte_T_min',
    ])  
    df = pd.DataFrame(_tmp, columns=[
        'Zugtyp',
        'Laufzeit',
        'Installationen',
        'v [km/h]',
        'Achsanzahl',
        'n_Z [Züge/a]',
        'Züge/a',
        'B_j [Mt/a]',
        'Last [t/d]',
        'F_R [t]',
        'F_0 [kN]',
        'F_dyn [kN]',
        'Lebensdauer [a]',
        'Erneuerungskosten [€/m*a]',
        'Rückbaukosten [€/m*a]',
        'Oberbau [€/m*a]',
        'Schwelle [€/m*a]',
        'Schiene [€/m*a]',
        'Inspektion [€/m*a]',
        'Instandhaltung [€/m*a]',
        'Betriebserschwerniskosten [€/m*a]',
        'k_ges_o [€/m*a]',
        'k_ges [€/m*a]',
    ])

    _end = time.time()
    if debug: print(_end-_start)
    
    # total table
    #df = pd.concat([df_Schotter, df_FF, df_WaO], ignore_index=True, sort=False)
    df.set_index('Zugtyp', inplace=True)
    
    end = time.time()
    
    with output1:
        output1.clear_output()
        display(md("Generierte Tabellenzeilen: {} in {:.2f} sec".format(len(df), end - start)))

#o_update_dataframe = widgets.interactive_output(update_dataframe, controls_individual)
#o_update_dataframe.layout.min_height = '700px'
#display(o_update_dataframe)
In [6]:
def output_diagram_1(output=None, **values):
    global df
    if df.empty:
        return
    
    #if values["_normalized"]:
    #    df[['Erneuerungen', "k_ges [€/m*a]"]] = minmax_scale(df[["Installationen", "k_ges [€/m*a]"]])

    _F_0 = values["_F_R"] * 9.81 * 0.4 / 2
    _df_filtered = df.loc[
        (df["v [km/h]"] == values["_v"]) & 
        (df["Achsanzahl"] == values["_achsanzahl"]) & 
        (df["n_Z [Züge/a]"] == values["_n_Z"]) & 
        (df["F_0 [kN]"] == _F_0) & 
        (df["Laufzeit"] == values["_L"])
    ]
    if not values["_show_WaO"]:
        _df_filtered = _df_filtered[_df_filtered.index.isin(liste_ohne_WaO)]
        
    if values["_table"]:
        display(_df_filtered)
    
    #fig, axes = plt.subplots(nrows=1, ncols=2, figsize=(10, 8))
    #fig = plt.figure()
    
    ax = _df_filtered[["Schiene [€/m*a]","Inspektion [€/m*a]","Rückbaukosten [€/m*a]","Erneuerungskosten [€/m*a]","Betriebserschwerniskosten [€/m*a]", "Schwelle [€/m*a]"]].plot.bar(
        title="Kosten",
        #ax=axes[0],
        xlabel = 'k_ges [€/m*a]',
        ylabel = "Fahrbahn",
        grid=True,
        stacked=True,
    )
    ax.set_axisbelow(True)
    plt.legend(loc='center left', bbox_to_anchor=(1, 0.5))
    
    if output:
        output.clear_output()
    plt.show()


#o_output_diagram_1 = widgets.interactive_output(output_diagram_1, controls_fixed | controls_individual)
#o_output_diagram_1.layout.min_height = '700px'
#display(o_output_diagram_1)
In [7]:
def output_table(output=None, **values):
    global df, df_Schiene, df_Schwelle, df_Schotter
    if df.empty:
        return
    
    #if values["_normalized"]:
    #    df[['Erneuerungen', "k_ges [€/m*a]"]] = minmax_scale(df[["Installationen", "k_ges [€/m*a]"]])

    #df.to_csv('LCC_complete_table.csv')

    #with open("LCC_inputs.json", "w") as f:
    #    f.write(json.dumps(values, indent=2))
        
    #with zipfile.ZipFile('LCC.zip', 'w', compression=zipfile.ZIP_DEFLATED) as myzip:
    #    myzip.write("LCC_inputs.json")
    #    myzip.write('LCC_complete_table.csv')
    #    myzip.write("LCC_2.ipynb")

    if output:
        output.clear_output()
        
    #display(html("<a href='{}'>{} (~10 Mb)</a>".format('LCC.zip','LCC.zip')))
    #display(FileLink('LCC.zip'))
    _F_0 = values["_F_R"] * 9.81 * 0.4 / 2
    _df_filtered = df.loc[
        (df["v [km/h]"] == values["_v"]) & 
        (df["Achsanzahl"] == values["_achsanzahl"]) & 
        (df["n_Z [Züge/a]"] == values["_n_Z"]) & 
        (df["F_0 [kN]"] == _F_0) & 
        (df["Laufzeit"] == values["_L"])
    ]
    
    if not values["_show_WaO"]:
        _df_filtered = _df_filtered[_df_filtered.index.isin(liste_ohne_WaO)]

    rewrite = [
        #'Laufzeit',
        #'Installationen',
        ('v [km/h]','v [km/h]'),
        ('Achsanzahl','Achs-anzahl'),
        ('n_Z [Züge/a]','n_Z [Züge/a]'),
        ('Züge/a','Züge/a'),
        ('B_j [Mt/a]','B_j [Mt/a]'),
        ('Last [t/d]','Last [t/d]'),
        ('F_R [t]','F_R [t]'),
        ('F_0 [kN]','F_0 [kN]'),
        ('F_dyn [kN]','F_dyn [kN]'),
        ('Lebensdauer [a]','Lebens-dauer [a]'),
        ('Erneuerungskosten [€/m*a]','Erneuerungs-kosten [€/m*a]'),
        ('Rückbaukosten [€/m*a]','Rückbau-kosten [€/m*a]'),
        ('Oberbau [€/m*a]','Oberbau [€/m*a]'),
        ('Schwelle [€/m*a]','Schwelle [€/m*a]'),
        ('Schiene [€/m*a]','Schiene [€/m*a]'),
        ('Inspektion [€/m*a]','Inspektion [€/m*a]'),
        ('Instandhaltung [€/m*a]','Instand-haltung [€/m*a]'),
        ('Betriebserschwerniskosten [€/m*a]','Betriebs-erschwer-niskosten [€/m*a]'),
        ('k_ges_o [€/m*a]','k_ges_o [€/m*a]'),
        ('k_ges [€/m*a]','k_ges [€/m*a]'),
    ]
    _df = _df_filtered[[]]

    for i in rewrite:
        _df[i[1]] = _df_filtered[i[0]]
    
    #_df.style.format(decimal=',', precision=2)
    display(_df)

    display(html("<br/>"))

    _df_filtered = df_Schwelle.loc[
        (df_Schwelle["v [km/h]"] == values["_v"]) & 
        (df_Schwelle["Achsanzahl"] == values["_achsanzahl"]) & 
        (df_Schwelle["n_Z [Züge/a]"] == values["_n_Z"]) & 
        (df_Schwelle["F_0 [kN]"] == _F_0) & 
        (df_Schwelle["Laufzeit"] == values["_L"])
    ]
    _df_filtered.set_index('Schwellentyp', inplace=True)
    rewrite = [
        #'Laufzeit',
        #'Installationen',
        ('v [km/h]','v [km/h]'),
        ('Achsanzahl','Achsanzahl'),
        ('n_Z [Züge/a]','n_Z [Züge/a]'),
        ('Züge/a','Züge/a'),
        ('B_j [Mt/a]','B_j [Mt/a]'),
        ('Last [t/d]','Last [t/d]'),
        ('F_R [t]','F_R [t]'),
        ('F_0 [kN]','F_0 [kN]'),
        ('F_dyn [kN]','F_dyn [kN]'),
        ('Lebensdauer [a]','Lebensdauer [a]'),
        ('Erneuerungskosten k_E [€/m*a]','Erneuerungskosten [€/m*a]'),
        ('k_ges [€/m*a]','k_ges [€/m*a]'),
    ]
    
    _df = _df_filtered[[]]

    for i in rewrite:
        _df[i[1]] = _df_filtered[i[0]]

    display(_df)
    
    display(html("<br/>"))

    _df_filtered = df_Schiene.loc[
        (df_Schiene["v [km/h]"] == values["_v"]) & 
        (df_Schiene["Achsanzahl"] == values["_achsanzahl"]) & 
        (df_Schiene["n_Z [Züge/a]"] == values["_n_Z"]) & 
        (df_Schiene["F_0 [kN]"] == _F_0) & 
        (df_Schiene["Laufzeit"] == values["_L"])
    ]
    _df_filtered.set_index('Schienentyp', inplace=True)
    rewrite = [
        #'Laufzeit',
        #'Installationen',
        ('v [km/h]','v [km/h]'),
        ('Achsanzahl','Achs-anzahl'),
        ('n_Z [Züge/a]','n_Z [Züge/a]'),
        ('Züge/a','Züge/a'),
        ('B_j [Mt/a]','B_j [Mt/a]'),
        ('Last [t/d]','Last [t/d]'),
        ('F_R [t]','F_R [t]'),
        ('F_0 [kN]','F_0 [kN]'),
        ('F_dyn [kN]','F_dyn [kN]'),
        ('delta_B_Schleifen [Mt]','delta_B_-Schleifen [Mt]'),
        ('delta_T_Schleifen [a]','delta_T_-Schleifen [a]'),
        ('zul. Abnutzung [mm]','zul. Ab-nutzung [mm]'),
        ('Verschleißrate Rollkontakt','Verschleiß-rate Roll-kontakt'),
        ('Gesamtverschleiß [mm/Mt]','Gesamt-verschleiß [mm/Mt]'),
        ('Gesamtverschleiß [mm/a]','Gesamt-verschleiß [mm/a]'),
        ('Lebensdauer [a]','Lebens-dauer [a]'),
        ('Erneuerungskosten k_E [€/m*a]','Erneuerungs-kosten [€/m*a]'),
        ('Schleifkosten [€/m*a]','Schleif-kosten [€/m*a]'),
        ('k_ges [€/m*a]','k_ges [€/m*a]'),
    ]
    
    _df = _df_filtered[[]]

    for i in rewrite:
        _df[i[1]] = _df_filtered[i[0]]

    display(_df)
    
    display(html("<br/>"))
    
    _df_filtered = df_Schotter.loc[
        (df_Schotter["v [km/h]"] == values["_v"]) & 
        (df_Schotter["Achsanzahl"] == values["_achsanzahl"]) & 
        (df_Schotter["n_Z [Züge/a]"] == values["_n_Z"]) & 
        (df_Schotter["F_0 [kN]"] == _F_0) & 
        (df_Schotter["Laufzeit"] == values["_L"])
    ]
    _df_filtered.set_index('Zugtyp', inplace=True)
    rewrite = [
        #'Laufzeit',
        #'Installationen',
        ('stopfgang_i','stopf-gang_i'),
        ('stopfgang_j','stopf-gang_j'),
        ('reinigung_ii','reini-gung_ii'),
        ('v [km/h]','v [km/h]'),
        ('Achsanzahl','Achs-anzahl'),
        ('n_Z [Züge/a]','n_Z [Züge/a]'),
        ('Züge/a','Züge/a'),
        ('B_j [Mt/a]','B_j [Mt/a]'),
        ('Last [t/d]','Last [t/d]'),
        ('F_R [t]','F_R [t]'),
        ('F_0 [kN]','F_0 [kN]'),
        ('F_dyn [kN]','F_dyn [kN]'),
        ('_k_SI_0','_k_SI_0'),
        ('_setzungsintensitaetskonstante','_setzungs-intensitaets-konstante'),
        ('_k_SI_i','_k_SI_i'),
        ('_s_zul','_s_zul'),
        ('_stopfintervall_delta_b','_stopf-intervall-_delta_b'),
        ('_instandhaltungsintervall_delta_T','_instand-haltungs-intervall-_delta_T'),
        ('_instandhaltungsintervall_delte_T_min','_instand-haltungsi-ntervall-_delte_T-_min'),
    ]
    _df = _df_filtered[[]]

    for i in rewrite:
        _df[i[1]] = _df_filtered[i[0]]

    display(_df)
    
#o_output_table = widgets.interactive_output(output_table, controls_fixed | controls_individual)
#o_output_table.layout.min_height = '700px'
#display(o_output_table)
In [8]:
def output_diagram_kosten_gesamt(output=None, **values):
    global df
    if df.empty:
        return

    _F_0 = values["_F_R"] * 9.81 * 0.4 / 2
    _v = values["_v"]
    _masse_1_zug = ( _F_0 / 9.81 ) / 0.4 * 2 * values["_achsanzahl"]
    _zuege_pro_jahr = values["_n_Z"] * 365
    _B_j = _masse_1_zug * _zuege_pro_jahr / 1000000
    _F_dyn = _F_0 * (1 + pow((_v / 300), 2))
    
    #if values["_normalized"]:
    #    df[['Erneuerungen', "k_ges [€/m*a]"]] = minmax_scale(df[["Installationen", "k_ges [€/m*a]"]])
    
    fig, axes = plt.subplots(nrows=1, ncols=3, figsize=(15, 8))

    # 1
    _df = df.loc[
        (df["Achsanzahl"] == values["_achsanzahl"]) & 
        (df["n_Z [Züge/a]"] == values["_n_Z"]) & 
        (df["F_0 [kN]"] == _F_0) & 
        (df["Laufzeit"] == values["_L"])
    ]
    
    if not values["_show_WaO"]:
        _df = _df[_df.index.isin(liste_ohne_WaO)]

        
    if values["_table"]:
        display(_df)

    _df.reset_index(inplace=True)
    _df.set_index('v [km/h]', inplace=True)
    
    ax = _df.groupby("Zugtyp")["k_ges [€/m*a]"].plot(
        title="Vergleich",
        ax=axes[0],
        legend=True,
        grid=True,
        rot=0,
        xlabel="v [km/h]",
        ylabel="Kosten [€/m*a]"
    )
    axes[0].axvline(_v, color="red", linestyle="--")
    #ax.set_axisbelow(True)

    # 2
    _df = df.loc[
        (df["v [km/h]"] == values["_v"]) & 
        (df["Achsanzahl"] == values["_achsanzahl"]) & 
        (df["n_Z [Züge/a]"] == values["_n_Z"]) & 
        (df["Laufzeit"] == values["_L"])
    ]

    if not values["_show_WaO"]:
        _df = _df[_df.index.isin(liste_ohne_WaO)]
        
    if values["_table"]:
        display(_df)

    _df.reset_index(inplace=True)
    _df.set_index('F_dyn [kN]', inplace=True)
    
    ax = _df.groupby("Zugtyp")["k_ges [€/m*a]"].plot(
        title="Vergleich",
        legend=True,
        grid=True,
        ax=axes[1],
        rot=0,
        xlabel="F_dyn [kN]",
        ylabel="Kosten [€/m*a]"
    )
    axes[1].axvline(_F_dyn, color="red", linestyle="--")
    #ax.set_axisbelow(True)
    #axes[1].axes.get_yaxis().set_visible(False)
    
    # 3
    _df = df.loc[
        (df["v [km/h]"] == values["_v"]) & 
        (df["Achsanzahl"] == values["_achsanzahl"]) & 
        (df["n_Z [Züge/a]"] == values["_n_Z"]) & 
        (df["Laufzeit"] == values["_L"])
    ]

    if not values["_show_WaO"]:
        _df = _df[_df.index.isin(liste_ohne_WaO)]
        
    if values["_table"]:
        display(_df)

    _df.reset_index(inplace=True)
    _df.set_index('B_j [Mt/a]', inplace=True)
    
    ax = _df.groupby("Zugtyp")["k_ges [€/m*a]"].plot(
        title="Vergleich",
        legend=True,
        grid=True,
        ax=axes[2],
        rot=0,
        xlabel="B_j [Mt/a]",
        ylabel="Kosten [€/m*a]"
    )
    axes[2].axvline(_B_j, color="red", linestyle="--")
    
    if output:
        output.clear_output()
    plt.show()
    
#o_output_diagram_kosten_gesamt = widgets.interactive_output(output_diagram_kosten_gesamt, controls_fixed | controls_individual)
#o_output_diagram_kosten_gesamt.layout.min_height = '700px'
In [9]:
def output_diagram_kosten_gesplittet(output=None, **values):
    global df
    if df.empty:
        return
        
    _v = values["_v"]
    _F_0 = values["_F_R"] * 9.81 * 0.4 / 2
    _masse_1_zug = ( _F_0 / 9.81 ) / 0.4 * 2 * values["_achsanzahl"]
    _zuege_pro_jahr = values["_n_Z"] * 365
    _B_j = _masse_1_zug * _zuege_pro_jahr / 1000000
    _F_dyn = _F_0 * (1 + pow((_v / 300), 2))
    
    #if values["_normalized"]:
    #    df[['Erneuerungen', "k_ges [€/m*a]"]] = minmax_scale(df[["Installationen", "k_ges [€/m*a]"]])
    
    fig, axes = plt.subplots(nrows=1, ncols=4, figsize=(20, 8))

    # 1
    _df = df.loc[
        (df["Achsanzahl"] == values["_achsanzahl"]) & 
        (df["n_Z [Züge/a]"] == values["_n_Z"]) & 
        (df["F_0 [kN]"] == _F_0) & 
        (df["Laufzeit"] == values["_L"])
    ]

    if not values["_show_WaO"]:
        _df = _df[_df.index.isin(liste_ohne_WaO)]
        
    if values["_table"]:
        display(_df)

    _df.reset_index(inplace=True)
    _df.set_index('v [km/h]', inplace=True)

    ax = _df.groupby("Zugtyp")["Schiene [€/m*a]"].plot(
        title="Vergleich",
        ax=axes[0],
        legend=True,
        grid=True,
        rot=0,
        xlabel="v [km/h]",
        ylabel="Schiene [€/m*a]"
    )
    axes[0].axvline(_v, color="red", linestyle="--")
    #ax.set_axisbelow(True)

    # 2
    _df = df.loc[
        (df["Achsanzahl"] == values["_achsanzahl"]) & 
        (df["n_Z [Züge/a]"] == values["_n_Z"]) & 
        (df["F_0 [kN]"] == _F_0) & 
        (df["Laufzeit"] == values["_L"])
    ]

    if not values["_show_WaO"]:
        _df = _df[_df.index.isin(liste_ohne_WaO)]
        
    if values["_table"]:
        display(_df)

    _df.reset_index(inplace=True)
    _df.set_index('v [km/h]', inplace=True)
    
    ax = _df.groupby("Zugtyp")["Inspektion [€/m*a]"].plot(
        title="Vergleich",
        legend=True,
        grid=True,
        ax=axes[1],
        rot=0,
        xlabel="v [km/h]",
        ylabel="Inspektion [€/m*a]"
    )
    axes[1].axvline(_v, color="red", linestyle="--")
    #ax.set_axisbelow(True)
    #axes[1].axes.get_yaxis().set_visible(False)
    
    # 3
    _df = df.loc[
        (df["Achsanzahl"] == values["_achsanzahl"]) & 
        (df["n_Z [Züge/a]"] == values["_n_Z"]) & 
        (df["F_0 [kN]"] == _F_0) & 
        (df["Laufzeit"] == values["_L"])
    ]

    if not values["_show_WaO"]:
        _df = _df[_df.index.isin(liste_ohne_WaO)]
        
    #if values["_table"]:
    #    display(_df)

    _df.reset_index(inplace=True)
    _df.set_index('v [km/h]', inplace=True)

    _df2 = _df.loc[:, ["Zugtyp","Oberbau [€/m*a]","Schwelle [€/m*a]"]]
    _df2["sum"] =_df2[["Oberbau [€/m*a]","Schwelle [€/m*a]"]].sum(axis=1)
    
    ax = _df2.groupby("Zugtyp")["sum"].plot(
        title="Vergleich",
        legend=True,
        grid=True,
        ax=axes[2],
        rot=0,
        xlabel="v [km/h]",
        ylabel="Oberbau + Schwelle [€/m*a]"
    )
    axes[2].axvline(_v, color="red", linestyle="--")

    # 4
    _df = df.loc[
        (df["Achsanzahl"] == values["_achsanzahl"]) & 
        (df["n_Z [Züge/a]"] == values["_n_Z"]) & 
        (df["F_0 [kN]"] == _F_0) & 
        (df["Laufzeit"] == values["_L"])
    ]

    if not values["_show_WaO"]:
        _df = _df[_df.index.isin(liste_ohne_WaO)]
        
    if values["_table"]:
        display(_df)

    _df.reset_index(inplace=True)
    _df.set_index('v [km/h]', inplace=True)
    
    ax = _df.groupby("Zugtyp")["Betriebserschwerniskosten [€/m*a]"].plot(
        title="Vergleich",
        legend=True,
        grid=True,
        ax=axes[3],
        rot=0,
        xlabel="v [km/h]",
        ylabel="Betriebserschwerniskosten [€/m*a]"
    )
    axes[3].axvline(_v, color="red", linestyle="--")
    #ax.set_axisbelow(True)
    #axes[1].axes.get_yaxis().set_visible(False)
    
    if output:
        output.clear_output()
    plt.show()
    
#o_output_diagram_kosten_gesplittet = widgets.interactive_output(output_diagram_kosten_gesplittet, controls_fixed | controls_individual)
#o_output_diagram_kosten_gesplittet.layout.min_height = '700px'
In [10]:
def output_diagram_kosten_gesplittet_plotly(output=None, **values):
    global df
    if df.empty:
        return
        
    _v = values["_v"]
    _F_0 = values["_F_R"] * 9.81 * 0.4 / 2
    _masse_1_zug = ( _F_0 / 9.81 ) / 0.4 * 2 * values["_achsanzahl"]
    _zuege_pro_jahr = values["_n_Z"] * 365
    _B_j = _masse_1_zug * _zuege_pro_jahr / 1000000
    _F_dyn = _F_0 * (1 + pow((_v / 300), 2))

        
    # 1
    _df = df.loc[
        (df["Achsanzahl"] == values["_achsanzahl"]) & 
        (df["n_Z [Züge/a]"] == values["_n_Z"]) & 
        (df["F_0 [kN]"] == _F_0) & 
        (df["Laufzeit"] == values["_L"])
    ]

    if not values["_show_WaO"]:
        _df = _df[_df.index.isin(liste_ohne_WaO)]
        
    if values["_table"]:
        display(_df)

    _df.reset_index(inplace=True)
        
    #fig = make_subplots(rows=1, cols=3)
    
    _fig1 = px.line(_df[["v [km/h]", "Schiene [€/m*a]", "Zugtyp"]], x="v [km/h]", y="Schiene [€/m*a]", color="Zugtyp", markers=True)
    _fig1.add_vline(x=_v, line_dash="dash", line_color="red")
    _fig1.update_traces(showlegend=False)

    #fig.add_trace(_fig.data[0], row=1, col=1)
    
    _fig2 = px.line(_df[["v [km/h]", "Inspektion [€/m*a]", "Zugtyp"]], x="v [km/h]", y="Inspektion [€/m*a]", color="Zugtyp", markers=True)
    _fig2.add_vline(x=_v, line_dash="dash", line_color="red")
    _fig2.update_traces(showlegend=False)
    #fig.add_trace(_fig.data[0], row=1, col=2)
    
    _df2 = _df.loc[:, ["Zugtyp","v [km/h]","Oberbau [€/m*a]","Schwelle [€/m*a]"]]
    _df2["Oberbau + Schwelle [€/m*a]"] =_df2[["Oberbau [€/m*a]","Schwelle [€/m*a]"]].sum(axis=1)
    
    _fig3 = px.line(_df2, x="v [km/h]", y="Oberbau + Schwelle [€/m*a]", color="Zugtyp", markers=True)
    _fig3.add_vline(x=_v, line_dash="dash", line_color="red")
    #_fig3.update_traces(showlegend=False)
    #fig.add_trace(_fig.data[0], row=1, col=3)
    
    if output:
        output.clear_output()
    display(widgets.HBox([
        go.FigureWidget(data=_fig1.data, layout=go.Layout(xaxis={'title':'v [km/h]'},yaxis={'title':'Schiene [€/m*a]'})),
        go.FigureWidget(_fig2.data, layout=go.Layout(xaxis={'title':'v [km/h]'},yaxis={'title':'Inspektion [€/m*a]'})),
        go.FigureWidget(_fig3.data, layout=go.Layout(xaxis={'title':'v [km/h]'},yaxis={'title':'Oberbau + Schwelle [€/m*a]'})),
    ]))

    #fig.show()

#o_output_diagram_kosten_gesplittet_plotly = widgets.interactive_output(output_diagram_kosten_gesplittet_plotly, controls_fixed | controls_individual)
#o_output_diagram_kosten_gesplittet_plotly.layout.min_height = '700px'

#display(o_output_diagram_kosten_gesplittet_plotly)
In [11]:
def output_diagram_kosten_gesamt_plotly(output=None, **values):
    global df
    if df.empty:
        return

    _v = values["_v"]
    _F_0 = values["_F_R"] * 9.81 * 0.4 / 2
    _masse_1_zug = ( _F_0 / 9.81 ) / 0.4 * 2 * values["_achsanzahl"]
    _zuege_pro_jahr = values["_n_Z"] * 365
    _B_j = _masse_1_zug * _zuege_pro_jahr / 1000000
    _F_dyn = _F_0 * (1 + pow((_v / 300), 2))

    #1
    _df = df.loc[
        (df["Achsanzahl"] == values["_achsanzahl"]) & 
        (df["n_Z [Züge/a]"] == values["_n_Z"]) & 
        (df["F_0 [kN]"] == _F_0) & 
        (df["Laufzeit"] == values["_L"])
    ]
    
    if not values["_show_WaO"]:
        _df = _df[_df.index.isin(liste_ohne_WaO)]
        
    _df.reset_index(inplace=True)
        
    _fig1 = px.line(_df, x="v [km/h]", y="k_ges [€/m*a]", color="Zugtyp", markers=True)
    _fig1.add_vline(x=_v, line_dash="dash", line_color="red")
    _fig1.update_traces(showlegend=False)

    #2
    _df = df.loc[
        (df["v [km/h]"] == values["_v"]) & 
        (df["Achsanzahl"] == values["_achsanzahl"]) & 
        (df["n_Z [Züge/a]"] == values["_n_Z"]) & 
        (df["Laufzeit"] == values["_L"])
    ]
    
    if not values["_show_WaO"]:
        _df = _df[_df.index.isin(liste_ohne_WaO)]
        
    _df.reset_index(inplace=True)
        
    _fig2 = px.line(_df, x="F_dyn [kN]", y="k_ges [€/m*a]", color="Zugtyp", markers=True)
    _fig2.add_vline(x=_F_dyn, line_dash="dash", line_color="red")
    _fig2.update_traces(showlegend=False)


    #3
    _df = df.loc[
        (df["v [km/h]"] == values["_v"]) & 
        (df["Achsanzahl"] == values["_achsanzahl"]) & 
        (df["n_Z [Züge/a]"] == values["_n_Z"]) & 
        (df["Laufzeit"] == values["_L"])
    ]

    if not values["_show_WaO"]:
        _df = _df[_df.index.isin(liste_ohne_WaO)]
        
    _df.reset_index(inplace=True)    
    
    _fig3 = px.line(_df, x="B_j [Mt/a]", y="k_ges [€/m*a]", color="Zugtyp", markers=True)
    _fig3.add_vline(x=_F_dyn, line_dash="dash", line_color="red")
    #_fig3.update_traces(showlegend=False)

    if output:
        output.clear_output()
    display(widgets.HBox([
        go.FigureWidget(data=_fig1.data, layout=go.Layout(xaxis={'title':'v [km/h]'},yaxis={'title':'k_ges [€/m*a]'})),
        go.FigureWidget(_fig2.data, layout=go.Layout(xaxis={'title':'F_dyn [kN]'},yaxis={'title':'k_ges [€/m*a]'})),
        go.FigureWidget(_fig3.data, layout=go.Layout(xaxis={'title':'B_j [Mt/a]'},yaxis={'title':'k_ges [€/m*a]'})),
    ]))
    
#o_output_diagram_kosten_gesamt_plotly = widgets.interactive_outputcoutput_diagram_kosten_gesamt_plotly, controls_fixed | controls_individual)
#o_output_diagram_kosten_gesamt_plotly.layout.min_height = '700px'

#display(o_output_diagram_kosten_gesamt_plotly)
In [12]:
def output_compare_lcc(output=None, **values):
    global df, df_Schiene, df_Schwelle, df_Schotter

    if df.empty:
        return
    
    if output:
        output.clear_output()
        
    _v = values["_v"]
    _F_0 = values["_F_R"] * 9.81 * 0.4 / 2
    _masse_1_zug = ( _F_0 / 9.81 ) / 0.4 * 2 * values["_achsanzahl"]
    _zuege_pro_jahr = values["_n_Z"] * 365
    _B_j = _masse_1_zug * _zuege_pro_jahr / 1000000
    _F_dyn = _F_0 * (1 + pow((_v / 300), 2))

        
    # 1
    _df = df.loc[
        (df["Achsanzahl"] == values["_achsanzahl"]) & 
        (df["n_Z [Züge/a]"] == values["_n_Z"]) & 
        (df["F_0 [kN]"] == _F_0) & 
        (df["Laufzeit"] == values["_L"])
    ]
    
    mt_a = [3.65, 10.95, 2*10.95]
    ff_ld = [20, 40, 60]
    wao_ld = ff_ld
    
    _F_0 = 17 * 9.81 * 0.4 / 2

    # F_R bei 25 ideal
    
    print("F_R [t]", values["_F_R"])
    print("_L_WaO", values["_L_WaO"])
    print("_L_FF", values["_L_FF"])

    result_table = None
    result_table_bew = None
    
    # less efficient, doesnt matter
    #result_table = result_table.append({'A': i}, ignore_index=True)
    
    for _mt_a in mt_a:
        
        _df = df.loc[
            (df["B_j [Mt/a]"] <= _mt_a) &
            (df["F_R [t]"] == values["_F_R"])
        ] #sort_values(by=["B_j [Mt/a]"], ascending=False)

        _s1 = pd.Series(_df.groupby("Zugtyp").max()["Lebensdauer [a]"], name="LD")
        _s2 = pd.Series(_df.groupby("Zugtyp").max()["B_j [Mt/a]"], name="B_j [Mt/a]")
        _temp = pd.concat([_s1, _s2], axis=1)
        _temp_bew = pd.concat([_s1, _s2], axis=1)
        for _v in v:
            #print(len(_df))
            #display(_df[["B_j [Mt/a]", "v [km/h]", "F_R [t]", "F_0 [kN]", "n_Z [Züge/a]", "Achsanzahl", "k_ges_o [€/m*a]","k_ges [€/m*a]"]].head(n=8))
            _s1 = pd.Series(_df.loc[(_df["v [km/h]"] == _v)].groupby("Zugtyp").max()["k_ges [€/m*a]"], name=_v)
            _s2 = pd.Series(_df.loc[(_df["v [km/h]"] == _v)].groupby("Zugtyp").max()["k_ges_o [€/m*a]"], name=_v)
            _temp_bew = pd.concat([_temp_bew, _s1], axis=1)
            _temp = pd.concat([_temp, _s2], axis=1)
        
        result_table_bew = pd.concat([result_table_bew, _temp_bew])
        result_table = pd.concat([result_table, _temp])
        
    print("Inkl. BEW")
    display(result_table_bew)
    print("Exkl. BEW")
    display(result_table)
    
#o_output_compare_lcc = widgets.interactive_output(output_compare_lcc, controls_fixed | controls_individual)
#o_output_compare_lcc.layout.min_height = '700px'
#display(o_output_compare_lcc)
In [13]:
def output_compare_ihkbek(output=None, **values):
    global df, df_Schiene, df_Schwelle, df_Schotter

    if df.empty:
        return
    
    if output:
        output.clear_output()
        
    _v = values["_v"]
    _F_0 = values["_F_R"] * 9.81 * 0.4 / 2
    _masse_1_zug = ( _F_0 / 9.81 ) / 0.4 * 2 * values["_achsanzahl"]
    _zuege_pro_jahr = values["_n_Z"] * 365
    _B_j = _masse_1_zug * _zuege_pro_jahr / 1000000
    _F_dyn = _F_0 * (1 + pow((_v / 300), 2))

        
    # 1
    _df = df.loc[
        (df["Achsanzahl"] == values["_achsanzahl"]) & 
        (df["n_Z [Züge/a]"] == values["_n_Z"]) & 
        (df["F_0 [kN]"] == _F_0) & 
        (df["Laufzeit"] == values["_L"])
    ]
    
    mt_a = [3.65, 10.95, 2*10.95]
    ff_ld = [20, 40, 60]
    wao_ld = ff_ld
    
    _F_0 = 17 * 9.81 * 0.4 / 2

    # F_R bei 25 ideal
    
    print("F_R [t]", values["_F_R"])
    print("_L_WaO", values["_L_WaO"])
    print("_L_FF", values["_L_FF"])

    result_table_ihk = None
    result_table_bek = None
    
    # less efficient, doesnt matter
    #result_table = result_table.append({'A': i}, ignore_index=True)

    def calc_db(_row):
        return _row[80] * 0.34 + _row[120] * 0.26 + _row[160] * 0.10 + _row[230] * 0.27 + _row[300] * 0.03
    
    for _mt_a in mt_a:
        
        _df = df.loc[
            (df["B_j [Mt/a]"] <= _mt_a) &
            (df["F_R [t]"] == values["_F_R"])
        ] #sort_values(by=["B_j [Mt/a]"], ascending=False)

        _s1 = pd.Series(_df.groupby("Zugtyp").max()["Lebensdauer [a]"], name="LD")
        _s2 = pd.Series(_df.groupby("Zugtyp").max()["B_j [Mt/a]"], name="B_j [Mt/a]")
        _temp_ihk = pd.concat([_s1, _s2], axis=1)
        _temp_bek = pd.concat([_s1, _s2], axis=1)
        for _v in v:
            #print(len(_df))
            #display(_df[["B_j [Mt/a]", "v [km/h]", "F_R [t]", "F_0 [kN]", "n_Z [Züge/a]", "Achsanzahl", "k_ges_o [€/m*a]","k_ges [€/m*a]"]].head(n=8))
            _s1 = pd.Series(_df.loc[(_df["v [km/h]"] == _v)].groupby("Zugtyp").max()["Instandhaltung [€/m*a]"], name=_v)
            _s2 = pd.Series(_df.loc[(_df["v [km/h]"] == _v)].groupby("Zugtyp").max()["Betriebserschwerniskosten [€/m*a]"], name=_v)
            _temp_ihk = pd.concat([_temp_ihk, _s1], axis=1)
            _temp_bek = pd.concat([_temp_bek, _s2], axis=1)
        
        _temp_bek["Durchschnitt"] = _temp_bek.apply(calc_db, axis=1)
        _temp_ihk["Durchschnitt"] = _temp_ihk.apply(calc_db, axis=1)
        
        result_table_bek = pd.concat([result_table_bek, _temp_bek])
        result_table_ihk = pd.concat([result_table_ihk, _temp_ihk])
        
    print("IHK")
    display(result_table_ihk)
    print("BEK")
    display(result_table_bek)
    
#o_output_compare_ihkbek = widgets.interactive_output(output_compare_ihkbek, controls_fixed | controls_individual)
#o_output_compare_ihkbek.layout.min_height = '700px'
#display(o_output_compare_ihkbek)
In [14]:
def on_button_table_clicked(b):
    # workarouns
    values = {}
    for k,v in controls_individual.items():
        values[k] = v.value
        
    update_dataframe(**values)
    on_button_graphic_clicked(None)

o_update_table_button = widgets.Button(description="Tabelle berechnen")
o_update_table_button.on_click(on_button_table_clicked)

def on_button_graphic_clicked(b):
    for o in tab_nest.children:
        with o:
            o.clear_output()
    on_tab_clicked(None)

o_update_graphic_button = widgets.Button(description="Grafiken berechnen")
o_update_graphic_button.on_click(on_button_graphic_clicked)

buttons = []
buttons.append(widgets.HBox([o_update_table_button, o_update_graphic_button])) # w_normalized, w_table]))

for b in buttons:
    b.layout.min_height = "40px"
display(widgets.VBox(buttons))

output1 = widgets.Output()
output1.layout.min_height = "40px"
display(output1)
def on_tab_clicked(t):
    output2 = tab_nest.children[tab_nest.selected_index]
    with output2:
        output2.clear_output()
        display(HTML('<span style="color:red;">Berechne...</span>'))
        
    values = {}
    for k,v in controls_individual.items() | controls_fixed.items():
        values[k] = v.value

    _func = graphics[tab_nest.selected_index]['def']
    
    with output2:
        _func(output=output2, **values)

graphics = [
    {'title':'Kosten aufgesplittet','def':output_diagram_kosten_gesplittet},
    {'title':'Kosten aufgesplittet #2','def':output_diagram_kosten_gesplittet_plotly},
    {'title':'Kosten gesamt','def':output_diagram_kosten_gesamt},
    {'title':'Kosten gesamt #2','def':output_diagram_kosten_gesamt_plotly},
    {'title':'Kosten gestappelt','def':output_diagram_1},
    {'title':'Download','def':output_table},
    {'title':'Vergleich LCC','def':output_compare_lcc},
    {'title':'Vergleich IHK BEK','def':output_compare_ihkbek},
]
tab_nest = widgets.Tab()
tab_nest.children = [widgets.Output() for _ in graphics]
tab_nest.titles = ([x['title'] for x in graphics])
tab_nest.observe(on_tab_clicked, names='selected_index')
tab_nest.layout.min_height = '700px'

display(tab_nest)
VBox(children=(HBox(children=(Button(description='Tabelle berechnen', style=ButtonStyle()), Button(description…
Output(layout=Layout(min_height='40px'))
Tab(children=(Output(), Output(), Output(), Output(), Output(), Output(), Output(), Output()), layout=Layout(m…
In [20]:
_ = """def p_rev(y):
    m = -2.0258903908369246
    c = 115.26486604656881
    return math.exp((y-c)/m)
# radsatzlast in t
F_r = 25
F_r_kN = F_r * 9.81
_v = 160
F_s = F_r_kN * 0.4 / 2

F_dyn = F_r_kN * (1 + pow((_v / 300), 2))

F_s_dyn = F_dyn * 0.4 / 2
#print(F_r, F_r_kN, F_dyn, F_s, F_s_dyn, p_rev(F_s_dyn))

F_r = 18
F_r_kN = F_r * 9.81
_v = 300
F_s = F_r_kN * 0.4 / 2

F_dyn = F_r_kN * (1 + pow((_v / 300), 2))

F_s_dyn = F_dyn * 0.4 / 2
#print(F_r, F_r_kN, F_dyn, F_s, F_s_dyn, p_rev(F_s_dyn))

df.reset_index(inplace=True)

result = None
for _mt_a in [3.65, 10.95, 2*10.95]:
    for _F_R in [18, 20, 25]:
        _r = []
        for _v in v:
            _F_0 = _F_R * 9.81 * 0.4 / 2
            _F_dyn = _F_0 * (1 + pow((_v / 300), 2))
    
            
            _df = df.loc[
                (df["B_j [Mt/a]"] <= _mt_a) &
                # rundungsfehlere
                #(df["F_R [t]"] == _F_R) &
                (df["F_0 [kN]"] == _F_0) &
                (df["v [km/h]"] == _v) &
                (df["Zugtyp"] == "Zug auf WaO")
            ].sort_values(by=["B_j [Mt/a]"], ascending=False)
            #print(len(_df), _mt_a, _F_R,_F_0, _v)
            _n_Z = _df.iloc[0]["n_Z [Züge/a]"]
            _achsanzahl = _df.iloc[0]["Achsanzahl"]
            #display(_df.iloc[0])
            #print(_mt_a, _F_R, _v, _df["n_Z [Züge/a]"], _df["Achsanzahl"])
            _calc_L_WaO =  p_rev( _F_dyn ) /  ( _n_Z * _achsanzahl * 365 )
            _r.append('{:,.2f}'.format(_calc_L_WaO).replace(',','_').replace('.',',').replace('_','.'))
        _s = pd.Series(['{:,.2f}'.format(_df.iloc[0]["B_j [Mt/a]"]).replace(',','_').replace('.',',').replace('_','.'), _F_R]+ _r)
        result = pd.concat([result, _s], axis=1)
        
        print(['{:,.2f}'.format(_df.iloc[0]["B_j [Mt/a]"]).replace(',','_').replace('.',',').replace('_','.'), _F_R]+ _r)
display(result.T)
"""
In [ ]: