text:
import numpy as np

from application import application as app
from graphs import bar_chart_months, pie_chart, pie_chart_last_month
from settings import MONTH_ORDER
from settings import calc_categories, calc_accounts, calc_years, get_options, calc_type
from utils.support_functions import get_database

from dash.dependencies import Input, Output, State
from dash import dcc
from dash import html
from directories_pointer import directories
from colors import calculate_color
from apps import menu_page, dashboard
from utils.support_functions import shutdown_server
from investments_parser.parser import main as parser_investments
from statement_parser.parser import main as parser_cash_accounts

directory = directories()
CATEGORIES, CATEGORIES_DEPOSIT, CATEGORIES_WITHDRAWAL = calc_categories(directory)
ACCOUNT_TYPE, ACCOUNTS_CURRENCY = calc_accounts(directory)
YEARS_TO_PROCESS = calc_years(directory)
COLOR = calculate_color(ACCOUNTS_CURRENCY)
years_options, currencies_options, inv_accounts_options, cash_accounts_options, bond_accounts_options, rs_accounts_options, retirement_accounts_options = get_options(YEARS_TO_PROCESS, ACCOUNT_TYPE)

# update graphs dynamically:

@app.callback(Output(component_id='app-3-status', component_property='figure'),
              [Input(component_id='app-3-year', component_property='value'),
               Input(component_id='app-3-accounts', component_property='values'),
               Input(component_id='app-3-my-budget', component_property='value'),
               Input(component_id='app-3-my-budget-line', component_property='on'),
               Input(component_id='app-3-my-historical-average', component_property='on'),
               Input(component_id='app-3-my-total', component_property='on'),
               Input(component_id='app-3-currency', component_property='value'),
               Input(component_id='app-3-show-category', component_property='value'),
               Input(component_id='DATABASE', component_property='children')]
              )
def app_3_graph_update(year, accounts, budget, show_budget_line, show_3_year_average, show_total, currency, category,
                       data):
    if category == "income":
        return app_3_update_graph_income(year, accounts, show_3_year_average, show_total, currency, data)
    if category == "expenses":
        return app_3_update_graph_expenses(year, accounts, budget, show_budget_line, show_3_year_average, show_total,
                                           currency, data)
    if category == "spent":
        return app_3_update_graph_spent(year, accounts, currency, data)
    if category == "balance":
        return app_3_update_graph_balance(year, accounts, currency, data)

# update graphs dynamically:
@app.callback(Output(component_id='app-3-total-last-month', component_property='figure'),
              [Input(component_id='app-3-year', component_property='value'),
               Input(component_id='app-3-accounts', component_property='values'),
               Input(component_id='app-3-currency', component_property='value'),
               Input(component_id='app-3-show-category', component_property='value'),
               Input(component_id='DATABASE', component_property='children')]
              )
def app_3_graph_pie_update(year, accounts, currency, category, data):
    if category == "income":
        return app_3_update_income_pie(year, accounts, currency, data)
    if category == "expenses":
        return app_3_update_expenses_pie(year, accounts, currency, data)
    if category == "spent":
        return app_3_update_spent_pie(year, accounts, currency, data)
    if category == "balance":
        return app_3_update_balance_pie(year, accounts, currency, data)

def app_3_update_graph_expenses(year, accounts, budget, show_budget_line, show_3_year_average, show_total, currency,
                                data):
    data_processed = get_database("data_processed_with_investment", data[0]).pivot_table(
        index=["YEAR", "MONTH", "ACCOUNT"], columns="CAT",
        aggfunc=np.sum)
    data_frame = data_processed["DEBIT_" + currency]
    data_frame = data_frame.loc[int(year), :, accounts]
    data = data_frame.copy().pivot_table(index=['MONTH'], aggfunc=np.sum)
    analysis_fields_expenses = [x for x in CATEGORIES_WITHDRAWAL if x in data_frame.columns]

    if show_3_year_average:
        historical_data = data_processed.copy()["DEBIT_" + currency]
        check_num_years = historical_data.loc(axis=0)[:, :, accounts]
        m_years = len(set(check_num_years.index.get_level_values(0)))
        historical_data = historical_data.pivot_table(index=['MONTH'], aggfunc=np.sum)
        total = historical_data[analysis_fields_expenses].sum(axis=1) / m_years
    else:
        total = None
    graph = bar_chart_months(data, analysis_fields_expenses, budget=budget, show_budget_line=show_budget_line,
                             show_3_year_average=show_3_year_average,
                             historical_data=total, show_total=show_total)

    return graph

def app_3_update_graph_income(year, accounts, show_3_year_average, show_total, currency, data):
    data_processed = get_database("data_processed_with_investment", data[0]).pivot_table(
        index=["YEAR", "MONTH", "ACCOUNT"], columns="CAT",
        aggfunc=np.sum)
    data_frame = data_processed.copy()["CREDIT_" + currency]
    data_frame = data_frame.loc[int(year), :, accounts]
    data = data_frame.copy().pivot_table(index=['MONTH'], aggfunc=np.sum)
    analysis_fields_income = [x for x in CATEGORIES_DEPOSIT if x in data_frame.columns]

    if show_3_year_average:
        historical_data = data_processed.copy()["CREDIT_" + currency]
        check_num_years = historical_data.loc(axis=0)[:, :, accounts]
        m_years = len(set(check_num_years.index.get_level_values(0)))
        historical_data = historical_data.pivot_table(index=['MONTH'], aggfunc=np.sum)
        total = historical_data[analysis_fields_income].sum(axis=1) / m_years
    else:
        total = None
    graph = bar_chart_months(data, analysis_fields_income, show_3_year_average=show_3_year_average,
                             historical_data=total, show_total=show_total)

    return graph

def app_3_update_graph_spent(year, accounts, currency, data):
    data_processed = get_database("data_processed_with_investment", data[0]).pivot_table(
        index=["YEAR", "MONTH", "ACCOUNT"], columns="CAT",
        aggfunc=np.sum)
    # expenses
    data_frame = data_processed.copy()["DEBIT_" + currency]
    data_frame = data_frame.loc[int(year), :, accounts]
    historical_data_expenses = data_frame.pivot_table(index=['MONTH'], aggfunc=np.sum)
    analysis_fields_expenses = [x for x in CATEGORIES_WITHDRAWAL if x in data_frame.columns]
    historical_data_expenses["Expenses"] = historical_data_expenses[analysis_fields_expenses].sum(axis=1)

    # income
    data_frame = data_processed.copy()["CREDIT_" + currency]
    data_frame = data_frame.loc[int(year), :, accounts]
    historical_data_deposits = data_frame.pivot_table(index=['MONTH'], aggfunc=np.sum)
    analysis_fields_income = [x for x in CATEGORIES_DEPOSIT if x in data_frame.columns]
    historical_data_deposits["Income"] = historical_data_deposits[analysis_fields_income].sum(axis=1)

    # in percentage
    data = historical_data_expenses.join(historical_data_deposits, lsuffix='_x', rsuffix='_y')
    data["Percentage of Income Spent"] = ((data["Expenses"] / data["Income"]) * 100).round(2)
    data["Percentage of Income Saved"] = 100 - data["Percentage of Income Spent"]
    analysis_fields = ["Percentage of Income Spent", "Percentage of Income Saved"]
    graph = bar_chart_months(data, analysis_fields)

    return graph

def app_3_update_graph_balance(year, accounts, currency, data):
    data_processed = get_database("data_procesed_end_month_balance", data[0])
    data_frame = data_processed.pivot_table(index=["YEAR", "MONTH"], columns="ACCOUNT",
                                            values="BALANCE_" + currency, aggfunc=np.mean)
    data_frame = data_frame.fillna(0.0)
    data_frame = data_frame.loc[int(year), :]
    data = data_frame.copy().pivot_table(index=['MONTH'], aggfunc=np.mean)
    analysis_fields = accounts

    graph = bar_chart_months(data, analysis_fields)

    return graph

def app_3_update_spent_pie(year, accounts, currency, data):
    data_processed = get_database("data_processed_with_investment", data[0]).pivot_table(
        index=["YEAR", "MONTH", "ACCOUNT"], columns="CAT",
        aggfunc=np.sum)
    # expenses
    data_frame = data_processed["DEBIT_" + currency]
    data_frame = data_frame.loc[int(year), :, accounts]
    data_frame = data_frame.pivot_table(index=['MONTH'], aggfunc=np.sum)
    data_expenses = data_frame.sum(axis=0)
    analysis_fields_expenses = [x for x in CATEGORIES_WITHDRAWAL if x in data_frame.columns]
    data_expenses['Expenses'] = data_expenses[analysis_fields_expenses].sum()

    # income
    data_frame2 = data_processed["CREDIT_" + currency]
    data_frame2 = data_frame2.loc[int(year), :, accounts]
    data_frame2 = data_frame2.pivot_table(index=['MONTH'], aggfunc=np.sum)
    data_income = data_frame2.sum(axis=0)
    analysis_fields_income = [x for x in CATEGORIES_DEPOSIT if x in data_frame2.columns]
    data_income['Income'] = data_income[analysis_fields_income].sum()

    # get dataframe
    data = data_expenses.append(data_income)
    data["Percentage of Income Spent"] = data["Expenses"].round(2)
    data["Percentage of Income Saved"] = (data["Income"] - data["Expenses"]).round(2)
    analysis_fields = ["Percentage of Income Saved", "Percentage of Income Spent"]
    graph = pie_chart(data, analysis_fields, currency, percentage_flag=True, show_legend=False)

    return graph

def app_3_update_expenses_pie(year, accounts, currency, data):
    data_processed = get_database("data_processed_with_investment", data[0]).pivot_table(
        index=["YEAR", "MONTH", "ACCOUNT"], columns="CAT",
        aggfunc=np.sum)
    data_frame = data_processed["DEBIT_" + currency]
    data_frame = data_frame.loc[int(year), :, accounts]
    data_frame = data_frame.pivot_table(index=['MONTH'], aggfunc=np.sum)
    data = data_frame.sum(axis=0)
    analysis_fields_expenses = [x for x in CATEGORIES_WITHDRAWAL if x in data_frame.columns]
    graph = pie_chart(data, analysis_fields_expenses, currency, show_legend=False)

    return graph

def app_3_update_income_pie(year, accounts, currency, data):
    data_processed = get_database("data_processed_with_investment", data[0]).pivot_table(
        index=["YEAR", "MONTH", "ACCOUNT"], columns="CAT",
        aggfunc=np.sum)
    data_frame = data_processed["CREDIT_" + currency]
    data_frame = data_frame.loc[int(year), :, accounts]
    data_frame = data_frame.pivot_table(index=['MONTH'], aggfunc=np.sum)
    data = data_frame.sum(axis=0)
    analysis_fields_income = [x for x in CATEGORIES_DEPOSIT if x in data_frame.columns]
    graph = pie_chart(data, analysis_fields_income, currency, show_legend=False)

    return graph

def app_3_update_balance_pie(year, accounts, currency, data):
    data_processed = get_database("data_procesed_end_month_balance", data[0])
    data_frame = data_processed.pivot_table(index=["YEAR", "MONTH"], columns="ACCOUNT",
                                            values="BALANCE_" + currency, aggfunc=np.mean)
    data_frame = data_frame.fillna(0.0)
    data_frame = data_frame.loc[int(year), :]
    data = data_frame.copy().pivot_table(index=['MONTH'], aggfunc=np.mean)
    analysis_fields = accounts
    # find the last month in the data displayed
    for month in reversed(MONTH_ORDER):
        if month in data.index:
            last_month = month
            break

    graph = pie_chart_last_month(data, analysis_fields, currency, last_month)

    return graph

# update graphs dynamically:
@app.callback(Output('app-6-accounts', 'options'),
                [Input(component_id='app-6-year', component_property='value'),
                 Input(component_id='DATABASE', component_property='children')
                 ])
def update_options(selected_year, data):
    data_processed = get_database("data_processed_with_investment", data[0])
    existing_accounts = []
    for x in inv_accounts_options:
        account = list(x.values())[1]
        get_data_account = data_processed.loc[data_processed["ACCOUNT"] == account]
        if int(selected_year) in get_data_account["YEAR"].values:
            existing_accounts.append({"label":account, "value":account})
    return existing_accounts

@app.callback(Output('app-6-accounts', 'value'),
                [Input('app-6-accounts', 'options')])
def update_values(options):
    return list(options[0].values())[1]

@app.callback(Output(component_id='app-6-investment', component_property='figure'),
              [Input(component_id='app-6-year', component_property='value'),
               Input(component_id='app-6-accounts', component_property='value'),
               Input(component_id='app-6-currency', component_property='value'),
               Input(component_id='DATABASE', component_property='children')]
              )
def update_graph_barchart(year, account, currency, data):
    data_processed = get_database("data_processed_with_investment", data[0])
    # classify per account
    get_initial_investment = data_processed.loc[data_processed["ACCOUNT"] == account]
    get_initial_investment = get_initial_investment.loc[get_initial_investment["CAT"] == "Initial Investment"]
    get_initial_investment = get_initial_investment.sum(axis=0)
    get_initial_investment = get_initial_investment["CREDIT_" + currency]

    # get balance end of the month
    data_processed2 = get_database("data_procesed_end_month_balance", data[0])
    data_frame = data_processed2.pivot_table(index=["YEAR", "MONTH"], columns="ACCOUNT",
                                             values="BALANCE_" + currency, aggfunc=np.mean)
    data_frame = data_frame.fillna(0.0)
    data_frame = data_frame.loc[int(year), :]
    data = data_frame.copy().pivot_table(index=['MONTH'], aggfunc=np.mean)
    analysis_fields = [account]

    graph = bar_chart_months(data, analysis_fields, investment=get_initial_investment)

    return graph

@app.callback(Output(component_id='app-6-real', component_property='figure'),
              [Input(component_id='app-6-year', component_property='value'),
               Input(component_id='app-6-accounts', component_property='value'),
               Input(component_id='app-6-currency', component_property='value'),
               Input(component_id='DATABASE', component_property='children')]
              )
def update_graph_pie(year, account, currency, data):
    data_processed = get_database("data_processed_with_investment", data[0])
    get_initial_investment = data_processed.loc[data_processed["ACCOUNT"] == account]
    get_initial_investment = get_initial_investment.loc[get_initial_investment["CAT"] == "Initial Investment"]

    get_initial_investment_year = get_initial_investment["YEAR"].values
    get_initial_investment_month = get_initial_investment["MONTH"].values

    if get_initial_investment.shape[0] > 1:  # there two values
        get_initial_investment = get_initial_investment["CREDIT_" + currency].sum()
        get_initial_investment_year = get_initial_investment_year[0]
        get_initial_investment_month = get_initial_investment_month[0]
    else:
        get_initial_investment = get_initial_investment["CREDIT_" + currency].values[0]
        get_initial_investment_year = get_initial_investment_year[0]
        get_initial_investment_month = get_initial_investment_month[0]

    data_processed2 = get_database("data_procesed_end_month_balance", data[0])
    data_frame = data_processed2.pivot_table(index=["YEAR", "MONTH"], columns="ACCOUNT",
                                             values="BALANCE_" + currency, aggfunc=np.mean)
    data_frame = data_frame.fillna(0.0)
    data_frame = data_frame.loc[int(year), :]
    data = data_frame.copy().pivot_table(index=['MONTH'], aggfunc=np.mean)
    analysis_fields = ["Initial investment", 'Interests earned to date']

    # disocunt any investment out of the main investment for instance colimbian apartment ot pay other bonds
    data_invetments_out = data_processed.loc[data_processed["ACCOUNT"] == account]
    data_invetments_out = data_invetments_out.loc[data_invetments_out["CAT"] == "Investments"]
    data_invetments_out = data_invetments_out.sum(0)
    data_invetments_out = data_invetments_out["DEBIT_" + currency]

    # calculate total interest earned to date and initial investment
    data['Interests earned to date'] = data[account] - get_initial_investment + data_invetments_out
    data['Investments out'] = data_invetments_out
    data["Initial investment"] = get_initial_investment

    # find the last month in the data displayed
    for month in reversed(MONTH_ORDER):
        if month in data.index:
            last_month = month
            break

    graph = pie_chart_last_month(data, analysis_fields, currency, last_month, show_legend=True, show_interest=True,
                                 get_initial_investment_year=get_initial_investment_year,
                                 get_initial_investment_month=get_initial_investment_month,
                                 year=int(year))

    return graph

@app.callback(Output(component_id='menu_page', component_property='children'),
              [Input(component_id='button_dashboard', component_property='n_clicks')],
              [State(component_id='button_investment', component_property='n_clicks_timestamp'),
               State(component_id='button_accounts', component_property='n_clicks_timestamp'),
               State(component_id='exit_button', component_property='n_clicks_timestamp')]
              )
def change_page_login(clicks_button3, clicks_button1, clicks_button2, clicks_button4):
    if clicks_button3 is not None and (int(clicks_button1) and int(clicks_button2) and int(clicks_button4)) == 0:
        clicks_button3 = None
        return dashboard.layout
    else:
        return [menu_page,
                html.Div(id="status_bar_menu"),
                html.Div(id="status_bar_menu_button_parser_investments"),
                html.Div(id="status_bar_menu_button_parser_cash")]

@app.callback(Output(component_id='status_bar_menu', component_property='children'),
              [Input(component_id='exit_button', component_property='n_clicks')],
              [State(component_id='button_investment', component_property='n_clicks_timestamp'),
               State(component_id='button_accounts', component_property='n_clicks_timestamp'),
               State(component_id='button_dashboard', component_property='n_clicks_timestamp')]
              )
def turn_off(clicks_button3, clicks_button1, clicks_button2, clicks_button4):
    if clicks_button3 is not None and (int(clicks_button1) and int(clicks_button2) and int(clicks_button4)) == 0:
        shutdown_server()
        return html.H4("Good Bye!, you can close the browser now", style={'text-align': 'center'})
    else:
        return None

@app.callback(Output(component_id='status_bar_menu_button_parser_investments', component_property='children'),
              [Input(component_id='button_investment', component_property='n_clicks')],
              [State(component_id='exit_button', component_property='n_clicks_timestamp'),
               State(component_id='button_accounts', component_property='n_clicks_timestamp'),
               State(component_id='button_dashboard', component_property='n_clicks_timestamp')]
              )
def turn_off(clicks_button3, clicks_button1, clicks_button2, clicks_button4):
    if clicks_button3 is not None and (int(clicks_button1) and int(clicks_button2) and int(clicks_button4)) == 0:
        parser_investments()
        return html.H4("Investment data was successfully parsed", style={'text-align': 'center'})
    else:
        return None

@app.callback(Output(component_id='status_bar_menu_button_parser_cash', component_property='children'),
              [Input(component_id='button_accounts', component_property='n_clicks')],
              [State(component_id='exit_button', component_property='n_clicks_timestamp'),
               State(component_id='button_investment', component_property='n_clicks_timestamp'),
               State(component_id='button_dashboard', component_property='n_clicks_timestamp')]
              )
def turn_off(clicks_button3, clicks_button1, clicks_button2, clicks_button4):
    if clicks_button3 is not None and (int(clicks_button1) and int(clicks_button2) and int(clicks_button4)) == 0:
        parser_cash_accounts()
        return html.H4("Bank account data was successfully parsed", style={'text-align': 'center'})
    else:
        return None

# update graphs dynamically:

@app.callback(Output(component_id='app-4-accumulated-value', component_property='figure'),
              [Input(component_id='app-4-year', component_property='value'),
               Input(component_id='app-4-accounts', component_property='values'),
               Input(component_id='app-4-bonds', component_property='values'),
               Input(component_id='app-4-rfunds', component_property='values'),
               Input(component_id='app-4-cash', component_property='values'),
               Input(component_id='app-4-currency', component_property='value'),
               Input(component_id='app-4-category-boolean', component_property='value'),
               Input(component_id='DATABASE', component_property='children')]
              )
def update_graph_monthly_values(year, accounts, bonds, rfunds, cash, currency, category, data):
    data_processed= get_database("data_procesed_end_month_balance", data[0])
    if category == "True":
        data_processed_2 = data_processed.loc[data_processed["ACCOUNT"].isin(accounts + bonds + rfunds + cash)]
        data_processed_2.loc[:, "TYPE"] = data_processed_2["ACCOUNT"].apply(lambda x: calc_type(x, ACCOUNT_TYPE))
        data_frame = data_processed_2.pivot_table(index=["YEAR", "MONTH", "ACCOUNT"], columns="TYPE",
                                                  values="BALANCE_" + currency, aggfunc=np.mean)
        data_frame = data_frame.fillna(0.0)
        data_frame = data_frame.loc[int(year), :, :]
        data = data_frame.copy().pivot_table(index=['MONTH'], aggfunc=np.sum)
        analysis_fields = ACCOUNT_TYPE.keys()

        graph = bar_chart_months(data, analysis_fields)

    else:
        data_frame = data_processed.pivot_table(index=["YEAR", "MONTH"], columns="ACCOUNT",
                                                values="BALANCE_" + currency, aggfunc=np.mean)
        data_frame = data_frame.fillna(0.0)
        data_frame = data_frame.loc[int(year), :]
        data = data_frame.copy().pivot_table(index=['MONTH'], aggfunc=np.mean)
        analysis_fields = accounts + bonds + rfunds + cash

        graph = bar_chart_months(data, analysis_fields)

    return graph

@app.callback(Output(component_id='app-4-total-last-month', component_property='figure'),
              [Input(component_id='app-4-year', component_property='value'),
               Input(component_id='app-4-accounts', component_property='values'),
               Input(component_id='app-4-bonds', component_property='values'),
               Input(component_id='app-4-rfunds', component_property='values'),
               Input(component_id='app-4-cash', component_property='values'),
               Input(component_id='app-4-currency', component_property='value'),
               Input(component_id='app-4-category-boolean', component_property='value'),
               Input(component_id='DATABASE', component_property='children')]
              )
def update_graph_income_pie(year, accounts, bonds, rfunds, cash, currency, category, data):
    data_processed = get_database("data_procesed_end_month_balance", data[0])
    if category == "True":
        data_processed_2 = data_processed.loc[data_processed["ACCOUNT"].isin(accounts + bonds + rfunds + cash)]
        data_processed_2.loc[:, "TYPE"] = data_processed_2["ACCOUNT"].apply(lambda x: calc_type(x, ACCOUNT_TYPE))
        data_frame = data_processed_2.pivot_table(index=["YEAR", "MONTH", "ACCOUNT"], columns="TYPE",
                                                  values="BALANCE_" + currency, aggfunc=np.mean)
        data_frame = data_frame.fillna(0.0)
        data_frame = data_frame.loc[int(year), :, :]
        data = data_frame.copy().pivot_table(index=['MONTH'], aggfunc=np.sum)
        analysis_fields = ACCOUNT_TYPE.keys()

        # find the last month in the data displayed
        for month in reversed(MONTH_ORDER):
            if month in data.index:
                last_month = month
                break

        graph = pie_chart_last_month(data, analysis_fields, currency, last_month)

    else:
        data_frame = data_processed.pivot_table(index=["YEAR", "MONTH"], columns="ACCOUNT",
                                                values="BALANCE_" + currency, aggfunc=np.mean)
        data_frame = data_frame.fillna(0.0)
        data_frame = data_frame.loc[int(year), :]
        data = data_frame.copy().pivot_table(index=['MONTH'], aggfunc=np.mean)
        analysis_fields = accounts + bonds + rfunds + cash

        # find the last month in the data displayed
        for month in reversed(MONTH_ORDER):
            if month in data.index:
                last_month = month
                break

        graph = pie_chart_last_month(data, analysis_fields, currency, last_month)

    return graph

@app.callback(Output(component_id='app-1-placer_menu', component_property='children'),
              [Input(component_id='app-1-show-category', component_property='value')]
              )
def menu(category):
    if category == "True":
        return [dcc.Dropdown(id='app-1-year', options=years_options,
                             value=YEARS_TO_PROCESS[-1], placeholder='Please select a year')]
    else:
        return [dcc.Dropdown(id='app-1-year', options=years_options,
                             value=YEARS_TO_PROCESS, multi=True, placeholder='Please select a year')]

@app.callback(Output(component_id='app-1-net-worth', component_property='figure'),
              [Input(component_id='app-1-year', component_property='value'),
               Input(component_id='app-1-currency', component_property='value'),
               Input(component_id='app-1-show-category', component_property='value'),
               Input(component_id='DATABASE', component_property='children')]
              )
def update_net_worth(year, currency, category, data):
    data_procesed_end_month_balance = get_database("data_procesed_end_month_balance", data[0])
    if category== "True":
        data_processed_2 = data_procesed_end_month_balance.copy()
        data_processed_2["TYPE"] = data_processed_2["ACCOUNT"].apply(lambda x: calc_type(x, ACCOUNT_TYPE))
        data_frame = data_processed_2.pivot_table(index=["YEAR", "MONTH", "ACCOUNT"], columns="TYPE",
                                                  values="BALANCE_" + currency, aggfunc=np.mean)
        data_frame = data_frame.fillna(0.0)
        data_frame = data_frame.loc[int(year), :, :]
        data = data_frame.copy().pivot_table(index=['MONTH'], aggfunc=np.sum)
        analysis_fields = ACCOUNT_TYPE.keys()

        # find the last month in the data displayed
        for month in reversed(MONTH_ORDER):
            if month in data.index:
                last_month = month
                break

        graph = pie_chart_last_month(data, analysis_fields, currency, last_month, show_legend=True)
    else:
        years = [int(x) for x in year]
        data_processed_3 = data_procesed_end_month_balance.copy()
        data_processed_3["TYPE"] = data_processed_3["ACCOUNT"].apply(lambda x: calc_type(x, ACCOUNT_TYPE))
        data_frame = data_processed_3.pivot_table(index=["YEAR", "MONTH", "ACCOUNT"], columns="TYPE",
                                                  values="BALANCE_" + currency, aggfunc=np.mean)
        data_frame = data_frame.fillna(0.0)
        data_frame = data_frame.loc[years, "Dec", :]
        data = data_frame.copy().pivot_table(index=['YEAR'], aggfunc=np.sum)

        analysis_fields = ACCOUNT_TYPE.keys()

        graph = bar_chart_months(data, analysis_fields)

    return graph

@app.callback(Output(component_id='app-1-expenses-per-year', component_property='figure'),
              [Input(component_id='app-1-year', component_property='value'),
               Input(component_id='app-1-currency', component_property='value'),
               Input(component_id='app-1-show-category', component_property='value'),
               Input(component_id='DATABASE', component_property='children')]
              )
def update_graph_expenses_pie(year, currency, category, data):
    data_processed_with_investment = get_database("data_processed_with_investment", data[0])
    data_frame = data_processed_with_investment.pivot_table(index=["YEAR", "MONTH", "ACCOUNT"], columns="CAT",
                                                                   aggfunc=np.sum)["DEBIT_" + currency]
    if category == "True":
        data_frame = data_frame.loc[int(year), :, :]
        data_frame = data_frame.pivot_table(index=['MONTH'], aggfunc=np.sum)
        data = data_frame.sum(axis=0)
        analysis_fields_expenses = [x for x in CATEGORIES_WITHDRAWAL if x in data_frame.columns]
        graph = pie_chart(data, analysis_fields_expenses, currency)
    else:
        years = [int(x) for x in year]
        data_frame = data_frame.loc[years, :, :]
        data_frame = data_frame.pivot_table(index=['YEAR'], aggfunc=np.sum)
        analysis_fields_expenses = [x for x in CATEGORIES_WITHDRAWAL if x in data_frame.columns]

        graph = bar_chart_months(data_frame, analysis_fields_expenses, legend_font=8)

    return graph

@app.callback(Output(component_id='app-1-income-per-year', component_property='figure'),
              [Input(component_id='app-1-year', component_property='value'),
               Input(component_id='app-1-currency', component_property='value'),
               Input(component_id='app-1-show-category', component_property='value'),
               Input(component_id='DATABASE', component_property='children')]
              )
def update_graph_income_pie(year, currency, category, data):
    data_processed_with_investment = get_database("data_processed_with_investment", data[0])
    data_frame = data_processed_with_investment.copy().pivot_table(index=["YEAR", "MONTH", "ACCOUNT"], columns="CAT",
                                                                   aggfunc=np.sum)["CREDIT_" + currency]
    if category == "True":
        data_frame = data_frame.loc[int(year), :, :]
        data_frame = data_frame.pivot_table(index=['MONTH'], aggfunc=np.sum)
        data = data_frame.sum(axis=0)
        analysis_fields_income = [x for x in CATEGORIES_DEPOSIT if x in data_frame.columns]
        graph = pie_chart(data, analysis_fields_income, currency)
    else:
        years = [int(x) for x in year]
        data_frame = data_frame.loc[years, :, :]
        data_frame = data_frame.pivot_table(index=['YEAR'], aggfunc=np.sum)
        analysis_fields_expenses = [x for x in CATEGORIES_DEPOSIT if x in data_frame.columns]

        graph = bar_chart_months(data_frame, analysis_fields_expenses)

    return graph

max_stars_repo_name: JIMENOFONSECA/FonnachtsBankApp

max_issues_repo_name: JIMENOFONSECA/FineBank

max_forks_repo_name: JIMENOFONSECA/FineBank


text:
import pandas as pd
import numpy as np
import xarray as xr

from semantique.processor.types import TypePromoter
from semantique.processor.values import ValueRange
from semantique.processor.utils import np_null, np_null_as_zero

#
# BOOLEAN UNIVARIATE OPERATORS
#

def invert_(x, track_types = True, **kwargs):
  """Compute the boolean inverse of x.

  Parameters
  ----------
    x : :obj:`xarray.DataArray`
      Data cube containing the values to apply the operator to.
    track_types : :obj:`bool`
      Should the operator promote the value type of the output object, based
      on the value type of the input object?
    **kwargs:
      Ignored.

  Returns
  -------
    :obj:`xarray.DataArray`
      A data cube with the same shape as ``x`` containing the results of all
      evaluated expressions.

  Note
  -----
    When tracking value types, this operator uses the following type promotion
    manual, with the keys being the supported value types of ``x``, and the
    corresponding value being the promoted value type of the output.

    .. exec_code::
      :hide_code:

      from semantique.processor.types import TYPE_PROMOTION_MANUALS
      obj = TYPE_PROMOTION_MANUALS["invert"]
      obj.pop("__preserve_labels__")
      print(obj)

  """
  if track_types:
    promoter = TypePromoter(x, function = "invert")
    promoter.check()
  f = lambda x: np.where(pd.notnull(x), np.logical_not(x), np.nan)
  out = xr.apply_ufunc(f, x)
  if track_types:
    out = promoter.promote(out)
  return out

#
# NUMERICAL UNIVARIATE OPERATORS
#

def absolute_(x, track_types = True, **kwargs):
  """Compute the absolute value of x.

  Parameters
  ----------
    x : :obj:`xarray.DataArray`
      Data cube containing the values to apply the operator to.
    track_types : :obj:`bool`
      Should the operator promote the value type of the output object, based
      on the value type of the input object?
    **kwargs:
      Ignored.

  Returns
  -------
    :obj:`xarray.DataArray`
      A data cube with the same shape as ``x`` containing the results of all
      evaluated expressions.

  Note
  -----
    When tracking value types, this operator uses the following type promotion
    manual, with the keys being the supported value types of ``x``, and the
    corresponding value being the promoted value type of the output.

    .. exec_code::
      :hide_code:

      from semantique.processor.types import TYPE_PROMOTION_MANUALS
      obj = TYPE_PROMOTION_MANUALS["absolute"]
      obj.pop("__preserve_labels__")
      print(obj)

  """
  if track_types:
    promoter = TypePromoter(x, function = "absolute")
    promoter.check()
  f = lambda x: np.absolute(x)
  out = xr.apply_ufunc(f, x)
  if track_types:
    out = promoter.promote(out)
  return out

def cube_root_(x, track_types = True, **kwargs):
  """Compute the cube root of x.

  Parameters
  ----------
    x : :obj:`xarray.DataArray`
      Data cube containing the values to apply the operator to.
    track_types : :obj:`bool`
      Should the operator promote the value type of the output object, based
      on the value type of the input object?
    **kwargs:
      Ignored.

  Returns
  -------
    :obj:`xarray.DataArray`
      A data cube with the same shape as ``x`` containing the results of all
      evaluated expressions.

  Note
  -----
    When tracking value types, this operator uses the following type promotion
    manual, with the keys being the supported value types of ``x``, and the
    corresponding value being the promoted value type of the output.

    .. exec_code::
      :hide_code:

      from semantique.processor.types import TYPE_PROMOTION_MANUALS
      obj = TYPE_PROMOTION_MANUALS["cube_root"]
      obj.pop("__preserve_labels__")
      print(obj)

  """
  if track_types:
    promoter = TypePromoter(x, function = "cube_root")
    promoter.check()
  f = lambda x: np.cbrt(x)
  out = xr.apply_ufunc(f, x)
  if track_types:
    out = promoter.promote(out)
  return out

def exponential_(x, track_types = True, **kwargs):
  """Compute the exponential function of x.

  The exponential function of x is defined as e to the power x, in which e is
  Eulers number (approximately equal to 2.718). It is the inverse function of
  :func:`natural_logarithm_`.

  Parameters
  ----------
    x : :obj:`xarray.DataArray`
      Data cube containing the values to apply the operator to.
    track_types : :obj:`bool`
      Should the operator promote the value type of the output object, based
      on the value type of the input object?
    **kwargs:
      Ignored.

  Returns
  -------
    :obj:`xarray.DataArray`
      A data cube with the same shape as ``x`` containing the results of all
      evaluated expressions.

  Note
  -----
    When tracking value types, this operator uses the following type promotion
    manual, with the keys being the supported value types of ``x``, and the
    corresponding value being the promoted value type of the output.

    .. exec_code::
      :hide_code:

      from semantique.processor.types import TYPE_PROMOTION_MANUALS
      obj = TYPE_PROMOTION_MANUALS["exponential"]
      obj.pop("__preserve_labels__")
      print(obj)

  """
  if track_types:
    promoter = TypePromoter(x, function = "exponential")
    promoter.check()
  f = lambda x: np.exp(x)
  out = xr.apply_ufunc(f, x)
  if track_types:
    out = promoter.promote(out)
  return out

def natural_logarithm_(x, track_types = True, **kwargs):
  """Compute the natural logarithm of x.

  The natural logarithm of x is the logarithm with base e, in which e is
  Eulers number (approximately equal to 2.718). It is the inverse function of
  :func:`exponential_`.

  Parameters
  ----------
    x : :obj:`xarray.DataArray`
      Data cube containing the values to apply the operator to.
    track_types : :obj:`bool`
      Should the operator promote the value type of the output object, based
      on the value type of the input object?
    **kwargs:
      Ignored.

  Returns
  -------
    :obj:`xarray.DataArray`
      A data cube with the same shape as ``x`` containing the results of all
      evaluated expressions.

  Note
  -----
    When tracking value types, this operator uses the following type promotion
    manual, with the keys being the supported value types of ``x``, and the
    corresponding value being the promoted value type of the output.

    .. exec_code::
      :hide_code:

      from semantique.processor.types import TYPE_PROMOTION_MANUALS
      obj = TYPE_PROMOTION_MANUALS["natural_logarithm"]
      obj.pop("__preserve_labels__")
      print(obj)

  """
  if track_types:
    promoter = TypePromoter(x, function = "natural_logarithm")
    promoter.check()
  f = lambda x: np.where(np.equal(x, 0), np.nan, np.log(x))
  out = xr.apply_ufunc(f, x)
  if track_types:
    out = promoter.promote(out)
  return out

def square_root_(x, track_types = True, **kwargs):
  """Compute the square root of x.

  Parameters
  ----------
    x : :obj:`xarray.DataArray`
      Data cube containing the values to apply the operator to.
    track_types : :obj:`bool`
      Should the operator promote the value type of the output object, based
      on the value type of the input object?
    **kwargs:
      Ignored.

  Returns
  -------
    :obj:`xarray.DataArray`
      A data cube with the same shape as ``x`` containing the results of all
      evaluated expressions.

  Note
  -----
    When tracking value types, this operator uses the following type promotion
    manual, with the keys being the supported value types of ``x``, and the
    corresponding value being the promoted value type of the output.

    .. exec_code::
      :hide_code:

      from semantique.processor.types import TYPE_PROMOTION_MANUALS
      obj = TYPE_PROMOTION_MANUALS["square_root"]
      obj.pop("__preserve_labels__")
      print(obj)

  """
  if track_types:
    promoter = TypePromoter(x, function = "square_root")
    promoter.check()
  f = lambda x: np.sqrt(x)
  out = xr.apply_ufunc(f, x)
  if track_types:
    out = promoter.promote(out)
  return out

#
# ALGEBRAIC OPERATORS
#

def add_(x, y, track_types = True, **kwargs):
  """Add y to x.

  Parameters
  ----------
    x : :obj:`xarray.DataArray`
      Data cube containing the operands at the left-hand side of each
      expression.
    y :
      Operands at the right-hand side of each expression. May be a constant,
      meaning that the same value is used in each expression. May also be
      another data cube which can be aligned to the same shape as cube ``x``.
      In the latter case, when evaluating the expression for a pixel in cube
      ``x`` the second operand is the value of the pixel in cube ``y`` that
      has the same dimension coordinates.
    track_types : :obj:`bool`
      Should the operator promote the value type of the output object, based
      on the value type of the input objects?
    **kwargs:
      Ignored.

  Returns
  -------
    :obj:`xarray.DataArray`
      A data cube with the same shape as ``x`` containing the results of all
      evaluated expressions.

  Note
  -----
    When tracking value types, this operator uses the following type promotion
    manual, with the first layer of keys being the supported value types of
    ``x``, the second layer of keys being the supported value types of ``y``
    given the value type of ``x``, and the corresponding value being the
    promoted value type of the output.

    .. exec_code::
      :hide_code:

      from semantique.processor.types import TYPE_PROMOTION_MANUALS
      obj = TYPE_PROMOTION_MANUALS["add"]
      obj.pop("__preserve_labels__")
      print(obj)

  """
  if track_types:
    promoter = TypePromoter(x, y, function = "add")
    promoter.check()
  f = lambda x, y: np.add(x, y)
  y = xr.DataArray(y).sq.align_with(x)
  out = xr.apply_ufunc(f, x, y)
  if track_types:
    out = promoter.promote(out)
  return out

def divide_(x, y, track_types = True, **kwargs):
  """Divide x by y.

  Parameters
  ----------
    x : :obj:`xarray.DataArray`
      Data cube containing the operands at the left-hand side of each
      expression.
    y :
      Operands at the right-hand side of each expression. May be a constant,
      meaning that the same value is used in each expression. May also be
      another data cube which can be aligned to the same shape as cube ``x``.
      In the latter case, when evaluating the expression for a pixel in cube
      ``x`` the second operand is the value of the pixel in cube ``y`` that
      has the same dimension coordinates.
    track_types : :obj:`bool`
      Should the operator promote the value type of the output object, based
      on the value type of the input objects?
    **kwargs:
      Ignored.

  Returns
  -------
    :obj:`xarray.DataArray`
      A data cube with the same shape as ``x`` containing the results of all
      evaluated expressions.

  Note
  -----
    When tracking value types, this operator uses the following type promotion
    manual, with the first layer of keys being the supported value types of
    ``x``, the second layer of keys being the supported value types of ``y``
    given the value type of ``x``, and the corresponding value being the
    promoted value type of the output.

    .. exec_code::
      :hide_code:

      from semantique.processor.types import TYPE_PROMOTION_MANUALS
      obj = TYPE_PROMOTION_MANUALS["divide"]
      obj.pop("__preserve_labels__")
      print(obj)

  """
  if track_types:
    promoter = TypePromoter(x, y, function = "divide")
    promoter.check()
  f = lambda x, y: np.divide(x, np.where(np.equal(y, 0), np.nan, y))
  y = xr.DataArray(y).sq.align_with(x)
  out = xr.apply_ufunc(f, x, y)
  if track_types:
    out = promoter.promote(out)
  return out

def multiply_(x, y, track_types = True, **kwargs):
  """Multiply x by y.

  Parameters
  ----------
    x : :obj:`xarray.DataArray`
      Data cube containing the operands at the left-hand side of each
      expression.
    y :
      Operands at the right-hand side of each expression. May be a constant,
      meaning that the same value is used in each expression. May also be
      another data cube which can be aligned to the same shape as cube ``x``.
      In the latter case, when evaluating the expression for a pixel in cube
      ``x`` the second operand is the value of the pixel in cube ``y`` that
      has the same dimension coordinates.
    track_types : :obj:`bool`
      Should the operator promote the value type of the output object, based
      on the value type of the input objects?
    **kwargs:
      Ignored.

  Returns
  -------
    :obj:`xarray.DataArray`
      A data cube with the same shape as ``x`` containing the results of all
      evaluated expressions.

  Note
  -----
    When tracking value types, this operator uses the following type promotion
    manual, with the first layer of keys being the supported value types of
    ``x``, the second layer of keys being the supported value types of ``y``
    given the value type of ``x``, and the corresponding value being the
    promoted value type of the output.

    .. exec_code::
      :hide_code:

      from semantique.processor.types import TYPE_PROMOTION_MANUALS
      obj = TYPE_PROMOTION_MANUALS["multiply"]
      obj.pop("__preserve_labels__")
      print(obj)

  """
  if track_types:
    promoter = TypePromoter(x, y, function = "multiply")
    promoter.check()
  f = lambda x, y: np.multiply(x, y)
  y = xr.DataArray(y).sq.align_with(x)
  out = xr.apply_ufunc(f, x, y)
  if track_types:
    out = promoter.promote(out)
  return out

def power_(x, y, track_types = True, **kwargs):
  """Raise x to the yth power.

  Parameters
  ----------
    x : :obj:`xarray.DataArray`
      Data cube containing the operands at the left-hand side of each
      expression.
    y :
      Operands at the right-hand side of each expression. May be a constant,
      meaning that the same value is used in each expression. May also be
      another data cube which can be aligned to the same shape as cube ``x``.
      In the latter case, when evaluating the expression for a pixel in cube
      ``x`` the second operand is the value of the pixel in cube ``y`` that
      has the same dimension coordinates.
    track_types : :obj:`bool`
      Should the operator promote the value type of the output object, based
      on the value type of the input objects?
    **kwargs:
      Ignored.

  Returns
  -------
    :obj:`xarray.DataArray`
      A data cube with the same shape as ``x`` containing the results of all
      evaluated expressions.

  Note
  -----
    When tracking value types, this operator uses the following type promotion
    manual, with the first layer of keys being the supported value types of
    ``x``, the second layer of keys being the supported value types of ``y``
    given the value type of ``x``, and the corresponding value being the
    promoted value type of the output.

    .. exec_code::
      :hide_code:

      from semantique.processor.types import TYPE_PROMOTION_MANUALS
      obj = TYPE_PROMOTION_MANUALS["power"]
      obj.pop("__preserve_labels__")
      print(obj)

  """
  if track_types:
    promoter = TypePromoter(x, y, function = "power")
    promoter.check()
  f = lambda x, y: np.power(x, y)
  y = xr.DataArray(y).sq.align_with(x)
  out = xr.apply_ufunc(f, x, y)
  if track_types:
    out = promoter.promote(out)
  return out

def subtract_(x, y, track_types = True, **kwargs):
  """Subtract y from x.

  Parameters
  ----------
    x : :obj:`xarray.DataArray`
      Data cube containing the operands at the left-hand side of each
      expression.
    y :
      Operands at the right-hand side of each expression. May be a constant,
      meaning that the same value is used in each expression. May also be
      another data cube which can be aligned to the same shape as cube ``x``.
      In the latter case, when evaluating the expression for a pixel in cube
      ``x`` the second operand is the value of the pixel in cube ``y`` that
      has the same dimension coordinates.
    track_types : :obj:`bool`
      Should the operator promote the value type of the output object, based
      on the value type of the input objects?
    **kwargs:
      Ignored.

  Returns
  -------
    :obj:`xarray.DataArray`
      A data cube with the same shape as ``x`` containing the results of all
      evaluated expressions.

  Note
  -----
    When tracking value types, this operator uses the following type promotion
    manual, with the first layer of keys being the supported value types of
    ``x``, the second layer of keys being the supported value types of ``y``
    given the value type of ``x``, and the corresponding value being the
    promoted value type of the output.

    .. exec_code::
      :hide_code:

      from semantique.processor.types import TYPE_PROMOTION_MANUALS
      obj = TYPE_PROMOTION_MANUALS["subtract"]
      obj.pop("__preserve_labels__")
      print(obj)

  """
  if track_types:
    promoter = TypePromoter(x, y, function = "subtract")
    promoter.check()
  f = lambda x, y: np.subtract(x, y)
  y = xr.DataArray(y).sq.align_with(x)
  out = xr.apply_ufunc(f, x, y)
  if track_types:
    out = promoter.promote(out)
  return out

#
# BOOLEAN OPERATORS
#

def and_(x, y, track_types = True, **kwargs):
  """Test if both x and y are true.

  Parameters
  ----------
    x : :obj:`xarray.DataArray`
      Data cube containing the operands at the left-hand side of each
      expression.
    y :
      Operands at the right-hand side of each expression. May be a constant,
      meaning that the same value is used in each expression. May also be
      another data cube which can be aligned to the same shape as cube ``x``.
      In the latter case, when evaluating the expression for a pixel in cube
      ``x`` the second operand is the value of the pixel in cube ``y`` that
      has the same dimension coordinates.
    track_types : :obj:`bool`
      Should the operator promote the value type of the output object, based
      on the value type of the input objects?
    **kwargs:
      Ignored.

  Returns
  -------
    :obj:`xarray.DataArray`
      A data cube with the same shape as ``x`` containing the results of all
      evaluated expressions.

  Note
  -----
    When tracking value types, this operator uses the following type promotion
    manual, with the first layer of keys being the supported value types of
    ``x``, the second layer of keys being the supported value types of ``y``
    given the value type of ``x``, and the corresponding value being the
    promoted value type of the output.

    .. exec_code::
      :hide_code:

      from semantique.processor.types import TYPE_PROMOTION_MANUALS
      obj = TYPE_PROMOTION_MANUALS["and"]
      obj.pop("__preserve_labels__")
      print(obj)

  """
  if track_types:
    promoter = TypePromoter(x, y, function = "and")
    promoter.check()
  def f(x, y):
    y = np_null_as_zero(y)
    return np.where(pd.notnull(x), np.logical_and(x, y), np.nan)
  y = xr.DataArray(y).sq.align_with(x)
  out = xr.apply_ufunc(f, x, y)
  if track_types:
    out = promoter.promote(out)
  return out

def or_(x, y, track_types = True, **kwargs):
  """Test if either x or y are true.

  Parameters
  ----------
    x : :obj:`xarray.DataArray`
      Data cube containing the operands at the left-hand side of each
      expression.
    y :
      Operands at the right-hand side of each expression. May be a constant,
      meaning that the same value is used in each expression. May also be
      another data cube which can be aligned to the same shape as cube ``x``.
      In the latter case, when evaluating the expression for a pixel in cube
      ``x`` the second operand is the value of the pixel in cube ``y`` that
      has the same dimension coordinates.
    track_types : :obj:`bool`
      Should the operator promote the value type of the output object, based
      on the value type of the input objects?
    **kwargs:
      Ignored.

  Returns
  -------
    :obj:`xarray.DataArray`
      A data cube with the same shape as ``x`` containing the results of all
      evaluated expressions.

  Note
  -----
    When tracking value types, this operator uses the following type promotion
    manual, with the first layer of keys being the supported value types of
    ``x``, the second layer of keys being the supported value types of ``y``
    given the value type of ``x``, and the corresponding value being the
    promoted value type of the output.

    .. exec_code::
      :hide_code:

      from semantique.processor.types import TYPE_PROMOTION_MANUALS
      obj = TYPE_PROMOTION_MANUALS["or"]
      obj.pop("__preserve_labels__")
      print(obj)

  """
  if track_types:
    promoter = TypePromoter(x, y, function = "or")
    promoter.check()
  def f(x, y):
    y = np_null_as_zero(y)
    return np.where(pd.notnull(x), np.logical_or(x, y), np.nan)
  y = xr.DataArray(y).sq.align_with(x)
  out = xr.apply_ufunc(f, x, y)
  if track_types:
    out = promoter.promote(out)
  return out

def exclusive_or_(x, y, track_types = True, **kwargs):
  """Test if only one of x and y is true.

  Parameters
  ----------
    x : :obj:`xarray.DataArray`
      Data cube containing the operands at the left-hand side of each
      expression.
    y :
      Operands at the right-hand side of each expression. May be a constant,
      meaning that the same value is used in each expression. May also be
      another data cube which can be aligned to the same shape as cube ``x``.
      In the latter case, when evaluating the expression for a pixel in cube
      ``x`` the second operand is the value of the pixel in cube ``y`` that
      has the same dimension coordinates.
    track_types : :obj:`bool`
      Should the operator promote the value type of the output object, based
      on the value type of the input objects?
    **kwargs:
      Ignored.

  Returns
  -------
    :obj:`xarray.DataArray`
      A data cube with the same shape as ``x`` containing the results of all
      evaluated expressions.

  Note
  -----
    When tracking value types, this operator uses the following type promotion
    manual, with the first layer of keys being the supported value types of
    ``x``, the second layer of keys being the supported value types of ``y``
    given the value type of ``x``, and the corresponding value being the
    promoted value type of the output.

    .. exec_code::
      :hide_code:

      from semantique.processor.types import TYPE_PROMOTION_MANUALS
      obj = TYPE_PROMOTION_MANUALS["exclusive_or"]
      obj.pop("__preserve_labels__")
      print(obj)

  """
  if track_types:
    promoter = TypePromoter(x, y, function = "exclusive_or")
    promoter.check()
  def f(x, y):
    y = np_null_as_zero(y)
    return np.where(pd.notnull(x), np.logical_xor(x, y), np.nan)
  y = xr.DataArray(y).sq.align_with(x)
  out = xr.apply_ufunc(f, x, y)
  if track_types:
    out = promoter.promote(out)
  return out

#
# EQUALITY OPERATORS
#

def equal_(x, y, track_types = True, **kwargs):
  """Test if x is equal to y.

  Parameters
  ----------
    x : :obj:`xarray.DataArray`
      Data cube containing the operands at the left-hand side of each
      expression.
    y :
      Operands at the right-hand side of each expression. May be a constant,
      meaning that the same value is used in each expression. May also be
      another data cube which can be aligned to the same shape as cube ``x``.
      In the latter case, when evaluating the expression for a pixel in cube
      ``x`` the second operand is the value of the pixel in cube ``y`` that
      has the same dimension coordinates.
    track_types : :obj:`bool`
      Should the operator promote the value type of the output object, based
      on the value type of the input objects?
    **kwargs:
      Ignored.

  Returns
  -------
    :obj:`xarray.DataArray`
      A data cube with the same shape as ``x`` containing the results of all
      evaluated expressions.

  Note
  -----
    When tracking value types, this operator uses the following type promotion
    manual, with the first layer of keys being the supported value types of
    ``x``, the second layer of keys being the supported value types of ``y``
    given the value type of ``x``, and the corresponding value being the
    promoted value type of the output.

    .. exec_code::
      :hide_code:

      from semantique.processor.types import TYPE_PROMOTION_MANUALS
      obj = TYPE_PROMOTION_MANUALS["equal"]
      obj.pop("__preserve_labels__")
      print(obj)

  """
  if track_types:
    promoter = TypePromoter(x, y, function = "equal")
    promoter.check()
  f = lambda x, y: np.where(pd.notnull(x), np.equal(x, y), np.nan)
  y = xr.DataArray(y).sq.align_with(x)
  out = xr.apply_ufunc(f, x, y)
  if track_types:
    out = promoter.promote(out)
  return out

def in_(x, y, track_types = True, **kwargs):
  """Test if x is a member of set y.

  Parameters
  ----------
    x : :obj:`xarray.DataArray`
      Data cube containing the operands at the left-hand side of each
      expression.
    y : :obj:`list`
      Operands at the right-hand side of each expression. Should be a set of
      values, which remains constant among all evaluated expressions.
    track_types : :obj:`bool`
      Should the operator promote the value type of the output object, based
      on the value type of the input objects?
    **kwargs:
      Ignored.

  Returns
  -------
    :obj:`xarray.DataArray`
      A data cube with the same shape as ``x`` containing the results of all
      evaluated expressions.

  Note
  -----
    When tracking value types, this operator uses the following type promotion
    manual, with the first layer of keys being the supported value types of
    ``x``, the second layer of keys being the supported value types of ``y``
    given the value type of ``x``, and the corresponding value being the
    promoted value type of the output.

    .. exec_code::
      :hide_code:

      from semantique.processor.types import TYPE_PROMOTION_MANUALS
      obj = TYPE_PROMOTION_MANUALS["in"]
      obj.pop("__preserve_labels__")
      print(obj)

  """
  if track_types:
    promoter = TypePromoter(x, y, function = "in")
    promoter.check()
  def f(x, y):
    if isinstance(y, ValueRange):
      a = np.greater_equal(x, y.start)
      b = np.less_equal(x, y.end)
      return np.where(pd.notnull(x), np.logical_and(a, b), np.nan)
    else:
      return np.where(pd.notnull(x), np.isin(x, y), np.nan)
  out = xr.apply_ufunc(f, x, y)
  if track_types:
    out = promoter.promote(out)
  return out

def not_equal_(x, y, track_types = True, **kwargs):
  """Test if x is not equal to y.

  Parameters
  ----------
    x : :obj:`xarray.DataArray`
      Data cube containing the operands at the left-hand side of each
      expression.
    y :
      Operands at the right-hand side of each expression. May be a constant,
      meaning that the same value is used in each expression. May also be
      another data cube which can be aligned to the same shape as cube ``x``.
      In the latter case, when evaluating the expression for a pixel in cube
      ``x`` the second operand is the value of the pixel in cube ``y`` that
      has the same dimension coordinates.
    track_types : :obj:`bool`
      Should the operator promote the value type of the output object, based
      on the value type of the input objects?
    **kwargs:
      Ignored.

  Returns
  -------
    :obj:`xarray.DataArray`
      A data cube with the same shape as ``x`` containing the results of all
      evaluated expressions.

  Note
  -----
    When tracking value types, this operator uses the following type promotion
    manual, with the first layer of keys being the supported value types of
    ``x``, the second layer of keys being the supported value types of ``y``
    given the value type of ``x``, and the corresponding value being the
    promoted value type of the output.

    .. exec_code::
      :hide_code:

      from semantique.processor.types import TYPE_PROMOTION_MANUALS
      obj = TYPE_PROMOTION_MANUALS["not_equal"]
      obj.pop("__preserve_labels__")
      print(obj)

  """
  if track_types:
    promoter = TypePromoter(x, y, function = "not_equal")
    promoter.check()
  f = lambda x, y: np.where(pd.notnull(x), np.not_equal(x, y), np.nan)
  y = xr.DataArray(y).sq.align_with(x)
  out = xr.apply_ufunc(f, x, y)
  if track_types:
    out = promoter.promote(out)
  return out

def not_in_(x, y, track_types = True, **kwargs):
  """Test if x is not a member of set y.

  Parameters
  ----------
    x : :obj:`xarray.DataArray`
      Data cube containing the operands at the left-hand side of each
      expression.
    y : :obj:`list`
      Operands at the right-hand side of each expression. Should be a set of
      values, which remains constant among all evaluated expressions.
    track_types : :obj:`bool`
      Should the operator promote the value type of the output object, based
      on the value type of the input objects?
    **kwargs:
      Ignored.

  Returns
  -------
    :obj:`xarray.DataArray`
      A data cube with the same shape as ``x`` containing the results of all
      evaluated expressions.

  Note
  -----
    When tracking value types, this operator uses the following type promotion
    manual, with the first layer of keys being the supported value types of
    ``x``, the second layer of keys being the supported value types of ``y``
    given the value type of ``x``, and the corresponding value being the
    promoted value type of the output.

    .. exec_code::
      :hide_code:

      from semantique.processor.types import TYPE_PROMOTION_MANUALS
      obj = TYPE_PROMOTION_MANUALS["not_in"]
      obj.pop("__preserve_labels__")
      print(obj)

  """
  if track_types:
    promoter = TypePromoter(x, y, function = "not_in")
    promoter.check()
  def f(x, y):
    if isinstance(y, ValueRange):
      a = np.less(x, y.start)
      b = np.greater(x, y.end)
      return np.where(pd.notnull(x), np.logical_or(a, b), np.nan)
    else:
      return np.where(pd.notnull(x), np.isin(x, y, invert = True), np.nan)
  out = xr.apply_ufunc(f, x, y)
  if track_types:
    out = promoter.promote(out)
  return out

#
# REGULAR RELATIONAL OPERATORS
#

def greater_(x, y, track_types = True, **kwargs):
  """Test if x is greater than y.

  Parameters
  ----------
    x : :obj:`xarray.DataArray`
      Data cube containing the operands at the left-hand side of each
      expression.
    y :
      Operands at the right-hand side of each expression. May be a constant,
      meaning that the same value is used in each expression. May also be
      another data cube which can be aligned to the same shape as cube ``x``.
      In the latter case, when evaluating the expression for a pixel in cube
      ``x`` the second operand is the value of the pixel in cube ``y`` that
      has the same dimension coordinates.
    track_types : :obj:`bool`
      Should the operator promote the value type of the output object, based
      on the value type of the input objects?
    **kwargs:
      Ignored.

  Returns
  -------
    :obj:`xarray.DataArray`
      A data cube with the same shape as ``x`` containing the results of all
      evaluated expressions.

  Note
  -----
    When tracking value types, this operator uses the following type promotion
    manual, with the first layer of keys being the supported value types of
    ``x``, the second layer of keys being the supported value types of ``y``
    given the value type of ``x``, and the corresponding value being the
    promoted value type of the output.

    .. exec_code::
      :hide_code:

      from semantique.processor.types import TYPE_PROMOTION_MANUALS
      obj = TYPE_PROMOTION_MANUALS["greater"]
      obj.pop("__preserve_labels__")
      print(obj)

  """
  if track_types:
    promoter = TypePromoter(x, y, function = "greater")
    promoter.check()
  f = lambda x, y: np.where(pd.notnull(x), np.greater(x, y), np.nan)
  y = xr.DataArray(y).sq.align_with(x)
  out = xr.apply_ufunc(f, x, y)
  if track_types:
    out = promoter.promote(out)
  return out

def greater_equal_(x, y, track_types = True, **kwargs):
  """Test if x is greater than or equal to y.

  Parameters
  ----------
    x : :obj:`xarray.DataArray`
      Data cube containing the operands at the left-hand side of each
      expression.
    y :
      Operands at the right-hand side of each expression. May be a constant,
      meaning that the same value is used in each expression. May also be
      another data cube which can be aligned to the same shape as cube ``x``.
      In the latter case, when evaluating the expression for a pixel in cube
      ``x`` the second operand is the value of the pixel in cube ``y`` that
      has the same dimension coordinates.
    track_types : :obj:`bool`
      Should the operator promote the value type of the output object, based
      on the value type of the input objects?
    **kwargs:
      Ignored.

  Returns
  -------
    :obj:`xarray.DataArray`
      A data cube with the same shape as ``x`` containing the results of all
      evaluated expressions.

  Note
  -----
    When tracking value types, this operator uses the following type promotion
    manual, with the first layer of keys being the supported value types of
    ``x``, the second layer of keys being the supported value types of ``y``
    given the value type of ``x``, and the corresponding value being the
    promoted value type of the output.

    .. exec_code::
      :hide_code:

      from semantique.processor.types import TYPE_PROMOTION_MANUALS
      obj = TYPE_PROMOTION_MANUALS["greater_equal"]
      obj.pop("__preserve_labels__")
      print(obj)

  """
  if track_types:
    promoter = TypePromoter(x, y, function = "greater_equal")
    promoter.check()
  f = lambda x, y: np.where(pd.notnull(x), np.greater_equal(x, y), np.nan)
  y = xr.DataArray(y).sq.align_with(x)
  out = xr.apply_ufunc(f, x, y)
  if track_types:
    out = promoter.promote(out)
  return out

def less_(x, y, track_types = True, **kwargs):
  """Test if x is less than y.

  Parameters
  ----------
    x : :obj:`xarray.DataArray`
      Data cube containing the operands at the left-hand side of each
      expression.
    y :
      Operands at the right-hand side of each expression. May be a constant,
      meaning that the same value is used in each expression. May also be
      another data cube which can be aligned to the same shape as cube ``x``.
      In the latter case, when evaluating the expression for a pixel in cube
      ``x`` the second operand is the value of the pixel in cube ``y`` that
      has the same dimension coordinates.
    track_types : :obj:`bool`
      Should the operator promote the value type of the output object, based
      on the value type of the input objects?
    **kwargs:
      Ignored.

  Returns
  -------
    :obj:`xarray.DataArray`
      A data cube with the same shape as ``x`` containing the results of all
      evaluated expressions.

  Note
  -----
    When tracking value types, this operator uses the following type promotion
    manual, with the first layer of keys being the supported value types of
    ``x``, the second layer of keys being the supported value types of ``y``
    given the value type of ``x``, and the corresponding value being the
    promoted value type of the output.

    .. exec_code::
      :hide_code:

      from semantique.processor.types import TYPE_PROMOTION_MANUALS
      obj = TYPE_PROMOTION_MANUALS["less"]
      obj.pop("__preserve_labels__")
      print(obj)

  """
  if track_types:
    promoter = TypePromoter(x, y, function = "less")
    promoter.check()
  f = lambda x, y: np.where(pd.notnull(x), np.less(x, y), np.nan)
  y = xr.DataArray(y).sq.align_with(x)
  out = xr.apply_ufunc(f, x, y)
  if track_types:
    out = promoter.promote(out)
  return out

def less_equal_(x, y, track_types = True, **kwargs):
  """Test if x is less than or equal to y.

  Parameters
  ----------
    x : :obj:`xarray.DataArray`
      Data cube containing the operands at the left-hand side of each
      expression.
    y :
      Operands at the right-hand side of each expression. May be a constant,
      meaning that the same value is used in each expression. May also be
      another data cube which can be aligned to the same shape as cube ``x``.
      In the latter case, when evaluating the expression for a pixel in cube
      ``x`` the second operand is the value of the pixel in cube ``y`` that
      has the same dimension coordinates.
    track_types : :obj:`bool`
      Should the operator promote the value type of the output object, based
      on the value type of the input objects?
    **kwargs:
      Ignored.

  Returns
  -------
    :obj:`xarray.DataArray`
      A data cube with the same shape as ``x`` containing the results of all
      evaluated expressions.

  Note
  -----
    When tracking value types, this operator uses the following type promotion
    manual, with the first layer of keys being the supported value types of
    ``x``, the second layer of keys being the supported value types of ``y``
    given the value type of ``x``, and the corresponding value being the
    promoted value type of the output.

    .. exec_code::
      :hide_code:

      from semantique.processor.types import TYPE_PROMOTION_MANUALS
      obj = TYPE_PROMOTION_MANUALS["less_equal"]
      obj.pop("__preserve_labels__")
      print(obj)

  """
  if track_types:
    promoter = TypePromoter(x, y, function = "less_equal")
    promoter.check()
  f = lambda x, y: np.where(pd.notnull(x), np.less_equal(x, y), np.nan)
  y = xr.DataArray(y).sq.align_with(x)
  out = xr.apply_ufunc(f, x, y)
  if track_types:
    out = promoter.promote(out)
  return out

#
# SPATIAL RELATIONAL OPERATORS
#

def intersects_(x, y, track_types = True, **kwargs):
  """Test if x spatially intersects with y.

  This is a specific spatial relational operator meant to be evaluated with
  a spatial coordinate tuple as left-hand side operand, and
  :func:`semantique.geometries` as right-hand side operand. It will
  evaluate if the spatial point with the specified coordinates spatially
  intersects with any of the given geometries.

  Parameters
  ----------
    x : :obj:`xarray.DataArray`
      Data cube containing the operands at the left-hand side of each
      expression, which should be spatial coordinate tuples.
    y :
      Spatial geometries to be used as the right-hand side of each expression.
      May also be another data cube with spatial coordinate tuples. In the
      latter case, when evaluating the expression for a coordinate tuple in
      cube ``x`` the second operand is the spatial bounding box of all
      coordinate tuples in cube ``y``.
    track_types : :obj:`bool`
      Should the operator promote the value type of the output object, based
      on the value type of the input objects?
    **kwargs:
      Ignored.

  Returns
  -------
    :obj:`xarray.DataArray`
      A data cube with the same shape as ``x`` containing the results of all
      evaluated expressions.

  Note
  -----
  The spatial coordinate reference systems of x and y are expected to be equal.

  Note
  -----
    When tracking value types, this operator uses the following type promotion
    manual, with the first layer of keys being the supported value types of
    ``x``, the second layer of keys being the supported value types of ``y``
    given the value type of ``x``, and the corresponding value being the
    promoted value type of the output.

    .. exec_code::
      :hide_code:

      from semantique.processor.types import TYPE_PROMOTION_MANUALS
      obj = TYPE_PROMOTION_MANUALS["intersects"]
      obj.pop("__preserve_labels__")
      print(obj)

  """
  if track_types:
    promoter = TypePromoter(x, y, function = "intersects")
    promoter.check()
  try:
    y = y.unary_union
  except AttributeError:
    y = y.sq.trim().sq.grid_points.envelope.unary_union
  values = x.sq.grid_points.intersects(y).astype(int)
  coords = x[x.sq.spatial_dimension].coords
  out = xr.DataArray(values, coords = coords).sq.align_with(x)
  if track_types:
    out = promoter.promote(out)
  return out

#
# TEMPORAL RELATIONAL OPERATORS
#

def after_(x, y, track_types = True, **kwargs):
  """Test if x comes after y.

  This is a specific temporal relational operator meant to be evaluated with
  a temporal coordinate as left-hand side operand, and a
  :func:`semantique.time_instant` and/or :func:`semantique.time_interval` as
  right-hand side operand. It will evaluate if the specified temporal
  coordinate is later in time than the given time instant or the end of the
  given time interval.

  Parameters
  ----------
    x : :obj:`xarray.DataArray`
      Data cube containing the operands at the left-hand side of each
      expression, which should be temporal coordinates.
    y :
      Time instant or time interval to be used as the right-hand side of each
      expression. May also be another data cube with temporal coordinates. In
      the latter case, when evaluating the expression for a coordinate in cube
      ``x`` the second operand is the temporal bounding box of all coordinates
      in cube ``y``.
    track_types : :obj:`bool`
      Should the operator promote the value type of the output object, based
      on the value type of the input objects?
    **kwargs:
      Ignored.

  Returns
  -------
    :obj:`xarray.DataArray`
      A data cube with the same shape as ``x`` containing the results of all
      evaluated expressions.

  Note
  -----
  The timezones of x and y are expected to be equal.

  Note
  -----
    When tracking value types, this operator uses the following type promotion
    manual, with the first layer of keys being the supported value types of
    ``x``, the second layer of keys being the supported value types of ``y``
    given the value type of ``x``, and the corresponding value being the
    promoted value type of the output.

    .. exec_code::
      :hide_code:

      from semantique.processor.types import TYPE_PROMOTION_MANUALS
      obj = TYPE_PROMOTION_MANUALS["after"]
      obj.pop("__preserve_labels__")
      print(obj)

  """
  if track_types:
    promoter = TypePromoter(x, y, function = "after")
    promoter.check()
  f = lambda x, y: np.where(pd.notnull(x), np.greater(x, np.nanmax(y)), np.nan)
  out = xr.apply_ufunc(f, x, y)
  if track_types:
    out = promoter.promote(out)
  return out

def before_(x, y, track_types = True, **kwargs):
  """Test if x comes before y.

  This is a specific temporal relational operator meant to be evaluated with
  a temporal coordinate as left-hand side operand, and a
  :func:`semantique.time_instant` and/or :func:`semantique.time_interval` as
  right-hand side operand. It will evaluate if the specified temporal
  coordinate is earlier in time than the given time instant or the start of
  the given time interval.

  Parameters
  ----------
    x : :obj:`xarray.DataArray`
      Data cube containing the operands at the left-hand side of each
      expression, which should be temporal coordinates.
    y :
      Time instant or time interval to be used as the right-hand side of each
      expression. May also be another data cube with temporal coordinates. In
      the latter case, when evaluating the expression for a coordinate in cube
      ``x`` the second operand is the temporal bounding box of all coordinates
      in cube ``y``.
    track_types : :obj:`bool`
      Should the operator promote the value type of the output object, based
      on the value type of the input objects?
    **kwargs:
      Ignored.

  Returns
  -------
    :obj:`xarray.DataArray`
      A data cube with the same shape as ``x`` containing the results of all
      evaluated expressions.

  Note
  -----
  The timezones of x and y are expected to be equal.

  Note
  -----
    When tracking value types, this operator uses the following type promotion
    manual, with the first layer of keys being the supported value types of
    ``x``, the second layer of keys being the supported value types of ``y``
    given the value type of ``x``, and the corresponding value being the
    promoted value type of the output.

    .. exec_code::
      :hide_code:

      from semantique.processor.types import TYPE_PROMOTION_MANUALS
      obj = TYPE_PROMOTION_MANUALS["before"]
      obj.pop("__preserve_labels__")
      print(obj)

  """
  if track_types:
    promoter = TypePromoter(x, y, function = "before")
    promoter.check()
  f = lambda x, y: np.where(pd.notnull(x), np.less(x, np.nanmin(y)), np.nan)
  out = xr.apply_ufunc(f, x, y)
  if track_types:
    out = promoter.promote(out)
  return out

def during_(x, y, track_types = True, **kwargs):
  """Test if x is during interval y.

  This is a specific temporal relational operator meant to be evaluated with
  a temporal coordinate as left-hand side operand, and a
  :func:`semantique.time_interval` as right-hand side operand. It will evaluate
  if the specified temporal coordinate fall inside the given time interval.

  Parameters
  ----------
    x : :obj:`xarray.DataArray`
      Data cube containing the operands at the left-hand side of each
      expression, which should be temporal coordinates.
    y :
      Time interval to be used as the right-hand side of each expression. May
      also be another data cube with temporal coordinates. In the latter case,
      when evaluating the expression for a coordinate in cube ``x`` the second
      operand is the temporal bounding box of all coordinates in cube ``y``.
    track_types : :obj:`bool`
      Should the operator promote the value type of the output object, based
      on the value type of the input objects?
    **kwargs:
      Ignored.

  Returns
  -------
    :obj:`xarray.DataArray`
      A data cube with the same shape as ``x`` containing the results of all
      evaluated expressions.

  Note
  -----
  The timezones of x and y are expected to be equal.

  Note
  -----
    When tracking value types, this operator uses the following type promotion
    manual, with the first layer of keys being the supported value types of
    ``x``, the second layer of keys being the supported value types of ``y``
    given the value type of ``x``, and the corresponding value being the
    promoted value type of the output.

    .. exec_code::
      :hide_code:

      from semantique.processor.types import TYPE_PROMOTION_MANUALS
      obj = TYPE_PROMOTION_MANUALS["during"]
      obj.pop("__preserve_labels__")
      print(obj)

  """
  if track_types:
    promoter = TypePromoter(x, y, function = "during")
    promoter.check()
  def f(x, y):
    a = np.greater_equal(x, np.nanmin(y))
    b = np.less_equal(x, np.nanmax(y))
    return np.where(pd.notnull(x), np.logical_and(a, b), np.nan)
  out = xr.apply_ufunc(f, x, y)
  if track_types:
    out = promoter.promote(out)
  return out

#
# ASSIGNMENT OPERATORS
#

def assign_(x, y, track_types = True, **kwargs):
  """Replace x by y.

  Parameters
  ----------
    x : :obj:`xarray.DataArray`
      Data cube containing the operands at the left-hand side of each
      expression.
    y :
      Operands at the right-hand side of each expression. May be a constant,
      meaning that the same value is used in each expression. May also be
      another data cube which can be aligned to the same shape as cube ``x``.
      In the latter case, when evaluating the expression for a pixel in cube
      ``x`` the second operand is the value of the pixel in cube ``y`` that
      has the same dimension coordinates.
    track_types : :obj:`bool`
      Should the operator promote the value type of the output object, based
      on the value type of the input objects?
    **kwargs:
      Ignored.

  Returns
  -------
    :obj:`xarray.DataArray`
      A data cube with the same shape as ``x`` containing the results of all
      evaluated expressions.

  Note
  -----
    When tracking value types, this operator uses the following type promotion
    manual, with the first layer of keys being the supported value types of
    ``x``, the second layer of keys being the supported value types of ``y``
    given the value type of ``x``, and the corresponding value being the
    promoted value type of the output.

    .. exec_code::
      :hide_code:

      from semantique.processor.types import TYPE_PROMOTION_MANUALS
      obj = TYPE_PROMOTION_MANUALS["assign"]
      obj.pop("__preserve_labels__")
      print(obj)

  """
  if track_types:
    promoter = TypePromoter(x, y, function = "assign")
    promoter.check()
  y = xr.DataArray(y).sq.align_with(x)
  out = xr.where(np.isfinite(x), y, np_null(y))
  if track_types:
    out = promoter.promote(out)
  return out

ext: py

max_stars_repo_name: ZGIS/semantique

max_issues_repo_name: ZGIS/semantique

max_forks_repo_name: ZGIS/semantique

reason: import numpy


text:
######################################################################
#                                                                    #
#  Copyright 2020-2020 Lucas Heitzmann Gabrielli.                    #
#  This file is part of gdstk, distributed under the terms of the    #
#  Boost Software License - Version 1.0.  See the accompanying       #
#  LICENSE file or <http://www.boost.org/LICENSE_1_0.txt>            #
#                                                                    #
######################################################################

from tutorial_images import draw
import pathlib
import numpy
import gdstk

if __name__ == "__main__":
    n = 3     # Number of unit cells around defect
    d = 0.2   # Unit cell size
    r = 0.05  # Circle radius
    s = 1.5   # Scaling factor

    # Create a simple unit cell
    unit_cell = gdstk.Cell("Unit Cell")
    unit_cell.add(gdstk.ellipse((0, 0), r, tolerance=1e-3))

    # Build a resonator from a unit cell grid with a defect inside
    ressonator = gdstk.Cell("Resonator")
    patches = [
        gdstk.Reference(
            unit_cell, (-n * d, -n * d), columns=2 * n + 1, rows=n, spacing=(d, d)
        ),
        gdstk.Reference(
            unit_cell, (-n * d, d), columns=2 * n + 1, rows=n, spacing=(d, d)
        ),
        gdstk.Reference(unit_cell, (-n * d, 0), columns=n, rows=1, spacing=(d, d)),
        gdstk.Reference(unit_cell, (d, 0), columns=n, rows=1, spacing=(d, d)),
    ]
    # Defect
    rect = gdstk.rectangle((-r / 2, -r / 2), (r / 2, r / 2))
    # Path for illustration
    path = gdstk.FlexPath(
        [(-n * d, 0), (n * d, 0)],
        r,
        ends=(r, r),
        gdsii_path=True,
        scale_width=False,
        layer=1,
    )
    ressonator.add(rect, path, *patches)

    # Main output cell with the original resonator,…
    main = gdstk.Cell("Main")
    main.add(gdstk.Reference(ressonator))
    main.add(*gdstk.text("Original", d, ((n + 1) * d, -d / 2)))

    # … a copy created by scaling a reference to the original resonator,…
    main.add(gdstk.Reference(ressonator, (0, (1 + s) * (n + 1) * d), magnification=s))
    main.add(
        *gdstk.text("Reference\nscaling", d, (s * (n + 1) * d, (1 + s) * (n + 1) * d))
    )

    # … and another copy created by copying and scaling the Cell itself.
    ressonator_copy = ressonator.copy("Resonator Copy", magnification=s)
    main.add(gdstk.Reference(ressonator_copy, (0, (1 + 3 * s) * (n + 1) * d)))
    main.add(
        *gdstk.text(
            "Cell copy\nscaling", d, (s * (n + 1) * d, (1 + 3 * s) * (n + 1) * d)
        )
    )
    main.name = "transforms"
    path = pathlib.Path(__file__).parent.absolute() / "how-tos"
    path.mkdir(parents=True, exist_ok=True)
    draw(main, path)

max_stars_repo_name: joamatab/gdstk

max_issues_repo_name: joamatab/gdstk

max_forks_repo_name: joamatab/gdstk


text:
import numpy as np

def map_feature(x1,x2,power):
	x1 = x1.reshape((x1.size,1))
	x2 = x2.reshape((x2.size,1))
	result = np.ones(x1[:,0].shape)

	for i in range(1,power+1):
		for j in range(0,i+1):
			result = np.c_[result,(x1**(i-j))*(x2**j)]

	return result


text:
#!/usr/bin/python

import numpy as np
from matplotlib import pyplot as plt

def main(r=.1, R=1, w=1/3300, n=100):
    # out total time will be n periods
    T = n/w
    # lets just do 100 points per period
    t = np.arange(0, T, .01/w)
    theta = 2 * np.pi * w * t
    # calculate distances
    d = dist(theta, r, R)

    # now take fourier transform
    fft_d = np.fft.rfft(d)
    freqs = np.fft.rfftfreq(len(t), 0.01/w)
    plt.plot(freqs, fft_d.real)
    plt.plot(freqs, fft_d.imag)
    return fft_d, freqs

def dist(theta, r=.1, R=1):
    x = r * np.cos(theta)
    y = r * np.sin(theta)
    # let the observer be at x=R, y=0)
    return np.sqrt((R - x) ** 2 + y ** 2)

max_stars_repo_name: thevorpalblade/pydmgrav

max_issues_repo_name: thevorpalblade/pydmgrav

max_forks_repo_name: thevorpalblade/pydmgrav


text:
import numpy as np
import tensorflow as tf
import tensorflow.keras as keras

from tensorflow.keras.utils import plot_model
from tensorflow.keras.activations import sigmoid
from tensorflow.keras.optimizers import SGD
from tensorflow.keras.callbacks import LearningRateScheduler
from tensorflow.keras import backend as K

from VAE import *
from utils import npytar

learning_rate_1 = 0.0001
learning_rate_2 = 0.005
momentum = 0.9
batch_size = 10
epoch_num = 150

def data_loader(fname):
    reader = npytar.NpyTarReader(fname)
    xc = np.zeros((reader.length(), ) + input_shape, dtype = np.float32)
    reader.reopen()
    for ix, (x, name) in enumerate(reader):
        xc[ix] = x.astype(np.float32)
    return 3.0 * xc - 1.0

def weighted_binary_crossentropy(target, output):
    loss = -(98.0 * target * K.log(output) + 2.0 * (1.0 - target) * K.log(1.0 - output)) / 100.0
    return loss

def learning_rate_scheduler(epoch, lr):
    if epoch >= 1:
        lr = learning_rate_2
    return lr

if __name__ == '__main__':
    model = get_model()

    inputs = model['inputs']
    outputs = model['outputs']
    mu = model['mu']
    sigma = model['sigma']
    z = model['z']

    encoder = model['encoder']
    decoder = model['decoder']

    plot_model(encoder, to_file = 'vae_encoder.pdf', show_shapes = True)
    plot_model(decoder, to_file = 'vae_decoder.pdf', show_shapes = True)

    vae = model['vae']

    # kl_div = -0.5 * K.mean(1 + 2 * sigma - K.square(mu) - K.exp(2 * sigma))
    voxel_loss = K.cast(K.mean(weighted_binary_crossentropy(inputs, K.clip(sigmoid(outputs), 1e-7, 1.0 - 1e-7))), 'float32') # + kl_div
    vae.add_loss(voxel_loss)

    sgd = SGD(lr = learning_rate_1, momentum = momentum, nesterov = True)
    vae.compile(optimizer = sgd, metrics = ['accuracy'])

    plot_model(vae, to_file = 'vae.pdf', show_shapes = True)

    data_train = data_loader('datasets/shapenet10_chairs_nr.tar')

    vae.fit(
        data_train,
        epochs = epoch_num,
        batch_size = batch_size,
        validation_data = (data_train, None),
        callbacks = [LearningRateScheduler(learning_rate_scheduler)]
    )

    vae.save_weights('vae.h5')

max_stars_repo_name: IsaacGuan/Generative-Voxel-Modeling

max_issues_repo_name: IsaacGuan/Generative-Voxel-Modeling

max_forks_repo_name: IsaacGuan/Generative-Voxel-Modeling


text:
import re
import threading
import unittest

import pytest

import cupy
from cupy import cuda
from cupy.cuda import runtime
from cupy import testing

class TestDeviceComparison(unittest.TestCase):

    def check_eq(self, result, obj1, obj2):
        if result:
            assert obj1 == obj2
            assert obj2 == obj1
            assert not (obj1 != obj2)
            assert not (obj2 != obj1)
        else:
            assert obj1 != obj2
            assert obj2 != obj1
            assert not (obj1 == obj2)
            assert not (obj2 == obj1)

    def test_equality(self):
        self.check_eq(True, cuda.Device(0), cuda.Device(0))
        self.check_eq(True, cuda.Device(1), cuda.Device(1))
        self.check_eq(False, cuda.Device(0), cuda.Device(1))
        self.check_eq(False, cuda.Device(0), 0)
        self.check_eq(False, cuda.Device(0), None)
        self.check_eq(False, cuda.Device(0), object())

    def test_lt_device(self):
        assert cuda.Device(0) < cuda.Device(1)
        assert not (cuda.Device(0) < cuda.Device(0))
        assert not (cuda.Device(1) < cuda.Device(0))

    def test_le_device(self):
        assert cuda.Device(0) <= cuda.Device(1)
        assert cuda.Device(0) <= cuda.Device(0)
        assert not (cuda.Device(1) <= cuda.Device(0))

    def test_gt_device(self):
        assert not (cuda.Device(0) > cuda.Device(0))
        assert not (cuda.Device(0) > cuda.Device(0))
        assert cuda.Device(1) > cuda.Device(0)

    def test_ge_device(self):
        assert not (cuda.Device(0) >= cuda.Device(1))
        assert cuda.Device(0) >= cuda.Device(0)
        assert cuda.Device(1) >= cuda.Device(0)

    def check_comparison_other_type(self, obj1, obj2):
        with pytest.raises(TypeError):
            obj1 < obj2
        with pytest.raises(TypeError):
            obj1 <= obj2
        with pytest.raises(TypeError):
            obj1 > obj2
        with pytest.raises(TypeError):
            obj1 >= obj2
        with pytest.raises(TypeError):
            obj2 < obj1
        with pytest.raises(TypeError):
            obj2 <= obj1
        with pytest.raises(TypeError):
            obj2 > obj1
        with pytest.raises(TypeError):
            obj2 >= obj1

    def test_comparison_other_type(self):
        self.check_comparison_other_type(cuda.Device(0), 0)
        self.check_comparison_other_type(cuda.Device(0), 1)
        self.check_comparison_other_type(cuda.Device(1), 0)
        self.check_comparison_other_type(cuda.Device(1), None)
        self.check_comparison_other_type(cuda.Device(1), object())

@testing.gpu
class TestDeviceAttributes(unittest.TestCase):

    def test_device_attributes(self):
        d = cuda.Device()
        attributes = d.attributes
        assert isinstance(attributes, dict)
        assert all(isinstance(a, int) for a in attributes.values())
        # test a specific attribute that would be present on any supported GPU
        assert 'MaxThreadsPerBlock' in attributes

    def test_device_attributes_error(self):
        with pytest.raises(cuda.runtime.CUDARuntimeError):
            # try to retrieve attributes from a non-existent device
            cuda.device.Device(cuda.runtime.getDeviceCount()).attributes

@testing.gpu
class TestDevicePCIBusId(unittest.TestCase):
    def test_device_get_pci_bus_id(self):
        d = cuda.Device()
        pci_bus_id = d.pci_bus_id
        assert re.match(
            '^[a-fA-F0-9]{4}:[a-fA-F0-9]{2}:[a-fA-F0-9]{2}.[a-fA-F0-9]',
            pci_bus_id
        )

    def test_device_by_pci_bus_id(self):
        d1 = cuda.Device()
        d2 = cuda.Device.from_pci_bus_id(d1.pci_bus_id)
        assert d1 == d2
        d3 = cuda.Device(d2)
        assert d2 == d3

        with pytest.raises(cuda.runtime.CUDARuntimeError) as excinfo:
            cuda.Device.from_pci_bus_id('fake:id')
            assert excinfo == 'cudaErrorInvalidValue: invalid argument'

        with pytest.raises(cuda.runtime.CUDARuntimeError) as excinfo:
            cuda.Device.from_pci_bus_id('FFFF:FF:FF.F')
            assert excinfo == 'cudaErrorInvalidDevice: invalid device ordinal'

@testing.gpu
class TestDeviceHandles(unittest.TestCase):
    def _check_handle(self, func):
        handles = [func(), None, None]

        def _subthread():
            cupy.cuda.Device().use()
            handles[1] = func()
            handles[2] = func()

        t = threading.Thread(target=_subthread)
        t.start()
        t.join()
        assert handles[0] is not None
        assert handles[0] != handles[1]
        assert handles[1] == handles[2]

    def test_cublas_handle(self):
        self._check_handle(cuda.get_cublas_handle)

    def test_cusolver_handle(self):
        self._check_handle(cuda.device.get_cusolver_handle)

    def test_cusolver_sp_handle(self):
        self._check_handle(cuda.device.get_cublas_handle)

    @pytest.mark.xfail(
        runtime.is_hip, reason='ROCm/HIP sparse support is not yet ready')
    def test_cusparse_handle(self):
        self._check_handle(cuda.device.get_cusparse_handle)

class TestDeviceFromPointer(unittest.TestCase):
    def test_from_pointer(self):
        assert cuda.device.from_pointer(cupy.empty(1).data.ptr).id == 0

@testing.multi_gpu(2)
class TestDeviceContextManager(unittest.TestCase):
    def test_thread_safe(self):
        dev0 = cuda.Device(0)
        dev1 = cuda.Device(1)

        t0_setup = threading.Event()
        t1_setup = threading.Event()
        t0_first_exit = threading.Event()

        t0_exit_device = []
        t1_exit_device = []

        def t0_seq():
            with dev0:
                with dev0:
                    t0_setup.set()
                    t1_setup.wait()
                t0_exit_device.append(cuda.Device().id)
                t0_first_exit.set()

        def t1_seq():
            t0_setup.wait()
            with dev1:
                with dev0:
                    t1_setup.set()
                    t0_first_exit.wait()
                t1_exit_device.append(cuda.Device().id)

        t1 = threading.Thread(target=t1_seq)
        t1.start()
        t0_seq()
        t1.join()
        assert t0_exit_device[0] == 0
        assert t1_exit_device[0] == 1

max_stars_repo_name: insertinterestingnamehere/cupy

max_issues_repo_name: insertinterestingnamehere/cupy

max_forks_repo_name: insertinterestingnamehere/cupy

reason: import cupy,from cupy


text:
import numpy as np
import torch
from scipy.io.wavfile import write
import models
from tacotron2.text import text_to_sequence
import matplotlib.pyplot as plt
import sys
from scipy import signal
import librosa

def inv_mel_spectrogram(mel_spectrogram):
    # Converts mel spectrogram to waveform using librosa
    D = _denormalize(mel_spectrogram)
    S = _mel_to_linear(_db_to_amp(D + 20))  # Convert back to linear
    return inv_preemphasis(_griffin_lim(S ** 1.5),0.97)

def _build_mel_basis():
    #assert hparams.fmax <= hparams.sample_rate // 2

    #fmin: Set this to 55 if your speaker is male! if female, 95 should help taking off noise. (To test depending on dataset. Pitch info: male~[65, 260], female~[100, 525])
    #fmax: 7600, To be increased/reduced depending on data.
    #return librosa.filters.mel(hparams.sample_rate, hparams.fft_size, n_mels=hparams.num_mels,fmin=hparams.fmin, fmax=hparams.fmax)
    return librosa.filters.mel(24000, 2048, n_mels=80)  # fmin=0, fmax= sample_rate/2.0

def _mel_to_linear(mel_spectrogram):

    _inv_mel_basis = np.linalg.pinv(_build_mel_basis())
    return np.maximum(1e-10, np.dot(_inv_mel_basis, mel_spectrogram))
def _stft(y):

    return librosa.stft(y=y, n_fft=2048, hop_length=300, win_length=1200)

def _istft(y):
    return librosa.istft(y, hop_length=300, win_length=1200)

def _griffin_lim(S):
    # librosa implementation of Griffin-Lim
    # Based on https://github.com/librosa/librosa/issues/434

    angles = np.exp(2j * np.pi * np.random.rand(*S.shape))
    S_complex = np.abs(S).astype(np.complex)
    y = _istft(S_complex * angles)
    for i in range(60):
        angles = np.exp(1j * np.angle(_stft(y)))
        y = _istft(S_complex * angles)
    return y
def _db_to_amp(x):
    return np.power(10.0, (x) * 0.05)

def _denormalize(D):

    return (((np.clip(D, -4,
                      4) + 4) * -(-100) / (2 * 4))
            + (-100))
#         else:
#             return ((np.clip(D, 0, hparams.max_abs_value) * -hparams.min_level_db / hparams.max_abs_value) + hparams.min_level_db)
#
#     if hparams.symmetric_mels:
#         return (((D + hparams.max_abs_value) * -hparams.min_level_db / (2 * hparams.max_abs_value)) + hparams.min_level_db)
#     else:
#         return ((D * -hparams.min_level_db / hparams.max_abs_value) + hparams.min_level_db)
def inv_preemphasis(wav, k):

    return signal.lfilter([1], [1, -k], wav)

def plot_data(data, figsize=(16, 4)):
    fig, axes = plt.subplots(1, len(data), figsize=figsize)
    for i in range(len(data)):
        axes[i].imshow(data[i], aspect='auto', origin='bottom',
                       interpolation='none')
        fig.savefig('data'+str(i)+'.png')
    plt.close(fig)
sys.path.append('./waveglow')

tacotron_path = 'output/checkpoint_Tacotron2_30'
taco_checkpoint = torch.load(tacotron_path, map_location='cpu')
state_dict = torch.load(tacotron_path)['state_dict']
t2 = models.get_model('Tacotron2', taco_checkpoint['config'], to_cuda=True)

text = "아들 진수가 살아 돌아온다"
# preprocessing
inputs = np.array(text_to_sequence(text, ['korean_cleaners']))[None, :]
print(inputs)
inputs = torch.from_numpy(inputs).to(device='cuda', dtype=torch.int64)
#inputs = torch.from_numpy(np.array([bombom, kitkat], dtype=np.int64)).to(device='cuda', dtype=torch.int64)

#input_lengths = torch.IntTensor([inputs.size(1), inputs.size(1)]).cuda().long()
input_lengths = torch.IntTensor([inputs.size(1)]).cuda().long()
speaker_id = torch.IntTensor([0]).cuda().long()
embedded_speaker = t2.speakers_embedding(speaker_id)
print("speaker",embedded_speaker)

t2.load_state_dict(state_dict)
_ = t2.cuda().eval()

waveglow = torch.hub.load('nvidia/DeepLearningExamples:torchhub', 'nvidia_waveglow')
waveglow = waveglow.remove_weightnorm(waveglow)
waveglow = waveglow.to('cuda')
waveglow.eval()

'''
waveglow = torch.load('output/waveglow_128000')['model']
for m in waveglow.modules():
    if 'Conv' in str(type(m)):
        setattr(m, 'padding_mode', 'zeros')

waveglow = waveglow.remove_weightnorm(waveglow)
waveglow.cuda().eval().half()
print("load waveglow")
# waveglow = waveglow.half()
for k in waveglow.convinv:
    k.float()
    '''
# from apex import amp
# waveglow, _ = amp.initialize(waveglow, [], opt_level="O3")

# run the models
with torch.no_grad():
    print(speaker_id)
    mel_outputs, mel_outputs_postnet, _, alignments= t2.infer(inputs, speaker_id)
    plot_data((mel_outputs.float().data.cpu().numpy()[0],
               mel_outputs_postnet.float().data.cpu().numpy()[0],
               alignments.float().data.cpu().numpy()[0].T))
    mel = mel_outputs_postnet

    print(mel.shape)
    print("tacoinfered")
    # #griff-lim

    # audio = inv_mel_spectrogram(mel.cpu().numpy()[0])
    # #audio *= 32678.0
    # #
    # print((audio).min().item(),(audio).max().item())
    # write('grifffv01_6_epoch26_진수.wav', 24000, audio)

    audio = waveglow.infer(mel)
    print((audio).min().item(),(audio).max().item())
audio_numpy = audio[0].data.cpu().numpy()

# audio = waveglow.infer(mel, sigma=sigma)
# if denoiser_strength > 0:
#     audio = denoiser(audio, denoiser_strength)
# audio = audio * 32768.0
# print((audio).min().item(),(audio).max().item())
# audio = audio.squeeze()
# audio = audio.cpu().numpy()
# audio = audio.astype('int16')
# # audio_path = os.path.join(
# #     output_dir, "{}_synthesis.wav".format(file_name))
# # write(audio_path, sampling_rate, audio)
# plt.imshow(mel.squeeze(0).detach().cpu().numpy())
# audio_numpy = audio[0].data.cpu().numpy()
# min = np.amin(audio_numpy)
# max = np.amax(audio_numpy)
# print(min,max)
rate = 24000

#
write("torchhub.wav", rate, audio_numpy)
#

#

# m  = np.load('tacomol_02.0024'+'.npz')
# #m  = np.load('mv04_t05_s13'+'.npz')
# mel = m['mel']
# print(mel.shape)
# #mel = mel.transpose(1,0)
# print(mel.shape)
# audio = inv_mel_spectrogram(mel)
# write('sampleksss.wav', 24000, audio)

reason: import numpy,from scipy