def annotation_for_E(item):
    if item == 1:
        annotation_css(
            "Расчет проводится для случая прямых ребер " "постоянной толщины."
        )
    else:
        annotation_css(
            "Расчет проводится для случая круглых поперечных ребер "
            "постоянной толщины."
        )
def summary_table(fleet_name: str, data: Dict[str, Tuple]) -> NoReturn:
    """
    Возвращает фейковую сводку по ключевым показателям
    эксплуатации единиц техники
    """
    annotation_css(
        f"Аналитическая сводка ({fleet_name})",
        size=18,
        text_align="center",
        clr="#07689F",
    )

    st.markdown(
        f"*На объекте задействованно **{len(data.keys())}** единиц(ы) техники*"
    )

    catogories_downtime = [
        "Погодный",
        "Регламентный",
        "Логистический",
        "Технологический",
        "Почвенный",
    ]
    moda_cat_downtime = np.random.choice(catogories_downtime)
    prcnt_cat_downtime = 100 * np.random.rand()
    threshold_downtime_left = 43.27
    threshold_downtime_right = 81.63
    st.markdown(
        f"*Наиболее частый тип простоя: **{moda_cat_downtime}** "
        "(составляет **{:.2f}%)** *".format(
            prcnt_cat_downtime if threshold_downtime_left < prcnt_cat_downtime
            < threshold_downtime_right else (
                threshold_downtime_left if prcnt_cat_downtime <
                threshold_downtime_left else threshold_downtime_right)))

    num_precedent = np.random.randint(13, 58)
    st.markdown("*Зарегистрировано в общей сложности "
                f"**{num_precedent}** прецедент(а/ов) простоя техники*")

    num_equipment_maintenance = np.random.randint(1, 3)
    economic_costs_total = 25000 * np.random.randn() + 100000
    st.markdown(
        f"*На основании истории ремонтов ожидается, что "
        f"**{num_equipment_maintenance}** единиц(а/ы) потребуют внепланового "
        f"технического обслуживания на среднюю сумму **{economic_costs_total:.3f}, руб.** *"
    )

    summary_df = DataFrame.from_dict(
        {
            row: (
                150 * np.random.randn() + 500,
                100 * np.random.ranf(),
                100 * np.random.ranf(),
                np.random.randint(350, 2500),
                15000 * np.random.randn() + 100000,
            )
            for row in data.keys()
        },
        orient="index",
        columns=[
            "Суммарное время простоя от начала эксплуатации, час",
            "Процент вовлеченности единицы техники на объекте",
            "Процент загруженности единицы техники на объекте",
            "Время до внепланового ТО (рекомендация), час",
            "Приведенные экономические потери, руб.*",
        ],
    )
    st.table(summary_df)

    equipment_names = data.keys()
    equipment_irrational = np.random.choice(list(equipment_names),
                                            size=np.random.randint(1, 3),
                                            replace=False)

    frame_for_html_list = "<ul>{}</ul>"
    html_list = frame_for_html_list.format("".join(
        [f"<li>{elem}</li>" for elem in equipment_irrational]))

    annotation_css(
        text="<i>Эксплуатация следующих объектов нецелесообрзна "
        f"по показателю <b>приведенной стоимости владения</b>: "
        f"{html_list}",
        clr="#C5304A",
    )
    st.markdown(
        "_Рекомендуется рассмотреть сценарий лизинга. "
        "Например, [СберЛизинг](https://www.sberleasing.ru/leasing/otraslevye-resheniya/)_"
    )
def main_elements():
    """
    Создает шапку страницы
    """
    # === Верхняя часть шапки ===
    row1_1, row1_2 = st.beta_columns([2, 1])

    with row1_1:
        logo_css("АО XXXXXXXX", align="left", clr="#07689F", size=33)
        # logo_css(
        #     "<i>Департамент по восстановлению и утилизации<br>трубной продукции</i>",
        #     align="left",
        #     clr="#52616B",
        #     size=20,
        # )

    with row1_2:
        pass

    header_css(
        f"<i>{title_app}</i>",
        align="left",
        clr="#07689F",
        size=26,
    )

    row1, row2 = st.beta_columns([2, 1])
    with row1:
        pass

    with row2:
        pass

    # === Нижняя часть шапки ===
    row2_1, row2_2 = st.beta_columns([3, 1])

    with row2_1:
        uploaded_file = st.file_uploader(
            "Загрузить данные...",
            type=["xls", "xlsx", "csv", "tsv"],
            accept_multiple_files=False,
        )
        if uploaded_file is not None:
            st.info(
                "В демонстрационной версии приложения оперировать "
                "можно только тестовым набором данных, который генерируется "
                "при первой загрузке страницы или её последующих обновлениях")

    row3_1, row3_2 = st.beta_columns([1, 3])

    with row3_1:
        pass
    with row3_2:
        annotation_css(
            "ВАЖНО: в демонстрационной версии приложении используется "
            "автоматически генерируемый набор данных, обновляемый при "
            "взаимодействии с любым динамическим виджетом приложения",
            clr="#769FCD",
        )

    equipment_list = [
        ("УРБ-2А2", "УРБ-4Т", "ПБУ-74", "УШ-2Т4В", "HD2500RC"),
        ("МБШ-303", "УБН-Т", "МБШ-812", "МБШ-509", "БКМ-307", "БКМ-303"),
        ("СБУ-115", "СБУ-125", "БМ-302", "УРБ-4Т", "БКМ-307"),
    ]

    full_data_for_plot: List[Dict[str, Dict[str, Tuple]]] = []
    for idx, fleet_name in enumerate(
        ["Серпуховской ПТСН", "Челябинский ПТСН", "Екатеринбургский ПТСН"]):
        dict_fleet: Dict[str,
                         Dict[str,
                              Tuple]] = prepare_duration_downtime_for_plot(
                                  fleet_name, equipment_list[idx])
        full_data_for_plot.append(dict_fleet)

    fleet_names_for_selectbox = [
        list(fleet.keys())[0] for fleet in full_data_for_plot
    ]
    selected_fleet_equipment = st.selectbox("Выберите парк спец. техники",
                                            fleet_names_for_selectbox)

    selected_data_for_plot: Dict[str, Tuple] = [
        fleet[selected_fleet_equipment] for fleet in full_data_for_plot
        if selected_fleet_equipment in fleet.keys()
    ][0]

    # отображение
    summary_table(selected_fleet_equipment, selected_data_for_plot)

    annotation_css("Детали сводки",
                   size=18,
                   text_align="center",
                   clr="#07689F")
    duration_downtime_plot(selected_fleet_equipment, selected_data_for_plot)
    duration_downtime_boxplot(selected_fleet_equipment, selected_data_for_plot)
    duration_downtime_econ_costs_scatter_plot(selected_fleet_equipment,
                                              selected_data_for_plot)
def Ki_latex(
    K_isp: float, w: float, E: float, Fp: float, Fc: float, d: float, Fi: float
):
    st.latex(
        r"K_i = 4.606 \cdot \dfrac{w^{0.6}(E \cdot F_p"
        r"+ F_c)}{d\,{}^{0.4} \cdot F_i}=" + f"{K_isp:10.3f}"
    )
    annotation_css("Скорость ветра, [м/c]")
    st.latex(f"w = {w:.2f}")
    annotation_css("Коэффициент эффективности оребрения")
    st.latex(f"E = {E:.3f}")
    annotation_css("Площадь поверхности ребер, [м^2]")
    st.latex(r"F_p =" + f"{Fp:.3f}")
    annotation_css(
        "Площадь поверхности неоребренной части конденсатора, [м^2]"
    )
    st.latex(r"F_c =" + f"{Fc:.3f}")
    annotation_css("Наружный диаметр трубы конденсатора, [м]")
    st.latex(r"d =" + f"{d:.3f}")
    annotation_css("Площадь поверхности испарителя, [м^2]")
    st.latex(r"F_i =" + f"{Fi:.3f}")
def compute_heat_transfer_coef():
    """
    Вычисляет коэффициент теплопередачи от грунта
    к СОУ, отнесенный к площади поверхности испарителя
    """
    st.sidebar.header("Входные параметры")
    st.sidebar.subheader("Геометрические параметры")
    Eitems = (
        "Прямые ребра постоянной толщины",
        "Круглые поперечные ребра постоянной толщины",
    )
    Eitem = items_for_E(Eitems)  # вариант формы ребер
    # ------------------------------------------------------------------------
    rib_wall_thickness = st.sidebar.number_input(
        "Толщина стенки ребра, м",
        value=0.0005,
        min_value=0.0001,
        max_value=0.1,
        step=0.0001,
        format="%g",
    )
    dp_rib = st.sidebar.number_input(
        "Наружный диаметр круглого ребера, м",
        value=0.070,
        min_value=0.050,
        max_value=2.0,
        step=0.001,
        format="%f",
    )
    d_rib = st.sidebar.number_input(
        "Наружный диаметр трубы конденсатора, м",
        value=0.038,
        min_value=0.010,
        max_value=0.080,
        step=0.001,
        format="%f",
    )
    L_isp = st.sidebar.number_input(
        "Длина испарительной части, м",
        value=16.2,
        min_value=0.0,
        max_value=30.0,
        step=0.001,
        format="%f",
    )
    L_cond = st.sidebar.number_input(
        "Длина конденсаторной части, м",
        value=1.8,
        min_value=0.5,
        max_value=10.0,
        step=0.001,
        format="%f",
    )
    L_spiral = st.sidebar.number_input(
        "Длина оребренной части, м",
        value=1.44,
        min_value=0.200,
        max_value=5.0,
        step=0.001,
        format="%f",
    )
    step_spiral = st.sidebar.number_input(
        "Расстояние между ребрами, м",
        value=0.003,
        min_value=0.0005,
        max_value=5.0,
        step=0.001,
        format="%f",
    )
    st.sidebar.subheader("Прочие параметры")
    lambda_rib = st.sidebar.number_input(
        "Теплопроводность матер-ла оребрения, Вт/(м К)",
        value=210.0,
        min_value=8.0,
        max_value=1000.0,
        step=0.01,
        format="%f",
    )
    wind_speed = st.sidebar.selectbox("Скорость ветра, м/c", (1, 3))

    # Коэффициент теплоотдачи от гладкостенной трубы конденсатора
    # к окружающему воздуху, Вт/(м^2 K)
    alpha0 = 4.606 * wind_speed ** 0.6 / d_rib ** 0.4
    # Площаль поверхности неоребренной части конденсатора
    F_nonrib = math.pi * d_rib * L_cond
    # Площадь поверхности ребер
    F_rib = (
        2
        * (math.pi * dp_rib ** 2 / 4 - math.pi * d_rib ** 2 / 4)
        * L_spiral
        / step_spiral
    )
    # Площадь поверхности испарительной части
    F_isp = math.pi * d_rib * L_isp
    # Площадь наружной (оребрной) поверхности конденсатора
    Fpc = F_rib + F_nonrib
    # Высота ребер
    rib_hight = (dp_rib - d_rib) / 2
    # Коэффициент эффективности оребрения
    E = E_compute(
        Eitem, rib_hight, alpha0, lambda_rib, rib_wall_thickness, dp_rib, d_rib
    )
    # Приведнный коэффициент теплоотдачи от стенки конденсатора
    # к окружающему воздуху
    alpha_pr = alpha0 / Fpc * (E * F_rib + F_nonrib)
    # Коэффициент теплопередачи от грунта к СОУ, отнесенный
    # к площади поверхности испарителя
    K_isp = alpha_pr * Fpc / F_isp

    if st.button("Расчитать..."):
        annotation_normal_css("Сводка")
        annotation_for_E(Eitem)
        annotation_css(
            "Коэффициент теплопередачи от грунта к СОУ, [Вт/(м^2 К)]", size=15
        )
        if (K_isp > 14.5 and wind_speed == 1) or (
            K_isp > 21 and wind_speed == 3
        ):
            Ki_latex(K_isp, wind_speed, E, F_rib, F_nonrib, d_rib, F_isp)
        else:
            Ki_latex(K_isp, wind_speed, E, F_rib, F_nonrib, d_rib, F_isp)
            st.error(
                "Согласно п. 1.2.3 ТУ Коэффициент теплоотдачи от грунта "
                "к СОУ при скорости ветра 1 м/с должен быть "
                "не менее 14,5 Вт/(м^2 К)"
            )