import pandas as pd
import seaborn as sns
from pathlib import Path
from post_processing_multi import *

tags = [""]
# predefined budgets
budget_shots = [
    [None],
    {
        50000,
        1000,
        333,
        500,
        250,
        166,
        125,
        100,
        83,
        55,
        41,
        33,
        27,
        500000,
        10000,
        3333,
        5000,
        2500,
        1666,
        1250,
        1000,
        833,
        555,
        416,
        333,
        277,
        5000000,
        100000,
        33333,
        50000,
        25000,
        16666,
        12500,
        10000,
        8333,
        5555,
        4166,
        3333,
        2777,
        50000000,
        1000000,
        333333,
        500000,
        250000,
        166666,
        125000,
        100000,
        83333,
        55555,
        41666,
        33333,
        27777,
        500000000,
        10000000,
        3333333,
        5000000,
        2500000,
        1666666,
        1250000,
        1000000,
        833333,
        555555,
        416666,
        333333,
        277777,
        5000000000,
        100000000,
        33333333,
        50000000,
        25000000,
        16666666,
        12500000,
        10000000,
        8333333,
        5555555,
        4166666,
        3333333,
        2777777,
    },
]

def relative_shots(training_sets, noise_levels, max_copies, shots_budget):
    """Returns relative shots with less shots for COI when shots budget is high enough.

    Args:
        training_sets (int): number of training sets.
        noise_levels (int):  number of  noise levels
        max_copies (int): number of copies considred
        shots_budget (int): total budget

    Returns:
        pandas DF: dataframe with shot budgets
    """
    if shots_budget != 0:
        CDR_shots = shots_budget // training_sets
        vnCDR_shots = CDR_shots // noise_levels
        CGVD_shots = shots_budget // training_sets
        storage = pd.DataFrame(
            {
                "VD": [shots_budget // 2] * (max_copies),
                "ZNE": [shots_budget // 2] + [shots_budget // 4] * (max_copies - 1),
                "CDR": [CDR_shots] + [CDR_shots // 2] * (max_copies - 1),
                "vnCDR": [vnCDR_shots] * (max_copies),
                "CGVD": [
                    base_cost // (copy + 1) // 2
                    for copy, base_cost in enumerate([CGVD_shots] * (max_copies))
                ],
                "UNITED": [
                    x // noise_levels
                    for x in [
                        base_cost // (copy + 1)
                        for copy, base_cost in enumerate([CGVD_shots] * (max_copies))
                    ]
                ],
                "copies": list(range(1, max_copies + 1)),
            }
        )
    else:
        storage = pd.DataFrame(
            {
                "VD": None,
                "ZNE": None,
                "CDR": [None] * 6,
                "vnCDR": [None] * 6,
                "CGVD": [None] * 6,
                "UNITED": [None] * 6,
                "copies": list(range(1, max_copies + 1)),
            }
        )
    return pd.melt(storage, id_vars=("copies"))

def relative_shots_table(
    training_sets, noise_levels, max_copies, shots_budget, swap_levels
):
    """Returns relative shots used by techniques with no optimizations or considerations. Includes
    swap nosie.

    Args:
        training_sets (int): number of training sets.
        noise_levels (int):  number of  noise levels
        max_copies (int): number of copies considred
        shots_budget (int): total budget
        swap_levels (int): number of swap noise levels

    Returns:
        pandas DF: dataframe with shot budgets
    """
    if shots_budget != 0:
        CDR_shots = shots_budget // training_sets
        vnCDR_shots = CDR_shots // noise_levels
        CGVD_shots = shots_budget // training_sets
        storage = pd.DataFrame(
            {
                "VD": [shots_budget] + [shots_budget // 2] * (max_copies - 1),
                "ZNE": [shots_budget // 2] + [shots_budget // 4] * (max_copies - 1),
                "CDR": [CDR_shots] + [CDR_shots // 2] * (max_copies - 1),
                "vnCDR": [vnCDR_shots] + [vnCDR_shots // 2] * (max_copies - 1),
                "CGVD": [CGVD_shots]
                + [
                    base_cost // (copy + 2) // 2
                    for copy, base_cost in enumerate([CGVD_shots] * (max_copies - 1))
                ],
                "UNITED": [vnCDR_shots]
                + [
                    x // noise_levels // 2
                    for x in [
                        base_cost // (copy + 2)
                        for copy, base_cost in enumerate(
                            [CGVD_shots] * (max_copies - 1)
                        )
                    ]
                ],
                "UNITED+": [vnCDR_shots // swap_levels]
                + [
                    x // noise_levels // 2 // swap_levels
                    for x in [
                        base_cost // (copy + 2)
                        for copy, base_cost in enumerate(
                            [CGVD_shots] * (max_copies - 1)
                        )
                    ]
                ],
                "copies": list(range(1, max_copies + 1)),
            }
        )
    else:
        storage = pd.DataFrame(
            {
                "VD": None,
                "ZNE": None,
                "CDR": None,
                "vnCDR": None,
                "CGVD": None,
                "UNITED": None,
                "copies": list(range(1, max_copies + 1)),
            }
        )
    return storage

def single_qubit_gate_length(layers, qubits):
    return layers * 6 * (qubits - 1)

def two_qubit_gate_length(layers, qubits):
    return layers * (qubits - 1)

def circuit_length(layers, qubits):
    """calculates circuit length

    Args:
        layers (int): number of layers in RQC
        qubits (int): number of qubtis in system

    Returns:
        int: decomposed circuit depth
    """
    e1 = layers * 6 * (qubits - 1)
    e2 = layers * (qubits - 1)
    return e1 + e2

def total_error_rates_normal(layers, qubits, factor=1):
    """Generates total error rate in standard numerical experiment.

    Args:
        layers (int): number of layers of RQC.
        qubits (int): number of qubits
        factor (float, optional): noise scaling factor. Defaults to 1.

    Returns:
        float: total error rate.
    """
    e1 = layers * 6 * (qubits - 1) * 0.0011 * factor
    e2 = layers * (qubits - 1) * 0.0021 * factor
    return e1 + e2

def load_multiple_files(
    Q,
    p,
    num_seeds,
    nlsp_list=[1, 2, 3],
    N=10,
    Nts=100,
    max_copies=6,
    tags=[""],
    density_matrices=False,
    shots=[None],
    folder="",
    train=True,
):
    """Loads multiple files and processes all the data through the various techniques.

    Args:
        Q (list): list of qubits
        p (list): depth list, same length as Q
        num_seeds (int): number of seeds considered
        nlsp_list (list, optional): list of noise levels. Defaults to [1,2,3].
        N (int, optional): non clifford gates in simulation. Defaults to 10.
        Nts (int, optional): training set size. Defaults to 100.
        max_copies (int, optional): max number of copies in VD. Defaults to 6.
        tags (list, optional): list of additional tags. Defaults to [''].
        density_matrices (bool, optional): Do you have density matrices?. Defaults to False.
        shots (list, optional): shots of finite shot simulations. Defaults to [None].
        folder (str, optional): folder to be analyzed. Defaults to ''.
        train (bool, optional): existance of training data. Defaults to True.

    Returns:
        (absolute_error_df, error_rescaling_df, mitigated_values_df) : Various dfs of processed and organized data.
    """
    dfs_error_rescaling = []
    dfs_absolute_error = []
    dfs_standard_values = []
    for qubit_no, depth in zip(Q, p):
        print(f"Qubit: {Q}, depth: {p}")
        data_processing = VD_CDR(
            qubit_no,
            depth,
            num_seeds,
            N,
            Nts,
            max_copies,
            nlsp_list,
            shots=shots,
            folder=folder,
            autoprocessing=True,
            plots=False,
            density_matrices=density_matrices,
            extra_tags=tags,
            train=train,
        )

        dfs_absolute_error.append(
            data_processing.abs_error_df.assign(Qubits=qubit_no, depth=depth)
        )
        dfs_error_rescaling.append(
            data_processing.calculated_vals_df.assign(Qubits=qubit_no, depth=depth)
        )
        dfs_standard_values.append(
            data_processing.standard_df.assign(Qubits=qubit_no, depth=depth)
        )
    dfs_absolute_error = pd.concat(dfs_absolute_error)
    dfs_error_rescaling = pd.concat(dfs_error_rescaling)
    dfs_standard_values = pd.concat(dfs_standard_values)

    return dfs_absolute_error, dfs_error_rescaling, dfs_standard_values

def clean_data(maxcut_df):
    """cleans up data and assigns noisy data label to appropiate data,
    also puts converged values in appropiate places. This is just the high
    budget ZNE and Noisy values that converged already to infinity at 10**5."""
    noisy = maxcut_df.query(
        'abs_error > 0  & copies == 1 & nlsp==1 & res_type=="abs_error" & ( type=="VD")'
    )
    noisy["type"] = "noisy"
    extra = maxcut_df.query('Qubits==4&budget==10**12&(type=="VD"|type=="ZNE")')
    extra_vd = maxcut_df.query('budget==10**12& type=="VD" & copies==1')
    extra_noise = maxcut_df.query('budget==10**12& type=="VD" & copies==1')
    extra_vd["budget"] = 10 ** 10
    extra["budget"] = 10 ** 10
    extra_noise["budget"] = 10 ** 9
    return pd.concat([maxcut_df, extra, extra_vd, extra_noise])

def load_multiple_files_budget(
    Q,
    p,
    num_seeds,
    nlsp_list=[1, 2, 3],
    N=10,
    Nts=100,
    max_copies=6,
    tags=[""],
    density_matrices=False,
    shots=[[None]],
    folders=[""],
    train=True,
    budgets=[1],
    train_use=100,
):
    """Loads multiple files and processes all the data through the various techniques, assigns budget as well.
    But this needs to be further filtered.

    Args:
        Q (list): list of qubits
        p (list): depth list, same length as Q
        num_seeds (int): number of seeds considered
        nlsp_list (list, optional): list of noise levels. Defaults to [1,2,3].
        N (int, optional): non clifford gates in simulation. Defaults to 10.
        Nts (int, optional): training set size. Defaults to 100.
        max_copies (int, optional): max number of copies in VD. Defaults to 6.
        tags (list, optional): list of additional tags. Defaults to [''].
        density_matrices (bool, optional): Do you have density matrices?. Defaults to False.
        shots (list[lists], optional): list of lists of shots of finite shot simulations. Defaults to [[None]].
        folder (str, optional): folder to be analyzed. Defaults to ''.
        train (bool, optional): existance of training data. Defaults to True.
        budgets (list): list with same number of entries as shots lists corresponding to relative budget.
        train_use (int): how many trainig sets do you want to use?

    Returns:
        (absolute_error_df, error_rescaling_df, mitigated_values_df) : Various dfs of processed and organized data.
    """

    dfs_error_rescaling = []
    dfs_absolute_error = []
    dfs_standard_values = []
    for tag, folder in zip(tags, folders):
        print(tag)
        for budget_i, budget in enumerate(budgets):
            for qubit_no, depth in zip(Q, p):
                print(f"Qubit: {qubit_no}, depth: {depth}, budget:{budget}")
                # try:
                data_processing = VD_CDR(
                    qubit_no,
                    depth,
                    num_seeds,
                    N,
                    Nts,
                    max_copies,
                    nlsp_list,
                    shots=shots[budget_i],
                    folder=folder,
                    autoprocessing=True,
                    density_matrices=density_matrices,
                    extra_tags=[tag],
                    train=train,
                    budget=budget,
                    train_use=train_use,
                )
                dfs_absolute_error.append(
                    data_processing.abs_error_df.assign(
                        Qubits=qubit_no, depth=depth, budget=budget
                    )
                )
                dfs_error_rescaling.append(
                    data_processing.calculated_vals_df.assign(
                        Qubits=qubit_no, depth=depth, budget=budget
                    )
                )
                dfs_standard_values.append(
                    data_processing.standard_df.assign(
                        Qubits=qubit_no, depth=depth, budget=budget
                    )
                )
    dfs_absolute_error = pd.concat(dfs_absolute_error)
    dfs_error_rescaling = pd.concat(dfs_error_rescaling)
    dfs_standard_values = pd.concat(dfs_standard_values)
    return dfs_absolute_error, dfs_error_rescaling, dfs_standard_values

def filter_budget(df, budgets, training=100, max_copies=6, noise_levels=3):
    """Filters appropiate budget and shots for the technique in question.

    Args:
        df (result_df from load_multiple_files): Appropiate dataframe.
        budgets (list): list of budgets.
        training_use (int): how many training samples are actually used.
        noise_levels (int): maximum number of noise levels considered.
        copies (int): maximum number of copies considered.

    Returns:
        filtered_dataframe: dataframe with correct shot count data for appropiate technique
    """

    filtered_dfs = []
    for budget_i, budget in enumerate(budgets):
        shot_budget = relative_shots(training, noise_levels, max_copies, budget)
        for deets in shot_budget.iterrows():
            copy_no = deets[1][0]
            technique = deets[1][1]
            allowance = deets[1][2]
            if budget == 0:
                df_temp_abs = df.query(f"budget=={budget} & copies == {copy_no}")
            else:
                df_temp_abs = df.query(
                    f'type=="{technique}" & shots == {allowance} &  copies == {copy_no}'
                ).assign(budget=budget)
            filtered_dfs.append(df_temp_abs)
    filtered_dfs = pd.concat(filtered_dfs)

    return filtered_dfs

def load_max_cut_data(qubit_number: int, training_set=100):
    from pathlib import Path

    if Path("./MaxCut_runs/full_data_MC{qubit_number}.pq").is_file():
        Q = pd.read_parquet(f"./MaxCut_runs/full_data_MC{qubit_number}.pq")
    else:
        base_folder = f"./MaxCut_runs/Q{qubit_number}/"
        folders = [base_folder + ""]
        tags = [""]
        Q, _, _ = load_multiple_files_budget(
            [qubit_number],
            [0],
            29,
            nlsp_list=[1, 2, 3],
            N=10,
            Nts=training_set,
            max_copies=6,
            tags=tags,
            density_matrices=False,
            shots=budget_shots,
            folders=folders,
            train=True,
            budgets=[0, 1],
            train_use=100,
        )

        Q = Q.assign(description="3nlsp_full")
        Q.to_parquet(f"./MaxCut_runs/full_data_MC{qubit_number}.pq")
    Q_filtered = (
        filter_budget(
            Q, [0, 10 ** 5, 10 ** 6, 10 ** 7, 10 ** 8, 10 ** 9, 10 ** 10], 100
        )
        .drop(["shots"], axis=1)
        .query("abs_error>0")
    )

    ###
    Q_filtered.loc[Q_filtered["budget"] == 0, "budget"] = 10 ** 12
    ### Only done for plotting purposes, so that infinity is at the end of the plot rather than the start
    return Q_filtered

def figure_5(df, statistic_to_plot="mean"):
    """Plots figure five, which is the performance of the techniques over budget. This is extended in the sense that it returns
    all qubit results in a panel."""
    zero_copy_methods = df.query(
        'abs_error > 0  & copies == 1 & nlsp==1 & description == "3nlsp_full" & res_type=="abs_error" & ( type == "ZNE" | type == "vnCDR")'
    )
    noisy = df.query(
        'abs_error > 0  & copies == 1 & nlsp==1 & description == "3nlsp_full" & res_type=="abs_error" & ( type=="VD")'
    )
    few_copy_methods = df.query(
        'abs_error >  0  & nlsp==1 & copies==2 & description == "3nlsp_full" & res_type=="abs_error" & ( type=="VD")'
    )
    many_copy_methods = df.query(
        'abs_error > 0  &nlsp==1  & copies==4 & description == "3nlsp_full" & res_type=="abs_error" & ( type=="UNITED")'
    )
    noisy["type"] = "noisy"
    plot_df = pd.concat(
        [noisy, zero_copy_methods, few_copy_methods, many_copy_methods],
        axis=0,
        ignore_index=True,
    )
    fig = sns.relplot(
        data=plot_df.reset_index(),
        kind="line",
        x="budget",
        y="abs_error",
        hue="type",
        col="Qubits",
        col_wrap=2,
        estimator=statistic_to_plot,
        markers=True,
        ci=None,
    )
    fig.set(yscale="log", xscale="log")
    fig.set_ylabels(statistic_to_plot + " of absolute error")
    ax = fig.axes[0]
    xticks = ax.get_xticks().tolist()
    for i in range(len(xticks) - 1):
        xticks[i] = rf"$10^{{{i+3}}}$"
    xticks[-3] = r"$\infty$"
    xticks[-4] = r"$\cdots$"
    ax.set_xticklabels(xticks)
    return fig

def figure_4(maxcut_df, statistic_to_plot="mean", like_paper=True):
    """"Plot figure 5 from the paper, which is the absoulte error over qubits at different budgets."""
    if like_paper:
        df = maxcut_df.query("budget>0&budget<10**11&budget!=10**9&budget!=10**7")
    else:  # Basically will show all computed budgets
        df = maxcut_df.query("budget>0&budget<10**11")
    zero_copy_methods = df.query(
        'abs_error > 0  & copies == 1 & nlsp==1 & description == "3nlsp_full" & res_type=="abs_error" & ( type == "ZNE" | type == "vnCDR")'
    )
    noisy = df.query(
        'abs_error > 0  & copies == 1 & nlsp==1 & description == "3nlsp_full" & res_type=="abs_error" & ( type=="VD")'
    )
    few_copy_methods = df.query(
        'abs_error >  0  & nlsp==1 & copies==2 & description == "3nlsp_full" & res_type=="abs_error" & ( type=="VD")'
    )
    many_copy_methods = df.query(
        'abs_error > 0  &nlsp==1  & copies==4& description == "3nlsp_full" & res_type=="abs_error" & ( type=="UNITED")'
    )
    noisy["type"] = "noisy"
    plot_df = pd.concat(
        [noisy, zero_copy_methods, few_copy_methods, many_copy_methods],
        axis=0,
        ignore_index=True,
    )
    fig = sns.relplot(
        data=plot_df.reset_index(),
        kind="line",
        x="Qubits",
        col="budget",
        col_wrap=2,
        y="abs_error",
        hue="type",
        estimator=statistic_to_plot,
        markers=True,
        ci=None,
    )
    fig.set_ylabels(statistic_to_plot + " of absolute error")
    fig.set(yscale="log")
    return fig

def load_all_data():
    if Path("./MaxCut_runs/filtered_df.pq").is_file():
        maxcut_df = pd.read_parquet("./MaxCut_runs/filtered_df.pq")
    else:
        results = {qubit: load_max_cut_data(qubit) for qubit in [4, 6, 8, 10]}
        maxcut_df = pd.concat(results.values())
        maxcut_df = clean_data(maxcut_df)
        maxcut_df.to_parquet("./MaxCut_runs/filtered_df.pq")
    return maxcut_df

def load_unfiltered_data():
    dfs = []
    for i in [4, 6, 8, 10]:
        dfs.append(pd.read_parquet(f"./MaxCut_runs/full_data_MC{i}.pq"))
    return pd.concat(dfs).reset_index()

def load_raw_maxcut_data():
    """Returns a dictionary of the coi data and training data with indices 'coi' and 'train'."""
    import os

    def quick_load(fi, dir_path):
        res = []
        files = []
        for file in os.listdir(dir_path):
            if file.endswith(".pq") and file.startswith(f"pandas_{fi}"):
                res.append(
                    pd.read_parquet(dir_path + file).assign(file=file).assign(data=fi)
                )
                files.append(file)
        res = pd.concat(res)
        res = res.reset_index()
        res = res.reset_index()
        res = res.drop(["result_type"], axis=1)
        res["exact"] = pd.to_numeric(res["exact"])
        res["expectation"] = pd.to_numeric(res["expectation"])
        res["exact_abs"] = np.abs(res["exact"])
        return res

    train = []
    coi = []
    for i in [4, 6, 8, 10]:
        path = f"./MaxCut_runs/Q{i}/"
        train.append(quick_load("train", path))
        coi.append(quick_load("COI", path))
    train = pd.concat(train).reset_index().drop("level_0", axis=1)
    coi = pd.concat(coi).reset_index().drop("level_0", axis=1)
    return {"coi": coi, "train": train}

def figure_7(df, budget=10 ** 10, statistic_to_plot="mean"):
    """Plots figure 7 for any budget"""
    df = df.query(f"budget=={budget}")
    few_copy_methods = df.query(
        'abs_error >  0  & nlsp==1  & description == "3nlsp_full" & res_type=="abs_error" & ( type=="VD")'
    )
    many_copy_methods = df.query(
        'abs_error > 0  &nlsp==1  & description == "3nlsp_full" & res_type=="abs_error" & ( type=="UNITED")'
    )
    plot_df = pd.concat(
        [few_copy_methods, many_copy_methods], axis=0, ignore_index=True,
    )
    fig = sns.relplot(
        data=plot_df.reset_index(),
        kind="line",
        x="copies",
        y="abs_error",
        hue="Qubits",
        style="type",
        estimator=statistic_to_plot,
        ci=None,
    )
    fig.set(yscale="log", title=f"budget {budget}")
    fig.set_ylabels(statistic_to_plot + " of absolute error")
    return fig

def figure_8(dataset):
    """Plots the disctibution of training data and circuit of interest for desired qubit"""
    sns.displot(
        kind="hist",
        data=dataset,
        x="exact",
        col="qubits",
        col_wrap=2,
        bins=25,
        facet_kws=dict(sharey=True),
    ).set(yscale="log")


"""Initialize Flask app."""

from pathlib import Path

from flask import Flask

import capitulo.adapters.repository as repo
from capitulo.adapters.memory_repository import MemoryRepository
from capitulo.adapters import memory_repository, database_repository, repository_populate
from capitulo.adapters.orm import metadata, map_model_to_tables

# imports from SQLAlchemy
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker, clear_mappers
from sqlalchemy.pool import NullPool

def create_app(test_config=None):
    # Create the flask app object
    app = Flask(__name__)

    # Configure the app from configuration-file settings.
    app.config.from_object('config.Config')
    data_path = Path('capitulo') / 'adapters' / 'data'

    if test_config is not None:
        # Load test configuration, and override any configuration settings.
        app.config.from_mapping(test_config)
        data_path = app.config['TEST_DATA_PATH']

    # Here the "magic" of our repository pattern happens. We can easily switch between in memory data and
    # persistent database data storage for our application.

    if app.config['REPOSITORY'] == 'memory':
        # Create the MemoryRepository implementation for a memory-based repository
        repo.repo_instance = memory_repository.MemoryRepository()
        # fill the content of the repository from the provided csv files (has to be done every time we start app)
        database_mode = False
        repository_populate.populate(data_path, repo.repo_instance, database_mode)
    elif app.config['REPOSITORY'] == 'database':
        # Configure database
        database_uri = app.config['SQLALCHEMY_DATABASE_URI']

        # We create a comparatively simple SQLite database, which is based on a single file (see .env for URI)
        database_echo = app.config['SQLALCHEMY_ECHO']
        # Do not change the settings for connect_args and poolclass
        database_engine = create_engine(database_uri, connect_args={"check_same_thread": False}, poolclass=NullPool,
                                        echo=database_echo)

        # Create the database session factory using sessionmaker (this has to be done once in a global manner)
        session_factory = sessionmaker(autocommit=False, autoflush=True, bind=database_engine)
        # Create the SQLAlchemy DatabaseRepository instance for an sqlite3-based repository
        repo.repo_instance = database_repository.SqlAlchemyRepository(session_factory)

        if app.config['TESTING'] == 'True' or len(database_engine.table_names()) == 0:
            print("REPOPULATING DATABASE...")
            # For testing, or first-time use of the web application, reinitialise the database.
            clear_mappers()
            metadata.create_all(database_engine)  # Conditionally create database tables
            for table in reversed(metadata.sorted_tables):  # Remove any data from the tables
                database_engine.execute(table.delete())

            # Generate mappings that map domain model classes to the database tables
            map_model_to_tables()

            database_mode = True
            repository_populate.populate(data_path, repo.repo_instance, database_mode)
            print("REPOPULATING DATABASE... FINISHED")
        else:
            # Solely generate mappings that map domain model classes to the database tables
            map_model_to_tables()

    # Create the MemoryRepository implementation for a memory-based repository.
    #repo.repo_instance = MemoryRepository()
    # fill the content of the repository from the provided csv files
    #populate(data_path, repo.repo_instance)

    # Build the application
    with app.app_context():
        # Register blueprints
        from .home import home
        app.register_blueprint(home.home_blueprint)

        from .about_us import about_us
        app.register_blueprint(about_us.about_us_blueprint)

        from .books import books
        app.register_blueprint(books.books_blueprint)

        from .authentication import authentication
        app.register_blueprint(authentication.authentication_blueprint)

        from .utilities import utilities
        app.register_blueprint(utilities.utilities_blueprint)

        from .reading_list import reading_list
        app.register_blueprint(reading_list.reading_list_blueprint)

        # Register a callback that makes sure that database sessions are associated with http requests
        # We reset the session inside the database repository before a new flask request is generated
        @app.before_request
        def before_flask_http_request_function():
            if isinstance(repo.repo_instance, database_repository.SqlAlchemyRepository):
                repo.repo_instance.reset_session()

        # Register a tear-down method that will be called after each request has been processed
        @app.teardown_appcontext
        def shutdown_session(exception=None):
            if isinstance(repo.repo_instance, database_repository.SqlAlchemyRepository):
                repo.repo_instance.close_session()

    return app


number1 = float(input("Enter the first operand: "))
number2 = float(input("Enter the second operand: "))
calculation_operation = input("Enter a operation('+','-','%','x','/','^') ")

if calculation_operation == "+":
    print(number1+number2)
elif calculation_operation == "-":
    print(number1-number2)
elif calculation_operation == "%":
    print(number1%number2)
elif calculation_operation == "x":
    print(number1*number2)
elif calculation_operation == "/":
    print(number1/number2)
elif calculation_operation == "^":
    print(number1**number2)
else:
    print("I don't understand the command")

#quiz
ans = input("Are you ready to start the the quiz(yes/no)").lower()
score = 0
total_q = 5

if ans == 'yes':

    q1 = input("What is the capital of India :")
    print(q1)
    if q1.lower() == 'new delhi':
        score += 1
        print("Correct")
    else:
        print("Incorrect")

    question2 = input("What is capital of pakistan:")
    print(question2)
    if question2 .lower() == 'islamabad':
        score += 1
        print("Correct")
    else:
        print("Incorrect")

    q3 = input("What is the capital of sri lanka:")
    print(q3)
    if q3.lower() == 'colombo':
        score += 1
        print("Correct")
    else:
        print("Incorrect")

    q4 = input("what is the capital of nepal :")
    print(q4)
    if q4.lower() == 'kathamandu':
        score += 1
        print("Correct")
    else:
        print("Incorrect")

    q5 = input("what is the capital of bhutan :")
    print(q5)
    if q5.lower() == 'thimpu':
        score += 1
        print("Correct")
    else:
        print("Incorrect")

print("your score is", score)

percent = score / total_q * 100

print(percent)

#car game

command = ""
started = False
while command != "quit":
    command = input("> ").lower()
    if command == "start":
        if started:
            print("car is already started")
        else:
            started = True
            print("car started")
    elif command == "stop":
        if not started:
            print("car is already stopped")
        else:
            started =False
            print("car stoped")
    elif command == "help":
        print('''start = to start the car
                 stop = to stop the car
                 quit = to quit the game''')
    elif command == "quit":
        print("game ended")
    else:
        print("I dont't understand the command")

#for loops

for item in range[11]:
    print(item)


# Task
'''
Your local library needs your help! Given the expected and actual return dates for a library book, create a program that calculates the fine (if any). The fee structure is as follows:

>>> If the book is returned on or before the expected return date, no fine will be charged (i.e. fine=0) .
>>> If the book is returned after the expected return day but still within the same calendar month and year as the
    expected return date, fine= 15 Hackos x number of days late.
>>> If the book is returned after the expected return month but still within the same calendar year as the expected
    return date, the fine= 500Hackos x number of days late.
>>> If the book is returned after the calendar year in which it was expected, there is a fixed fine of 10000 Hackos
'''

# Sample Input
'''
STDIN       Function
-----       --------
9 6 2015    day = 9, month = 6, year = 2015 (date returned)
6 6 2015    day = 6, month = 6, year = 2015 (date due)
'''

# Sample Output
'''
45
'''

# Explanation
'''
Given the following return dates:
Returned: D1=9, M1=6, Y1=2015
Due: D2=6, M2=6, Y2=2015

Because Y2==Y1, it is less than a year late.
Because M2==M1, it is less than a month late.
Because D2<D1, it was returned late (but still within the same month and year).

Per the library's fee structure, we know that our fine will be 15 Hackos x (# Days Late). We then print the result of 15 * (D1 - D2) = 15*(9-6) = 45 as our output.
'''

# Code
# Enter your code here. Read input from STDIN.
# Print output to STDOUT
return_date = list(map(int,input().split(' ')))
expected_date = list(map(int,input().split(' ')))

fine = 0

if return_date[2] > expected_date[2]:
    fine = 10000

elif return_date[2] == expected_date[2]:

    if return_date[1] > expected_date[1]:
        fine = (return_date[1] - expected_date[1])*500

    elif return_date[1] == expected_date[1]:
        if return_date[0] > expected_date[0]:
            fine = (return_date[0] - expected_date[0])*15

print(fine)


import numpy as np

# Rounding for each step to help normalize out floating point errors
DECIMAL_PLACES = 3

def to_prey_at_site(arr):
    arr[arr != -1] = 1
    arr[arr == -1] = 0
    return arr

def ipa(initial_proportionality, verbose=False):
    """
    Implementation of the Iterative Preference Averaging (IPA) algorithm
    specified by https://journals.plos.org/plosone/article?id=10.1371/journal.pone.0268520

    Author:
        Chase McManning <cmcmanning@gmail.com>

    Args:
        initial_proportionality (pd.DataFrame): Matrix of estimated within-site preferences
            for available prey. If a particular prey j is not present at site i, use `mat[i, j] = -1`
    """

    total_sites, total_prey = initial_proportionality.shape

    estimated_preference = np.zeros(
        [total_sites, total_prey]
    )

    prey_at_site = to_prey_at_site(initial_proportionality.copy())

    # def proportionality(prey, site):
    #     denom = 0
    #     for j in enumerate(prey):
    #         denom += eaten[j][site] / density[j][site]

    #     return (eaten[j][site] / density[j][site]) / denom

    # We're using a static dataset that is precomputed.
    # Otherwise, this comes from real data for the initial.
    # def initialize_preferences():
    #     for i in range(total_sites):
    #         for j in range(total_prey):
    #             if is_prey_in_site(prey, site):
    #                 estimated_preference[prey][site] = proportionality(prey, site)
    #             else:
    #                 estimated_preference[prey][site] = '-'

    if verbose:
        print('\nInitial proportionality')
        print(initial_proportionality)
        print('\nRow sums')
        print(initial_proportionality.sum(axis=1))
        print('\nPrey at site matrix')
        print(prey_at_site)

    prev_overall_preference = np.array([])

    # Compute initial overall preferences
    e = 1.0 / total_prey
    overall_preference = np.around(
        np.array([e] * total_prey),
        DECIMAL_PLACES
    )

    if verbose:
        print('\nOverall preference p_1')
        print(overall_preference)
        print('\nOverall preference row sum')
        print(overall_preference.sum())

    def scaling_constant(site):
        # Compute c_i for site i in current iteration k
        # Eq(3)
        sum = 0
        for j in range(total_prey):
            # M_j - prey *not* in site
            if prey_at_site[site][j] == 0:
                sum += overall_preference[j]

        return 1 - sum

    def next_mean_estimate(prey):
        # Compute next overall estimate
        # based on the means of the columns of the matrix
        # Returns: p_•j(k+1)
        sum = 0

        # This is the mean of the estimated preference column for the given prey
        for i in range(total_sites):
            sum += estimated_preference[i, prey]

        return sum / float(total_sites)

    def iteration(k):
        nonlocal prev_overall_preference, overall_preference, estimated_preference

        prev_overall_preference = overall_preference.copy()
        estimated_preference = np.around(
            initial_proportionality, DECIMAL_PLACES)

        # Step 3
        c = np.around(
            [scaling_constant(i) for i in range(total_sites)],
            DECIMAL_PLACES
        )

        # Steps 3 & 4
        for i in range(total_sites):
            for j in range(total_prey):
                # Step 3: Rescale by multiplying the constant
                if estimated_preference[i, j] != -1:
                    estimated_preference[i, j] *= c[i]
                else:
                    # Replace missing value with overall preference
                    estimated_preference[i, j] = overall_preference[j]

        estimated_preference = np.around(estimated_preference, DECIMAL_PLACES)

        # Step 5 - estimate new overall preferences
        overall_preference = np.around(
            [next_mean_estimate(j) for j in range(total_prey)],
            DECIMAL_PLACES
        )

        if verbose:
            print(f'\nScaling constant for k={k}')
            print(c)
            print(f'\nEstimated Preference P_{k}')
            print(estimated_preference)
            print('\nRow sums')
            print(estimated_preference.sum(axis=1))
            print(f'\nOverall Preference p_{k+1}')
            print(overall_preference)
            print('\nOverall preference row sum')
            print(overall_preference.sum())

    k = 1
    while True:
        iteration(k)

        diff = abs(prev_overall_preference - overall_preference)

        if verbose:
            print(f'\nDifference between overall preferences')
            print(diff)

        # If we've hit all zeros, stop iteration
        if not np.any(diff > 0.001):
            break

        k += 1

    if verbose:
        print(f'\nFinal Preference found at k={k}')

    return estimated_preference, overall_preference

# Test case - this is the same demonstrative test case as
# the "A method to predict overall food preferences" paper.
if __name__ == '__main__':
    # Going to do a mock initial preference
    # that's normalized to sum each row to 1
    # (this come from the paper). I can build
    # one from our dataset later.
    sample_initial_preferences = np.array([
        [0.27, 0.28, 0.36, 0.09, -1, -1],
        [0.29, 0.12, -1, 0.06, 0.29, 0.24],
        [0.20, 0.10, 0.20, 0.07, 0.23, 0.20],
        [-1, 0.20, 0.31, 0.06, 0.12, 0.31]
    ])

    print(ipa(sample_initial_preferences, verbose=True))

    # Expectation:
    #  Final Preference found at k=4
    # [[0.163 0.169 0.217 0.054 0.184 0.212]
    #  [0.226 0.093 0.222 0.047 0.226 0.187]
    #  [0.2   0.1   0.2   0.07  0.23  0.2  ]
    #  [0.196 0.161 0.249 0.048 0.096 0.249]]


#Kimhaeun
#22100224
#GuessNumbers

import random

def check_list(listname, input_num):
    while input_num in listname:
        print("Duplicate number")
        input_num=int(input("Input a number:"))
    return input_num

c_numList=random.sample(range(0,10),4)

trial=0
u_numList=[]
while c_numList!=u_numList:
    u_numList=[]
    for i in range(4):
        n=int(input("Input a number:"))
        while n not in range(10):
            print("Please input a number from 0 to 9")
            n=int(input("Input a number:"))
        n=check_list(u_numList,n)
        u_numList.append(n)

    strike=0
    ball=0

    for i in range(4):
        for j in range(4):
            if c_numList[i]==u_numList[j]:
                if i==j:
                    strike+=1
                else:
                    ball+=1
    print(strike,"strike,",ball,"ball")
    trial+=1

print("You win! on",trial,"try...")

3주차/성온이 화이팅/코로나 이전/과제_퀴즈_수업내코딩/과제_퀴즈_수업내코딩/HW5_22100224_Kimhaeun/3.GuessNumbers.py


import pytest
from src.generators.player_localization import PlayerLocalization
from src.enums.user_enums import Statuses

import tables

@pytest.mark.parametrize('status', [
    # "ACTIVE",
    # "BANNED",
    # "DELETED",
    # "INACTIVE"
    *Statuses.list()

])
def test_something(status, get_player_generator):
    print(get_player_generator.set_status(status).build())

@pytest.mark.parametrize('balance_value', [
    '100',
    '0',
    '-10',
    'asdd'

])
def test_something_balance(balance_value, get_player_generator):
    print(get_player_generator.set_balance(balance_value).build())

@pytest.mark.parametrize('delete_key', [
    'account_status',
    'balance',
    'localize',
    'avatar'

])
def test_something_delete(delete_key, get_player_generator):
    object_to_send = get_player_generator.build()
    del object_to_send[delete_key]
    print(object_to_send)

def test_something_excange_localize(get_player_generator):
    object_to_send = get_player_generator.update_inner_value(
        'localize', PlayerLocalization('fr_FR').set_number(15).build()
    ).build()
    print(object_to_send)

def test_something_excange_localize_deep_into(get_player_generator):
    object_to_send = get_player_generator.update_inner_value(
        ['localize', 'state', 'country'],
        PlayerLocalization('fr_FR').set_number(15).build()
    ).build()
    print(object_to_send)

@pytest.mark.parametrize('localizations, loc', [
    ('fr', 'fr_FR')
])
def test_something_excange_localizations(get_player_generator, localizations, loc):
    object_to_send = get_player_generator.update_inner_value(
        ['localize', localizations],
        PlayerLocalization(loc).set_number(15).build()
    ).build()
    print(object_to_send)

def test_get_data_fields(get_db_session):
    data = get_db_session.query(tables.Films).first()
    print(data.title)

def test_try_to_delete_something(get_delete_method, get_db_session):
    get_delete_method(get_db_session, tables.ItemType, (tables.ItemType.item_id == 3))

def test_try_to_add_testdata(get_db_session, get_add_method):
    new_item_type = {'item_type': 'new_type'}
    item = tables.ItemType(**new_item_type)
    get_add_method(get_db_session, item)
    print(item.item_id)

def test_try_to_add_testdata2(get_db_session, get_add_method, get_item_type_generator):
    item = tables.ItemType(**get_item_type_generator.build())
    get_add_method(get_db_session, item)
    print(item.item_id)

def test_finally(generate_item_type):
    print(generate_item_type.item_id)


class Solution(object):
    def search(self, nums, target):
        low, high = 0, len(nums)-1
        while low < high:
            mid = (low+high)//2
            if nums[mid] == target:
                return True
            if nums[mid] > nums[high]:
                if nums[mid]>target and nums[low]<=target:
                    high = mid
                else:
                    low = mid + 1
            elif nums[mid] < nums[high]:
                if nums[mid]<target and nums[high] >= target:
                    low = mid+1
                else:
                    high = mid
            else:
                high -= 1
        return low < len(nums) and nums[low] == target


from collections import deque

def bfs(graph, groups, visited, start_node):
    q = deque([(start_node, 0)])

    while len(q) > 0:
        src_node, step = q.pop()
        if src_node not in visited:
            visited.add(src_node)
            groups[step % 2].add(src_node)

            for dst_node in graph[src_node]:
                q.appendleft((dst_node, step + 1))

class Solution:
    def isBipartite(self, graph: List[List[int]]) -> bool:
        if len(graph) == 0: return True
        groups = [set(), set()]
        visited = set()

        for node in range(len(graph)):
            bfs(graph, groups, visited, node)

        for group in groups:
            for src_node in group:
                for dst_node in graph[src_node]:
                    if dst_node in group:
                        return False
        return True


from io import StringIO
import logging
import numpy as np
import serial
from sampling.sampling import Streamer

logger = logging.getLogger(__name__)

class SerialStreamer(Streamer):
    # noinspection SpellCheckingInspection
    def __init__(
        self,
        sampling_rate,
        port=None,
        baudrate=115200,
        bytesize=serial.EIGHTBITS,
        parity=serial.PARITY_NONE,
        stopbits=serial.STOPBITS_ONE,
        timeout=0.2,
        xonxoff=False,
        rtscts=False,
        write_timeout=None,
        dsrdtr=False,
        inter_byte_timeout=None,
        genfromtxt_kws=None,
    ):
        self._serial = serial.Serial(
            port,
            baudrate,
            bytesize,
            parity,
            stopbits,
            timeout,
            xonxoff,
            rtscts,
            write_timeout,
            dsrdtr,
            inter_byte_timeout,
        )
        self._sampling_rate = sampling_rate
        self.__genfromtxt_kws = {} if genfromtxt_kws is None else genfromtxt_kws
        self.__paused = True
        self.start()
        self._remain = ""

    def read(self):
        if not self.__paused:
            n = self._serial.in_waiting
            if not n > 0:
                return self._empty
            # logger.debug(f"serial {self._serial.port} has {n} bytes in waiting")
            lines = self._serial.read(n).decode("ascii")
            lines = self._remain + lines
            if "\n" not in lines:
                self._remain = lines
                return self._empty
            pos2 = lines.rfind("\n")
            # noinspection PyTypeChecker
            out = np.genfromtxt(StringIO(lines[:pos2]), **self.__genfromtxt_kws)
            out = np.atleast_2d(out).T
            self._remain = lines[pos2 + 1 :]
            return out
        else:
            return self._empty

    def start(self):
        self._serial.reset_output_buffer()
        self._serial.reset_input_buffer()
        for _ in range(5):
            # discards a few lines to make sure the buffer does not contain partial lines
            self._serial.readline()
        self.__paused = False
        logger.info(f"Started Reading from serial port {self._serial}")

    def stop(self):
        self.__paused = True


"The Console Layout"
import re

import tkinter as tk

from layouts.layout_base import Fore, Output, get_rid_of_coloring

def _add_color(message):
    compile_header_regex = re.compile(
        r"Compiling fileset \".*\" in \".*\" for \".*\""
    )
    no_color_stripped_message = get_rid_of_coloring(message).strip()
    if no_color_stripped_message.startswith("###"):
        message = message.replace(Fore.RESET, '')
        message = f"{Fore.ORANGE}{message}{Fore.RESET}"
    elif no_color_stripped_message.startswith("compiling"):
        message = message.replace(Fore.RESET, '')
        message = f"{Fore.GREEN}{message}{Fore.RESET}"
    elif compile_header_regex.match(no_color_stripped_message):
        message = message.replace(Fore.RESET, '')
        message = f"{Fore.BOLD_WHITE}{message}{Fore.RESET}"
    return message

class ConsoleLayout:
    "The Console Frame"

    def __init__(self, context):
        self.text_widget = None
        self._output = None
        self._context = context

    def clear_console(self):
        "clears the console"
        self.text_widget.config(state=tk.NORMAL)
        self.text_widget.delete('1.0', tk.END)
        self.text_widget.config(state=tk.DISABLED)

    def render(self, parent, **grid_options):
        "Renders the frame"
        console_frame = tk.Frame(parent)
        console_frame.grid(**grid_options)
        console_frame.rowconfigure(0, weight=1)
        console_frame.columnconfigure(0, weight=1)

        vertical_scrool_bar = tk.Scrollbar(console_frame)
        self.text_widget = tk.Text(
            console_frame,
            yscrollcommand=vertical_scrool_bar.set
        )

        vertical_scrool_bar.config(command=self.text_widget.yview)

        self.text_widget.grid(
            row=0, column=0,
            sticky=tk.NSEW
        )
        vertical_scrool_bar.grid(row=0, column=1, sticky=tk.N+tk.S+tk.W)

        self._output = Output(self.text_widget, apply=_add_color)

        return console_frame

    @property
    def file(self):
        "returns the file where the output goes"
        return self._output

    def __getattr__(self, key):
        try:
            return self.__getattribute__(key)
        except AttributeError:
            return getattr(self._output, key)


# Number 1

class Rectangle:

    def __init__(self, a, b):

        self.square = Rectangle.square_rectangle(a, b)

    @staticmethod
    def square_rectangle(a, b):
        return a*b

p1 = Rectangle(3, 5)
p2 = Rectangle(4, 9)

print(p1.square, p2.square)

# Number 2

class Dog:
    count = 0

    def __new__(cls, *args, **kwargs):
        if Dog.count < 5:
            Dog.count += 1
            return super(Dog, cls).__new__(cls)

    def __init__(self, name, age, breed):

        self.name = name
        self.age = age
        self.breed = breed

a1 = Dog('a1', 1, 'rr')
a2 = Dog('a2', 2, 'rr')
a3 = Dog('a3', 3, 'rr')
a4 = Dog('a4', 4, 'rr')
a5 = Dog('a5', 5, 'rr')
a6 = Dog('a5', 6, 'rr')

print(id(a1), id(a2), id(a3), id(a4), id(a5), id(a6))
print(a1.name, a2.name, a3.name, a4.name)


from mpl_toolkits import mplot3d
import numpy as np
import matplotlib.pyplot as plt
import math
import matplotlib.animation as animation
import sys
# https://en.wikipedia.org/wiki/Two-body_problem
# https://towardsdatascience.com/modelling-the-three-body-problem-in-classical-mechanics-using-python-9dc270ad7767
# https://evgenii.com/blog/two-body-problem-simulator/

x1 = []
x2 = []
y1 = []
y2 = []
z1 = []
z2 = []
t = []
R = []
r = []

# default parameters, overwritten by config.ini
PARAMETER_m1 = 1
PARAMETER_m2 = 0.5
PARAMETER_step = 0.1
PARAMETER_points = 1000

G = 6.67408e-11 # N-m2/kg2
m_nd = 1.989e+30 #kg #mass of the sun
r_nd = 5.326e+12 #m #distance between stars in Alpha Centauri
v_nd = 30000 #m/s #relative velocity of earth around the sun
t_nd = 79.91*365*24*3600*0.51 #s #orbital period of Alpha Centauri#Net constants

FACTOR_K1 = 1#G*t_nd*m_nd/(r_nd**2*v_nd)     uncomment for ex2/sci
FACTOR_K2 = 1#v_nd*t_nd/r_nd                 uncomment for ex2/sci
ZERO_R = True                              #R is zeroed

def init(pnumberofvalues):
    global x1,x2,y1,y2,z1,z2,t,R,r
    t = np.zeros(pnumberofvalues)
    x1 = np.zeros([pnumberofvalues,2])
    x2 = np.zeros([pnumberofvalues,2])
    y1 = np.zeros([pnumberofvalues,2])
    y2 = np.zeros([pnumberofvalues,2])
    z1 = np.zeros([pnumberofvalues,2])
    z2 = np.zeros([pnumberofvalues,2])

    R = np.zeros([pnumberofvalues,3])
    r = np.zeros([pnumberofvalues,3])

# Finds value of y for a given t using step size h
# and initial value y0 at x0.
'''
k1 = h * dydt(t0, y)
k2 = h * dydt(t0 + 0.5 * h, y + 0.5 * k1)
k3 = h * dydt(t0 + 0.5 * h, y + 0.5 * k2)
k4 = h * dydt(t0 + h, y + k3)

y[i] = y[i-1] + (1.0 / 6.0)*(k1 + 2 * k2 + 2 * k3 + k4)
'''
def twobodiesExample2(pnumberofpoints, h, K1, K2, m1, m2):
    global x1, x2, y1, y2, z1, z2
    import scipy as sci#Import matplotlib and associated modules for 3D and animations
    # Count number of iterations using step size or
    # step height h
    #Define masses
    t=[]
    r=[]
    R=[]
    r1=[-0.5,0,0] #m
    r2=[0.5,0,0] #m#Convert pos vectors to arrays
    r1=np.array(r1,dtype="float64")
    r2=np.array(r2,dtype="float64")#Find Centre of Mass
    r_com=(m1*r1+m2*r2)/(m1+m2)#Define initial velocities
    v1=[0.01,0.01,0] #m/s
    v2=[-0.05,0,-0.1] #m/s#Convert velocity vectors to arrays
    v1=np.array(v1,dtype="float64")
    v2=np.array(v2,dtype="float64")#Find velocity of COM
    v_com=(m1*v1+m2*v2)/(m1+m2)

    #Package initial parameters
    init_params=np.array([r1,r2,v1,v2]) #create array of initial params
    init_params=init_params.flatten() #flatten array to make it 1D
    time_span=np.linspace(0,1,pnumberofpoints) #8 orbital periods and 500 points#Run the ODE solver
    import scipy.integrate

    #A function defining the equations of motion
    def TwoBodyEquations(w,t,G,m1,m2,K1,K2):
        r1=w[:3]
        r2=w[3:6]
        v1=w[6:9]
        v2=w[9:12]
        r=sci.linalg.norm(r2-r1) #Calculate magnitude or norm of vector
        dv1bydt=K1*m2*(r2-r1)/r**3
        dv2bydt=K1*m1*(r1-r2)/r**3
        dr1bydt=K2*v1
        dr2bydt=K2*v2
        r_derivs=np.concatenate((dr1bydt,dr2bydt))
        derivs=np.concatenate((r_derivs,dv1bydt,dv2bydt))
        return derivs

    two_body_sol=sci.integrate.odeint(TwoBodyEquations,init_params,time_span,args=(G,m1,m2,K1,K2))

    r1_sol=two_body_sol[:,:3]
    r2_sol=two_body_sol[:,3:6]

    init(pnumberofpoints)

    for idx in range(len(x1)):
        x1[idx][0] = r1_sol[idx,0]
        y1[idx][0] = r1_sol[idx,1]
        z1[idx][0] = r1_sol[idx,2]
        x2[idx][0] = r2_sol[idx,0]
        y2[idx][0] = r2_sol[idx,1]
        z2[idx][0] = r2_sol[idx,2]
    '''
    fig=plt.figure(figsize=(15,15))#Create 3D axes
    ax=fig.add_subplot(111,projection="3d")#Plot the orbits
    ax.plot(r1_sol[:,0],r1_sol[:,1],r1_sol[:,2],color="darkblue")
    ax.plot(r2_sol[:,0],r2_sol[:,1],r2_sol[:,2],color="tab:red")#Plot the final positions of the stars
    ax.scatter(r1_sol[-1,0],r1_sol[-1,1],r1_sol[-1,2],color="darkblue",marker="o",s=100,label="Alpha Centauri A")
    ax.scatter(r2_sol[-1,0],r2_sol[-1,1],r2_sol[-1,2],color="tab:red",marker="o",s=100,label="Alpha Centauri B")#Add a few more bells and whistles
    ax.set_xlabel("x-coordinate",fontsize=14)
    ax.set_ylabel("y-coordinate",fontsize=14)
    ax.set_zlabel("z-coordinate",fontsize=14)
    ax.set_title("Visualization of orbits of stars in a two-body system\n",fontsize=14)
    ax.legend(loc="upper left",fontsize=14)
    plt.show()
    '''

def twobodiesExample1(pnumberofpoints, h, K1, K2, m1, m2):
    global r,R,x1,x2,y1,y2,z1,z2,t
    # Count number of iterations using step size or
    # step height h
    t0 = 0

    init(pnumberofpoints)

    x1[0][0] = 1
    y1[0][0] = 0
    z1[0][0] = 0
    x2[0][0] = 0
    y2[0][0] = 0
    z2[0][0] = 0

    x1[0][1] = 0
    y1[0][1] = 0
    z1[0][1] = 0
    x2[0][1] = 0
    y2[0][1] = 1.59687
    z2[0][1] = 0

    r[0][0] = (x2[0][0]-x1[0][0])
    r[0][1] = (y2[0][0]-y1[0][0])
    r[0][2] = (z2[0][0]-z1[0][0])

    R[0][0]=(m1*x1[0][0]+m2*x2[0][0])/(m1+m2)   # TODO
    R[0][1]=(m1*y1[0][0]+m2*y2[0][0])/(m1+m2)   # TODO
    R[0][2]=(m1*z1[0][0]+m2*z2[0][0])/(m1+m2)   # TODO

    a = [h/2.0, h/2.0, h, 0]
    b = [h/6.0, h/3.0, h/3.0, h/6.0]

    def deriveVelocityAndAcceleration(px1,py1,pz1,px2,py2,pz2,m1,m2):
        global K1, K2
        rnormed = math.sqrt((px1[0]-px2[0])**2 + (py1[0]-py2[0])**2 + (pz1[0]-pz2[0])**2)
        dx1 = [0,0]
        dy1 = [0,0]
        dz1 = [0,0]

        dx2 = [0,0]
        dy2 = [0,0]
        dz2 = [0,0]

        dx1[0] = px1[1]
        dy1[0] = py1[1]
        dz1[0] = pz1[1]

        dx2[0] = px2[1]
        dy2[0] = py2[1]
        dz2[0] = pz2[1]

        dx1[1] = (m2)  * (px2[0]-px1[0])/ (rnormed**3)
        dy1[1] = (m2) * (py2[0]-py1[0])/ (rnormed**3)
        dz1[1] = (m1) * (pz2[0]-pz1[0]) / (rnormed**3)

        dx2[1] = (m1) * (px1[0]-px2[0]) / (rnormed**3)
        dy2[1] = (m1) * (py1[0]-py2[0]) / (rnormed**3)
        dz2[1] = (m2) * (pz1[0]-pz2[0]) / (rnormed**3)
        return dx1,dy1,dz1,dx2,dy2,dz2

    for i in range(1, len(t)):
        xn1 = np.zeros(2)     # Position and velocity
        xn2 = np.zeros(2)
        yn1 = np.zeros(2)
        yn2 = np.zeros(2)
        zn1 = np.zeros(2)
        zn2 = np.zeros(2)

        # Runge-Kutta
        xn1[0] = x1[i-1][0]
        xn1[1] = x1[i-1][1]

        xn2[0] = x2[i-1][0]
        xn2[1] = x2[i-1][1]

        yn1[0] = y1[i-1][0]
        yn1[1] = y1[i-1][1]

        yn2[0] = y2[i-1][0]
        yn2[1] = y2[i-1][1]

        zn1[0] = z1[i-1][0]
        zn1[1] = z1[i-1][1]

        zn2[0] = z2[i-1][0]
        zn2[1] = z2[i-1][1]

        #vars
        xvar1 = [0,0]
        yvar1 = [0,0]
        zvar1 = [0,0]

        xvar2 = [0,0]
        yvar2 = [0,0]
        zvar2 = [0,0]

        xvar1[0] = xn1[0]
        yvar1[0] = yn1[0]
        zvar1[0] = zn1[0]

        xvar1[1] = xn1[1]
        yvar1[1] = yn1[1]
        zvar1[1] = zn1[1]

        xvar2[0] = xn2[0]
        yvar2[0] = yn2[0]
        zvar2[0] = zn2[0]

        xvar2[1] = xn2[1]
        yvar2[1] = yn2[1]
        zvar2[1] = zn2[1]

        #k
        kx1 = [0,0]
        kx2 = [0,0]
        ky1 = [0,0]
        ky2 = [0,0]
        kz1 = [0,0]
        kz2 = [0,0]

        for idx in range(4):

            dxvar1,dyvar1,dzvar1, dxvar2,dyvar2,dzvar2 = deriveVelocityAndAcceleration(xvar1,yvar1,zvar1,xvar2,yvar2,zvar2,m1, m2)

            dxvar1[0] = K2*dxvar1[0]
            dyvar1[0] = K2*dyvar1[0]
            dzvar1[0] = K2*dzvar1[0]

            dxvar1[1] = K1*dxvar1[1]
            dyvar1[1] = K1*dyvar1[1]
            dzvar1[1] = K1*dzvar1[1]

            kx1[0] = kx1[0] + dxvar1[0]*b[idx]
            ky1[0] = ky1[0] + dyvar1[0]*b[idx]
            kz1[0] = kz1[0] + dzvar1[0]*b[idx]
            kx1[1] = kx1[1] + dxvar1[1]*b[idx]
            ky1[1] = ky1[1] + dyvar1[1]*b[idx]
            kz1[1] = kz1[1] + dzvar1[1]*b[idx]

            kx2[0] = kx2[0] + dxvar2[0]*b[idx]
            ky2[0] = ky2[0] + dyvar2[0]*b[idx]
            kz2[0] = kz2[0] + dzvar2[0]*b[idx]
            kx2[1] = kx2[1] + dxvar2[1]*b[idx]
            ky2[1] = ky2[1] + dyvar2[1]*b[idx]
            kz2[1] = kz2[1] + dzvar2[1]*b[idx]

            # next step
            xvar1[0] = xn1[0]+(dxvar1[0]* a[idx])
            xvar1[1] = xn1[1]+(dxvar1[1] * a[idx])

            yvar1[0] = yn1[0]+(dyvar1[0]* a[idx])
            yvar1[1] = yn1[1]+(dyvar1[1] * a[idx])

            zvar1[0] = zn1[0]+(dzvar1[0]  * a[idx])
            zvar1[1] = zn1[1]+(dzvar1[1] * a[idx])

            xvar2[0] = xn2[0]+(dxvar2[0]* a[idx])
            xvar2[1] = xn2[1]+(dxvar2[1] * a[idx])

            yvar2[0] = yn2[0]+(dyvar2[0]* a[idx])
            yvar2[1] = yn2[1]+(dyvar2[1] * a[idx])

            zvar2[0] = zn2[0]+(dzvar2[0]  * a[idx])
            zvar2[1] = zn2[1]+(dzvar2[1] * a[idx])
            #print(idx)
            #print("-------->  ku::("+str(kx1))
            #print("-------->  ku::("+str(ky1))
            #print("-------->  ku::("+str(kz1))
            #print("-------->  ku::("+str(kx2))
            #print("-------->  ku::("+str(ky2))
            #print("-------->  ku::("+str(kz2))
            #print(str(idx)+")x ---> "+str(xvar1[0] )+" "+str(dxvar1[0]) )

        x1[i][0]  = xn1[0]  + kx1[0]
        y1[i][0]  = yn1[0]  + ky1[0]
        z1[i][0]  = zn1[0]  + kz1[0]

        x2[i][0]  = xn2[0]  + kx2[0]
        y2[i][0]  = yn2[0]  + ky2[0]
        z2[i][0]  = zn2[0]  + kz2[0]

        x1[i][1]  = xn1[1]  + kx1[1]
        y1[i][1]  = yn1[1]  + ky1[1]
        z1[i][1]  = zn1[1]  + kz1[1]

        x2[i][1]  = xn2[1]  + kx2[1]
        y2[i][1]  = yn2[1]  + ky2[1]
        z2[i][1]  = zn2[1]  + kz2[1]

        print(str(i)+" -----------------------------")
        print("u::"+str(x1[i]))
        print("u::"+str(y1[i]))
        print("u::"+str(z1[i]))
        print("u::"+str(x2[i]))
        print("u::"+str(y2[i]))
        print("u::"+str(z2[i]))
        print("----------------------------------")

        R[i][0]=(m1*x1[i][0]+m2*x2[i][0])/(m1+m2)   # TODO
        R[i][1]=(m1*y1[i][0]+m2*y2[i][0])/(m1+m2)   # TODO
        R[i][2]=(m1*z1[i][0]+m2*z2[i][0])/(m1+m2)   # TODO

        t0 = t0 + h
        t[i] = t0

        r[i][0] = (x2[i][0]-x1[i][0])
        r[i][1] = (y2[i][0]-y1[i][0])
        r[i][2] = (z2[i][0]-z1[i][0]) #

def twobodiesExample0(pnumberofpoints, h, K1, K2, m1, m2):
    global r, t, R
    # Count number of iterations using step size or
    # step height h

    init(pnumberofpoints)
    def deriveVelocityAndAcceleration(x1,y1,z1,m1, m2):
        rr = math.sqrt(x1[0]**2 + y1[0]**2)# + z1[0]**2)
        dx1 = [0,0]
        dy1 = [0,0]
        dz1 = [0,0]

        dx1[0] = x1[1]
        dy1[0] = y1[1]
        dz1[0] = z1[1]

        dx1[1] = (-(1+m2)* x1[0]) / (rr**3)
        dy1[1] = (-(1+m2) * y1[0]) / (rr**3)
        dz1[1] = (-(1+m2) * z1[0]) / (rr**3)
        return dx1,dy1,dz1

    t0 = 0
    rx1 = [1,0]
    ry1 = [0, 1.59687]
    rz1 = [0,0]

    r[0][0] = rx1[0]
    r[0][1] = ry1[0]
    r[0][2] = rz1[0]

    a = [h/2.0, h/2.0, h, 0.0]
    b = [h/6.0, h/3.0, h/3.0, h/6.0]
    for i in range(1,len(t)):
        # Runge-Kutta
        xn1 = [0,0]
        yn1 = [0,0]
        zn1 = [0,0]

        xn1[0] = rx1[0]
        xn1[1] = rx1[1]

        yn1[0] = ry1[0]
        yn1[1] = ry1[1]

        zn1[0] = rz1[0]
        zn1[1] = rz1[1]

        #print("####"+str(i)+" x:"+str(xn1)+" y:"+str(yn1))
        kx1 = [0,0]
        ky1 = [0,0]
        kz1 = [0,0]

        xvar1 = xn1[:]
        yvar1 = yn1[:]
        zvar1 = zn1[:]

        for idx in range(4):

            #print(str(xn1)+" "+str(yn1))
            dx1,dy1,dz1 = deriveVelocityAndAcceleration(xvar1,yvar1,zvar1,m1, m2)

            kx1[0] = kx1[0] + (K2*dx1[0]*b[idx])
            ky1[0] = ky1[0] + (K2*dy1[0]*b[idx])
            kz1[0] = kz1[0] + (K2*dz1[0]*b[idx])

            kx1[1] = kx1[1] + (K1*dx1[1]*b[idx])
            ky1[1] = ky1[1] + (K1*dy1[1]*b[idx])
            kz1[1] = kz1[1] + (K1*dz1[1]*b[idx])

            # next step
            xvar1[0] = xn1[0]+(K2*dx1[0]  * a[idx])
            yvar1[0] = yn1[0]+(K2*dy1[0]  * a[idx])
            zvar1[0] = zn1[0]+(K2*dz1[0]  * a[idx])

            xvar1[1] = xn1[1]+(K1*dx1[1]  * a[idx])
            yvar1[1] = yn1[1]+(K1*dy1[1]  * a[idx])
            zvar1[1] = zn1[1]+(K1*dz1[1]  * a[idx])

            #print("-------->("+str(idx)+")")
            #print("-------->  u ::("+str(xn1))
            #print("-------->  u ::("+str(xvar1[0])+"\t"+ str(yvar1[0])+"\t"+str(xvar1[1])+"\t"+str(yvar1[1]))
            #print("-------->  du::("+str(dx1[0])+"\t"+ str(dy1[0])+"\t"+str(dx1[1])+"\t"+str(dy1[1]))
            #print("-------->  ut::("+str(kx1[0])+"\t"+ str(ky1[0])+"\t"+str(kx1[1])+"\t"+str(ky1[1]))

        #print("->kx:"+str(kx1))
        #print("->ky:"+str(kx1))
        rx1[0]  = xn1[0]  + kx1[0]
        ry1[0]  = yn1[0]  + ky1[0]
        rz1[0]  = zn1[0]  + kz1[0]

        rx1[1]  = xn1[1]  + kx1[1]
        ry1[1]  = yn1[1]  + ky1[1]
        rz1[1]  = zn1[1]  + kz1[1]

        r[i][0] = rx1[0]
        r[i][1] = ry1[0]
        r[i][2] = rz1[0]

        t0 = t0 + h
        t[i] = t0

def writeData(path, typeofdata):
    global ZERO_R, PARAMETER_m1,PARAMETER_m2, t, r, R
    print("## %d values generated"%(len(t)))
    f = open(path+"data.out","w+")

    tstring = "t ="

    f.write("m1 = %s\n"%(PARAMETER_m1))
    f.write("m2 = %s\n"%(PARAMETER_m2))

    if typeofdata == 0:
        x1string = "x1 ="
        y1string = "y1 ="
        z1string = "z1 ="

        x2string = "x2 ="
        y2string = "y2 ="
        z2string = "z2 ="

        for i in range(len(t)):
            tstring =  tstring+" "+str(t[i])
            x1string = x1string+" "+str(x1[i][0])
            y1string = y1string+" "+str(y1[i][0])
            z1string = z1string+" "+str(z1[i][0])
            x2string = x2string+" "+str(x2[i][0])
            y2string = y2string+" "+str(y2[i][0])
            z2string = z2string+" "+str(z2[i][0])
        f.write(tstring+"\n")
        f.write (x1string+"\n")
        f.write (y1string+"\n")
        f.write (z1string+"\n")
        f.write (x2string+"\n")
        f.write (y2string+"\n")
        f.write (z2string+"\n")
    elif typeofdata == 1:
        rxstring = "rx ="
        rystring = "ry ="
        rzstring = "rz ="
        Rxstring = "Rx ="
        Rystring = "Ry ="
        Rzstring = "Rz ="
        for i in range(len(t)):
            tstring =  tstring+" "+str(t[i])
            rxstring = rxstring+" "+str(r[i][0])
            rystring = rystring+" "+str(r[i][1])
            rzstring = rzstring+" "+str(r[i][2])

            if ZERO_R:
                Rxstring = Rxstring+" 0"
                Rystring = Rystring+" 0"
                Rzstring = Rzstring+" 0"
            else:
                Rxstring = Rxstring+" "+str(R[i][0])
                Rystring = Rystring+" "+str(R[i][1])
                Rzstring = Rzstring+" "+str(R[i][2])

        f.write (tstring+"\n")
        f.write (rxstring+"\n")
        f.write (rystring+"\n")
        f.write (rzstring+"\n")

        f.write (Rxstring+"\n")
        f.write (Rystring+"\n")
        f.write (Rzstring+"\n")

    f.close()

def readInputData(path):
    global PARAMETER_m1, PARAMETER_m2, PARAMETER_step, PARAMETER_points

    try:
        f = open(path+"config.ini","r")
        data = f.readlines()
        f.close()
        for line in data:
            if line[0] == "#":
                continue

            idx = line.index(":")
            param = line[0:idx]

            if idx != -1:
                if param == "m1":
                    PARAMETER_m1 = float(line[idx+1:].strip())
                elif param == "m2":
                    PARAMETER_m2 = float(line[idx+1:].strip())
                elif param == "step":
                    PARAMETER_step = float(line[idx+1:].strip())
                elif param == "points":
                    PARAMETER_points = int(line[idx+1:].strip())
    except:
        print("config.ini couldn't be interpreted, using default parameters")

if __name__ == "__main__":
    typer = 1
    typex = 0
    path = ""

    if len(sys.argv) > 1:

        if len(sys.argv) == 3:
            path = sys.argv[2]+"/"

        readInputData(path)
        if sys.argv[1] == "-ex0":
            twobodiesExample0(PARAMETER_points, PARAMETER_step, FACTOR_K1, FACTOR_K2, PARAMETER_m1, PARAMETER_m2)
            writeData(path,typer)
        elif sys.argv[1] == "-ex1":
            twobodiesExample1(PARAMETER_points, PARAMETER_step, FACTOR_K1, FACTOR_K2, PARAMETER_m1, PARAMETER_m2)
            writeData(path,typer)
        elif sys.argv[1] == "-ex2":
            twobodiesExample2(PARAMETER_points, PARAMETER_step, FACTOR_K1, FACTOR_K2, PARAMETER_m1, PARAMETER_m2)
            writeData(path, typex)
    else:
        print("# no action")


from skimage import data, color, io
from matplotlib import pyplot as plt
import numpy as np
import math

image = io.imread('test.png')
r = image[:, :, 0]
g = image[:, :, 1]
b = image[:, :, 2]
# RGB颜色空间中的分割
# 选择样本区域
r_template = r[128:255, 85:169]
# 计算该区域的彩色点的平均向量a的红色分量
r_template_u = np.mean(r_template)
# 计算样本点红色分量的标准差
r_template_d = 0.0
for i in range(r_template.shape[0]):
    for j in range(r_template.shape[1]):
        r_template_d = r_template_d + (r_template[i, j] - r_template_u) * (r_template[i, j] - r_template_u)

r_template_d = math.sqrt(r_template_d / r_template.shape[0] / r_template.shape[1])
# 寻找符合条件的点，r_cut为红色分割图像
r_cut = np.zeros(r.shape, dtype='uint8')
for i in range(r.shape[0]):
    for j in range(r.shape[1]):
        if r[i, j] >= (r_template_u - 1.25 * r_template_d) and r[i, j] <= (r_template_u + 1.25 * r_template_d):
            r_cut[i, j] = 1
# image_cut为根据红色分割后的RGB图像
image_cut = np.zeros(image.shape, dtype='uint8')
for i in range(r.shape[0]):
    for j in range(r.shape[1]):
        if r_cut[i, j] == 1:
            image_cut[i, j, :] = image[i, j, :]

plt.figure()
plt.axis('off')
plt.imshow(image)  # 显示原始图像

plt.figure()
plt.axis('off')
plt.imshow(r)  # 显示R图像

plt.figure()
plt.axis('off')
plt.imshow(g)  # 显示G图像

plt.figure()
plt.axis('off')
plt.imshow(b)  # 显示B图像

plt.figure()
plt.axis('off')
plt.imshow(r_cut)  # 显示红色分割图像图像

plt.figure()
plt.axis('off')
plt.imshow(image_cut)  # 显示分割后的RGB图像

plt.show()


# 백준 4375번 1
# SILVER 3
# 알고리즘 분류 : 수학, 브루트포스 알고리즘, 정수론
while True :
    try :
        n = int(input())
        num = 1
        while True :
            if num%n == 0 :
                print(len(str(num)))
                break
            num = num*10 + 1
    except :
        break


"""bbs URL Configuration

The `urlpatterns` list routes URLs to views. For more information please see:
    https://docs.djangoproject.com/en/4.1/topics/http/urls/
Examples:
Function views
    1. Add an import:  from my_app import views
    2. Add a URL to urlpatterns:  path('', views.home, name='home')
Class-based views
    1. Add an import:  from other_app.views import Home
    2. Add a URL to urlpatterns:  path('', Home.as_view(), name='home')
Including another URLconf
    1. Import the include() function: from django.urls import include, path
    2. Add a URL to urlpatterns:  path('blog/', include('blog.urls'))
"""
from django.urls import re_path as url
from django.views.static import serve
from django.contrib import admin
from django.urls import path

from bbs import settings
from app import views

urlpatterns = [
    #后台管理
    url(r'^admin/', admin.site.urls),
    #暴露后端用户数据文件夹
    url(r'^media/(?P<path>.*)',serve,{'document_root':settings.MEDIA_ROOT}),

    # 院庆日程
    url(r'^schedule/', views.schedule,name='bbs_home'),
    #首页
    # url(r'^$', views.bbs_home,name='home'),
    url(r'^bbs/home/', views.bbs_home,name='bbs_home'),

    # 注册
    url(r'^bbs/register/', views.bbs_register,name='bbs_register'),
    # 获取图片验证码
    url(r'^bbs/get_code/', views.bbs_get_code,name='bbs_get_code'),
    # 登陆
    url(r'^bbs/login/', views.bbs_login,name='bbs_login'),
    # 获取邮箱验证码
    url(r'^bbs/get_register_code/', views.bbs_register_email,name='bbs_register_email'),
    # 注销
    url(r'^bbs/logout/', views.bbs_logout,name='bbs_logout'),
    # 获取用户头像
    url(r'^bbs/get_avatar/', views.bbs_get_avatar,name='bbs_get_avatar'),

     # 文章详情
    # url(r'^bbs/article/',views.bbs_article_detail),
    url(r'^bbs/article/(?P<article_id>\d+)/',views.article_detail),
    # 我的帖子
    url(r'^bbs/my_site/',views.bbs_my_site,name='bbs_my_site'),
    # 点赞
    url(r'^bbs/like/',views.bbs_like),
    # 评论
    url(r'^bbs/comment/', views.bbs_comment,name='bbs_comment'),
    # 删除文章
    url(r'^bbs/delete_article/', views.bbs_delete_article,name='bbs_delete_article'),
    # 添加文章
    url(r'^bbs/add_article/', views.bbs_add_article,name='bbs_add_article'),
    # 我的消息
    url(r'^bbs/new_comment/', views.comment_to_me,name='comment_to_me'),

    url(r'^bbs/add_myclass/',views.add_myclass,name='bbs_add_myclass'),
    url(r'^bbs/search_class/',views.search_class,name='bbs_search_class'),
    url(r'^bbs/AI_PIL/', views.AI_PIL, name='bbs_AI_PIL'),
    url(r'^bbs/new_comment/', views.comment_to_me, name='comment_to_me'),

    url(r'^bbs/person_msg/',views.person_msg,name='person_msg'),
    #修改头像
    url(r'^bbs/set_avatar/',views.set_avatar,name='set_avatar'),

    url(r'^bbs/send_message/', views.send_message, name='send_message'),#接口 实现发送私信
    url(r'^bbs/my_message/', views.my_message, name='my_message'),#接口实现我的私信
    #私信详情的url请记得放到最后面
    url(r'^bbs/message_detail/(?P<username>\w+)/',views.message_Detail),# 实现私信详情

]


#!/usr/bin/env python3
"""
Function that creates the config file for running AQM.
"""

import os
import sys
import argparse
from textwrap import dedent
import tempfile

from python_utils import (
    import_vars,
    print_input_args,
    str_to_type,
    print_info_msg,
    cfg_to_yaml_str,
    load_shell_config,
    flatten_dict
)

# These come from ush/python_utils/workflow-tools
from scripts.templater import set_template

def create_aqm_rc_file(cdate, run_dir, init_concentrations):
    """ Creates an aqm.rc file in the specified run directory

    Args:
        cdate: cycle date
        run_dir: run directory
        init_concentrations
    Returns:
        Boolean
    """

    print_input_args(locals())

    #import all environment variables
    import_vars()
    #pylint: disable=undefined-variable

    #
    #-----------------------------------------------------------------------
    #
    # Create the aqm.rc file in the specified run directory.
    #
    #-----------------------------------------------------------------------
    #
    print_info_msg(f'''
        Creating the aqm.rc file (\"{AQM_RC_FN}\") in the specified
        run directory (run_dir):
          run_dir = \"{run_dir}\"''', verbose=VERBOSE)
    #
    # Set output file path
    #
    aqm_rc_fp=os.path.join(run_dir, AQM_RC_FN)
    #
    # Extract from cdate the starting year, month, and day of the forecast.
    #
    yyyymmdd=cdate.strftime('%Y%m%d')
    mm=f"{cdate.month:02d}" # pylint: disable=invalid-name
    hh=f"{cdate.hour:02d}" # pylint: disable=invalid-name
    #
    # Set parameters in the aqm.rc file.
    #
    aqm_rc_bio_file_fp=os.path.join(DCOMINbio, AQM_BIO_FILE)

    # Fire config
    aqm_rc_fire_file_fp=os.path.join(
        COMIN,
        "FIRE_EMISSION",
        f"{AQM_FIRE_FILE_PREFIX}_{yyyymmdd}_t{hh}z{AQM_FIRE_FILE_SUFFIX}"
        )

    # Dust config
    aqm_rc_dust_file_fp=os.path.join(
            DCOMINdust,
            f"{AQM_DUST_FILE_PREFIX}_{PREDEF_GRID_NAME}{AQM_DUST_FILE_SUFFIX}",
            )

    # Canopy config
    aqm_rc_canopy_file_fp=os.path.join(
        DCOMINcanopy,
        PREDEF_GRID_NAME,
        f"{AQM_CANOPY_FILE_PREFIX}.{mm}{AQM_CANOPY_FILE_SUFFIX}",
        )
    #
    #-----------------------------------------------------------------------
    #
    # Create a multiline variable that consists of a yaml-compliant string
    # specifying the values that the jinja variables in the template
    # AQM_RC_TMPL_FN file should be set to.
    #
    #-----------------------------------------------------------------------
    #
    settings = {
        "do_aqm_dust": DO_AQM_DUST,
        "do_aqm_canopy": DO_AQM_CANOPY,
        "do_aqm_product": DO_AQM_PRODUCT,
        "ccpp_phys_suite": CCPP_PHYS_SUITE,
        "aqm_config_dir": AQM_CONFIG_DIR,
        "init_concentrations": init_concentrations,
        "aqm_rc_bio_file_fp": aqm_rc_bio_file_fp,
        "dcominbio": DCOMINbio,
        "aqm_rc_fire_file_fp": aqm_rc_fire_file_fp,
        "aqm_rc_fire_frequency": AQM_RC_FIRE_FREQUENCY,
        "aqm_rc_dust_file_fp": aqm_rc_dust_file_fp,
        "aqm_rc_canopy_file_fp": aqm_rc_canopy_file_fp,
        "aqm_rc_product_fn": AQM_RC_PRODUCT_FN,
        "aqm_rc_product_frequency": AQM_RC_PRODUCT_FREQUENCY
    }
    settings_str = cfg_to_yaml_str(settings)

    print_info_msg(
        dedent(
            f"""
            The variable \"settings\" specifying values to be used in the \"{AQM_RC_FN}\"
            file has been set as follows:\n
            settings =\n\n"""
        )
        + settings_str,
        verbose=VERBOSE,
    )
    #
    #-----------------------------------------------------------------------
    #
    # Call a python script to generate the experiment's actual AQM_RC_FN
    # file from the template file.
    #
    #-----------------------------------------------------------------------
    #
    with tempfile.NamedTemporaryFile(
            dir="./",
            mode="w+t",
            prefix="aqm_rc_settings",
            suffix=".yaml") as tmpfile:
        tmpfile.write(settings_str)
        tmpfile.seek(0)
        set_template(
            [
                "-q",
                "-c",
                tmpfile.name,
                "-i",
                AQM_RC_TMPL_FP,
                "-o",
                aqm_rc_fp,
            ]
        )
    return True

def parse_args(argv):
    """ Parse command line arguments"""
    parser = argparse.ArgumentParser(description="Creates aqm.rc file.")

    parser.add_argument("-r", "--run-dir",
                        dest="run_dir",
                        required=True,
                        help="Run directory.")

    parser.add_argument("-c", "--cdate",
                        dest="cdate",
                        required=True,
                        help="Date string in YYYYMMDD format.")

    parser.add_argument("-i", "--init_concentrations",
                        dest="init_concentrations",
                        required=True,
                        help="Flag for initial concentrations.")

    parser.add_argument("-p", "--path-to-defns",
                        dest="path_to_defns",
                        required=True,
                        help="Path to var_defns file.")

    return parser.parse_args(argv)

if __name__ == "__main__":
    args = parse_args(sys.argv[1:])
    cfg = load_shell_config(args.path_to_defns)
    cfg = flatten_dict(cfg)
    import_vars(dictionary=cfg)
    create_aqm_rc_file(
        run_dir=args.run_dir,
        cdate=str_to_type(args.cdate),
        init_concentrations=str_to_type(args.init_concentrations),
    )


import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

def wykresZestawienie( daneNBP, daneTrends ):
    """Zwraca notowania waluty dla danego roku"""

    fig = plt.figure()
    ax1 = fig.add_subplot(111)
    print( daneNBP.head() )
    print( daneTrends.head() )
    ax1.plot( x = daneTrends.index.values, y= daneTrends[ 'Średnia'] )
    ax1.plot( x=daneNBP.index.values, y=daneNBP[ 'usd' ] )
    ax1.legend()
    plt.xlabel("Data")
    fig.savefig('zestawienie', dpi=None, facecolor='w', edgecolor='w',\
                orientation='portrait', papertype='a4', format=None,\
                transparent=False, bbox_inches=None, pad_inches=0.1,\
                metadata=None)


def run_test():
    colors = ["black", "white"]
    sizes = ["S", "M", "L"]

    tshirts = [(c, s) for c in colors for s in sizes]
    # print(tshirts)

    # generator expression
    for a in (f"color:{c}; size:{s}" for c in colors for s in sizes):
        print(a)

if __name__ == "__main__":
    run_test()


import collections
import datetime
import itertools
import math
import os

import numpy as np
import torch

from .abstract_game import AbstractGame

class MuZeroConfig:
    def __init__(self):
        # 这里有更多信息: https://github.com/werner-duvaud/muzero-general/wiki/Hyperparameter-Optimization

        self.seed = 0  # numpy、torch和游戏的种子
        self.max_num_gpus = None  # 确定要使用的最大GPU数。如果有足够的显存，使用单个GPU（将其设置为1）通常会更快。None会使用所有可用的GPU

        ### 游戏
        self.observation_shape = (3, 11, 11)  # 游戏观察的尺寸必须为3（通道、高度、宽度）。对于1D数组，请将其形状改为（1，1，数组长度）
        self.action_space = list(range(11 * 11))  # 所有可能动作的固定列表。您应该只编辑长度
        self.players = list(range(2))  # 玩家的列表。您应该只编辑长度
        self.stacked_observations = 0  # 要添加到 当前观察 的 先前观察 和 先前动作 的数量

        # 评估
        self.muzero_player = 0  # Muzero 玩游戏的先后手（0:Muzero 先手，1:Muzero 后手）
        self.opponent = "random"  # MuZero 对战的硬编码智能体，以评估他在多人游戏中的进展。它不影响训练。如果在游戏类中实现，分为 None, "random" or "expert"

        ### 自博弈
        self.num_workers = 1  # 给回放池提供数据的并发自博弈 工作进程/线程 数目
        self.selfplay_on_gpu = False
        self.max_moves = 121  # 如果游戏未在之前完成，则能移动的最大数量
        self.num_simulations = 300  # 自模拟的未来移动次数（MCTS对当前根结点展开模拟的次数）
        self.discount = 1  # 按时间顺序排列的奖励折扣
        self.temperature_threshold = None  # 将 visit_softmax_temperature_fn 给出的温度降至0（即选择最佳动作）之前的移动次数。如果是 None，visit_softmax_temperature_fn 每次都会被用到

        # 根先验探索噪声
        self.root_dirichlet_alpha = 0.3  # 狄利克雷分布的α参数
        self.root_exploration_fraction = 0.25  # 噪声所占的比例

        # UCB 公式
        self.pb_c_base = 19652
        self.pb_c_init = 1.25

        ### 神经网络
        self.network = "resnet"  # "resnet" 或 "fullyconnected"
        self.support_size = 10  # 价值和奖励被缩放（几乎都是用sqrt）并编码在一个向量上，向量的范围为-support_size到support_size。选择它以便使 support_size <= sqrt(max(abs(discounted reward)))

        # 残差网络
        self.downsample = False  # 表示网络 前的下采样观测值, False / "CNN" (更轻量级的) / "resnet" (见论文附录网络架构)
        self.blocks = 3  # ResNet中的块数
        self.channels = 64  # ResNet中的通道数
        self.reduced_channels_reward = 2  # 奖励头 中的通道数
        self.reduced_channels_value = 2  # 价值头 中的通道数
        self.reduced_channels_policy = 4  # 策略头 中的通道数
        self.resnet_fc_reward_layers = [32]  # 在 动态网络 的 奖励头 中定义隐藏层
        self.resnet_fc_value_layers = [32]  # 在 预测网络 的 价值头 中定义隐藏层
        self.resnet_fc_policy_layers = [32]  # 在 预测网络 的 策略头 中定义隐藏层

        # 全连接神经网络
        self.encoding_size = 32
        self.fc_representation_layers = []  # 定义 表示网络 中的隐藏层
        self.fc_dynamics_layers = [64]  # 定义 动态网络 中的隐藏层
        self.fc_reward_layers = [64]  # 定义 奖励网络 中的隐藏层
        self.fc_value_layers = []  # 定义 价值网络 中的隐藏层
        self.fc_policy_layers = []  # 定义 策略网络 中的隐藏层

        ### 训练
        self.results_path = os.path.join(os.path.dirname(os.path.realpath(__file__)), "../results", os.path.basename(__file__)[:-3], datetime.datetime.now().strftime("%Y-%m-%d--%H-%M-%S"))  # 存储 模型权重 和 Tensorboard 日志的路径
        self.save_model = True  # 将 results_path 中的检查点另存为 model.checkpoint
        self.training_steps = 2000  # 训练步总数（即根据批次更新权重）
        self.batch_size = 64  # 在每个训练步中 训练的游戏片段 的数量
        self.checkpoint_interval = 5  # 保存模型的训练步间隔
        self.value_loss_weight = 1  # 缩放价值损失以避免价值函数的过拟合，论文建议为0.25（见论文附录 重新分析）
        self.train_on_gpu = torch.cuda.is_available()  # 在GPU上训练（如果可用）

        self.optimizer = "Adam"  # "Adam" or "SGD". 论文中使用 SGD
        self.weight_decay = 1e-4  # L2权重正则化
        self.momentum = 0.9  # 仅当优化器为SGD时使用

        # 指数学习速率调度器
        self.lr_init = 0.002  # 初始学习率
        self.lr_decay_rate = 0.9  # 将其设置为1以使用恒定的学习速率
        self.lr_decay_steps = self.training_steps

        ### 回放池
        self.replay_buffer_size = 10000  # 要保留在回放池中的自博弈游戏盘数
        self.num_unroll_steps = 121  # 每盘游戏为批元素保留的游戏移动数（移动为样本的单位），即论文中的“展开的K假设步”
        self.td_steps = 121  # 计算 目标价值 时要考虑的未来步数，即论文中的“n-step前瞻的n”
        self.PER = True  # 优先回放（见论文附录 训练），优先选择回放池中网络意外的元素
        self.PER_alpha = 0.5  # 使用多少优先级，0对应于uniform分布的情况，论文建议1

        # 重新分析（见论文附录 重新分析）
        self.use_last_model_value = False  # 使用最后一个模型提供更新鲜、稳定的 n-step 价值（见论文附录 重新分析）
        self.reanalyse_on_gpu = False

        ### 调整 自博弈/训练 比率，以避免 过拟合/欠拟合
        self.self_play_delay = 0  # 每次玩一盘游戏后等待的秒数
        self.training_delay = 0  # 每个训练步后等待的秒数
        self.ratio = 1 / 50  # 每个 自博弈步 的 期望训练步 比率。与同步版本等效，训练可能需要更长的时间。设置为“None”以禁用它

    def visit_softmax_temperature_fn(self, trained_steps):
        """
        更改 访问次数分布 的参数——确保随着训练的进行，动作选择变得更加贪婪。越小，越有可能选择最佳行动（即访问次数最多）。

        Returns:
            Positive float.
        """
        if trained_steps < 0.5 * self.training_steps:
            return 1.0
        elif trained_steps < 0.75 * self.training_steps:
            return 0.5
        else:
            return 0.25

class Game(AbstractGame):
    """
    游戏装饰器
    """

    def __init__(self, seed=None):
        self.env = Hex()

    def step(self, action):
        """
        在游戏中执行一个动作

        Args:
            action : 要采取的 动作空间 中的 动作。

        Returns:
            新的观察、奖励和（标记游戏是否结束）布尔值。
        """
        observation, reward, done = self.env.step(action)
        return observation, reward, done

    def to_play(self):
        """
        返回当前的玩家

        Returns:
            当前玩家，它应该是配置中玩家列表的一个元素
        """
        return self.env.to_play()

    def legal_actions(self):
        """
        应在每个回合返回合法动作，如果不可用，可返回整个动作空间。在每个回合，游戏必须能够处理一个返回的动作。
        对于计算合法动作太长的复杂游戏，其想法是将合法动作定义为整个动作空间，但如果动作非法，则返回负奖励。

        Returns:
            An array of integers，动作空间的子集
        """
        return self.env.legal_actions()

    def reset(self):
        """
        为新游戏重置游戏

        Returns:
            游戏的初始化观察
        """
        return self.env.reset()

    def close(self):
        """
        正确地结束游戏
        """
        pass

    def render(self):
        """
        可视化（渲染）游戏观察
        """
        self.env.render()
        # input("Press enter to take a step ")

    def human_to_action(self):
        """
        对于多人游戏，要求用户采取合法动作并返回相应的动作编号

        Returns:
            An integer from the action space.
        """
        valid = False
        while not valid:
            valid, action = self.env.human_input_to_action()
        return action

    def action_to_string(self, action):
        """
        将动作编号转换为表示该动作的字符串
        Args:
            action_number: an integer from the action space.
        Returns:
            表示该动作的 字符串
        """
        return self.env.action_to_human_input(action)

class Hex:
    def __init__(self):
        self.board_size = 11
        self.board = np.zeros((self.board_size, self.board_size), dtype="int32")
        self.player = 1  # 红棋为1，蓝棋为-1
        self._directions = [(-1, 0), (0, -1), (1, -1), (1, 0), (0, 1), (-1, 1)]
        self.column_markers = [
            chr(x) for x in range(ord("A"), ord("A") + self.board_size)
        ]
        self.row_markers = [
            str(x) for x in range(1, self.board_size + 1)
        ]

    def to_play(self):
        return 0 if self.player == 1 else 1  # 先手返回0，后手返回1

    def reset(self):
        self.board = np.zeros((self.board_size, self.board_size), dtype="int32")
        self.player = 1
        return self.get_observation()

    def step(self, action):
        x = math.floor(action / self.board_size)
        y = action % self.board_size
        self.board[x][y] = self.player

        done = self.is_finished()

        reward = 1 if done else 0  # 当前玩家获胜，奖励为1   R(St)对应Player(St-1)

        self.player *= -1

        return self.get_observation(), reward, done

    def get_observation(self):
        board_player1 = np.where(self.board == 1, 1.0, 0.0)
        board_player2 = np.where(self.board == -1, 1.0, 0.0)
        board_to_play = np.full((11, 11), self.player, dtype="int32")
        return np.array([board_player1, board_player2, board_to_play])  # 3, 11, 11

    def legal_actions(self):
        legal = []
        for i in range(self.board_size):
            for j in range(self.board_size):
                if self.board[i][j] == 0:
                    legal.append(i * self.board_size + j)
        return legal

    def is_finished(self):
        for j in range(self.board_size):
            if self.is_connected((0, j), 1):
                return True
        for i in range(self.board_size):
            if self.is_connected((i, 0), -1):
                return True
        return False  # 游戏未结束

    def is_connected(self, root, color):
        """判断从上到下或者从左到右是否形成完整的连接，若是则返回True，否则返回False"""
        if self.board[root] != color:
            return False
        visited, queue = {root}, collections.deque([root])
        while queue:
            pos = queue.popleft()
            for neighbor in self.get_neighbors(pos, color):
                if neighbor not in visited:
                    if (color == 1 and neighbor[0] == self.board_size - 1) or (
                            color == -1 and neighbor[1] == self.board_size - 1):
                        return True
                    visited.add(neighbor)
                    queue.append(neighbor)
        return False

    def get_neighbors(self, pos, color):
        """返回一个包含所有同颜色邻居的列表"""
        x, y = pos
        neighbors = []
        for x_offset, y_offset in self._directions:
            nx, ny = (x + x_offset, y + y_offset)
            if self.is_valid_pos(nx, ny):
                if self.board[(nx, ny)] == color:
                    neighbors.append((nx, ny))
        return neighbors

    def is_valid_pos(self, i, j):
        if i < 0 or j < 0 or i >= self.board_size or j >= self.board_size:
            return False
        return True

    def render(self):
        pretty_print_map = {
            1: '\x1b[0;36;41mR  ',
            0: '\x1b[0;31;43m-  ',
            -1: '\x1b[0;31;46mB  ',
        }
        board = np.copy(self.board)
        # 原始棋盘内容
        raw_board_contents = []
        for i in range(self.board_size):
            row = []
            for j in range(self.board_size):
                row.append(pretty_print_map[board[i, j]])
                row.append('\x1b[0m')
            raw_board_contents.append(''.join(row))
        # 行标签 N~1
        row_labels_left = [" " * (self.board_size - i) + '%2d' % i + "\\" for i in
                           range(self.board_size, 0, -1)]
        row_labels_right = ["\\ " + '%2d' % i for i in range(self.board_size, 0, -1)]
        # 带标注的每一行的内容
        annotated_board_contents = [''.join(r) for r in zip(row_labels_left, raw_board_contents, row_labels_right)]
        # 列标签
        header_footer_rows = ['   ' + '  '.join('ABCDEFGHIJK'[:self.board_size]) + '   ']
        tailer_footer_rows = ["   " + " " * (self.board_size) + '  '.join(
            'ABCDEFGHIJK'[:self.board_size]) + '   ']
        # 带标注的棋盘
        # itertools.chain将不同容器中的元素连接起来，便于遍历
        annotated_board = '\n'.join(itertools.chain(header_footer_rows, annotated_board_contents, tailer_footer_rows))
        print(annotated_board)

    def human_input_to_action(self):
        human_input = input("Enter an action: ")
        if (
            len(human_input) == 2
            and human_input[0] in self.column_markers
            and human_input[1:] in self.row_markers
        ):
            y = ord(human_input[0]) - 65
            x = self.board_size - int(human_input[1:])
            if self.board[x][y] == 0:
                return True, x * self.board_size + y
        return False, -1

    def action_to_human_input(self, action):
        x = math.floor(action / self.board_size)
        y = action % self.board_size
        x = str(self.board_size - x)
        y = chr(y + 65)
        return y + x


# importing needed Frameworks
import eel

# initializing EEL
eel.init('ui')

class Game:

    # initialsing the Game-Variables
    def __init__(self):

        self.is_running = False     # to check if the Game is running or not
        self.word = ""              # setting the Word (default= Empty) like: "secret"
        self.hint = ""              # used to show the Word with * like: s*cr*t
        self.letters = ""           # list of all used Letters like: ['s','c', 'r', 't', 'o', 'z']
        self.guessed = []           # Array of guessed Word like: ['s', '*', 'c', 'r', '*', 't']
        self.mistakes = 0           # counts the wrong guessed Letters
        self.score = 0              # will be calculated based on speed and wrong guesses

# just some Lines of testing Stuff
# ##### #
game = Game()
# ##### #

# starting the Game
@eel.expose
def start(self=game):
    self.is_running = True

# stopping the Game
@eel.expose
def stop(self=game):
    self.is_running = False

# Guessing a Letter
@eel.expose
def guess(letter, self=game):

    # if the Letter is not in the Word add 1 to the mistakes
    if letter.lower() not in self.word.lower():
        self.mistakes += 1

    # checking each Letter in the Word if it's the guessed Letter
    for i in range(len(self.word)):

        if self.word[i].lower() == letter.lower():
            self.guessed[i] = letter.lower()

    # clearing the Hint
    self.hint = ""
    print(letter)

    # filling the Hint with all guessed Letters
    for i in self.guessed:
        self.hint += i

    if '_' not in self.guessed:
        stop()

# setting the Word
@eel.expose
def set_word(word, self=game):

    self.word = word
    self.hint = ""
    self.guessed = []
    start()

    # creating an Array with * for each Letter
    for i in self.word:
        if i == ' ':
            self.guessed.append(' ')
        else:
            self.guessed.append('_')

    # clearing the Hint
    self.hint = ""

    # filling the Hint with all guessed Letters
    for i in self.guessed:
        self.hint += i

# return Hint with guessed Letters
@eel.expose
def get_hidden_word(self=game):
    return self.hint

@eel.expose
def gen_btns():

    btns = ""
    letters = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"]

    for letter in letters:
        btns += f'<button type="button" name="bnt_word" class="send_guess" onclick="set_guess(\'{letter}\')">{letter}</button>'

    return btns

# starting EEL
eel.start('index.html')


import numpy as np
import warnings
from mclust.exceptions import ModelError, AbstractMethodError
from mclust.fortran.mclust import hcvvv, hceii
from mclust.utility import traceW, partconv, scale

class HC:
    """
    Agglomerative hierarchical clustering based on maximum likelihood criteria
    for Gaussian mixture models parameterized by eigenvalue decomposition.
    """
    def __init__(self, data):
        self.data = data.copy(order='F')
        self.pairs = None
        self.partition = None
        self.n = None
        self.p = None
        self.l = None
        self.m = None
        pass

    def fit(self, minclus=1):
        # For now only Mclust default: SVD
        # all values should be finite
        data_scaled = scale(self.data, center=True, rescale=True)
        p = min(data_scaled.shape)
        _, d, v = np.linalg.svd(data_scaled, full_matrices=False)
        z = data_scaled \
            .dot(v.transpose()) \
            .dot(np.diag(np.concatenate((1/np.sqrt(d),
                                         np.zeros(p-len(d)))))
                 )
        z = np.asfortranarray(z)
        self._handle_input(minclus)
        self.hc_fortran(z)

    def _handle_input(self, minclus=1):
        if minclus < 1:
            raise ModelError("minclus must be positive")
        if np.any(np.equal(self.data, None)):
            raise ModelError("Missing values not allowed in data")

        self.n, self.p = self.data.shape
        if self.n <= self.p:
            warnings.warn("Number of observations <= data dimension")

        if self.partition is None:
            self.partition = np.arange(1, self.n+1)
        elif len(self.partition) != self.n:
            raise ModelError("Partition must assign a class to each observation")
        self.partition = partconv(self.partition, consec=True)
        self.l = np.array(len(np.unique(self.partition)), int, order='F')
        self.m = np.array(self.l - minclus, int, order='F')
        if self.m <= 0:
            raise ModelError("initial number of clusters is not greater than minclus")

    def hc_fortran(self, z):
        raise AbstractMethodError()

    def get_class_matrix(self, g):
        """
        Determines the classifications corresponding to different numbers of
        groups given merge pairs from hierarchical agglomeration.

        :param g: vector of integers giving the number of clusters for which
        the corresponding classifications are wanted.
        :return: A matrix with length(g) columns, each column corresponding to
                 a classification. Columns are indexed by the character
                 representation of the integers in g.
        """
        n = len(self.partition)
        k = len(np.unique(self.partition))
        g = np.sort(g)[::-1]
        select = k - g
        if len(select) == 1 and select[0] == 0:
            return self.partition.reshape(n, 1)
        bad = np.logical_or(select < 0, select >= k)
        if all(bad):
            raise ModelError("No classification with the specified number of clusters")
        if any(bad):
            warnings.warn("Some selected classifications are inconsistent with mclust objects")

        l = len(select)
        cl = np.full((n, l), float('nan'), float, order='F')
        m = 0
        if select[0] == 0:
            cl[:, 0] = self.partition
            m = 1
        for li in range(max(select)):
            ij = self.pairs[:, li]
            i = min(ij)
            j = max(ij)
            self.partition[self.partition == j] = i
            if select[m] == li + 1:
                cl[:, m] = self.partition
                m = m + 1

        return np.apply_along_axis(partconv, 0, cl[:, range(l-1, -1, -1)])

class HCVVV(HC):
    def hc_fortran(self, z, alpha=1, beta=1):
        ll = int((self.l * (self.l-1))/2)
        ld = np.array(max(self.n, ll + 1, 3 * self.m))
        alpha = np.array(max(alpha * traceW(z / np.sqrt(self.n * self.p)), np.finfo(float).eps), float, order='F')
        beta = np.array(beta, float, order='F')
        data_stacked = np.column_stack((z, np.zeros(self.n)))
        v = np.zeros(self.p, float, order='F')
        u = np.zeros(self.p * self.p, float).reshape(self.p, self.p, order='F')
        s = np.zeros(self.p * self.p, float).reshape(self.p, self.p, order='F')
        r = np.zeros(self.p * self.p, float).reshape(self.p, self.p, order='F')
        d = np.zeros(ld, order='F')
        hcvvv(data_stacked,
              self.partition,
              self.l,
              self.m,
              alpha,
              beta,
              v,
              u,
              s,
              r,
              ld,
              d
              )
        self.pairs = data_stacked[0:self.m, 0:2].transpose()

class HCEII(HC):
    def hc_fortran(self, z):
        ld = np.array(max((self.l * (self.l - 1))/2, 3 * self.m), int, order='F')
        v = np.zeros(self.p, float, order='F')
        d = np.zeros(ld, float, order='F')
        hceii(z,
              np.array(self.p, int, order='F'),
              self.partition,
              self.l,
              self.m,
              v,
              ld,
              d
              )
        self.pairs = z[0:self.m, 0:2].transpose()


# -*- coding:utf-8 -*-
# -*- coding: euc-kr -*-
from urllib.request import urlopen
from bs4 import BeautifulSoup

html = urlopen("http://cs.hanyang.ac.kr/board/info_board.php")
source = "http://cs.hanyang.ac.kr/board/info_board.php"
soup = BeautifulSoup(html, "html.parser")
results = soup.find_all('td', {'class': 'left'})

for result in results:
    text = result.find('a').get_text()
    link = result.find('a')['href']

    if link.find("http") == -1:
        try:
            print(("Notice : " + text + " / Link : " + source + link))
        except:
            print(("Notice : " + link + " / Link : " + link))
    else:
        try:
            print(("Notice : " + text + " / Link : " + link))
        except:
            print("error")


# coding: utf-8

# # Practico 4 - Manipulación de imágenes
#
# Escribir un programa que permita seleccionar un rectángulo de una imagen, luego:
#
# * con la letra “g” guarda la imagen dentro del rectángulo en el disco,
# * con la letra “r” restaura la imagen original y permite realizar nuevamente la selección,
# * con la “q” finaliza.

# In[59]:

import cv2
import numpy as np

# In[60]:

drawing = False # true if mouse is pressed
ix, iy = -1, -1
fx, fx = -1, -1

# In[61]:

def crop_rectangle(event, x, y, flags, param):
    global ix, iy, fx, fy, drawing
    if event == cv2.EVENT_LBUTTONDOWN:
        drawing = True
        ix, iy = x, y
    elif event == cv2.EVENT_MOUSEMOVE:
        if drawing is True:
            fx, fy = x, y
    elif event == cv2.EVENT_LBUTTONUP:
        drawing = False
        cv2.rectangle(img, (ix, iy), (fx, fy), (0, 255, 0) , 1)

# In[62]:

img = cv2.imread('../practico2/hojas.png', 1)
aux_img = img.copy()
cv2.namedWindow('image')
cv2.setMouseCallback('image', crop_rectangle)

while(1):
    cv2.imshow('image', img)
    k = cv2.waitKey(1) & 0xFF
    if k == ord('g'):
        crop_img = img[iy:fy, ix:fx]
        cv2.imwrite('recorte.png', crop_img)
        break
    elif k == ord('r'):
        img = aux_img.copy()
    elif k == ord('q'):
        break
cv2.destroyAllWindows()


from oslo_config import cfg
from oslo_log import log as logging

from mistral.db.v2.sqlalchemy import models

cfg.CONF.import_opt('workflow_trace_log_name', 'mistral.config')

WF_TRACE = logging.getLogger(cfg.CONF.workflow_trace_log_name)

def info(obj, msg, *args, **kvargs):
    """Logs workflow trace record for Execution or Task.

    :param obj: If type is TaskExecution or WorkflowExecution,
        appends execution_id and task_id to the log message.

    The rest of parameters follow logger.info(...)
    """
    debug_info = ''

    if type(obj) is models.TaskExecution:
        exec_id = obj.workflow_execution_id
        task_id = obj.id
        debug_info = '(wf_ex_id=%s, task_ex_id=%s)' % (exec_id, task_id)

    elif type(obj) is models.WorkflowExecution:
        debug_info = '(execution_id=%s,' \
                     'task_ex_id=%s)' % (obj.id, obj.task_execution_id)

    if debug_info:
        msg = '%s %s' % (msg, debug_info)

    WF_TRACE.info(msg, *args, **kvargs)