#%%  run simulations for different loads
# compare load statistics
import numpy as np
from simulation_functions import *
import matplotlib.pyplot as plt
from util import SEED

#%% [markdown]
# ## Check the behaviour of FIFO and SJF
#

#%%
np.random.seed(SEED)
n_sims = 200
n_jobs = 20000
mu = 0.95
rho_list = np.arange(0.8, 1.0, 0.01)
FIFOdatalist = []

for load in rho_list:
    FIFOdatalist.append(run_simulation(load,mu, n_servers=1, n_jobs=n_jobs,n_sims=n_sims,debug=1, iteration_function=FIFO_iteration))

#%%
SJFdatalist = []
for load in rho_list:
    SJFdatalist.append(run_simulation(load, mu, n_servers=1, n_jobs=n_jobs, n_sims=n_sims, debug=1, iteration_function=SJF_iteration))

#%%
from util import save_data
data_dict = {
    "parameters": {
        "simulations": n_sims,
        "jobs": n_jobs,
        "mu": mu,
        "system_type":"MM1",
        "desc": "Simulation with multiple values for the load(rho)"
    },
    "xdata": list(rho_list),
    "ydata": {
        "FIFO": FIFOdatalist,
        "SJF": SJFdatalist
    }
}

save_data(data_dict, f"load_chr_FIFO_SJF_errorbar_drho=0.02_mu=095_njobs=20000-2")
# %%
plt.style.use('seaborn')
from util import plot_errorHue

fig, ax = plt.subplots(1, 1, )
plot_errorHue(rho_list, FIFOdatalist, "FIFO", ax)
plot_errorHue(rho_list, SJFdatalist, "SJF", ax)
ax.set(
    xlabel=r'load ($\rho$)',
    ylabel='average waiting time',
    title='load characeristics of service systems',
    xticks=rho_list[np.arange(0,20,2)]
)
ax.legend(loc="upper left", frameon=True, shadow=True)

# plt.savefig("load_chr_FIFO_SJF_errorHue_drho=0.01_mu=095_njobs=20000-2.png")
#%%

from util import plot_errorbar

fig, ax = plt.subplots(1, 1, )
plot_errorbar(rho_list, FIFOdatalist, "FIFO", ax)
plot_errorbar(rho_list, SJFdatalist, "SJF", ax)
ax.set(
    xlabel=r'load $(\rho)$',
    ylabel='average waiting time',
    title='load characeristics of service systems',
    xticks=rho_list
)
# plt.savefig("figures/load_chr_FIFO_SJF_errorbar_drho=0.02_mu=095_njobs=20000-1.png")

#%% Plot distributions of watining times  for 4 values of rho
n_sims = 500
n_jobs = 20000
mu = 0.95
rho_list = [0.8, 0.85, 0.90]
FIFOdatalist = []

for load in rho_list:
    FIFOdatalist.append(run_simulation(load,mu, n_servers=1, n_jobs=n_jobs,n_sims=n_sims,debug=1, iteration_function=FIFO_iteration, return_data=True))

SJFdatalist = []
for load in rho_list:
    SJFdatalist.append(run_simulation(load, mu, n_servers=1, n_jobs=n_jobs, n_sims=n_sims, debug=1, iteration_function=SJF_iteration,return_data=True))

#%%
import seaborn as sns
import pandas as pd
plt.style.use("seaborn")

# %% Getting the data in the right format for seaborn plot
meandata_list = []
skip_first_FIFO = 0
skip_first_SJF = 0
for i in range(len(rho_list)):
    for j in range(len(FIFOdatalist[i][3])):
        meandata_list.append((
            FIFOdatalist[i][3][j],
            "FIFO",
            str(rho_list[i])))

for i in range(len(rho_list)):
    for j in range(len(SJFdatalist[i][3])):
        meandata_list.append((
            SJFdatalist[i][3][j],
            "SJF",
            str(rho_list[i])))

df = pd.DataFrame(meandata_list, columns=["time", "service", "rho"],)
df.to_csv("data/load_chr_FIFO_SJF_dataframe_nsims=200-big.csv")

df.head()
#%%
sns.displot(df,bins=200,x="time", hue="service",col="rho",kde=True, legend=True)
# plt.ylim(top=200)
# plt.xlim(right=40)
plt.savefig("figures/load_chr_FIFO_SJF_kde_3rhos_mu=0.95_njobs=20000_nsim=200-2.png", dpi=600)

#%%
# isRho09or08 = df['rho']== ( 0.9 | 0.8 )
# df_filtered=df[df['rho'].isin([0.8, 0.85, 0.9])]
# fig, ax = plt.subplots(1, 1, figsize=(10,8))
# sns.violinplot(data= df,x="rho",y="time",hue="service",legend=True,ax=ax)
fig, ax = plt.subplots(1, 3, figsize=(10,5))
# order=["H", "M", "D"]
sns.violinplot(data=df[df["rho"] == "0.8"],  y="time", x="rho",hue="service",ax=ax[0] )
sns.violinplot(data=df[df["rho"] == "0.85"], y="time", x="rho",hue="service",ax=ax[1])
sns.violinplot(data=df[df["rho"] == "0.9"],  y="time", x="rho",hue="service",ax=ax[2] )
ax[0].get_legend().remove()
ax[0].set(xlabel="")
ax[1].get_legend().remove()
ax[1].set(ylabel="")
ax[2].set(ylabel="")
ax[2].set(xlabel="")
plt.tight_layout()
plt.savefig("figures/load_chr_FIFO_SJF_violin_3rhos_mu=0.95_njobs=20000_nsim=200-2.png", dpi=600)

#%% Saving general stats to json
print(F"for rho {[(stat[0], stat[1], stat[2]) for stat in FIFOdatalist]}")
fifostatslist = []
for i in range(len(FIFOdatalist)):
    fifostatslist.append(
        {
            rho_list[i]: {
                "mean": FIFOdatalist[i][0],
                "std": FIFOdatalist[i][1],
                "ci": FIFOdatalist[i][2],
            }
        }
    )
sjfstatslist = []
for i in range(len(SJFdatalist)):
    sjfstatslist.append(
        {
            "rho_" + str(rho_list[i]): {
                "mean": SJFdatalist[i][0],
                "std": SJFdatalist[i][1],
                "ci": SJFdatalist[i][2],
            }
        }
    )

stats_dict = {
    "FIFO": fifostatslist,
    "SJF": sjfstatslist
}
print(stats_dict)
#%%
# from util import save_data
save_data(stats_dict, "load_chr_FIFO_SJF_general_stats-2")


# -*- coding: utf-8 -*-
import pylab as plt
import numpy as np

from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg
from PyQt5.QtWidgets import QSizePolicy

class Graph(FigureCanvasQTAgg):
    def __init__(self, parent=None, width=10, height=10, dpi=100):
        figure = plt.Figure(figsize=(width, height), dpi=dpi)
        figure.subplots_adjust(left   = 0.0,
                               right  = 1.0,
                               top    = 1.0,
                               bottom = 0.0,
                               wspace = 0.0,
                               hspace = 0.0)
        super(Graph, self).__init__(figure)

        self.parent = parent
        self.figure = figure

        # Fill the area with the graph
        self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)

        self.axes = figure.add_subplot(111)
        self.axes.set_xticks(())
        self.axes.set_yticks(())

        self.im = None

        self.is_interactive = True
        self.corners_callback = None
        self.corners = None

        self.scatter_plots = []

        figure.canvas.mpl_connect("button_press_event", self.button_press_event)

    def clear_corners(self):
        self.corners = None

        # Clear scatterplot overlays if they exist
        if len(self.scatter_plots) > 0:
            for plot in self.scatter_plots:
                plot.remove()

        self.scatter_plots = []
        self.draw()

    def button_press_event(self, event):
        if not self.is_interactive:
            return

        # Right-click erases scatterplot overlays
        if event.button == 3:
            self.clear_corners()

        # Left-click adds point markers
        elif event.button == 1 and event.xdata and event.ydata:
            p = np.array([event.xdata, event.ydata])

            if self.corners is None:
                self.corners = np.array([p])

            else:
                temp = np.vstack((self.corners, p))
                self.corners = temp

            draw_plot = True
            if self.corners_callback:
                draw_plot = self.corners_callback()

            if draw_plot and self.corners is not None:
                # Draw new overlay
                plot = self.axes.scatter(*zip(*self.corners), c="r", s=2)
                self.scatter_plots.append(plot)
                self.draw()

    def imshow(self, im):
        # Fixes the issue of plot auto-rescaling
        # When overlaying scatterplot points
        self.axes.set_xlim([0, im.shape[1]])
        self.axes.set_ylim([im.shape[0], 0])

        self.im = im
        self.axes.imshow(im)
        self.draw()


import wlan
from machine import Pin
import json
import utime
import machine
from utilities import *
import uasyncio as asyncio
import web_page
import cnc
import gc
import config
gc.collect()

pins = config.grbl_1_4

neo_status = NeoMgr(pins['neo_status'], 1)
neo_status.fill(0,5,5)
sta = wlan.connect()
neo_status.fill(0,0,0)
my_ip = sta.ifconfig()[0]

# detect = Pin(25, Pin.IN)
uart1 = UartMgr(1, baudrate=115200, rx=pins['uart_rx'], tx=pins['uart_tx'])
hbt = HBT(pin=pins['hbt'], interval=500)
can = CanMgr(0, tx=pins['can_tx'], rx=pins['can_rx'], extframe=True, mode=CAN.NORMAL, baudrate=250000, slp_pin=pins['can_slp'])
sd = SDMgr(slot=pins['sd_slot'])
try:
    sd.mount()
except OSError:
    print('sd failed to mount')
    pass
grbl = cnc.GRBL(sd, can, uart1, hbt_int=8000, debug=True, resets=True)

def print_state(state, button):
    print(state, button.can_id)
func_button = Button('func button', 36, False, 54, print_state)

async def chk_hw():
    while True:
        hbt.chk()
        func_button.chk()
        await asyncio.sleep_ms(50)

async def grblchk():
    while True:
        uart1.chk()
        grbl.chk()
        await asyncio.sleep_ms(10)

cmds = {
    '/led=on': lambda: neo_status.fill(0, 25, 0),
    '/led=off': lambda: neo_status.fill(0, 0, 0),
    '/light_show': lambda: can.send([1], 1),
    '/broadcast': lambda: can.send([1], 4),
    '/!broadcast': lambda: can.send([0], 4),
    '/demo1': lambda: demo1()
}

cmds.update(**grbl.web_buts())

async def handle_client(reader, writer):
    request = (await reader.read(1024)).decode('ascii')
    page = None
    # print(request)
    end = request.find(' HTTP')
    action = request[4:end]
    print(action)
    if action == '/cnc':
        web_page.page = 'cnc'
    elif action == '/home':
        web_page.page = None

    if action in cmds:
        cmds[action]()
    elif action.find('/move') == 0:
        grbl.parse_move(request)

    elif action.find('/offset') == 0:
        grbl.set_offset(request)
    elif action.find('/can') == 0:
        # can.send(**web_page.parse_can(action))
        print(web_page.parse_can(action))
    elif action.find('/sub') == 0:
        # can.create_sub(**web_page.parse_sub(action))
        print(web_page.parse_sub(action))
    elif action.find('/prog') == 0:
        can.create_prog(action)
    elif action == '/reset':
        can.connections = ''
        can.send([1], 2)
    elif action == '/?run_export':
        print('run export file')
        sd.opener('t.txt')
        grbl.run()
    elif action.find('/file') == 0:
        name = action.split('=')[1]
        print('opening file {}'.format(name))
        sd.opener(name)
    elif action.find('/direct') == 0:
        fn = action.split('=')
        action = fn[1].replace('+', ' ')
        print('sending direct ' + action)
        grbl.send_g(action)
    elif action.find('/feeder') == 0:
        fn = action.split('=')
        print(fn)

    else:
        print('unknown command')

    await writer.awrite(
        b'HTTP/1.1 200 OK\r\nContent-Type: text/html\r\nConnection: close\r\n\r\n')
    if web_page.page == 'cnc':
        await writer.awrite(grbl.web_page())
    else:
        await writer.awrite(web_page.web_page(can.connections, sd.html_list))
    await writer.aclose()
    return True

test_move = [
{'cmd': 'move.linear', 'x':1000, 'feed':10000},
{'cmd': 'move.linear', 'x':0, 'feed':10000},
None
]
grbl.buf = test_move

gc.collect()
print(gc.mem_free())
async def main():
    asyncio.create_task(asyncio.start_server(handle_client, my_ip, 80))
    asyncio.create_task(chk_hw())
    asyncio.create_task(can.chk())
    asyncio.create_task(grblchk())
    while True:
        await asyncio.sleep(5)

gc.collect()
while True:
    asyncio.run(main())


from sqlalchemy import create_engine
from sklearn.metrics import classification_report
from sklearn.model_selection import train_test_split, GridSearchCV
from sklearn.pipeline import Pipeline
from sklearn.multioutput import MultiOutputClassifier
from sklearn.neural_network import MLPClassifier
from sklearn.decomposition import TruncatedSVD
from sklearn.ensemble import RandomForestClassifier
from sklearn.feature_extraction.text import TfidfVectorizer
from nltk.stem import WordNetLemmatizer, PorterStemmer
from nltk.tokenize import word_tokenize
from nltk.corpus import stopwords
import sys
import re
import numpy as np
import pandas as pd
import nltk
nltk.download(['punkt', 'wordnet', 'averaged_perceptron_tagger'])

def load_data(data_file):
    # read in file
    engine = create_engine(f'sqlite:///{data_file}.db')
    df = pd.read_sql(f'select * from {data_file}', con=engine)

    # define features and label arrays
    X = df.message
    Y = df.loc[:, 'related':]
    target_names = Y.columns
    y = Y.to_numpy()

    return X, y

def tokenize(message, stem='lemm'):
    """Text processing.

    Args:
        stem(str): stem or lemm.

    Returns:
        list: Cleaned tokens.
    """
    # 1. Cleaning

    # 2. Normalization
    text = re.sub(r"[^a-zA-Z0-9]", " ", message.lower())

    # 3. Tokenization
    tokens = word_tokenize(text)

    # 4. Stop Word Removal
    stop_words = stopwords.words("english")
    tokens = list(filter(lambda w: w not in stop_words, tokens))

    # 5. Part of Speech Tagging / Named Entity Recognition

    # 6. Stemming or Lemmatization
    # Because the targets are not roots, we should use Lemmatization

    clean_tokens = []
    if stem == 'stem':
        stemmer = PorterStemmer()
        for tok in tokens:
            clean_tok = stemmer.stem(tok).strip()
            clean_tokens.append(clean_tok)
    else:
        lemmatizer = WordNetLemmatizer()
        for tok in tokens:
            clean_tok = lemmatizer.lemmatize(tok).strip()
            clean_tokens.append(clean_tok)

    return clean_tokens

def build_model():
    # text processing and model pipeline
    # Neural Network needs much more time for modeling
    # mlp = MLPClassifier(random_state=42, max_iter=200, verbose=True, early_stopping=True)
    vect = TfidfVectorizer(tokenizer=tokenize, use_idf=True, smooth_idf=True)
    svd = TruncatedSVD(random_state=42)
    forest = RandomForestClassifier(random_state=42)
    multi_label_clf = MultiOutputClassifier(forest)

    pipeline = Pipeline([
        ('vect', vect),
        ('svd', svd),
        ('multi_clf', MultiOutputClassifier(forest))
    ])

    # define parameters for GridSearchCV
    parameters = {
        'vect__ngram_range': ((1, 1), (1, 2)),
        'vect__max_df': (0.5, 0.75, 1.0),
        'vect__max_features': (None, 5000, 10000),
        'svd__n_components': [500, 1000, 3000],
        'multi_clf__estimator__max_depth': (None, 300, 500),
        'multi_clf__estimator__n_estimators': [50, 150, 300],
        'multi_clf__estimator__min_samples_split': [2, 3, 4]
    }

    # create gridsearch object and return as final model pipeline
    cv = GridSearchCV(pipeline, param_grid=parameters,
                      scoring='f1_macro', verbose=2)

    return cv

def tuning(X, y, model):
    # train test split
    X_train, X_test, y_train, y_test = train_test_split(
        X, y, test_size=0.2, random_state=42)

    # fit model
    model.fit(X_train, y_train)
    y_pred = model.predict(X_test)

    with open('best_params.txt', 'w') as f:
        f.write(model.best_params_)

def run_pipeline(data_file):
    X, y = load_data(data_file)  # run ETL pipeline
    model = build_model()
    tuning(X, y, model)  # tuning

if __name__ == '__main__':
    data_file = 'disaster_response'  # get filename of dataset
    run_pipeline(data_file)  # run data pipeline


# mailroom_04.py
# opcode6502: SP_Online_PY210

import datetime
import sys
import tempfile

def add_donation(database, donor_name, donation_amount):
    try:
        database[donor_name] = float(donation_amount)
        # print_debug_message('add_donation(database, donor_name, donation_amount): Success!')
        return True
    except Exception as e:
        print_error_message('add_donation(database, donor_name, donation_amount): Error!')
        print_error_message('e: ' + str(e))

def add_to_dict(database, key, value):
    try:
        database[key] = value
    except Exception as e:
        print_error_message('add_to_dict(database, key, value): Error!')
        print_error_message('e: ' + str(e))

def check_user_response(user_response):
    #
    # Check 'user_response'.
    if user_response == 1:
        send_thank_you()
    elif user_response == 2:
        create_report(donors_db)
    elif user_response == 3:
        timestamp = get_timestamp()
        send_thank_you_global(donors_db, timestamp)
    elif user_response == 4:
        exit_script()
    #
    # [ DEBUG ]: menu items.
    elif user_response == 5:
        print_database(donors_db)
    elif user_response == 6:
        list_donor_names(donors_db)
    elif user_response == 7:
        add_donation(donors_db, 'Donor 10', float(100.00))
    elif user_response == 8:
        comprehensions_test()
    #
    # [ ERROR ]: message.
    else:
        print_error_message('Select item: [ 1 / 2 / 3 / 4 / 5 / 6 / 7 / 8 ].')

def create_donor(database, donor_name):
    try:
        database[donor_name] = float(0.00)
        # print_debug_message('create_donor(donor_name): ' + str(donor_name) + ': Success!')
    except Exception as e:
        print_error_message('create_donor(donor_name): Error!')
        print_error_message('e: ' + str(e))

def create_donors_db():
    #
    # Try to create a dict and print an error if this fails.
    try:
        donors_db = dict()
        #
        # print_debug_message('create_donors_db(): Success!')
        return donors_db
    except Exception as e:
        print_error_message('create_donors_db(): Error!')
        print_error_message('e: ' + str(e))

def create_main_menu():
    #
    # Try to create a dict and print an error if this fails.
    try:
        main_menu = dict()
        # print_debug_message('create_main_menu(): Success!')
        return main_menu
    except Exception as e:
        print_error_message('create_main_menu(): Error!')
        print_error_message('e: ' + str(e))

def create_report(database):
    #
    # Print the header rows.
    print('{:25} | {:1} | {:1} | {:1}'.format(
        'Donor Name',
        'Total Given',
        'Num Gifts',
        'Average Gift'))
    print('-'*66)
    #
    # Initialize 'donors_db_sorted'.
    donors_db_sorted = dict()
    #
    # Sort the donor list.
    donors_db_sorted = sort_database(database)
    #
    # Print the sorted donors list.
    # Note: This for loop just prints data; not a Comprehension candidate.
    for key, value in donors_db_sorted.items():
        donor_name = key
        donor_total = value
        number_of_gifts = 1 # len(donor[1])
        average_gift = float(donor_total) / float(number_of_gifts)
        # average_gift = donor_total / number_of_gifts
        print('{:26} ${:>11.2f} {:>11}  ${:>12.2f}'.format(
              donor_name,
              donor_total,
              number_of_gifts,
              average_gift))

def display_main_menu():
    #
    # Display the main menu and process the user's response.
    while True:
        #
        # Print the 'main_menu'.
        print_main_menu()
        #
        # Get 'user_response' and test input.
        user_response = get_user_response_integer()
        #
        # Check 'user_response'.
        check_user_response(user_response)

def exit_script():
    #
    # Exit the script.
    sys.exit()

def exit_script_ctrl_c():
    #
    # Print a newline and exit the script.
    print()
    sys.exit()

def format_text(text):
    for i in text:
        text = text.replace(' ', '_')
    return text

def get_timestamp():
    timestamp = format_text(str(datetime.datetime.now()))
    return timestamp

def get_user_response():
    # Get 'user_response' (any input) and test input.
    try:
        user_response = input('[ INPUT ]: ')
        return user_response
    except KeyboardInterrupt:
        exit_script_ctrl_c()
    except Exception as e:
        print_error_message('get_user_response(): try: user_response: Error!')
        print_error_message('e: ' + str(e))

def get_user_response_integer():
    # Get 'user_response' (integer only) and test input.
    try:
        user_response = int(input('[ INPUT ]: '))
        return user_response
    except KeyboardInterrupt:
        exit_script_ctrl_c()
    except Exception as e:
        print_error_message('get_user_response_integer(): Error!')
        print_error_message('e: ' + str(e))

def list_donor_names(database):
    #
    print_debug_header_line()
    #
    # Initialize 'donors_db_sorted'.
    donors_db_sorted = dict()
    #
    # Sort the donor list.
    donors_db_sorted = sort_database(database)
    #
    # Print the sorted donors database to the screen.
    # Note: This for loop just prints data; not a Comprehension candidate.
    for key, value in donors_db_sorted.items():
        print('{:10}'.format(str(key)), end='')
        print('{:10.2f}'.format(value))
    #
    # pytest: Additions.
    # This return statement will be ignored when called from
    # check_user_response(user_response).
    # However, we want this return statement here so we can test with pytest.
    return donors_db_sorted

def print_database(database):
    #
    # This is a helper function. This will print the database to the screen.
    # Note: This for loop just prints data; not a Comprehension candidate.
    for key, value in database.items():
        print_debug_header_line()
        print('[ DEBUG ]: str(key)                     : ' + str(key))
        print('[ DEBUG ]: str(type(key))               : ' + str(type(key)))
        print('[ DEBUG ]: str(value)                   : ' + str(value))
        print('[ DEBUG ]: str(type(value))             : ' + str(type(value)))

def print_debug_header_line():
    #
    # Debug message.
    print('[ ----- ]: -------------------------------------------------------')

def print_debug_message(message):
    #
    # Debug message.
    print_debug_header_line()
    print('[ DEBUG ]: ' + str(message))

def print_error_message(message):
    #
    # Debug message.
    print_debug_header_line()
    print('[ ERROR ]: ' + str(message))

def print_main_menu():
    #
    # Create 'main_menu'.
    main_menu = create_main_menu()
    #
    # Populate 'main_menu'.
    add_to_dict(main_menu, '01', '[ ----- ]: -------------------------------------------------------')
    add_to_dict(main_menu, '02', '[  MAIN ]: Select an option:' )
    add_to_dict(main_menu, '03', '[ ----- ]: -------------------------------------------------------')
    add_to_dict(main_menu, '04', '[     1 ]: Send a Thank You to a single donor.')
    add_to_dict(main_menu, '05', '[     2 ]: Create a Report.')
    add_to_dict(main_menu, '06', '[     3 ]: Send letters to all donors.')
    add_to_dict(main_menu, '07', '[     4 ]: Quit')
    add_to_dict(main_menu, '08', '[     5 ]: [ DEBUG ]: print_database(donors_db)')
    add_to_dict(main_menu, '09', '[     6 ]: [ DEBUG ]: list_donor_names(donors_db)')
    add_to_dict(main_menu, '10', '[     7 ]: [ DEBUG ]: add_donation(donors_db, \'Donor 10\', float(100.00))')
    add_to_dict(main_menu, '11', '[     8 ]: [ DEBUG ]: comprehensions_test()')
    #
    # Print the 'main_menu'.
    # Note: This for loop just prints data; not a Comprehension candidate.
    for value in main_menu:
        print(main_menu[value])

def print_send_thank_you_menu():
    #
    # Create 'send_thank_you_menu'.
    try:
        send_thank_you_menu = dict()
    except Exception as e:
        print_error_message('create_donors_db(): Error!')
        print_error_message('e: ' + str(e))
    #
    # Populate 'send_thank_you_menu'.
    add_to_dict(send_thank_you_menu, '01', '[ ----- ]: -------------------------------------------------------')
    add_to_dict(send_thank_you_menu, '02', '[ DONOR ]: Select an option:')
    add_to_dict(send_thank_you_menu, '03', '[ ----- ]: -------------------------------------------------------')
    add_to_dict(send_thank_you_menu, '04', '[     1 ]: Type: \'list\'')
    add_to_dict(send_thank_you_menu, '05', '[       ]:        Display a list of donors.')
    add_to_dict(send_thank_you_menu, '06', '[     2 ]: Type: \'Existing Donor\'s Name\'')
    add_to_dict(send_thank_you_menu, '07', '[       ]:        Add a new donation for a donor.')
    add_to_dict(send_thank_you_menu, '08', '[     3 ]: Type: \'New Donor\'s Name\'')
    add_to_dict(send_thank_you_menu, '09', '[       ]:        Create a new donor.')
    add_to_dict(send_thank_you_menu, '10', '[     4 ]: Type: \'main\'')
    add_to_dict(send_thank_you_menu, '11', '[       ]:        Return to the Main Menu.')
    #
    # Note: This for loop just prints data; not a Comprehension candidate.
    for value in send_thank_you_menu:
        print(send_thank_you_menu[value])

def print_thank_you_message(key, donation_amount):
    print_debug_header_line()
    print(f'\n'
    'Dear {},\n\n'
    'Thank you for your donation of ${}.\n\n'
    '  Regards,\n'
    '  - the Thank You bot\n'.format(key, donation_amount))

def send_thank_you():
    while True:
        #
        # Print the 'send_thank_you_menu'.
        print_send_thank_you_menu()
        #
        # Get user_response.
        user_response = get_user_response()
        #
        # Check user_response.
        if user_response.lower() == 'list':
            list_donor_names(donors_db)
            continue
        elif user_response.lower() == 'main':
            break
        for key, value in donors_db.items():
            if user_response == key:
                #
                # Get the donation amount.
                try:
                    donation_amount = input('[ INPUT ]: Amount to add for {}: '.format(user_response))
                except KeyboardInterrupt:
                    exit_script_ctrl_c()
                except Exception as e:
                    print_error_message('send_thank_you(): try: donation_amount: Error!')
                    print_error_message('e: ' + str(e))
                    break
                #
                # Add the donation; check for success.
                if add_donation(donors_db, user_response, donation_amount):
                    #
                    # If we succeeded, print the thank you mail.
                    print_thank_you_message(key, donation_amount)
                #
                # We have to break here.
                break
        else:
            create_donor(donors_db, user_response)

def send_thank_you_global(database, timestamp):
    #
    # This is the template for the thank you message.
    thank_you_template = str(timestamp) + '\n  Dear {},\n  Thank you for your donation of ${}.\n Regards, \n    - the Thank You bot \n'
    #
    # Get the location of 'tempdir'.
    temp_file_path = tempfile.gettempdir()
    # print_debug_message('temp: ' + str(temp_file_path))
    #
    # Iterate through each donor in the database.
    for key, value in database.items():
        #
        # Format to keep things neat on disk.
        formatted_key = format_text(key)
        formatted_file_name = str(formatted_key) + '_' + str(timestamp) + '.txt'
        formatted_file_path = temp_file_path + '/' + formatted_file_name
        #
        # Format and write the files to disk.
        try:
            with open(formatted_file_path,'w') as file:
                thank_you_letter = thank_you_template.format(key,value)
                file.write(thank_you_letter)
                file.close()
                print_debug_message('file: ' + str(formatted_file_name) + ': Success!')
        except Exception as e:
            print_error_message('file: ' + str(formatted_file_name) + ': Error!')
            print_error_message('e: ' + str(e))

def sort_database(database):
    try:
        database_sorted = dict(sorted(database.items(), key=lambda item: item[1], reverse=True))
        return database_sorted
    except Exception as e:
        print_error_message('sort_database(database): Error!')
        print_error_message('e: ' + str(e))

# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
def comprehensions_test():
    print_debug_message('This is a test of comprehensions!')
    #
    # Try a list comprehension.
    new_list_01 = [i for i in range(10)]
    print_debug_message(new_list_01)
    #
    # Try comprehensions with items in our database.
    new_dict_01 = { d.lower() : donors_db.get(d.lower(), 0) for d in donors_db.keys() }
    new_dict_02 = { d.upper() : donors_db.get(d.upper(), 0) for d in donors_db.keys() }
    print_debug_message(new_dict_01)
    print_debug_message(new_dict_02)
    #
    # This really isn't what comprehensions are for but I wanted to test
    # out comprehensions in deeper detail.
    print_debug_header_line()
    fizzbuzz = [
        print('[  FIZZ ]: n: ' + str(n) + ' fizzbuzz') if n % 3 == 0 and n % 5 == 0
        else print('[  FIZZ ]: n: ' + str(n) + ' fizz') if n % 3 == 0
        else print('[  FIZZ ]: n: ' + str(n) + ' buzz') if n % 5 == 0
        else print('[  FIZZ ]: n: ' + str(n))
        for n in range(101)
    ]
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #

if __name__=='__main__':

    # Create 'donors_db'.
    donors_db = create_donors_db()
    #
    # Populate 'donors_db'.
    add_donation(donors_db, 'Donor 01', float(100.00))
    add_donation(donors_db, 'Donor 02', float(222.22))
    add_donation(donors_db, 'Donor 03', float(333.33))
    add_donation(donors_db, 'Donor 04', float(499.99))
    #
    # Smoke test: This _should_ generate an error in the console.
    # add_donation(donors_db, 'Donor 01', 'z')

    # Call display_main_menu().
    display_main_menu()


# import cv2
# import SimpleITK as sitk
# import matplotlib.pyplot as plt
# import numpy as np
# filename = 'D:/oukai/dataset/Camus/training/patient0001/patient0001_2CH_ED.mhd'
# itk_img = sitk.ReadImage(filename)
# img_array = sitk.GetArrayFromImage(itk_img)
# print(img_array.shape)

# import SimpleITK as sitk
# import os
# import cv2
# filename = 'D:/oukai/dataset/Camus/training/patient0001/patient0001_2CH_ED.mhd'
# path = 'D:/oukai/dataset/Camus'   #存放拆分得到图像的路径
# itk_img = sitk.ReadImage(filename)
# img_array = sitk.GetArrayFromImage(itk_img)
# for i, im in enumerate(img_array):
#   cv2.imwrite(os.path.join(path, '{}.png'.format(i)), im)

import SimpleITK as sitk
import cv2
filename = 'D:/oukai/dataset/Camus/training/patient0001/patient0001_2CH_ED.mhd'
itk_img = sitk.ReadImage(filename)
img_array = sitk.GetArrayFromImage(itk_img)
frame_num, width, height = img_array.shape
path = 'D:/oukai/dataset/Camus'   #存放拆分得到图像的路径
index = -1
for img_item in img_array:
    index = index + 1
    cv2.imwrite("%s/%d.png" % (path, index), img_item)
print("done!")


from nipype.pipeline import engine as pe
from nipype.interfaces import utility as niu

from niworkflows.engine.workflows import LiterateWorkflow as Workflow

from ... import data

INPUT_FIELDS = ("metadata", "in_data")
_PEPOLAR_DESC = """\
A *B0*-nonuniformity map (or *fieldmap*) was estimated based on two (or more)
echo-planar imaging (EPI) references """

def init_topup_wf(
    grid_reference=0,
    omp_nthreads=1,
    sloppy=False,
    debug=False,
    name="pepolar_estimate_wf",
):
    """
    Create the PEPOLAR field estimation workflow based on FSL's ``topup``.

    Workflow Graph
        .. workflow ::
            :graph2use: orig
            :simple_form: yes

            from sdcflows.workflows.fit.pepolar import init_topup_wf
            wf = init_topup_wf()

    Parameters
    ----------
    grid_reference : :obj:`int`
        Index of the volume (after flattening) that will be taken for gridding reference.
    sloppy : :obj:`bool`
        Whether a fast configuration of topup (less accurate) should be applied.
    debug : :obj:`bool`
        Run in debug mode
    name : :obj:`str`
        Name for this workflow
    omp_nthreads : :obj:`int`
        Parallelize internal tasks across the number of CPUs given by this option.

    Inputs
    ------
    in_data : :obj:`list` of :obj:`str`
        A list of EPI files that will be fed into TOPUP.
    metadata : :obj:`list` of :obj:`dict`
        A list of dictionaries containing the metadata corresponding to each file
        in ``in_data``.

    Outputs
    -------
    fmap : :obj:`str`
        The path of the estimated fieldmap.
    fmap_ref : :obj:`str`
        The path of an unwarped conversion of files in ``in_data``.
    fmap_mask : :obj:`str`
        The path of mask corresponding to the ``fmap_ref`` output.
    fmap_coeff : :obj:`str` or :obj:`list` of :obj:`str`
        The path(s) of the B-Spline coefficients supporting the fieldmap.
    method: :obj:`str`
        Short description of the estimation method that was run.

    """
    from nipype.interfaces.fsl.epi import TOPUP
    from niworkflows.interfaces.nibabel import MergeSeries, ReorientImage
    from niworkflows.interfaces.images import RobustAverage

    from ...utils.misc import front as _front
    from ...interfaces.epi import GetReadoutTime, SortPEBlips
    from ...interfaces.utils import UniformGrid, PadSlices, ReorientImageAndMetadata
    from ...interfaces.bspline import TOPUPCoeffReorient
    from ..ancillary import init_brainextraction_wf

    workflow = Workflow(name=name)
    workflow.__desc__ = f"""\
{_PEPOLAR_DESC} with `topup` (@topup; FSL {TOPUP().version}).
"""

    inputnode = pe.Node(niu.IdentityInterface(fields=INPUT_FIELDS), name="inputnode")
    outputnode = pe.Node(
        niu.IdentityInterface(
            fields=[
                "fmap",
                "fmap_ref",
                "fmap_coeff",
                "fmap_mask",
                "jacobians",
                "xfms",
                "out_warps",
                "method",
            ]
        ),
        name="outputnode",
    )
    outputnode.inputs.method = "PEB/PEPOLAR (phase-encoding based / PE-POLARity)"

    # Calculate the total readout time of each run
    readout_time = pe.MapNode(
        GetReadoutTime(),
        name="readout_time",
        iterfield=["metadata", "in_file"],
        run_without_submitting=True,
    )
    # Average each run so that topup is not overwhelmed (see #279)
    runwise_avg = pe.MapNode(
        RobustAverage(num_threads=omp_nthreads),
        name="runwise_avg",
        iterfield="in_file",
    )
    # Regrid all to the reference (grid_reference=0 means first averaged run)
    regrid = pe.Node(UniformGrid(reference=grid_reference), name="regrid")
    # Sort PE blips to ensure reproducibility
    sort_pe_blips = pe.Node(
        SortPEBlips(), name="sort_pe_blips", run_without_submitting=True
    )
    # Merge into one 4D file
    concat_blips = pe.Node(MergeSeries(affine_tolerance=1e-4), name="concat_blips")
    # Pad dimensions so that they meet TOPUP's expectations
    pad_blip_slices = pe.Node(PadSlices(), name="pad_blip_slices")
    # Run 3dVolReg between runs: uses RobustAverage for consistency and to generate
    # debugging artifacts (typically, one wants to look at the average across uncorrected runs)
    setwise_avg = pe.Node(RobustAverage(num_threads=omp_nthreads), name="setwise_avg")
    # The core of the implementation
    # Feed the input images in LAS orientation, so FSL does not run funky reorientations
    to_las = pe.Node(ReorientImageAndMetadata(target_orientation="LAS"), name="to_las")
    topup = pe.Node(
        TOPUP(
            config=str(data.load(f"flirtsch/b02b0{'_quick' * sloppy}.cnf"))
        ),
        name="topup",
    )
    # "Generalize" topup coefficients and store them in a spatially-correct NIfTI file
    fix_coeff = pe.Node(
        TOPUPCoeffReorient(), name="fix_coeff", run_without_submitting=True
    )

    # Average the output
    ref_average = pe.Node(RobustAverage(num_threads=omp_nthreads), name="ref_average")

    # Sophisticated brain extraction of fMRIPrep
    brainextraction_wf = init_brainextraction_wf()

    # fmt: off
    workflow.connect([
        (inputnode, runwise_avg, [("in_data", "in_file")]),
        (inputnode, readout_time, [("metadata", "metadata")]),
        (runwise_avg, regrid, [("out_file", "in_data")]),
        (regrid, readout_time, [("out_data", "in_file")]),
        (regrid, sort_pe_blips, [("out_data", "in_data")]),
        (readout_time, sort_pe_blips, [("readout_time", "readout_times"),
                                       ("pe_dir_fsl", "pe_dirs_fsl")]),
        (sort_pe_blips, topup, [("readout_times", "readout_times")]),
        (setwise_avg, fix_coeff, [("out_file", "fmap_ref")]),
        (sort_pe_blips, concat_blips, [("out_data", "in_files")]),
        (concat_blips, pad_blip_slices, [("out_file", "in_file")]),
        (pad_blip_slices, setwise_avg, [("out_file", "in_file")]),
        (setwise_avg, to_las, [("out_hmc_volumes", "in_file")]),
        (sort_pe_blips, to_las, [("pe_dirs_fsl", "pe_dir")]),
        (to_las, topup, [
            ("out_file", "in_file"),
            ("pe_dir", "encoding_direction"),
        ]),
        (topup, fix_coeff, [("out_fieldcoef", "in_coeff")]),
        (to_las, fix_coeff, [(("pe_dir", _front), "pe_dir")]),
        (topup, outputnode, [("out_jacs", "jacobians"),
                             ("out_mats", "xfms")]),
        (ref_average, brainextraction_wf, [("out_file", "inputnode.in_file")]),
        (brainextraction_wf, outputnode, [
            ("outputnode.out_file", "fmap_ref"),
            ("outputnode.out_mask", "fmap_mask")
        ]),
        (fix_coeff, outputnode, [("out_coeff", "fmap_coeff")]),
    ])
    # fmt: on

    if not debug:
        # Roll orientation back to original
        from_las = pe.Node(ReorientImage(), name="from_las")
        from_las_fmap = pe.Node(ReorientImage(), name="from_las_fmap")
        # fmt: off
        workflow.connect([
            (setwise_avg, from_las, [("out_file", "target_file")]),
            (setwise_avg, from_las_fmap, [("out_file", "target_file")]),
            (topup, from_las, [("out_corrected", "in_file")]),
            (from_las, ref_average, [("out_file", "in_file")]),
            (topup, from_las_fmap, [("out_field", "in_file")]),
            (topup, outputnode, [("out_warps", "out_warps")]),
            (from_las_fmap, outputnode, [("out_file", "fmap")]),
        ])
        # fmt: on
        return workflow

    from sdcflows.interfaces.bspline import ApplyCoeffsField

    # Separate the runs again, as our ApplyCoeffsField corrects them separately
    unwarp = pe.Node(ApplyCoeffsField(), name="unwarp")
    unwarp.interface._always_run = True
    concat_corrected = pe.Node(MergeSeries(), name="concat_corrected")

    # fmt:off
    workflow.connect([
        (fix_coeff, unwarp, [("out_coeff", "in_coeff")]),
        (setwise_avg, unwarp, [("out_hmc_volumes", "in_data")]),
        (sort_pe_blips, unwarp, [("readout_times", "ro_time"),
                                 ("pe_dirs", "pe_dir")]),
        (unwarp, outputnode, [("out_field", "fmap")]),
        (unwarp, concat_corrected, [("out_corrected", "in_files")]),
        (concat_corrected, ref_average, [("out_file", "in_file")]),
    ])
    # fmt:on

    return workflow

def init_3dQwarp_wf(omp_nthreads=1, debug=False, name="pepolar_estimate_wf"):
    """
    Create the PEPOLAR field estimation workflow based on AFNI's ``3dQwarp``.

    This workflow takes in two EPI files that MUST have opposed
    :abbr:`PE (phase-encoding)` direction.
    Therefore, EPIs with orthogonal PE directions are not supported.

    Workflow Graph
        .. workflow ::
            :graph2use: orig
            :simple_form: yes

            from sdcflows.workflows.fit.pepolar import init_3dQwarp_wf
            wf = init_3dQwarp_wf()

    Parameters
    ----------
    debug : :obj:`bool`
        Whether a fast configuration of topup (less accurate) should be applied.
    name : :obj:`str`
        Name for this workflow
    omp_nthreads : :obj:`int`
        Parallelize internal tasks across the number of CPUs given by this option.

    Inputs
    ------
    in_data : :obj:`list` of :obj:`str`
        A list of two EPI files, the first of which will be taken as reference.

    Outputs
    -------
    fmap : :obj:`str`
        The path of the estimated fieldmap.
    fmap_ref : :obj:`str`
        The path of an unwarped conversion of the first element of ``in_data``.

    """
    from nipype.interfaces import afni
    from niworkflows.interfaces.header import CopyHeader
    from niworkflows.interfaces.fixes import (
        FixHeaderRegistration as Registration,
        FixHeaderApplyTransforms as ApplyTransforms,
    )
    from niworkflows.interfaces.freesurfer import StructuralReference
    from niworkflows.func.util import init_enhance_and_skullstrip_bold_wf
    from ...utils.misc import front as _front, last as _last
    from ...interfaces.utils import Flatten, ConvertWarp

    workflow = Workflow(name=name)
    workflow.__desc__ = f"""{_PEPOLAR_DESC} \
with `3dQwarp` (@afni; AFNI {''.join(['%02d' % v for v in afni.Info().version() or []])}).
"""

    inputnode = pe.Node(
        niu.IdentityInterface(fields=["in_data", "metadata"]), name="inputnode"
    )

    outputnode = pe.Node(
        niu.IdentityInterface(fields=["fmap", "fmap_ref"]), name="outputnode"
    )

    flatten = pe.Node(Flatten(), name="flatten")
    sort_pe = pe.Node(
        niu.Function(function=_sorted_pe, output_names=["sorted", "qwarp_args"]),
        name="sort_pe",
        run_without_submitting=True,
    )

    merge_pes = pe.MapNode(
        StructuralReference(
            auto_detect_sensitivity=True,
            initial_timepoint=1,
            fixed_timepoint=True,  # Align to first image
            intensity_scaling=True,
            # 7-DOF (rigid + intensity)
            no_iteration=True,
            subsample_threshold=200,
            out_file="template.nii.gz",
        ),
        name="merge_pes",
        iterfield=["in_files"],
    )

    pe0_wf = init_enhance_and_skullstrip_bold_wf(
        omp_nthreads=omp_nthreads, name="pe0_wf"
    )
    pe1_wf = init_enhance_and_skullstrip_bold_wf(
        omp_nthreads=omp_nthreads, name="pe1_wf"
    )

    align_pes = pe.Node(
        Registration(
            from_file=data.load("translation_rigid.json"),
            output_warped_image=True,
        ),
        name="align_pes",
        n_procs=omp_nthreads,
    )

    qwarp = pe.Node(
        afni.QwarpPlusMinus(
            blur=[-1, -1],
            environ={"OMP_NUM_THREADS": f"{min(omp_nthreads, 4)}"},
            minpatch=9,
            nopadWARP=True,
            noweight=True,
            pblur=[0.05, 0.05],
        ),
        name="qwarp",
        n_procs=min(omp_nthreads, 4),
    )

    to_ants = pe.Node(ConvertWarp(), name="to_ants", mem_gb=0.01)

    cphdr_warp = pe.Node(CopyHeader(), name="cphdr_warp", mem_gb=0.01)

    unwarp_reference = pe.Node(
        ApplyTransforms(
            dimension=3,
            float=True,
            interpolation="LanczosWindowedSinc",
        ),
        name="unwarp_reference",
    )

    # fmt: off
    workflow.connect([
        (inputnode, flatten, [("in_data", "in_data"),
                              ("metadata", "in_meta")]),
        (flatten, sort_pe, [("out_list", "inlist")]),
        (sort_pe, qwarp, [("qwarp_args", "args")]),
        (sort_pe, merge_pes, [("sorted", "in_files")]),
        (merge_pes, pe0_wf, [(("out_file", _front), "inputnode.in_file")]),
        (merge_pes, pe1_wf, [(("out_file", _last), "inputnode.in_file")]),
        (pe0_wf, align_pes, [("outputnode.skull_stripped_file", "fixed_image")]),
        (pe1_wf, align_pes, [("outputnode.skull_stripped_file", "moving_image")]),
        (pe0_wf, qwarp, [("outputnode.skull_stripped_file", "in_file")]),
        (align_pes, qwarp, [("warped_image", "base_file")]),
        (inputnode, cphdr_warp, [(("in_data", _front), "hdr_file")]),
        (qwarp, cphdr_warp, [("source_warp", "in_file")]),
        (cphdr_warp, to_ants, [("out_file", "in_file")]),
        (to_ants, unwarp_reference, [("out_file", "transforms")]),
        (inputnode, unwarp_reference, [("in_reference", "reference_image"),
                                       ("in_reference", "input_image")]),
        (unwarp_reference, outputnode, [("output_image", "fmap_ref")]),
        (to_ants, outputnode, [("out_file", "fmap")]),
    ])
    # fmt: on
    return workflow

def _sorted_pe(inlist):
    """
    Generate suitable inputs to ``3dQwarp``.

    Example
    -------
    >>> paths, args = _sorted_pe([
    ...     ("dir-AP_epi.nii.gz", {"PhaseEncodingDirection": "j-"}),
    ...     ("dir-AP_bold.nii.gz", {"PhaseEncodingDirection": "j-"}),
    ...     ("dir-PA_epi.nii.gz", {"PhaseEncodingDirection": "j"}),
    ...     ("dir-PA_bold.nii.gz", {"PhaseEncodingDirection": "j"}),
    ...     ("dir-AP_sbref.nii.gz", {"PhaseEncodingDirection": "j-"}),
    ...     ("dir-PA_sbref.nii.gz", {"PhaseEncodingDirection": "j"}),
    ... ])
    >>> paths[0]
    ['dir-AP_epi.nii.gz', 'dir-AP_bold.nii.gz', 'dir-AP_sbref.nii.gz']

    >>> paths[1]
    ['dir-PA_epi.nii.gz', 'dir-PA_bold.nii.gz', 'dir-PA_sbref.nii.gz']

    >>> args
    '-noXdis -noZdis'

    >>> paths, args = _sorted_pe([
    ...     ("dir-AP_epi.nii.gz", {"PhaseEncodingDirection": "j-"}),
    ...     ("dir-LR_epi.nii.gz", {"PhaseEncodingDirection": "i"}),
    ... ])  # doctest: +IGNORE_EXCEPTION_DETAIL
    Traceback (most recent call last):
    ValueError:

    """
    out_ref = [inlist[0][0]]
    out_opp = []

    ref_pe = inlist[0][1]["PhaseEncodingDirection"]
    for d, m in inlist[1:]:
        pe = m["PhaseEncodingDirection"]
        if pe == ref_pe:
            out_ref.append(d)
        elif pe[0] == ref_pe[0]:
            out_opp.append(d)
        else:
            raise ValueError("Cannot handle orthogonal PE encodings.")

    return (
        [out_ref, out_opp],
        {"i": "-noYdis -noZdis", "j": "-noXdis -noZdis", "k": "-noXdis -noYdis"}[
            ref_pe[0]
        ],
    )


from __future__ import annotations
from discord.ext.commands import Context
from beginner.cog import Cog
from beginner.config import get_setting
from beginner.colors import *
import discord

class ResourcesCog(Cog):
    @Cog.command(aliases=("r", "resource"))
    async def resources(self, ctx: Context, *, lang_name: str = "py"):
        lang_code = get_setting(
            lang_name.casefold(), scope="lang_aliases", default=lang_name.casefold()
        )
        lang = get_setting(lang_code, scope="resources")

        if not lang:
            await ctx.send(f"Could not find any resources for `{lang_code}`")
            return

        embed = discord.Embed(
            title=f"Helpful {lang['name']} Resources",
            description="Here are some resources you may find helpful.",
            color=YELLOW,
        )

        for title, resources in (
            section for section in lang.items() if section[0] != "name"
        ):
            embed.add_field(
                name=title,
                value="\n".join(f"[{name}]({url})" for name, url in resources.items()),
                inline=False,
            )

        await ctx.send(embed=embed)

    @Cog.command(aliases=["project-ideas", "ideas"])
    async def project(self, ctx):
        project_embed = discord.Embed(
            title="Project Ideas",
            description=(
                f"{ctx.author.mention} Here's our official list of "
                f"[project ideas!](https://github.com/beginnerpy-com/project-ideas)"
            ),
            color=BLUE,
            url="https://github.com/beginnerpy-com/project-ideas",
        ).set_thumbnail(url="https://emojipedia-us.s3.dualstack.us-west-1.amazonaws.com/thumbs/120/twitter/282/brain_1f9e0.png")
        await ctx.send(embed=project_embed)

def setup(client):
    client.add_cog(ResourcesCog(client))


import pandas as pd
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.metrics.pairwise import cosine_similarity
import joblib
import re
from colorama import Fore, Back, Style, init
import os

# Renkleri başlat
init(autoreset=True)

# Ekran genişliği ve yüksekliği
screen_width = os.get_terminal_size().columns
screen_height = os.get_terminal_size().lines

# Metin
title = "Python Makine Öğrenimi Sql Sorgu Oluşturma"
author = "GitHub: @abdullaheroll"

# Metni renklendirme
colored_title = Fore.GREEN + title
colored_author = Fore.YELLOW + author

# Metni tam ortalamak için hesaplamalar
title_padding = (screen_width - len(title)) // 2
author_padding = (screen_width - len(author)) // 2

# Metni tam ortaya yerleştirme
centered_title = " " * title_padding + colored_title
centered_author = " " * author_padding + colored_author

# Başlık ve yazarı yazdırma
print("*" * screen_width)
print(centered_title)
print(centered_author)
print("*" * screen_width)

# Veri setini oku
data = pd.read_csv('turkish_query_answ_sql.csv')

# Veri kümesindeki input ve query alanları
inputs = data['Input']
queries = data['Query']

# TF-IDF vektörlerini oluştur
vectorizer = TfidfVectorizer()
tfidf_matrix = vectorizer.fit_transform(inputs)

# Modeli eğit
cosine_sim = cosine_similarity(tfidf_matrix)

# Modeli kaydet
joblib.dump(cosine_sim, 'cosine_similarity_model.pkl')

# Kaydedilen modeli yükle
cosine_sim = joblib.load('cosine_similarity_model.pkl')

# Kullanıcıdan metin tabanlı input al
user_input = input("Metin Giriniz: ")

# Veriyi temizleme fonksiyonu
def preprocess_text(text):
    text = re.sub(r'[^\w\s]', '', text)
    text = text.lower()
    return text

    # Temizlenmiş kullanıcı girdisi
clean_user_input = preprocess_text(user_input)

# En benzer sorguyu bul
max_similarity = -1
best_query = None

# Kullanıcı girdisini vektöre dönüştür
user_input_vector = vectorizer.transform([clean_user_input])

for i, input_text in enumerate(inputs):
    similarity = cosine_similarity(user_input_vector, tfidf_matrix[i])[0][0]
    if similarity > max_similarity:
        max_similarity = similarity
        best_query = queries[i]

if max_similarity > 0:
    print("Eşleşen sorgu:", best_query)
else:
    print("Eşleşen sorgu bulunamadı.")


import streamlit as st
import pandas as pd
import numpy as np
import plotly.express as px

st.set_page_config(layout='wide')

df = pd.read_csv('india.csv')

st.sidebar.title("India ka vizualization")

# state wise list

list_of_states = sorted(list(df['State'].unique()))
list_of_states.insert(0,'Overall India')

# list of states
selected_state = st.sidebar.selectbox("Select a State", list_of_states)

# list of categories
category_list = sorted(df.columns[5:])
category_list.insert(0,'Select a category')
primary_parameter = st.sidebar.selectbox('Select primary parameter', category_list)
secondary_parameter = st.sidebar.selectbox('Select secondary parameter', category_list)

plot = st.sidebar.button("Plot Graph")

if plot:
    st.text("Size represents Primary parameters")
    st.text("Color represents Secondary parameters")
    if selected_state == 'Overall India':
        # plot for india
        fig = px.scatter_mapbox(df, lat="Latitude", lon="Longitude",
                                zoom=5, size=primary_parameter, color=secondary_parameter,size_max=50,
                                mapbox_style='carto-positron',color_continuous_scale=px.colors.cyclical.IceFire,
                                hover_data=['State','District','Population'],
                                width=1200,height=800)
        st.plotly_chart(fig, use_container_width=True)
    else:
        # plot for state
        state_df = df[df['State'] == selected_state]
        fig = px.scatter_mapbox(state_df, lat="Latitude", lon="Longitude",
                                zoom=6, size=primary_parameter, color=secondary_parameter,size_max=50,
                                mapbox_style='carto-positron',color_continuous_scale=px.colors.cyclical.IceFire,
                                hover_data=['State', 'District', 'Population'],
                                width=1200,height=800)
        st.plotly_chart(fig, use_container_width=True)


import copy
import matplotlib
matplotlib.use("Qt5Agg")
import matplotlib.patches as mpatches
import matplotlib.pyplot as plt
import multiprocessing
import numpy as np
import os
import os.path
import pickle
import sys
import tensorflow as tf
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.figure import Figure
from PyQt5 import QtCore, QtGui, QtWidgets
from constants import *
from gamestate import *
from mcts import *
from model import *
from util import extract_inputs, transform, get_state_sequence, reshape_feature_sequence, index_to_pos, pos_to_index

class GameWindow(QtWidgets.QMainWindow):
  def __init__(self):
    super(GameWindow, self).__init__()
    self.player_black = HUMAN_PLAYER
    self.player_white = HUMAN_PLAYER
    self.evaluator = BEST_PLAYER
    self.hint = False
    self.start = False
    self.state = None
    self.move_history = None
    self.state_history = None

    # Basic configurations.
    self.setAttribute(QtCore.Qt.WA_DeleteOnClose)
    self.update_title()
    self.setFixedSize(500, 600)

    # Add menubar.
    self.menu = QtWidgets.QMenu("Menu", self)
    # New game action.
    self.new_game_action = QtWidgets.QAction("New Game", self.menu)
    self.new_game_action.setShortcut(QtCore.Qt.CTRL + QtCore.Qt.Key_N)
    self.new_game_action.triggered.connect(self.new_game_handler)
    # Edit players action.
    self.players_action = QtWidgets.QAction("Players", self.menu)
    self.players_action.setShortcut(QtCore.Qt.CTRL + QtCore.Qt.Key_P)
    self.players_action.triggered.connect(self.players_handler)
    # Quit action.
    self.quit_action = QtWidgets.QAction("Quit", self.menu)
    self.quit_action.setShortcut(QtCore.Qt.CTRL + QtCore.Qt.Key_Q)
    self.quit_action.triggered.connect(self.quit_handler)
    # Add actions to the menubar.
    self.menu.addAction(self.new_game_action)
    self.menu.addAction(self.players_action)
    self.menu.addAction(self.quit_action)
    self.menuBar().addMenu(self.menu)

    # Add optionbar.
    self.option = QtWidgets.QMenu("Options", self)
    # Undo action.
    self.undo_action = QtWidgets.QAction("Undo", self.option)
    self.undo_action.setShortcut(QtCore.Qt.CTRL + QtCore.Qt.Key_Z)
    self.undo_action.triggered.connect(self.undo_handler)
    # Hint action.
    self.hint_action = QtWidgets.QAction("Hint", self.option)
    self.hint_action.setShortcut(QtCore.Qt.CTRL + QtCore.Qt.Key_H)
    self.hint_action.triggered.connect(self.hint_handler)
    # Start action.
    self.start_action = QtWidgets.QAction("Start", self.option)
    self.start_action.setShortcut(QtCore.Qt.CTRL + QtCore.Qt.Key_S)
    self.start_action.triggered.connect(self.start_handler)
    # Evaluate action.
    self.eval_action = QtWidgets.QAction("Evaluate", self.option)
    self.eval_action.setShortcut(QtCore.Qt.CTRL + QtCore.Qt.Key_E)
    self.eval_action.triggered.connect(self.eval_handler)
    # Add actions to the optionbar.
    self.option.addAction(self.undo_action)
    self.option.addAction(self.hint_action)
    self.option.addAction(self.start_action)
    self.option.addAction(self.eval_action)
    self.menuBar().addMenu(self.option)

    # Add main widget.
    self.main_widget = QtWidgets.QWidget(self)

    # Add buttonbar.
    self.button_widget = QtWidgets.QWidget(self.main_widget)
    # Undo button.
    self.undo_button = QtWidgets.QPushButton("Undo (Z)", self.button_widget)
    self.undo_button.setFixedSize(100, 30)
    self.undo_button.setToolTip("Undo the last move.")
    self.undo_button.clicked.connect(self.undo_handler)
    # Hint button.
    self.hint_button = QtWidgets.QPushButton("Hint (H)", self.button_widget)
    self.hint_button.setFixedSize(100, 30)
    self.hint_button.setToolTip("Show legal moves.")
    self.hint_button.clicked.connect(self.hint_handler)
    # Start button.
    self.start_button = QtWidgets.QPushButton("Start (S)", self.button_widget)
    self.start_button.setFixedSize(100, 30)
    self.start_button.setToolTip("Start the bot player(s).")
    self.start_button.clicked.connect(self.start_handler)
    # Evaluate button.
    self.eval_button = QtWidgets.QPushButton("Evaluate (E)", self.button_widget)
    self.eval_button.setFixedSize(100, 30)
    self.eval_button.setToolTip("Evaluate the current state.")
    self.eval_button.clicked.connect(self.eval_handler)
    # Add buttons to the buttonbar.
    button_layout = QtWidgets.QHBoxLayout(self.button_widget)
    button_layout.addWidget(self.undo_button)
    button_layout.addWidget(self.hint_button)
    button_layout.addWidget(self.start_button)
    button_layout.addWidget(self.eval_button)

    # Create game canvas.
    self.game_canvas = GameCanvas(self.main_widget, self)

    # Add contents.
    main_layout = QtWidgets.QVBoxLayout(self.main_widget)
    main_layout.addWidget(self.button_widget)
    main_layout.addWidget(self.game_canvas)
    main_layout.setContentsMargins(0, 0, 0, 0)

    # Add pass button.
    self.pass_button = QtWidgets.QPushButton("Pass", self.main_widget)
    self.pass_button.setGeometry(225, 540, 50, 30)
    self.pass_button.clicked.connect(self.pass_button_handler)

    # Update buttons.
    self.update_buttons()

    self.main_widget.setFocus()
    self.setCentralWidget(self.main_widget)

  def new_game_handler(self):
    # Update and store state.
    self.state = GameState()
    self.move_history = []
    self.state_history = []
    self.state_history.append(copy.deepcopy(self.state))
    if self.player_black != HUMAN_PLAYER:
      self.mcts_black = MCTS([self.state], self.player_black, None)
    else:
      self.mcts_black = None
    if self.player_white != HUMAN_PLAYER:
      self.mcts_white = MCTS([self.state], self.player_white, None)
    else:
      self.mcts_white = None

    # Update game board.
    self.game_canvas.draw_gameboard()

    # Update title.
    self.update_title()

    # Update buttons.
    if self.start:
      self.start_action.trigger()
    self.update_buttons()

  def players_handler(self):
    edit_players_dialog = EditPlayersDialog([self.player_black, self.player_white, self.evaluator])
    if edit_players_dialog.exec_() == QtWidgets.QDialog.Accepted:
      value = edit_players_dialog.get_value()
      player_black_old = self.player_black
      player_white_old = self.player_white
      self.player_black = value[0]
      self.player_white = value[1]
      self.evaluator = value[2]
      if self.state != None:
        # Update MCTS states.
        if self.player_black != HUMAN_PLAYER:
          if self.player_black != player_black_old:
            self.mcts_black = MCTS([self.state], self.player_black, None)
        else:
          self.mcts_black = None
        if self.player_white != HUMAN_PLAYER:
          if self.player_white != player_white_old:
            self.mcts_white = MCTS([self.state], self.player_white, None)
        else:
          self.mcts_white = None

        # Update title.
        self.update_title()

        # Update buttons.
        if self.player_black != player_black_old or self.player_white != player_white_old:
          if self.start:
            self.start_action.trigger()
        self.update_buttons()

  def quit_handler(self):
    self.close()

  def pass_button_handler(self):
    # Update and store state.
    index = pos_to_index(PASS)
    index_i = np.argwhere(np.equal(self.state.legal_moves, index))[0][0]
    self.move_history.append(index)
    self.state_history.append(copy.deepcopy(self.state.select_move(index)))
    if self.mcts_black != None:
      self.mcts_black.get_subtree(0, index_i)
    if self.mcts_white != None:
      self.mcts_white.get_subtree(0, index_i)

    # Update game board.
    self.game_canvas.draw_gameboard()

    # Update buttons.
    self.update_buttons()

    # Run bots.
    if not self.state.game_ends and self.start:
      if self.state.is_black:
        if self.player_black != HUMAN_PLAYER:
          t = threading.Thread(target = self.run_bot, args = (BLACK,))
          t.start()
      else:
        if self.player_white != HUMAN_PLAYER:
          t = threading.Thread(target = self.run_bot, args = (WHITE,))
          t.start()

  def undo_handler(self):
    # Remove and restore state.
    self.move_history.pop()
    self.state_history.pop()
    self.state = copy.deepcopy(self.state_history[-1])
    if self.mcts_black != None:
      self.mcts_black = MCTS([self.state], self.player_black, None)
    if self.mcts_white != None:
      self.mcts_white = MCTS([self.state], self.player_white, None)

    # Update game board.
    self.game_canvas.draw_gameboard()

    # Update buttons.
    if self.start:
      self.start_action.trigger()
    self.update_buttons()

  def hint_handler(self):
    if not self.hint:
      self.hint = True
      self.hint_action.setText("Hide")
      self.hint_button.setText("Hide (H)")
      self.hint_button.setToolTip("Hide legal moves.")
    else:
      self.hint = False
      self.hint_action.setText("Hint")
      self.hint_button.setText("Hint (H)")
      self.hint_button.setToolTip("Show legal moves.")
    if self.state is not None:
      self.game_canvas.draw_gameboard()

  def start_handler(self):
    # Update buttons.
    if not self.start:
      self.start = True
      self.start_action.setText("Stop")
      self.start_button.setText("Stop (S)")
      self.start_button.setToolTip("Stop the bot player(s).")
    else:
      self.start = False
      self.start_action.setText("Start")
      self.start_button.setText("Start (S)")
      self.start_button.setToolTip("Start the bot player(s).")
    self.update_buttons()

    # Run bots.
    if not self.state.game_ends and self.start:
      if self.state.is_black:
        if self.player_black != HUMAN_PLAYER:
          t = threading.Thread(target = self.run_bot, args = (BLACK,))
          t.start()
      else:
        if self.player_white != HUMAN_PLAYER:
          t = threading.Thread(target = self.run_bot, args = (WHITE,))
          t.start()

  def eval_handler(self):
    # Evaluate the probability distribution.
    mcts = MCTS([self.state], self.evaluator, None)
    pi = mcts.tree_search()[0]
    # Get the predicted action sequence.
    a = mcts.get_action_sequence()

    # Evaluate the value.
    model = Model(enhance = True, imitate = True, optimize = 0)
    with tf.Session() as sess:
      saver = tf.train.Saver()
      # Restore the player.
      if self.evaluator == BEST_PLAYER:
        file_name = "BestPlayer"
      else:
        file_name = "Player_" + format(self.evaluator, "05d")
      saver.restore(sess, PLAYER_DIR + file_name)

      # Transform the action sequence into state sequence.
      state_sequence, sequence_length, sequence_index = get_state_sequence([self.state], a)

      # Randomly transform the state.
      n = np.random.choice(SYMMETRY)
      transformed_state = copy.deepcopy(self.state)
      transformed_state = transform(transformed_state, n)
      # Update the state sequence.
      state_sequence = [transform(x, n) for x in state_sequence]
      # Extract inputs from state.
      inputs = extract_inputs([transformed_state])
      inputs_sequence = extract_inputs(state_sequence)

      # Compute the feature sequence.
      feature_sequence = sess.run(model.x, feed_dict = {model.Inputs: inputs_sequence})
      feature_sequence = reshape_feature_sequence(feature_sequence, sequence_length, sequence_index)

      # Compute the value and policy.
      feed_dict = {model.Inputs: inputs, model.Feature_Sequence: feature_sequence, model.Sequence_Length: sequence_length}
      target = [model.v, model.p, model.v_prime, model.p_prime, model.v_hat, model.p_hat]
      v, p, v_prime, p_prime, v_hat, p_hat = sess.run(target, feed_dict = feed_dict)
      v = v[0, 0]
      p = normalize_probability(p, [transformed_state.legal_moves])
      p = p[0]
      v_prime = v_prime[0, 0]
      p_prime = normalize_probability(p_prime, [transformed_state.legal_moves])
      p_prime = p_prime[0]
      v_hat = v_hat[0, 0]
      p_hat = normalize_probability(p_hat, [transformed_state.legal_moves])
      p_hat = p_hat[0]

      print("V     = " + str(v))
      print("V'    = " + str(v_prime))
      print("V_hat = " + str(v_hat))
      print("P     = " + str(p))
      print("P'    = " + str(p_prime))
      print("P_hat = " + str(p_hat))
      print("Pi    = " + str(pi))
      print("===================")
    tf.contrib.keras.backend.clear_session()
    self.game_canvas.draw_gameboard(pi, v)

  def update_title(self):
    if self.state == None:
      self.setWindowTitle("Othello")
    else:
      if self.player_black == HUMAN_PLAYER:
        black_name = "Human"
      elif self.player_black == BEST_PLAYER:
        black_name = "Best Bot"
      else:
        black_name = "Bot " + str(self.player_black)
      if self.player_white == HUMAN_PLAYER:
        white_name = "Human"
      elif self.player_white == BEST_PLAYER:
        white_name = "Best Bot"
      else:
        white_name = "Bot " + str(self.player_white)
      self.setWindowTitle("Othello " + black_name + "[B] vs. " + white_name + "[W]")

  def update_buttons(self):
    # Pass button.
    if self.state != None and (not self.start or self.start and (self.player_black == HUMAN_PLAYER if self.state.is_black else self.player_white == HUMAN_PLAYER)):
      if not self.state.game_ends and self.state.legal_moves[0] == pos_to_index(PASS):
        self.pass_button.setEnabled(True)
      else:
        self.pass_button.setEnabled(False)
    else:
      self.pass_button.setEnabled(False)

    # Undo button.
    if self.state != None and self.state.step > 0:
      self.undo_action.setEnabled(True)
      self.undo_button.setEnabled(True)
    else:
      self.undo_action.setEnabled(False)
      self.undo_button.setEnabled(False)

    # Hint button.
    if self.state != None:
      self.hint_action.setEnabled(True)
      self.hint_button.setEnabled(True)
    else:
      self.hint_action.setEnabled(False)
      self.hint_button.setEnabled(False)

    # Evaluate button.
    if self.state != None and not self.state.game_ends:
      self.eval_action.setEnabled(True)
      self.eval_button.setEnabled(True)
    else:
      self.eval_action.setEnabled(False)
      self.eval_button.setEnabled(False)

    # Start button.
    if self.state != None and not self.state.game_ends and (self.player_black != HUMAN_PLAYER or self.player_white != HUMAN_PLAYER):
      self.start_action.setEnabled(True)
      self.start_button.setEnabled(True)
    else:
      if self.start:
        self.start_action.trigger()
      self.start_action.setEnabled(False)
      self.start_button.setEnabled(False)

  def run_bot(self, color):
    mcts = self.mcts_black if color == BLACK else self.mcts_white
    # Run the Monte-Carlo Tree Search for the current player.
    pi = mcts.tree_search()[0]

    arg_max = np.argwhere(pi == np.amax(pi))
    pi = np.zeros_like(pi)
    pi[arg_max] = 1 / len(arg_max)
    index_i = np.random.choice(len(self.state.legal_moves), p = pi)
    index = self.state.legal_moves[index_i]

    # Update and store states.
    self.move_history.append(index)
    self.state_history.append(copy.deepcopy(self.state.select_move(index)))
    if self.mcts_black != None:
      self.mcts_black.get_subtree(0, index_i)
    if self.mcts_white != None:
      self.mcts_white.get_subtree(0, index_i)

    # Update game board.
    self.game_canvas.draw_gameboard()

    # Update buttons.
    self.update_buttons()

    # Run bots.
    if not self.state.game_ends and self.start:
      if self.state.is_black:
        if self.player_black != HUMAN_PLAYER:
          t = threading.Thread(target = self.run_bot, args = (BLACK,))
          t.start()
      else:
        if self.player_white != HUMAN_PLAYER:
          t = threading.Thread(target = self.run_bot, args = (WHITE,))
          t.start()

class GameCanvas(FigureCanvas):
  def __init__(self, parent, window):
    self.window = window
    fig = Figure(figsize = (5, 5), dpi = 100, facecolor = (1, 1, 0.8))
    # Draw the empty game board.
    self.ax = fig.add_subplot(111)
    self.ax.set_position([0.1, 0.1, 0.8, 0.8])
    self.ax.set_facecolor("none")
    self.ax.set_xticks(range(BOARD_SIZE_X + 1))
    self.ax.set_yticks(range(BOARD_SIZE_Y + 1))
    self.ax.grid(color = "k", linestyle = "-", linewidth = 1)
    self.ax.xaxis.set_tick_params(bottom = "off", top = "off", labelbottom = "off")
    self.ax.yaxis.set_tick_params(left = "off", right = "off", labelleft = "off")
    self.ax.invert_yaxis()

    super(GameCanvas, self).__init__(fig)
    self.mpl_connect("button_press_event", self.onclick)
    self.setParent(parent)
    FigureCanvas.setSizePolicy(self, QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)
    FigureCanvas.updateGeometry(self)

  def draw_gameboard(self, pi = None, v = None):
    self.ax.cla()
    # Draw the empty game board.
    self.ax.set_xticks(range(BOARD_SIZE_X + 1))
    self.ax.set_yticks(range(BOARD_SIZE_Y + 1))
    self.ax.grid(color = "k", linestyle = "-", linewidth = 1)
    self.ax.xaxis.set_tick_params(bottom = "off", top = "off", labelbottom = "off")
    self.ax.yaxis.set_tick_params(left = "off", right = "off", labelleft = "off")
    self.ax.invert_yaxis()

    # Create black stones and white stones.
    black_stone = mpatches.Circle((0, 0), 0.45, facecolor = (0, 0, 0, 1), edgecolor = (0, 0, 0, 1), linewidth = 1, clip_on = False, zorder = 10)
    white_stone = mpatches.Circle((0, 0), 0.45, facecolor = (0.9, 0.9, 0.9, 1), edgecolor = (0, 0, 0, 1), linewidth = 1, clip_on = False, zorder = 10)
    black_stone_shallow = mpatches.Circle((0, 0), 0.45, facecolor = (0, 0, 0, 0.5), edgecolor = (0, 0, 0, 0.5), linestyle = "--", linewidth = 1, clip_on = False, zorder = 10)
    white_stone_shallow = mpatches.Circle((0, 0), 0.45, facecolor = (0.9, 0.9, 0.9, 0.5), edgecolor = (0, 0, 0, 0.5), linestyle = "--", linewidth = 1, clip_on = False, zorder = 10)
    black_stone_highlight = mpatches.Circle((0, 0), 0.25, facecolor = (0, 0, 0, 1), edgecolor = (0.9, 0.9, 0.9, 1), fill = False, linewidth = 2, clip_on = False, zorder = 20)
    white_stone_highlight = mpatches.Circle((0, 0), 0.25, facecolor = (0, 0, 0, 1), edgecolor = (0, 0, 0, 1), fill = False, linewidth = 2, clip_on = False, zorder = 20)

    # Get positions of black stones and white stones.
    blacks = np.argwhere(np.equal(self.window.state.board, BLACK))
    whites = np.argwhere(np.equal(self.window.state.board, WHITE))

    # Add stones to the game board.
    for x in blacks:
      if x[0] != PASS[0]:
        black_copy = copy.copy(black_stone)
        black_copy.center = np.array([x[1], x[0]]) + 0.5
        self.ax.add_patch(black_copy)
        if not self.window.state.is_black and len(self.window.move_history) > 0:
          if x[0] == index_to_pos(self.window.move_history[-1])[0] and x[1] == index_to_pos(self.window.move_history[-1])[1]:
            # Highlight the last black stone.
            black_copy = copy.copy(black_stone_highlight)
            black_copy.center = np.array([x[1], x[0]]) + 0.5
            self.ax.add_patch(black_copy)

    for x in whites:
      if x[0] != PASS[0]:
        white_copy = copy.copy(white_stone)
        white_copy.center = np.array([x[1], x[0]]) + 0.5
        self.ax.add_patch(white_copy)
        if self.window.state.is_black and len(self.window.move_history) > 0:
          if x[0] == index_to_pos(self.window.move_history[-1])[0] and x[1] == index_to_pos(self.window.move_history[-1])[1]:
            # Highlight the last white stone.
            white_copy = copy.copy(white_stone_highlight)
            white_copy.center = np.array([x[1], x[0]]) + 0.5
            self.ax.add_patch(white_copy)

    if self.window.hint or pi is not None:
      for i in range(len(self.window.state.legal_moves)):
        pos = np.array(index_to_pos(self.window.state.legal_moves[i]))
        if pos[0] != PASS[0]:
          if self.window.state.is_black:
            # Show legal moves.
            black_copy = copy.copy(black_stone_shallow)
            black_copy.center = np.array([pos[1], pos[0]]) + 0.5
            self.ax.add_patch(black_copy)
            if pi is not None:
              # Add predictions.
              self.ax.text(pos[1]+0.5, pos[0]+0.5, str(int(pi[i]*100)), horizontalalignment="center", verticalalignment="center", fontsize=12)
          else:
            white_copy = copy.copy(white_stone_shallow)
            white_copy.center = np.array([pos[1], pos[0]]) + 0.5
            self.ax.add_patch(white_copy)
            if pi is not None:
              self.ax.text(pos[1]+0.5, pos[0]+0.5, str(int(pi[i]*100)), horizontalalignment="center", verticalalignment="center", fontsize=12)

    # Add description.
    step_desc = "Step " + format(self.window.state.step, "02d") + ", "
    if self.window.state.game_ends:
      if self.window.state.score[0] == 1:
        color_desc = "Black wins, "
      elif self.window.state.score[0] == 0:
        color_desc = "Draw, "
      else:
        color_desc = "White wins, "
    else:
      if self.window.state.is_black:
        color_desc = "Black, "
      else:
        color_desc = "White, "
    if v != None:
      stone_desc = "B: " + format(len(blacks), "02d") + ", W: " + format(len(whites), "02d") + ", "
      value_desc = "VN = " + format((v + 1) / 2 * 100, ".2f") + "%. "
      self.ax.set_title(step_desc + color_desc + stone_desc + value_desc)
    else:
      stone_desc = "B: " + format(len(blacks), "02d") + ", W: " + format(len(whites), "02d") + "."
      self.ax.set_title(step_desc + color_desc + stone_desc)

    self.draw()

  def onclick(self, event):
    if event.inaxes == self.ax:
      if not self.window.start or self.window.start and (self.window.player_black == HUMAN_PLAYER if self.window.state.is_black else self.window.player_white == HUMAN_PLAYER):
        if self.window.state != None:
          index = pos_to_index([int(event.ydata), int(event.xdata)])
          if index in self.window.state.legal_moves:
            # Update and store states.
            index_i = np.argwhere(np.equal(self.window.state.legal_moves, index))[0][0]
            self.window.move_history.append(index)
            self.window.state_history.append(copy.deepcopy(self.window.state.select_move(index)))
            if self.window.mcts_black != None:
              self.window.mcts_black.get_subtree(0, index_i)
            if self.window.mcts_white != None:
              self.window.mcts_white.get_subtree(0, index_i)

            #get_activations(self.window.state)

            # Update game board.
            self.draw_gameboard()

            # Update buttons.
            self.window.update_buttons()

            # Run bots.
            if not self.window.state.game_ends and self.window.start:
              if self.window.state.is_black:
                if self.window.player_black != HUMAN_PLAYER:
                  t = threading.Thread(target = self.window.run_bot, args = (BLACK,))
                  t.start()
              else:
                if self.window.player_white != HUMAN_PLAYER:
                  t = threading.Thread(target = self.window.run_bot, args = (WHITE,))
                  t.start()

class EditPlayersDialog(QtWidgets.QDialog):
  def __init__(self, value):
    super(EditPlayersDialog, self).__init__()
    self.setFixedSize(450, 200)
    self.setWindowTitle("Players")

    # Add widgets.
    self.player_black_widget = EditPlayerWidget("Black:", value[0], True)
    self.player_white_widget = EditPlayerWidget("White:", value[1], True)
    self.evaluator_widget = EditPlayerWidget("Evaluator:", value[2], False)
    layout = QtWidgets.QVBoxLayout(self)
    layout.addWidget(self.player_black_widget)
    layout.addWidget(self.player_white_widget)
    layout.addWidget(self.evaluator_widget)

    # Add button box.
    buttonbox = QtWidgets.QDialogButtonBox(self)
    buttonbox.addButton(QtWidgets.QDialogButtonBox.Ok)
    buttonbox.addButton(QtWidgets.QDialogButtonBox.Cancel)
    buttonbox.setOrientation(QtCore.Qt.Horizontal)
    buttonbox.accepted.connect(self.accept)
    buttonbox.rejected.connect(self.reject)
    layout.addWidget(buttonbox)

  def get_value(self):
    return [self.player_black_widget.value, self.player_white_widget.value, self.evaluator_widget.value]

class EditPlayerWidget(QtWidgets.QWidget):
  def __init__(self, tag, value, enable_human_player):
    super(EditPlayerWidget, self).__init__()
    self.value = value

    # Add radio buttons.
    layout = QtWidgets.QHBoxLayout(self)
    self.label = QtWidgets.QLabel(tag)
    self.radio_humanplayer = QtWidgets.QRadioButton("Human")
    self.radio_humanplayer.toggled.connect(self.radio_humanplayer_handler)
    if not enable_human_player:
      self.radio_humanplayer.setEnabled(False)
      self.radio_humanplayer.setToolTip("Only for bots.")
    else:
      self.radio_humanplayer.setToolTip("Select human player.")
    self.radio_bestplayer = QtWidgets.QRadioButton("Best Bot")
    self.radio_bestplayer.toggled.connect(self.radio_bestplayer_handler)
    self.radio_bestplayer.setToolTip("Select the best bot player.")
    self.radio_customplayer = QtWidgets.QRadioButton("Custom Bot")
    self.radio_customplayer.toggled.connect(self.radio_customplayer_handler)
    self.radio_customplayer.setToolTip("Select a specific bot. Fill in the bot id (0~99999).")
    self.customplayer_edit = QtWidgets.QLineEdit()
    self.customplayer_edit.setFixedWidth(50)
    self.customplayer_edit.setValidator(QtGui.QIntValidator(0, 99999))
    self.customplayer_edit.textChanged.connect(self.text_changed_handler)
    self.customplayer_edit.setEnabled(False)
    layout.addWidget(self.label)
    layout.addWidget(self.radio_humanplayer)
    layout.addWidget(self.radio_bestplayer)
    layout.addWidget(self.radio_customplayer)
    layout.addWidget(self.customplayer_edit)

    # Set initial value.
    if self.value == HUMAN_PLAYER:
      self.radio_humanplayer.setChecked(True)
    elif self.value == BEST_PLAYER:
      self.radio_bestplayer.setChecked(True)
    else:
      self.radio_customplayer.setChecked(True)
      self.customplayer_edit.setText(str(self.value))

  def radio_humanplayer_handler(self):
    if self.radio_humanplayer.isChecked():
      self.value = HUMAN_PLAYER

  def radio_bestplayer_handler(self):
    if self.radio_bestplayer.isChecked():
      self.value = BEST_PLAYER

  def radio_customplayer_handler(self):
    if self.radio_customplayer.isChecked():
      self.customplayer_edit.setEnabled(True)
    else:
      self.customplayer_edit.setEnabled(False)

  def text_changed_handler(self):
    if self.customplayer_edit.text() != "":
      self.value = int(self.customplayer_edit.text())
    else:
      self.value = 0

if __name__ == "__main__":
  os.environ["TF_CPP_MIN_LOG_LEVEL"] = "2"
  qApp = QtWidgets.QApplication(sys.argv)
  gamewindow = GameWindow()
  gamewindow.show()
  sys.exit(qApp.exec_())


from psychopy import gui
from psychopy import core
from datetime import datetime
import os
from psychopy import visual, monitors, event
import numpy as np

## Dialog box exercises
## Part 1
exp_info = {'subject_nr':'',
            'age':'',
            'handedness':('right','left','ambi'),
            'gender':'',
            'session':1}

print(exp_info)

## Part 2
#=====================
#COLLECT PARTICIPANT INFO
#=====================
#-create a dialogue box that will collect current participant number, age, gender, handedness
print("All variables have been created! Now ready to show the dialog box!")
my_dlg = gui.DlgFromDict(dictionary=exp_info,
                        title="subject info",
                        fixed=['session'],
                        order = ['session','subject_nr', 'age', 'gender', 'handedness'])

#check the correctness of the entered data
#if exp_info['subject_nr'] ==0: #nothing entered
#    err_dlg = gui.Dlg(title='error message')
#    err_dlg.addText('Enter a valid subject number!') #Error message
#    err_dlg.show() #show the dlg
#    core.quit() #quit the experiment
#if exp_info['age'] < 18: #age is below 18
#    err_dlg = gui.Dlg(title='error message')
#    err_dlg.addText('%d year olds cannot give consent!' % (exp_info['age'])) #Error message
#    err_dlg.show() #show the dlg
#    core.quit() #quit the experiment

#get date and time
date = datetime.now()
print(date)
exp_info['date'] = str(date.hour)+ '-'+ str(date.day) + '-'+ str(date.month) + '-'+ str(date.year)
print(exp_info['date'])

#create a filename for the data
filename = str(exp_info['subject_nr']) + '_' + exp_info['date'] + '.csv'
print(filename)

#define where to store the data
main_dir = os.getcwd()
sub_dir = os.path.join(main_dir,'sub_info',filename)

## Monitor and window exercises

#Question 1: How does changing "units" affect how you define your window size?
#Change the uniit can affect the window size.abs
#We can use various units through Psychypy. The choice of the unit can be deterimined by devices and conditions you use.
#For example, when doing the demo, we usually use ‘norm’ and ‘height’ for units.
#Since these units can naturally change when adjusting the window size.
#Consider the experiment could be done in various devices (e.g. smart phone), using the height unit means
#the experiment window can be changde relativedly with participants'devices' screen.

#Question 2: How does changing colorSpace affect how you define the color of your window? Can you define colors by name?
#Changing the colorSpace can change the color of the window. You can access various colour using PsychoPy Builder.
#And explore the value of color in different colorSpaces.
#We can use colorSpace: RGB, DKL, HSV, LMS. But the HSV colorSpace is device specific.
#The colors can be defined by names using strings. You can set the colour
#through the words, hex value.

#Question 3:
#=====================
#CREATION OF WINDOW AND STIMULI
#=====================
#-define the monitor settings using psychopy functions
mon = monitors.Monitor('myMonitor', width=38.1, distance=60)
mon.setSizePix([1440,900])
mon.save()
#-define the window (size, color, units, fullscreen mode) using psychopy functions
win = visual.Window(monitor=mon,
                    size=(800,800),
                    color=[-1,-1,-1],
                    units='pix',
                    fullscr=True)

## Stimulus exercises

#Question 1

my_image = visual.ImageStim(win, units='pix', size = (400,400))

main_dir = os.getcwd()
image_dir = os.path.join(main_dir,'images')

stims = ['face01.jpg','face02.jpg','face03.jpg']
nTrials=3

for trial in range(nTrials):
    my_image.image = os.path.join(image_dir,stims[trial])
    my_image.draw()
    win.flip()
    event.waitKeys()

win.close()

#Question2
mon = monitors.Monitor('myMonitor', width=38.1, distance=60)
mon.setSizePix([1440,900])
mon.save()
thisSize = mon.getSizePix()
thisWidth = thisSize[0]
thisHeight = thisSize[1]

win = visual.Window(monitor = mon, fullscr = True)

fix_text = visual.TextStim(win, text = '+')
my_image = visual.ImageStim(win, units='pix', size = (400,400)) #the size of the pic will be 400*400 in unit of pixel
nTrials = 4
image_dir = os.path.join(main_dir, 'images')
stims = ['face01.jpg', 'face02.jpg', 'face03.jpg','face04.jpg']

horizMult = [-1, 1, 1, -1]
verMult = [1, 1, -1, -1]

for trial in range(nTrials):
    my_image.image = os.path.join(image_dir, stims[trial])
    #divided the width and height by 4 to calculate window locations
    my_image.pos = (horizMult[trial] * thisWidth/4, verMult[trial] * thisHeight/4)
    my_image.draw()
    fix_text.draw()
    win.flip()
    event.waitKeys()

win.close()

#Question 3
fix_text = visual.TextStim(win, text='+')

#Question 4
#=====================
#CREATION OF WINDOW AND STIMULI
#=====================
mon = monitors.Monitor('myMonitor', width=38.1, distance=60)
mon.setSizePix([1440,900])
mon.save()

main_dir = os.getcwd()
image_dir = os.path.join(main_dir,'images')
my_image = visual.ImageStim(win, units='pix', size = (400,400))

#-define experiment start text unsing psychopy functions
start_msg = "Welcome to my experiment!"

#-define block (start)/end text using psychopy functions
block_msg = "Press any key to continue to the next block."
end_trial_msg = "End of trial"

#-define stimuli using psychopy functions (images, fixation cross)
stims = ['face01.jpg', 'face02.jpg', 'face03.jpg','face04.jpg']
fix_text = visual.TextStim(win,text='+')

#=====================
#START EXPERIMENT
#=====================
#-present start message text
start_text = visual.TextStim(win, text=start_msg)
start_text.draw()
win.flip()

#-allow participant to begin experiment with button press
event.waitKeys()
#=====================
#BLOCK SEQUENCE
#=====================
nBlocks=2
nTrials=3

#-for loop for nBlocks
for block in range(nBlocks):
    #-present block start message
    block_text = visual.TextStim(win, text=block_msg)
    block_text.draw()
    win.flip()
    event.waitKeys()
    #-randomize order of trials here
    np.random.shuffle(stims)
    #=====================
    #TRIAL SEQUENCE
    #=====================
    #-for loop for nTrials
    for trial in range(nTrials):
        #-set stimuli and stimulus properties for the current trial
        my_image.image = os.path.join(image_dir, stims[trial])
        #=====================
        #START TRIAL
        #=====================
        #-draw fixation
        fix_text.draw()
        #-flip window
        win.flip()
        #-wait time (stimulus duration)
        event.waitKeys()

        #-draw image
        my_image.draw()
        #-flip window
        win.flip()
        #-wait time (stimulus duration)
        event.waitKeys()

        #-draw end trial text
        endtrial_text = visual.TextStim(win, text=end_trial_msg)
        endtrial_text.draw()
        #-flip window
        win.flip()
        #-wait time (stimulus duration)
        event.waitKeys()

#======================
# END OF EXPERIMENT
#======================
#-close window
win.close()


import glob
import os
import time

import torch
import chess.engine
from chessboard import display

from aki_chess_ai.ChessPolicyNetwork import ChessPolicyNetwork
from aki_chess_ai.ChessValueNetwork import ChessValueNetwork
from aki_chess_ai.agents.ChessPlayer import ChessPlayer
from aki_chess_ai.config.Config import Config
from aki_chess_ai.umgebung.ChessEnv import ChessEnv, Winner

class ChessGameVisualizer:
    def __init__(self, config: Config, policy_model: ChessPolicyNetwork, value_model: ChessValueNetwork):
        self.env = ChessEnv().reset()
        self.white = ChessPlayer(value_model, policy_model)
        self.black = ChessPlayer(value_model, policy_model)
        self.config = config
        self.board = display.start(self.env.board.fen())
        self.score = {"white": 0, "black": 0}
        try:
            self.engine = chess.engine.SimpleEngine.popen_uci(config.demonstration.stockfish_path)
        except:
            print("Stockfish not found. Please specify the path to the engine in the config file.")
            print("Download it from here: https://stockfishchess.org/download/\n"
                  "And configurate your path like it is descriped here https://python-chess.readthedocs.io/en/latest/engine.html")

            exit()

    def play_game(self):
        self.reset()
        while not self.env.done:
            if self.env.white_to_move:
                action = self.white.select_move(self.env)
            else:
                action = self.black.select_move(self.env)

            print(f"Move: {action}")
            self.env.step(action)
            self.evaluation()
            self.update_chess_board()

            time.sleep(self.config.demonstration.time_between_moves)  # add this line to wait for 1 second
            if self.env.num_halfmoves >= self.config.demonstration.max_moves:
                self.env.adjudicate()
        print("Game over.")
        if self.env.winner == Winner.white:
            print("White wins!")
            self.score["white"] += 1

        elif self.env.winner == Winner.black:
            print("Black wins!")
            self.score["black"] += 1
        else:
            print("Draw!")

    def reset(self):
        self.env = ChessEnv().reset()
    def play_game_against_stockfish(self):
        self.reset()
        while not self.env.done:
            if self.env.white_to_move:
                action = self.white.select_move(self.env)
            else:
                action = self.stockfish_select_move(self.env)

            print(f"Move: {action}")
            self.env.step(action)
            self.evaluation()
            self.update_chess_board()

            time.sleep(self.config.demonstration.time_between_moves)
            if self.env.num_halfmoves >= self.config.demonstration.max_moves:
                self.env.adjudicate()
        print("Game over.")
        if self.env.winner == Winner.white:
            print("White wins!")
            self.score["white"] += 1

        elif self.env.winner == Winner.black:
            print("Black wins!")
            self.score["black"] += 1
        else:
            print("Draw!")

    def stockfish_select_move(self, env):
        result = self.engine.play(env.board, chess.engine.Limit(time=0.1))
        return result.move.uci()
    def update_chess_board(self):

        display.update(self.env.board.fen(), self.board)
        display.check_for_quit()

    def evaluation(self, time_limit=0.01):
        result = self.engine.analyse(self.env.board, chess.engine.Limit(time=time_limit))
        print(result["score"])

def load_model() -> (ChessPolicyNetwork, ChessValueNetwork):
    policy_model = ChessPolicyNetwork()
    value_model = ChessValueNetwork()

    policy_model, value_model = load_latest_checkpoint("../", policy_model, value_model)

    return policy_model, value_model

def load_latest_checkpoint(folder, policy_model, value_model):
    print("Loading latest checkpoint...")
    policy_folder = os.path.join(folder, "policy_training_models")
    value_folder = os.path.join(folder, "value_training_models")

    value_checkpoints = glob.glob(os.path.join(value_folder, 'model_*.pt'))
    policy_checkpoints = glob.glob(os.path.join(policy_folder, 'model_*.pt'))

    # Find the latest checkpoint (highest number in the filename)
    latest_value_checkpoint = max(value_checkpoints, key=os.path.getctime)
    latest_policy_checkpoint = max(policy_checkpoints, key=os.path.getctime)

    value_model.load_state_dict(torch.load(latest_value_checkpoint))
    policy_model.load_state_dict(torch.load(latest_policy_checkpoint))

    print("Loaded latest value model from:", latest_value_checkpoint)
    print("Loaded latest policy model from:", latest_policy_checkpoint)
    print("Loading checkpoint done.")

    return policy_model, value_model

if __name__ == '__main__':
    policy_model, value_model = load_model()
    config = Config()

    visualizer = ChessGameVisualizer(Config(), policy_model, value_model)
    for i in range(100):
        visualizer.play_game()
    print(visualizer.score)
    display.terminate()


from django.conf import settings
import imgix
import imgproxy

def construct_cache_key(image, filter_spec, backend):
    return f"{backend.cache_key}-{image.id}-{filter_spec}"

class BaseImageProcessingBackend:
    cache_key = ""

    def __init__(self, source_url, filter_spec):
        self.source_url = source_url
        self.filter_spec = filter_spec
        self.kwargs = self.parse(filter_spec)

    def parse(self, filter_spec):
        raise NotImplementedError

    def get_url(self):
        raise NotImplementedError

    @staticmethod
    def get_original_rendition_url_prefix():
        return ""

    def __call__(self):
        return self.get_url()

class ImgProxyBackend(BaseImageProcessingBackend):
    cache_key = "imgproxy"
    operation_mappings = {
        "resize": "resizing_type",
    }

    def get_url(self):
        imgproxy_url = imgproxy.ImgProxy(
            image_url=self.source_url,
            proxy_host=settings.IMGPROXY_HOST,
            key=settings.IMGPROXY_KEY,
            salt=settings.IMGPROXY_SALT,
            **self.kwargs,
        )
        return imgproxy_url()

    def parse(self, filter_spec):
        kwargs = {"advanced": []}
        for directive in filter_spec.split("|"):
            if directive == "enlarge":
                kwargs["enlarge"] = True
            else:
                try:
                    param, arg = directive.split("-")
                    kwargs[self.operation_mappings.get(param, param)] = arg
                except ValueError:
                    kwargs["advanced"].append(directive)
        return kwargs

class ImgixBackend(BaseImageProcessingBackend):
    operation_mappings = {
        "height": "h",
        "width": "w",
        "resize": "fit",
    }

    @staticmethod
    def get_original_rendition_url_prefix():
        return settings.PROXY_URL_FOR_IMGIX

    def get_url(self):
        builder = imgix.UrlBuilder(
            settings.IMGIX_DOMAIN, sign_key=settings.IMGIX_SIGNATURE_KEY
        )
        return builder.create_url(self.source_url, self.kwargs)

    def parse(self, filter_spec):
        # Only width, height, and resize mode have been tested
        kwargs = {}
        for directive in filter_spec.split("|"):
            if directive == "enlarge":
                kwargs["enlarge"] = True
            else:
                param, arg = directive.split("-")
                kwargs[self.operation_mappings.get(param, param)] = arg
        return kwargs


import psycopg2

try:
    conn = psycopg2.connect("dbname='donut_tycoon' user='Austin' host='localhost'")
    cursor = conn.cursor()
except:
    print("I am unable to connect to the database")

def getAll(table):
    cursor.execute("SELECT * FROM {0}".format(table))
    out = cursor.fetchall()
    return out

def getWhere(table, col, val):
    cursor.execute("SELECT * FROM {0} WHERE {1} = {2}".format(table, col, val))
    out = cursor.fetchall()
    return out


# Import your dependencies
import os
from nylas import Client
from dotenv import load_dotenv

# Load your env variables
load_dotenv()

# Set Nylas API_KEY
nylas = Client(
    api_key=os.environ.get("API_KEY")
)

# Read settings from environment variables
grant_id = os.environ.get("GRANT_ID")
calendar_id = os.environ.get("CALENDAR_ID")
event_id = os.environ.get("EVENT_ID")

# Set status confirmation
status = 'maybe'   # yes | no | maybe

# If the calendar_id is another than the email please be sure to point to correct calendar_id
try:
    response = nylas.events.send_rsvp(grant_id, event_id, {"status": status}, {"calendar_id": calendar_id})
except Exception as e:
    print(f'An error occurred, exception {str(e)}')
else:
    print(f'RSVP Response succeed, request id: {response.request_id}')

# Check event RSVP status
try:
    response = nylas.events.find(grant_id, event_id, {"calendar_id": calendar_id})
except Exception as e:
    print(f'An error occurred, exception {str(e)}')
else:
    event = response.data
    print(f'Event: {event.title}, id: {event.id}')

    # Search for participant email
    for participant in event.participants:
        print(f'Participant: {participant.email},  status: {participant.status}')