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 [ ]: