# get the data needed to plot the TEP with a quiver plot on top of it

import numpy as np
#import pickle
import os
import pandas as pd
import csv
from scipy.interpolate import interp1d

import sys
sys.path.insert(0,'../../functions') # so I can import the functions
from cycle_funcs import calc_fitness, calc_dfitness, sample_wsV_dimorph

# =====================================================================================================================

# model parameters
# ---

# which parameter set to find the isoclines for (comment out ones I've done)
suffix = '_1'

'''
# default parameter values
ID = 0
ngrid = 31 # number of grid points in log space along the resident1 axis
'''
# high dispersal cost parameter values
ID = 17
ngrid = 31 # number of grid points in log space along the resident1 axis

# where results will be stored
dir_results = '../../results/circular/'

# default algorithm parameters
params = {
        'tol_res': 1e-10,       # the euclidean distance in final resident structure before say it's equilibriated
        'tol_res_dimorph': 1e-6,# the euclidean distance in final dimorphic resident structure before say it's equilibriated
        'tol_mut': 1e-10,       # the euclidean distance in final mutant structure before say it's equilibriated
        'delta_m': 1e-9,        # step size to estimate gradients; default heuristic sqrt(machine error) * approx value
        }

# read in the info from the sing_strat_x.csv file and repopulate params dictionary
# ---

par_names = ['suffix', 'layout', 'f', 'c', 'r', 'KL', 'h', 'KS_mean', 'p_cat'] # names of missing parameter values

fname = dir_results + 'sing_strat' + suffix + '.csv'
df = pd.read_csv(fname)
ss_res = df.iloc[ID] # the particular row we want

for par_name in par_names:

    params[par_name] = ss_res[par_name]

# read in the isoclines to define the TEP region
# ---

fname = dir_results + 'isocline' + suffix + '_' + str(ID) + '.csv'
df = pd.read_csv(fname)
df = df.sort_values(by=['m_mut'])

# grab the isoclines
m_iso1v = df['m_res'].values
m_iso2v = df['m_mut'].values

# flip all points below the diagonal so that we define the TEP region
region = [ (m_mut, m_res) if m_res > m_mut else (m_res, m_mut) for m_res, m_mut in zip(m_iso1v, m_iso2v) ]

# make sure the first entry is 0,0
if region[0] != (0,0):
    region += [(0,0)] + region

# make sure the last entry is 0,y_intercept
if region[-1][1] == 1:
    region[-1] = (0, ss_res['y_intercept'])
else:
    region += [(0, ss_res['y_intercept'])]

# split the region boundary into an upper and lower bound on resident 2
# ---

# find the extremal point of the region in the resident 1 dimension, the bulging out to the right of the PIP graph
m_iso1V, m_iso2V = zip(*region)
extremal_res1 = max(m_iso1V)
extremal_idx = m_iso1V.index( extremal_res1 )
extremal_res2 = m_iso2V[extremal_idx]

# split the region boundary into two lines, one for a lower bound on res2, and one for an upper bound
line_lo = [ (m_res1, m_res2) for m_res1, m_res2 in region if m_res2 <= extremal_res2 ]
line_hi = [ (m_res1, m_res2) for m_res1, m_res2 in region if m_res2 >= extremal_res2 ]

# create functions that will return the lower and upper bound on res2 for a given res1
m_res1V, m_res2V = zip(*line_lo)
f_lo = interp1d(m_res1V, m_res2V)
m_res1V, m_res2V = zip(*line_hi)
f_hi = interp1d(m_res1V, m_res2V)

# create a grid along the resident 1 dimension, and find the isocline at each point along that grid
# ---

# do it in log space
pwrV = np.linspace(-6, np.log10(extremal_res1), ngrid)[:-1]
m_res1V = [ 10**pwr for pwr in pwrV ]

# if the csv file doesn't exist yet, create it, and include the resident 1 = 0 point in the grid
# ---

fname = dir_results + 'dimorph_isocline' + suffix + '_' + str(ID) + '.csv'
if not os.path.isfile(fname):

    # add the zero point to our search
    m_res1V = [0] + m_res1V

    # write the column headers
    with open(fname, "w", newline="") as ftarget:
        writer = csv.writer(ftarget)
        writer.writerow( ['m_res1', 'm_res2', 'dfit2'] )

# for each resident 1 strategy, find where the resident 2 mutant invasion fitness gradient equals 0
# (I know that this is an attractor)
# ---

for m_res1 in m_res1V:

    m_res2_hi_bnd = f_hi([m_res1])[0]
    m_res2_lo_bnd = f_lo([m_res1])[0]

    # find where resident 2 invasion fitness gradient goes positive
    # ---

    # initialise
    m_res2_lo = m_res2_hi_bnd
    dfit2_lo = -1   # at this point, the resident-2 fitness gradient is negative
    nL = None

    print('find where gradient goes positive')

    while dfit2_lo < 0:

        print(m_res2_lo)

        # update
        m_res2_hi = m_res2_lo
        dfit2_hi = dfit2_lo
        nL_hi = nL

        # halve distance to lower bound for the new low estimate
        m_res2_lo = (m_res2_lo_bnd + m_res2_hi) / 2

        # find the fitness gradient here
        wsV, nL = sample_wsV_dimorph(m_res1, m_res2_lo, params, return_nT=True, nL=nL)
        dfit2_lo = calc_dfitness(m_res2_lo, wsV, params)

    nL_lo = nL

    print('m_res2_lo = ' + str(m_res2_lo))

    # use bisection method to find the root
    # ---

    print('find root')

    tol_dfit = 1e-7 # maximum derivative that we'll accept as being close enough to 0
    dfit2_mid = dfit2_lo
    while abs(dfit2_mid) > tol_dfit:

        m_res2_mid = (m_res2_lo + m_res2_hi) / 2
        nL_mid = [ (nL_lo[0]+nL_hi[0])/2 , (nL_lo[1]+nL_hi[1])/2 ]
        wsV_mid, nL_mid = sample_wsV_dimorph(m_res1, m_res2_mid, params, return_nT=True, nL=nL_mid)
        dfit2_mid = calc_dfitness(m_res2_mid, wsV_mid, params)

        if np.sign(dfit2_lo) == np.sign(dfit2_mid):
            nL_lo = nL_mid
            wsV_lo = wsV_mid
            dfit2_lo = dfit2_mid
            m_res2_lo = m_res2_mid
        else:
            nL_hi = nL_mid
            wsV_hi = wsV_mid
            dfit2_hi = dfit2_mid
            m_res2_hi = m_res2_mid

        print(m_res2_mid)

    # write this isocline point to the csv
    # ---

    with open(fname, "a", newline="") as ftarget:

        writer = csv.writer(ftarget)
        writer.writerow([m_res1, m_res2_mid, dfit2_mid])


#!/usr/bin/env python

#这个脚本创建一个UPD客户端，它提示用户输入发送给服务器的消息，并接收服务器加入时间戳前缀的消息，然后显示给用户

from socket import *

HOST = 'localhost'
PORT = 21567
BUFF = 1024
ADDR = (HOST, PORT)

udpCliSock = socket(AF_INET, SOCK_DGRAM)

while True:
    data = input('> ')
    if not data:
        break
    udpCliSock.sendto(bytes(data, 'utf-8'), ADDR)
    data, ADDR = udpCliSock.recvfrom(BUFF)
    if not data:
        break
    print(data)

udpCliSock.close()


from unittest.mock import MagicMock, patch

import pytest

from app.domain.entities import Tank
from app.domain.enums import Direction
from app.domain.utils import Size, Vector

class _ModulePatch:
    _PATH = "app.domain.entities.tank"
    BULLET_FACTORY = f"{_PATH}.BulletFactory"

class TestsTank:
    @patch(_ModulePatch.BULLET_FACTORY, new_callable=MagicMock)
    def test__post_init(self, factory):
        tank_obj = MagicMock()

        Tank.__post_init__(tank_obj)

        factory.assert_called_once_with(tank_obj._bullet_schema)
        tank_obj._bullet_factory = factory.return_value

    def test__get_bullet(self):
        bullet_schema = MagicMock()
        tank_obj = MagicMock(_bullet_schema=bullet_schema)

        bullet = Tank.get_bullet(tank_obj)

        tank_obj._get_bullet_position.assert_called_once_with(bullet_schema.size)
        tank_obj._bullet_factory.create.assert_called_once_with(
            position=tank_obj._get_bullet_position.return_value,
            direction=tank_obj.direction,
        )
        assert bullet == tank_obj._bullet_factory.create.return_value

    @pytest.mark.parametrize(
        "tank_location,tank_size,bullet_size,direction,expected",
        [
            (Vector(0, 0), Size(10, 10), Size(2, 2), Direction.DOWN, Vector(4, -3)),
            (Vector(10, 20), Size(10, 10), Size(2, 2), Direction.UP, Vector(14, 31)),
            (Vector(20, 10), Size(10, 10), Size(2, 2), Direction.LEFT, Vector(17, 14)),
            (Vector(40, 50), Size(10, 10), Size(2, 2), Direction.RIGHT, Vector(51, 54)),
        ],
    )
    def test__get_bullet_location(
        self, tank_location, tank_size, bullet_size, direction, expected
    ):
        tank_obj = MagicMock(
            direction=direction, position=tank_location, size=tank_size
        )

        actual = Tank._get_bullet_position(tank_obj, bullet_size)

        assert actual == expected


import numpy as np
import gym
import matplotlib.pyplot as plt

if __name__ == "__main__":
    ENV = gym.make("FrozenLake-v0")
    DISCOUNT = 0.9
    EPSILON = 0.1
    POSSIBLE_ACTIONS = [0, 1, 2, 3]
    STATE_SPACE = list(range(16))
    ESTIMATES = {}
    RETURNS = {}
    PAIRS_VISITED = {}

    for state in STATE_SPACE:
        for action in POSSIBLE_ACTIONS:
            ESTIMATES[(state, action)] = 0
            RETURNS[(state, action)] = 0
            PAIRS_VISITED[(state, action)] = 0

    POLICY = {}
    for state in STATE_SPACE:
        POLICY[state] = np.random.choice(POSSIBLE_ACTIONS)

    NUM_EPISODES = 100000
    STATUS_INTERVAL = 5000

    for i in range(NUM_EPISODES):
        states_actions_returns = []
        if i % STATUS_INTERVAL == 0:
            print("starting episode", i)
        observation = ENV.reset()
        memory = []
        done = False
        while not done:
            action = POLICY[observation]
            observation_, reward, done, info = ENV.step(action)
            memory.append((observation, action, reward))
            observation = observation_

        memory.append((observation, action, reward))
        returns = 0
        last = True # start at t = T - 1
        for state, action, reward in reversed(memory):
            if last:
                last = False
            else:
                states_actions_returns.append((state, action, returns))
            returns = DISCOUNT * returns + reward

        states_actions_returns.reverse()
        states_and_actions = []
        for state, action, returns in states_actions_returns:
            if (state, action) not in states_and_actions:
                PAIRS_VISITED[(state, action)] += 1
                RETURNS[(state, action)] += (
                    (1 / PAIRS_VISITED[(state, action)])
                    * (returns - RETURNS[(state, action)])
                )
                ESTIMATES[(state, action)] = RETURNS[(state, action)]
                states_and_actions.append((state, action))
                values = np.array(
                    [ESTIMATES[(state, a)] for a in POSSIBLE_ACTIONS]
                )
                best = np.random.choice(np.where(values == values.max())[0])
                rand = np.random.random()
                if rand < 1 - EPSILON:
                    POLICY[state] = POSSIBLE_ACTIONS[best]
                else:
                    POLICY[state] = np.random.choice(POSSIBLE_ACTIONS)
    NUM_GAMES = 1000
    REWARDS = np.zeros(NUM_GAMES)
    EPISODE_REWARDS = 0
    for i in range(NUM_GAMES):
        observation = ENV.reset()
        done = False
        while not done:
            action = POLICY[observation]
            observation_, reward, done, info = ENV.step(action)
            observation = observation_
            EPISODE_REWARDS += reward
        REWARDS[i] = EPISODE_REWARDS
    print(EPISODE_REWARDS / NUM_GAMES)
    plt.plot(REWARDS)
    plt.show()


import sys
import nltk.data
from nltk.tokenize import sent_tokenize

tokenizer = nltk.data.load('tokenizers/punkt/japanese.pickle')
SAMPLE_SIZE = 1024

sample = sys.stdin.read(SAMPLE_SIZE)
while sample:

    tokenized_sents = tokenizer.tokenize(sample)

    for sentence in tokenized_sents:
        sys.stdout.write(sentence + '\n')

    sample = sys.stdin.read(SAMPLE_SIZE)


def fibonacciFonksiyon():

    fibonacciList = []
    birinciSayi = 0
    ikinciSayi = 1

    fibonacciList.append(birinciSayi)
    fibonacciList.append(ikinciSayi)

    alinanSayi=int(input("Merhaba 20 veya 20'den büyük bir sayi giriniz: "))

    if(alinanSayi<20):
        print("Yanlış değer girdiniz !! Lütfen 20 veya 20'den büyük bir sayı giriniz.")

    else:
        for i in range(alinanSayi):

            ucuncuSayi = birinciSayi + ikinciSayi
            birinciSayi = ikinciSayi
            ikinciSayi = ucuncuSayi

            fibonacciList.append(ucuncuSayi)
        print(fibonacciList)

fibonacciFonksiyon()


from sorteios import Lotofacil as LF

#LOTOFACIL

#TOTAL DE SAIDAS, POR NUMERO.

sorteios = LF()

palpite = [2,4,7,10,11,13,14,15,16,19,20,21,23,24,25]

print('Sorteios = ',len(sorteios))
print()

for i in range(len(palpite)):

	indice = palpite[i]
	total_saidas = 0

	for x in sorteios:
		for numero in x:
			if numero == indice:
				total_saidas += 1
				valor = numero

	print(' ', palpite[i], ' > ', total_saidas)


import os
from argparse import ArgumentParser

import datasets
import yaml

from togepi.data_processors.tokenizers.tokenizer import TogepiTokenizer
from togepi.utils.utils import set_seed

def main(config_path, hf_dataset_path, path_to_store_hf_tokenizer):
    set_seed(seed=42)

    with open(config_path, 'r') as fp:
        config = yaml.safe_load(fp)

    hf_dataset = datasets.load_from_disk(dataset_path=hf_dataset_path)
    tokenizer = TogepiTokenizer(**config['tokenizer']['args'])
    tokenizer.train(hf_dataset['train'])
    tokenizer.save(path_to_store_hf_tokenizer)

if __name__ == '__main__':
    parser = ArgumentParser(description='build tokenizer using a huggingface dataset')
    parser.add_argument('--config_path', type=str, help='path to config file')
    parser.add_argument('--hf_dataset_path', type=str, help='path to the huggingface dataset', default=os.getcwd())
    parser.add_argument('--path_to_store_hf_tokenizer', type=str, help='path to store the tokenizer',
                        default=os.getcwd())

    args = parser.parse_args()

    main(config_path=args.config_path, hf_dataset_path=args.hf_dataset_path,
         path_to_store_hf_tokenizer=args.path_to_store_hf_tokenizer)


# -*- coding: utf-8 -*-

import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import scipy as sp
import scipy.stats

'''
Git command line:

git add 'baseball_data.py'
git commit -m 'initial commit'
git remote add origin https://github.com/cjpeck/baseball_data.git
git push -u origin master
'''

def get_team_stats(bt, pt, fd, tm):

    tFrame = [1985, 2014]
    years = list(range(tFrame[0], tFrame[1]+1))

    tm_keys = ['G', 'W', 'L', 'DivWin', 'WCWin', 'LgWin', 'WSWin']
    bt_keys = ['AB', 'R', 'H', '2B', '3B', 'HR', 'RBI', 'SB', 'CS', 'BB',
               'SO', 'IBB', 'HBP', 'SH', 'SF', 'GIDP']
    pt_keys = ['CG', 'SHO', 'SV', 'IPouts', 'H', 'ER', 'HR', 'BB',
               'SO',  'BFP', 'R']
    fd_keys = ['E', 'SB', 'CS']
    bt_keys.remove('AB')
    bt_keys.remove('R')
    bt_keys.remove('H')
    pt_keys.remove('IPouts')
    pt_keys.remove('SV')
    pt_keys.remove('R')
    pt_keys.remove('BFP')

    keys = [x + '_bt' for x in bt_keys]
    keys += [x + '_pt' for x in pt_keys]
    keys += [x + '_fd' for x in fd_keys]
    keys += ['salary', 'n_over_2SD', 'n_over_3SD', 'n_over_4SD']

    indices = [[], []]
    remove = []
    for year in years:
        tm_year = tm[str(year)]
        if np.sum(tm_year['G'] < 160):
            print('skipping year ' + str(year))
            remove.append(year)
            continue
        teams = tm_year['teamID']
        #indices.extend([(year, team) for team in teams])
        indices[0].extend([year for _ in teams])
        indices[1].extend([team for team in teams])
    for year in remove:
        years.remove(year)

    dfx = pd.DataFrame(index=indices, columns=keys)
    dfy = pd.DataFrame(index=indices, columns=tm_keys)

    for year in years:
        tm_year = tm[str(year)]
        sal_year =  sal[str(year)]
        bt_year = bt[bt['yearID']==year]
        pt_year = pt[pt['yearID']==year]
        fd_year = fd[fd['yearID']==year]
        teams = tm_year['teamID']

        for team in teams:

            # team results
            team_data = tm_year[tm_year['teamID']==team]
            s = pd.Series(team_data[tm_keys].sum(skipna=True))
            dfy.ix[(year, team)] = s

            #append batting information
            team_data = bt_year[bt_year['teamID']==team]
            s = pd.Series(team_data[bt_keys].sum(skipna=True))
            s.index = [s.index[i] + '_bt' for i in range(len(s))]
            count = len(s)

            #append pitching information
            team_data = pt_year[pt_year['teamID']==team]
            s = s.append(team_data[pt_keys].sum(skipna=True))
            s.index = [s.index[i] + '_pt' if i >= count else s.index[i]
                       for i in range(len(s))]
            count = len(s)

            #append fielding information
            team_data = fd_year[fd_year['teamID']==team]
            s = s.append(team_data[fd_keys].sum(skipna=True))
            s.index = [s.index[i] + '_fd' if i >= count else s.index[i]
                       for i in range(len(s))]
            count = len(s)

            #append salaray information
            team_data = sal_year[sal_year['teamID']==team]['salary']
            salary = float(team_data.sum())
            mean = float(sal[str(year)].mean())
            std = float(sal[str(year)].std())
            n_over_2SD = (team_data >= mean + 2*std).sum()
            n_over_3SD = (team_data >= mean + 3*std).sum()
            n_over_4SD = (team_data >= mean + 4*std).sum()
            s =  s.append(pd.Series([salary, n_over_2SD, n_over_3SD, n_over_4SD],
                                    index=['salary', 'n_over_2SD', 'n_over_3SD', 'n_over_4SD']))

            #append to dataframe
            dfx.ix[(year, team)] = s

    return dfx, dfy

### ANALYSIS OF SALARY PREDICTING WINSS
def salary_figures(dfx, dfy):

    directory = '/Users/cjpeck/Dropbox/spyder2/baseball/figures/'

    # parameters for sliding window regression
    years = dfx.index.levels[0]
    tInt = 10
    tShift = 1
    tStart = []
    tEnd = []
    i = 0
    while i + tInt < len(years):
        tStart.append(years[i])
        tEnd.append(years[i+tInt])
        i += tShift

    #normalize
    dfx_z = dfx.apply(lambda x: (x - dfx.ix[x.name[0]].mean()) /
                                 dfx.ix[x.name[0]].std(), axis=1)

    # overall regression (for all years) and sliding regression
    beta = sp.stats.linregress(dfx_z['salary'], dfy['W'])
    beta_sliding = []
    for t in range(len(tStart)):
        tmp =sp.stats.linregress(dfx_z.ix[tStart[t]:tEnd[t], 'salary'],
                                 dfy.ix[tStart[t]:tEnd[t], 'W'])
        beta_sliding.append(tmp[0])

    # scatter of salary predicting wins
    plt.figure()
    xmin = dfx_z['salary'].min()
    xmax = dfx_z['salary'].max()
    plt.plot((xmin, xmax), (xmin * beta[0] + beta[1], xmax * beta[0] + beta[1]),
                     color='r', linestyle='-')
    plt.scatter(dfx_z['salary'], dfy['W'])
    plt.title('b1=%1.2f, p=%1.4f' % (beta[0], beta[3]))
    plt.savefig(directory + 'salary_wins.eps', bbox_inches='tight')
    plt.show()

    # mean salary as a function of year
    plt.figure()
    plt.plot(years, dfx.mean(axis=0, level=0)/1e6)
    plt.xlabel('Year')
    plt.ylabel('Mean salary (millions $)')
    plt.savefig(directory + 'mean_salary.eps', bbox_inches='tight')
    plt.show()

    # change in z-score as function to time (sliding window regression) to win
    # 'wins_desired' more games
    plt.figure()
    wins_desired = 4
    money_needed = wins_desired / np.array(beta_sliding)
    plt.plot(np.mean(np.c_[tStart, tEnd], 1), money_needed)
    plt.xlabel('Year')
    plt.ylabel('Change in z-score, to get %d wins' % wins_desired)
    plt.savefig(directory + 'year_wins.eps', bbox_inches='tight')
    plt.show()

    # salary as a function of year for common z-scores
    z_vals = np.array([0, 1, 2])
    z_chart = pd.DataFrame()
    for i in z_vals:
        z_chart[i] = (dfx.mean(level=0)['salary'] +
                      dfx.std(level=0)['salary'] * i) / 1e6
    z_chart.plot()
    plt.xlabel('Year')
    plt.ylabel('Salary')
    plt.savefig(directory + 'year_salary.eps', bbox_inches='tight')
    plt.show()

    # how does salary increase predict an increase in probability of winning
    # the World Series
    plt.figure()

    keys = ['DivWin', 'WCWin', 'LgWin', 'WSWin']
    nkeys = ['nDivWin', 'nWCWin', 'nLgWin', 'nWSWin']

    bin_size = 10 # need to be an int divisble by 2 and a factor of 100
    x_vals = list(range(int(bin_size/2), 100, bin_size))
    df = pd.DataFrame(index=x_vals, columns=keys+nkeys)
    for i in range(len(x_vals)):
        lb = np.percentile(dfx_z['salary'], i * bin_size)
        ub = np.percentile(dfx_z['salary'], (i+1) * bin_size)
        winners = dfy.ix[(dfx_z['salary'] > lb) & (dfx_z['salary'] <= ub), keys] == 'Y'
        losers = dfy.ix[(dfx_z['salary'] > lb) & (dfx_z['salary'] <= ub), keys] == 'N'
        n = winners.sum().add(losers.sum())
        df.ix[x_vals[i], keys] = winners.sum().divide(n)
        df.ix[x_vals[i], nkeys] = n.rename({keys[i]: nkeys[i] for i in range(len(n))})
    df[keys].plot(xlim=[0,100])
    plt.savefig(directory + 'playoff_prob.eps', bbox_inches='tight')

    plt.figure()
    x2 = dfx['n_over_2SD'] + (.1 * np.random.random(size=(len(dfx),)) - 0.05)
    x3 = dfx['n_over_3SD'] + (.1 * np.random.random(size=(len(dfx),)) - 0.05)
    x4 = dfx['n_over_4SD'] + (.1 * np.random.random(size=(len(dfx),)) - 0.05)
    plt.scatter(x2, dfy['W'], c='b', s=5)
    plt.scatter(x3, dfy['W'], c='r')
    plt.scatter(x4, dfy['W'], c='g')
    b2 = sp.stats.linregress(x2, dfy['W'])
    b3 = sp.stats.linregress(x3, dfy['W'])
    b4 = sp.stats.linregress(x4, dfy['W'])
    plt.show()

if __name__ == '__main__':

    # Load data
    master_fname = '/Users/cjpeck/Dropbox/spyder2/baseball/lahman-csv_2015-01-24/Master.csv'
    ms = pd.DataFrame.from_csv(master_fname)

    batting_fname = '/Users/cjpeck/Dropbox/spyder2/baseball/lahman-csv_2015-01-24/Batting.csv'
    bt = pd.DataFrame.from_csv(batting_fname)
    bt['AVG'] = bt['H'] / bt['AB']
    bt['SLG'] = (bt['H'] + 1*bt['2B'] + 2*bt['3B'] + 3*bt['HR']) / bt['AB']

    pitching_fname = '/Users/cjpeck/Dropbox/spyder2/baseball/lahman-csv_2015-01-24/Pitching.csv'
    pt = pd.DataFrame.from_csv(pitching_fname)

    fielding_fname = '/Users/cjpeck/Dropbox/spyder2/baseball/lahman-csv_2015-01-24/Fielding.csv'
    fd = pd.DataFrame.from_csv(fielding_fname)

    team_fname = '/Users/cjpeck/Dropbox/spyder2/baseball/lahman-csv_2015-01-24/Teams.csv'
    tm = pd.DataFrame.from_csv(team_fname)

    sal = pd.DataFrame.from_csv(
        '/Users/cjpeck/Dropbox/spyder2/baseball/lahman-csv_2015-01-24/Salaries.csv')

    # error in the salaries CSV which includes teams 'SFG' and 'NYM' which
    # should instead be 'SFN' and 'NYN' - applies to 2014 only
    sal.ix[(sal.index==pd.Timestamp('2014-01-01')) &
           (sal['teamID']=='NYM'), 'teamID'] = 'NYN'
    sal.ix[(sal.index==pd.Timestamp('2014-01-01')) &
           (sal['teamID']=='SFG'), 'teamID'] = 'SFN'

    for year in range(bt['yearID'].min(), bt['yearID'].max() + 1):
        bt_teams = bt.ix[bt['yearID']==year, 'teamID'].unique()
        pt_teams = pt.ix[pt['yearID']==year, 'teamID'].unique()
        fd_teams = fd.ix[fd['yearID']==year, 'teamID'].unique()
        tm_teams = tm.ix[str(year), 'teamID'].unique()
        n_teams = [len(bt_teams), len(pt_teams), len(fd_teams), len(tm_teams)]
        if str(year) in sal.index:
            sal_teams = sal.ix[str(year), 'teamID'].unique()
            n_teams.append(len(sal_teams))
        if len(np.unique(n_teams)) > 1:
            print(str(year), str(n_teams))

    dfx, dfy = get_team_stats(bt, pt, fd, tm)
    salary_figures(dfx, dfy)


# -*- coding: utf-8 -*-
# https://github.com/latefyr/kicadcreo.git
# MIT license
#
# Parse Creo Schematic cable file and take harness numbers and
# wire/cable lengths back to Kicad schematic.
#
# Do not overwrite the original Schematic.
#
# Copyright (C) LasseFyr 2019.
#
# This has been tested only with Creo 4.0 070
#
"""
    @package
    Generate a net list file.

    Command line:
    Run from Kicad eeschema with default parameters "%I" "%O"

	Changes:
	2023.05.01	Kicad 7.0.2 hierarchical refdes issue patch. Not tested to work with all combinations.
	2022.03.01	Previous update broke V5 operation. Fixed.
	2022.01.01	added preliminary support for KicadV6
"""

from __future__ import print_function
from xml.dom import minidom
import sys
import sch
import glob
import os
import datetime
import shutil
import math
#import sexpdata

class xmlReadCreo:
	def __init__(self):
		self.__infoString = ""
		self.__errorString = ""
		self.__warningString = ""
		self.refDesVals = []
		self.harnessNum = []
		self.wireLength = []
		self.sheets = []
		self.alreadyProsessed = []
		self.prosessedSheets = []
		self.kiCadSch = object()

#-----------------------------------------------------------------------------------------
# Create backup files of the schematic first
#
#-----------------------------------------------------------------------------------------
	def backUpFile( self, fileToBackup ):
		self.fileToProcess = fileToBackup
		self.fileFirstBackup = fileToBackup+".bak"
		self.fileSecondBackup = fileToBackup+".bak2"
		self.returnVal = False

		if os.path.exists( self.fileFirstBackup ):
			shutil.move( self.fileFirstBackup, self.fileSecondBackup)
			self.writeInfoStr("Moved first backup to second backup "+ self.fileSecondBackup + "\n")
			#print( "Moved first backup to second backup "+ self.fileSecondBackup, file=sys.stdout )

		if ( os.path.exists( self.fileToProcess )):
			try:
				os.rename( self.fileToProcess, self.fileFirstBackup )
				self.returnVal = True
			except OSError as error:
				self.writeErrorStr(" Could not create Backupfile: " + self.fileFirstBackup + "\n")
		else:
			self.writeInfoStr( " File " + self.fileToProcess + " does not exist!\n" )

		return self.returnVal

#-----------------------------------------------------------------------------------------
# Write Kicad Schematic Sheet Data
#
#-----------------------------------------------------------------------------------------
	def writeKicadSheet( self, sheetName ):
		for component in sheetName.components:
			for name, value in component.labels.items():
				if value[:1]=="W" or value[:3]=="CBL":
					refDes=value
					for field in component.fields:
						for key in field.keys():
							# Get the component field "Length" and modify
							if field[key] == "\"Length\"":
								thisIsTheLengthParam = key
								try:
									myindex = self.refDesVals.index(refDes)
								except ValueError:
									self.writeErrorStr( "Refdes \""+refDes+"\" does not exist! Not routed yet?\n" )
									continue
								roundedIntLen = math.ceil(float(self.wireLength[myindex]))
								roundedWireLen = str(roundedIntLen).split('.')[0] 				# Round up and no decimal places
								self.writeInfoStr("Name: " + "{0:<6}".format(refDes) + " Harness Name: " + "{0:<15}".format(self.harnessNum[myindex]) + " lenght: " +roundedWireLen + "\n")
								field['ref'] = "\""+roundedWireLen+"mm\""
							if field[key] == "\"Harness_name\"":
								thisIsTheHarnName = key
								try:
									myindex = self.refDesVals.index(refDes)
								except ValueError:
									self.writeErrorStr( "Refdes \""+refDes+"\" does not exist! Not routed yet?\n" )
									continue
								harnessName = self.harnessNum[myindex]
								field['ref'] = "\""+harnessName+"\""

#		print( self.refDesVals )
#		print( self.wireLength )
#		print( self.harnessNum )

#-----------------------------------------------------------------------------------------
# Find the Last refdes from the symbol -> instances-record
# Kicad has an uninvestigated way of storing the visible RefDes-values. This change was
# added to Kicad 7.0.2. Without understanding why I just read the last refdes available...
# In current tests the the recursion count has been 9. Might get bigger
# with deeper hierarchical designs.
#-----------------------------------------------------------------------------------------
#	recursiveCtr = 0
	lastRefDes = ""
	def find_RefDes( self, listItem ):
		from sexpdata import Symbol, car, cdr
		#self.recursiveCtr+=1
		for i, j in  enumerate(listItem):
			if ( not hasattr(j, "__getitem__") ):
				return
			elif ( isinstance( car(j), Symbol ) and ( car(j) != Symbol("reference")) ):
				if( hasattr(j, "__getitem__") ):
					self.find_RefDes( j )
			elif( isinstance( car(j), Symbol) and ( car(j)== Symbol("reference")) ):
				self.lastRefDes = cdr(j)[0]

#-----------------------------------------------------------------------------------------
# Write Kicad V6 Schematic Sheet Data
#
#-----------------------------------------------------------------------------------------
	def writeKicadSch_v6( self ):
		from sexpdata import Symbol, car, cdr
		for i, x in enumerate(self.kiCadSch):
			if ( car(x) == Symbol('symbol') ):
				refDes = ""
				for j, y in enumerate(x):
				#---------------------------------------------------
				# Check if this item is a cable or a wire. If not then continue
				#---------------------------------------------------
					if ( (car(y) == Symbol('property')) and  ( cdr(y)[0]== "Reference" )):
						if( (cdr(y)[1][:1] == 'W') or (cdr(y)[1][:3]=="CBL")):
							refDes = cdr(y)[1]
							# Find instance reference designator
							for d, z in  enumerate(x):
								if ( car(z) == Symbol('instances') ):
									#self.recursiveCtr=0
									self.lastRefDes = ""
									self.find_RefDes( z )
									#print( "FINAL REFDES = "+self.lastRefDes)
									#print( "recursionCount = "+ str(self.recursiveCtr))
									if(self.lastRefDes):
										refDes = self.lastRefDes
						else:
							continue

				#---------------------------------------------------
				# Process the lengths and the Part Numbers
				#---------------------------------------------------
				# Update the Harness Name String if it exists
					if ( car(y) == Symbol('property') ):
						if( cdr(y)[0].lower() == "harness_name" ):		#note - lower case
							try:
								myindex = self.refDesVals.index(refDes)
							except ValueError:
								self.writeErrorStr( "Refdes \""+refDes+"\" does not exist! Not routed yet?\n" )
								continue
							harnessName = self.harnessNum[myindex]
							y[2] = harnessName
					#---------------------------------------------------
					# Update the Harness Length String if it exists
						if( cdr(y)[0].lower() == "length" ):
							try:
								myindex = self.refDesVals.index(refDes)
							except ValueError:
								self.writeErrorStr( "Refdes \""+refDes+"\" does not exist! Not routed yet?\n" )
								continue
							roundedIntLen = math.ceil(float(self.wireLength[myindex]))
							roundedWireLen = str(roundedIntLen).split('.')[0] 				# Round up and no decimal places
							self.writeInfoStr( "Name: " + "{0:<6}".format(refDes) + " Harness Name: " + "{0:<15}".format(self.harnessNum[myindex]) + " lenght: " +roundedWireLen + "\n" )
							y[2] = (roundedWireLen+"mm")

#-----------------------------------------------------------------------------------------
# Read data from Creo xml and store the read lengths, part numbers, and refdes values.
#
#-----------------------------------------------------------------------------------------
	def readCreoPartNumsAndLengths( self, fileName ):
		"""
		This function Reads the wirenames (creo part names) and their lengths.

		Args:
			arg1: Original design name

		Note:
			cables.inf file is used if possible. I now create cables.inf with mapkey
			and read the latest version from the work directory. cables.inf must not be
			older than 1 hour.

		Returns:
			True if succesful
		"""

		file_path = "C:\PTC\work9\cables.inf"  # Replace with the actual path to your text file
		readCblName = ""
		harnessName = ""

		self.refDesVals = []
		self.harnessNum = []
		self.wireLength = []

		self.writeInfoStr( "Creo Back Annotation - Lengths and Harness Names\n" )
		self.writeInfoStr( "------------------------------------------------\n" )

		files = glob.glob( file_path + '.*' )
		sorted_files = sorted(files, key=lambda x: os.path.splitext(x)[1], reverse=True )

		# Test whether the cables.inf.x file exists and is not older than one hour
		# Cables.Inf works also for flat cables. I could not get the length for the ribbon
		# cable when exporting the creo schematic xml.
		if( (sorted_files) and self.is_file_newer_than_one_hour( sorted_files[0] ) ):
			self.writeInfoStr( "Using "+ sorted_files[0] + " for back-annotation\n" )
			with open(sorted_files[0], "r") as file:
				for line in file:
					# Process each line here
					thisLine = line.strip()
					if(thisLine.startswith("HARNESS NAME:")):
						tokens = thisLine.split(":")
						#print("Harness Name = "+tokens[1])
						harnessName = tokens[1]
						continue

					if( thisLine.startswith("W") or thisLine.startswith("CBL") ):
						tokens = thisLine.split()
						if(readCblName == tokens[0].split(":",1)[0]):
							#print("Already read cbl")
							continue

						readCblName =  tokens[0]
						cblLength = tokens[2]

						self.harnessNum.append( harnessName )
						self.refDesVals.append( readCblName )
						self.wireLength.append( cblLength )
		# else continue with the old method of reading _creoin.xml from the current directory

		else:
			self.creoSchXmlName = os.path.splitext(fileName)[0] +"_creoin.xml"
			self.writeInfoStr( "Using "+ self.creoSchXmlName + " for back-annotation\n" )

			if( os.path.isfile(self.creoSchXmlName) ):
				self.writeInfoStr( "Creo Schematic Xml-file OK: " + self.creoSchXmlName + "\n" )
			else:
				self.writeErrorStr( "Creo Schematic Inputfile NOT FOUND: " + self.creoSchXmlName + "\n" )
				self.writeInfoStr( "NOTE:You need to export Creo Schematic xml file with name: " + self.creoSchXmlName + "\n" )
				self.writeInfoStr( "(Cabling -> Logical Data -> Export -> Creo Schematic)\n" )
				return False

			creoXml = minidom.parse( self.creoSchXmlName )
			connections = creoXml.getElementsByTagName("CONNECTION")

			for connection in connections:
				readCblName = connection.getAttribute("name")
				type = connection.getAttribute("type")
				varName = ""
				harnessName = ""
				if readCblName[:1] =="W" or type == "ASSEMBLY":
					self.refDesVals.append(readCblName)
					parameters = connection.getElementsByTagName('PARAMETER')
					for param in parameters:
						varName = param.getAttribute('name')
						harnessName = param.getAttribute('value')
						if( varName == "LENGTH" ):
							self.wireLength.append(harnessName)
						if( varName == "HARNESS_NAME"):
							self.harnessNum.append(harnessName)

		return True

	def is_file_newer_than_one_hour( self, file_path ):
		"""
		This function Checks whether the cables.inf file was generated within the past hour.
		If not then return false.

		Args:
			arg1: Path to the file to check

		Returns:
			The result true if file is generated within the past hour.
			The result is False if file doesn't exist or was generated over an hour ago.
		"""
		if not os.path.isfile(file_path):
			return False  # File doesn't exist

		file_stat = os.stat(file_path)
		modified_time = datetime.datetime.fromtimestamp(file_stat.st_mtime)
		current_time = datetime.datetime.now()

		time_difference = current_time - modified_time
		time_difference_in_hours = time_difference.total_seconds() / 3600

		return time_difference_in_hours < 1

#-----------------------------------------------------------------------------------------
# Read existing sheetnames in the design
#
#-----------------------------------------------------------------------------------------
	def readCreoSheetNames( self, fileName ):
		self.creoSchXmlName = fileName +".xml"

		creoXml = minidom.parse( self.creoSchXmlName )
		sheetNames = creoXml.getElementsByTagName("sheet")

		self.sheets = []
		for mysheet in sheetNames:
			x = mysheet.getElementsByTagName("source")[0]
			y =x.childNodes[0];
			self.sheets.append( y.nodeValue )

		del creoXml

#-----------------------------------------------------------------------------------------
# Read data from Creo Schematic file (Created with Creo)
# and write the cable lengths and part numbers to Kicad Schematic file
#
#
#-----------------------------------------------------------------------------------------
	def backAnnotate( self, fileName ):
		self.creoSchXmlName = fileName +"_creoin.xml"
		self.kiCadOutputName = fileName +"_creo.sch"
		self.kiCadOriginalFile = fileName +".sch"

		self.writeInfoStr( "Creo Back Annotation - Lengths and Harness Names\n" )
		self.writeInfoStr( "------------------------------------------------\n" )

		if( os.path.isfile(self.creoSchXmlName) ):
			self.writeInfoStr( "Creo Schematic Inputfile OK: " + self.creoSchXmlName + "\n" )
		else:
			self.writeErrorStr( "Creo Schematic Inputfile NOT FOUND: " + self.creoSchXmlName + "\n" )
			self.writeInfoStr( "NOTE:You need to export Creo Schematic xml file with name: " + self.creoSchXmlName + "\n" )
			self.writeInfoStr( "(Cabling -> Logical Data -> Export -> Creo Schematic)\n" )
			return False

		if( os.path.isfile(self.kiCadOriginalFile) ):
			self.writeInfoStr( "Kicad Schematic Inputfile OK: " + self.kiCadOriginalFile + "\n" )
		else:
			self.writeErrorStr( "Kicad Schematic Inputfile NOT FOUND: " + self.kiCadOriginalFile + "\n" )
			return False

		creoXml = minidom.parse(self.creoSchXmlName)
		connections = creoXml.getElementsByTagName("CONNECTION")
		self.refDesVals = []
		self.harnessNum = []
		self.wireLength = []
		for connection in connections:
			wireName = connection.getAttribute("name")
			type = connection.getAttribute("type")
			varName = ""
			varValue = ""
			if wireName[:1] =="W" or type == "ASSEMBLY":
				self.refDesVals.append(wireName)
				parameters = connection.getElementsByTagName('PARAMETER')
				for param in parameters:
					varName = param.getAttribute('name')
					varValue = param.getAttribute('value')
					if( varName == "LENGTH" ):
						self.wireLength.append(varValue)
					if( varName == "HARNESS_NAME"):
						self.harnessNum.append(varValue)

		# Put lenghts to Kicad Schematic
		# Do not overwrite the original file
		self.writeInfoStr( "\nProcessing wires and cables:\n" )
		self.writeInfoStr( "----------------------------\n" )
		self.writeInfoStr( str(self.refDesVals) + "\n\n" )

		myvariable = self.backUpFile( self.kiCadOriginalFile )
		kiCadSch = sch.Schematic( self.kiCadOriginalFile+".bak")
		self.writeKicadSheet( kiCadSch )
		kiCadSch.save( self.kiCadOriginalFile )

		# Process subsheets
		self.prosessedSheets = []
		for sheet in kiCadSch.sheets:
			for field in sheet.fields:
				if( field['id'] =="F1" ):
					subSheetFilename = field['value'].replace('"', "")

					if( os.path.exists( subSheetFilename ) ):
						if( subSheetFilename in self.prosessedSheets ):
							self.writeWarningStr( "Child .sch already processed: " + subSheetFilename + "!\n" )
							self.writeWarningStr( "NOTE: Reusing schematic shows the same wire\n" )
							self.writeWarningStr( "lengths and partnames in all instances of the file.\n" )
							self.writeWarningStr( "Copy the .sch to a new name if you need\n" )
							self.writeWarningStr( "to have unique names and wire lengths!\n" )
						else:
							self.writeInfoStr( "\nProcessing child sheet " + subSheetFilename + "\n" )
							myvariable = self.backUpFile( subSheetFilename )
							kicadChildSheet = sch.Schematic(subSheetFilename+".bak")
							self.writeKicadSheet( kicadChildSheet )
							kicadChildSheet.save( subSheetFilename )
							self.prosessedSheets.append(subSheetFilename)
					else:
						self.writeErrorStr( "File does not exist!: " + subSheetFilename + "\n" )
		return True

#-----------------------------------------------------------------------------------------
# Read data from Creo Schematic file (Created with Creo)
# and write the cable lengths and part numbers to Kicad V6 Schematic file
#
#
#-----------------------------------------------------------------------------------------
	def backAnnotateV6( self, fileName ):
		from sexpdata import loads, dumps

		# Put lenghts to Kicad Schematic
		# Do not overwrite the original file
		self.writeInfoStr( "\nProcessing wires and cables:\n" )
		self.writeInfoStr( "----------------------------\n" )
		self.writeInfoStr( str(self.refDesVals) + "\n\n" )

		self.prosessedSheets = []
		currentDirectory = os.path.dirname( fileName )
		for myfilename in self.sheets:
			#------------------------------------------------------------------
			# Error Cheking
			myfilename = os.path.join( currentDirectory, myfilename )
			if( os.path.exists( myfilename ) ):
				if( myfilename in self.prosessedSheets ):
					self.writeWarningStr( "Child .sch already processed: " + myfilename + "!\n" )
					self.writeWarningStr( "NOTE: Reusing schematic shows the same wire\n" )
					self.writeWarningStr( "lengths and partnames in all instances of the file.\n" )
					self.writeWarningStr( "Copy the .sch to a new name if you need\n" )
					self.writeWarningStr( "to have unique names and wire lengths!\n" )
					continue
				elif ( self.backUpFile( myfilename ) ):
					self.writeInfoStr( "\nBacking up " + myfilename + " OK\n" )
				else:
					self.writeErrorStr( "\nBacking up " + myfilename + " FAILED\n" )
					continue
			#------------------------------------------------------------------
			# Process sheet for partnumbers and lengths
				try:
					f = open((myfilename+".bak"),"r")
					self.line = f.read()
				except:
					self.writeErrorStr( "Could not read file: " + myfilename +".bak !\n" )
					continue
				finally:
					self.kiCadSch = loads( self.line )
					self.writeKicadSch_v6( )
					f.close( )
				try:
					f = open( myfilename, "w" )
					f.write(dumps( self.kiCadSch ))
				except:
					self.writeErrorStr( "Could not write file: " + myfilename + "!\n" )
				finally:
					self.writeInfoStr( "Updated file: " + myfilename + " succesfully.\n" )
					f.close( )
				self.prosessedSheets.append( myfilename )

			else:
				self.writeErrorStr( "File does not exist!: " + myfilename + "\n" )
		return True

#-----------------------------------------------------------------------------------------
# Read the correct filename from the .xml file
#
#-----------------------------------------------------------------------------------------
	def getSourceFilenameFromXml( self, xmlFileName ):
		tmpObject = minidom.parse(xmlFileName)
		currentFileName = tmpObject.getElementsByTagName("source")
		del tmpObject
		return( currentFileName[0].firstChild.nodeValue )

#-----------------------------------------------------------------------------------------
# String Logger functions
#
# These fuctions log the strings and outputs data to stdout and stderr
#
#-----------------------------------------------------------------------------------------
	def writeInfoStr( self, iStr ):
		self.__infoString += iStr

	def getInfoStr( self ):
		return self.__infoString

	def writeErrorStr( self, eStr ):
		self.__errorString += eStr

	def getErrorStr( self ):
		if self.__errorString == "":
			self.__errorString="No Errors!"
		return self.__errorString

	def clearErrorStr( self ):
		self.__errorString=""

	def writeWarningStr( self, wStr ):
		self.__warningString += wStr

	def getWarningStr( self ):
		if self.__warningString == "":
			self.__warningString="No Warnigns!"
		return self.__warningString

	def clearWarningStr( self ):
		self.__warningString=""

#-----------------------------------------------------------------------------------------
# If this is called Independently
#
# Create instance and call with parameters
#
#-----------------------------------------------------------------------------------------
if __name__ == '__main__':
	fileToProcess = sys.argv[1]    				# unpack 2 command line arguments

	# Split the file extension away if it exists. This comes from command line
	# fileNameToProcess = os.path.splitext(fileToProcess)[0]

	# Initialize the function instance
	creoCablelengths = xmlReadCreo( )

	# Get the filename from the xml-File
	tempFileName = creoCablelengths.getSourceFilenameFromXml( fileToProcess )
	fileNameToProcess = os.path.splitext(tempFileName)[0]
	fileExtension = os.path.splitext(tempFileName)[1]

	if( fileExtension == ".sch" ):
		creoCablelengths.writeInfoStr( "\nProsess Kicad V5 file.\n")
		if( creoCablelengths.readCreoPartNumsAndLengths( fileToProcess ) ):
			creoCablelengths.readCreoSheetNames( fileNameToProcess )
			creoCablelengths.backAnnotate( fileNameToProcess )
	elif( fileExtension == ".kicad_sch" ):
		creoCablelengths.writeInfoStr( "\nProsess Kicad V6 file.\n")
		if( creoCablelengths.readCreoPartNumsAndLengths( fileToProcess ) ):
			creoCablelengths.readCreoSheetNames( fileNameToProcess )
			creoCablelengths.backAnnotateV6( fileNameToProcess )
	else:
		creoCablelengths.writeInfoStr( "\nNo Valid Filename found " + fileToProcess + "\n" )

	print("Info", file=sys.stdout)
	print( creoCablelengths.getInfoStr(), file=sys.stdout )

	print("Warnigns", file=sys.stdout)
	print( creoCablelengths.getWarningStr(), file=sys.stdout )

	print("Errors", file=sys.stderr)
	print( creoCablelengths.getErrorStr(), file=sys.stderr )
	print( "Please Reload the Kicad Schematic if Operation was Successful", file=sys.stdout )


import json
import random

with open('data/LLMScience.json',encoding='utf-8') as f:
    datas = json.load(f)

datas = datas[:200]

# datas = random.sample(datas, 5)

prompt = """Question: {}
A: {}
B: {}
C: {}
D: {}
E: {}
Answer: {}"""

# 筛选出所有答案为A,B,C,D,E的数据
data_A = [item for item in datas if item['answer'] == 'A']
data_B = [item for item in datas if item['answer'] == 'B']
data_C = [item for item in datas if item['answer'] == 'C']
data_D = [item for item in datas if item['answer'] == 'D']
data_E = [item for item in datas if item['answer'] == 'E']

# 检查每个答案是否都至少有一个数据
if not all([data_A, data_B, data_C, data_D, data_E]):
    print("数据中不包含所有的答案至少一次!")
else:
    sampled_data = []
    sampled_data.append(random.choice(data_A))
    sampled_data.append(random.choice(data_B))
    sampled_data.append(random.choice(data_C))
    sampled_data.append(random.choice(data_D))
    sampled_data.append(random.choice(data_E))

random.shuffle(sampled_data)

total_few_shot = ""
for data in sampled_data:
    question = data['prompt']
    A = data['A']
    B = data['B']
    C = data['C']
    D = data['D']
    E = data['E']
    answer = data['answer']
    total_few_shot+=prompt.format(question,A,B,C,D,E,answer)+"\n\n"

print(total_few_shot)


# Author : Tim Destan
# Feature based clusterer

from collections import defaultdict
from qbcommon import all_pairs_symmetric
from featurespace import *

import logging
logger = logging.getLogger("FeatureClusterer")

class ScoreTypes(object):
  DISTANCE = "DISTANCE"
  SIMILARITY = "SIMILARITY"

class GuidGenerator(object):
  """
  Generates globally unique identifiers.
  """
  def __init__(self):
    self.next = 0

  def new_id(self):
    """
    Returns a new ID
    """
    self.next += 1
    return self.next

class AgglomerativeCluster(object):
  """
  Agglomerative clusterer based on a feature distance function that takes
  features as vectors from names to values.
  """
  def __init__(self, compositeRecords, featureSets, scoreFunction,
      threshold=None, scoreType=ScoreTypes.DISTANCE, baseDistanceCache={},
      guidGenerator=GuidGenerator(), globalClusters={}):
    """
    Constructor

    :param compositeRecords: Collection of composite records to classify.
    :param featureSets: List of featuresets. Each base record is
      interpreted as an index into this list.
    :param threshold: Optional distance threshold for when to stop merging clusters.
    :param scoreFunction: A distance function to compute the distance between two
      feature vectors. Should be a distance metric.
    :param baseDistanceCache: A cache of distances between base records.
    """
    self.baseFeatureArray = featureSets
    self.scoreFunction = scoreFunction

    self.onMerge = lambda slf, thresh: ()

    self.informative_features = defaultdict(float)

    if scoreType == ScoreTypes.DISTANCE:
      self.scoreIsBetter = lambda score, best: score < best
    elif scoreType == ScoreTypes.SIMILARITY:
      self.scoreIsBetter = lambda score, best: score > best
    else:
      raise ValueError("Unknown Score type: %s" % repr(scoreType))

    if threshold is None:
      logger.warn("Threshold should probably be specified.. Defaulting to infinity..")
      self.threshold = InfiniteFeatureComparisonResult()
    else:
      self.threshold = ConstantValueFeatureComparisonResult(threshold)

    # Define two maps, one from records to cluster identifiers (which we will
    # start with each record in a cluster with its own identifier) and a second
    # from cluster identifiers to the records contained therein.
    #
    self.b2c = {}
    self.c2b = {}

    # Presently unused
    self.globalClusters = globalClusters

    self.guidGenerator = guidGenerator

    for compositeRecord in compositeRecords:
      clusterIndex = self._newClusterId()
      self.c2b[clusterIndex] = compositeRecord
      for baseRecord in compositeRecord:
        self.b2c[baseRecord] = clusterIndex

    # Cache distances between two clusters and between base recs.
    #
    if baseDistanceCache:
      self.baseDistanceCache = baseDistanceCache
    else:
      self.baseDistanceCache = {}
    self.clusterDistanceCache = {}

  def _newClusterId(self):
    """Gets a new cluster ID unique to this object"""
    return self.guidGenerator.new_id()

  def _baseDistance(self, b1, b2):
    """
    Computes the distance between two base records

    :param b1: one record
    :param b2: another one
    """
    if b1 > b2:
      b1, b2 = b2, b1
    distance = self.baseDistanceCache.get((b1,b2), None)
    if distance is None:
      distance = self.scoreFunction(\
        self.baseFeatureArray[b1], self.baseFeatureArray[b2])
      self.baseDistanceCache[(b1,b2)] = distance
    return distance

  def distance(self, c1, c2):
    """
    Computes the difference between the clusters with the given identifiers.

    :param c1: a cluster identifier
    :param c2: another cluster identifier

    :returns: The distance between the two identified clusters.
    """
    # Concrete class should provide implementation.
    #
    raise NotImplemented

  def mergeClusters(self,c1,c2):
    """
    Merges the two argument clusters.

    :param c1: A cluster identifier
    :param c2: Another cluster identifier.
    """
    combinedBaseRecords = (self.c2b[c1] | self.c2b[c2])
    # Remove these two clusters.
    del self.c2b[c1]
    del self.c2b[c2]
    cNew = self._newClusterId()
    self.c2b[cNew] = combinedBaseRecords
    for baseRecord in combinedBaseRecords:
      self.b2c[baseRecord] = cNew

  def mergeNearestClusters(self):
    """
    Finds the two clusters at the minimum distance and merges them together.

    :returns: True if we merged any clusters.
    """
    if len(self.c2b) <= 1:
      # Cannot merge if there is only 1 cluster remaining.
      #
      logger.debug("Only one cluster left, terminating clustering.")
      return False

    bestDistance = None
    cbest1, cbest2 = None, None

    for c1,c2 in all_pairs_symmetric(self.c2b.keys()):
      distance = self.distance(c1,c2)
      if (not bestDistance) or self.scoreIsBetter(distance, bestDistance):
        bestDistance = distance
        cbest1, cbest2 = c1, c2

    #assert(cbest1 is not None and cbest2 is not None)

    if self.scoreIsBetter(self.threshold, bestDistance):
      logger.debug("Best score %g passed score threshold %g, terminating clustering." % \
        (bestDistance.total(), self.threshold.total()))
      return False
    contrib = bestDistance.feature_contributions()
    for feat in contrib:
      self.informative_features[feat] += contrib[feat]
    # This line is just too much output, makes debug level unusuable. Occasionally
    # uncommented when something in this class needs to be carefully debugged.
    #
    #logger.debug("Merging " + repr(self.c2b[cbest1]) + " and " + repr(self.c2b[cbest2]) + \
    #  " with score " + repr(bestDistance.total()) + ".")
    self.mergeClusters(cbest1, cbest2)
    self.onMerge(self, bestDistance)
    return True

  def cluster(self):
    """Clusters the records and returns the resulting clusters"""
    logger.debug("Beginning feature based clustering on %d clusters." % len(self.c2b))
    # Merge the two nearest clusters until we can't.
    #
    while self.mergeNearestClusters():
      pass
    logger.debug("After clustering, there are now %d clusters remaining." % len(self.c2b))
    return self.c2b.values()

class MinDistanceAgglomerativeCluster(AgglomerativeCluster):
  """
  Agglomerative clusterer that compares two clusters by the distance between
  their closest two points.
  """
  def distance(self, c1, c2):
    """
    Computes the difference between the clusters with the given identifiers.

    :param c1: a cluster identifier
    :param c2: another cluster identifier

    :returns: The distance between the two identified clusters.
    """
    if c1 > c2:
      c1, c2 = c2, c1
    clusterDistance = self.clusterDistanceCache.get((c1,c2), None)
    if clusterDistance is None:
      # Find the minimum distance between any two pairs in the clusters.
      #
      minDistance = InfiniteFeatureComparisonResult()
      for b1 in self.c2b[c1]:
        for b2 in self.c2b[c2]:
          baseDistance = self._baseDistance(b1, b2)
          if baseDistance < minDistance:
            minDistance = baseDistance
      clusterDistance = minDistance
      self.clusterDistanceCache[(c1,c2)] = clusterDistance
    return clusterDistance

class MaxDistanceAgglomerativeCluster(AgglomerativeCluster):
  """
  Agglomerative clusterer that compares two clusters by the distance between
  their farthest two points.
  """
  def distance(self, c1, c2):
    """
    Computes the difference between the clusters with the given identifiers.

    :param c1: a cluster identifier
    :param c2: another cluster identifier

    :returns: The distance between the two identified clusters.
    """
    if c1 > c2:
      c1, c2 = c2, c1
    clusterDistance = self.clusterDistanceCache.get((c1,c2), None)
    if clusterDistance is None:
      # Find the maximum distance between any two pairs in the clusters.
      #
      maxDistance = ConstantValueFeatureComparisonResult(0.0)
      for b1 in self.c2b[c1]:
        for b2 in self.c2b[c2]:
          baseDistance = self._baseDistance(b1, b2)
          if baseDistance > maxDistance:
            maxDistance = baseDistance
      clusterDistance = maxDistance
      self.clusterDistanceCache[(c1,c2)] = clusterDistance
    return clusterDistance

class AverageDistanceAgglomerativeCluster(AgglomerativeCluster):
  """
  Agglomerative clusterer that compares two clusters by the average distance
  between the points in those clusters.
  """
  def distance(self, c1, c2):
    """
    Computes the difference between the clusters with the given identifiers.

    :param c1: a cluster identifier
    :param c2: another cluster identifier

    :returns: The distance between the two identified clusters.
    """
    if c1 > c2:
      c1, c2 = c2, c1
    clusterDistance = self.clusterDistanceCache.get((c1,c2), None)
    if clusterDistance is None:
      totalDistance = FeatureComparisonResult() # 0.0
      count = 0
      for b1 in self.c2b[c1]:
        for b2 in self.c2b[c2]:
          totalDistance = totalDistance.add(self._baseDistance(b1, b2))
          count += 1
      if count == 0:
        clusterDistance = FeatureComparisonResult() # 0.0
      else:
        clusterDistance = totalDistance.normalize(count)
      self.clusterDistanceCache[(c1,c2)] = clusterDistance
    return clusterDistance


import unittest
import data

class TestData(unittest.TestCase):
    def test_batch(self):
        sequences = [el.split() for el in \
                     ['I love it', 'My name is Earl', 'Whose line is it anyway', 'As you like it', 'Everybody']]
        words = list(set([el for lis in sequences for el in lis]))
        word_index = {wd: ix for ix, wd in enumerate(words)}
        word_index[data.PAD_TOKEN] = 170
        word_index[data.START_OF_VERSE_TOKEN] = 171
        word_index[data.END_OF_VERSE_TOKEN] = 172
        dataset, original_sequence_lengths = data.batch(sequences, 2, word_index)
        self.assertEqual(3, len(dataset))
        self.assertTrue(all([len(el) <= 2 for el in dataset]))
        self.assertTrue(all([len(seq) == 6 for seq in dataset[0]]))
        self.assertTrue(all([len(seq) == 7 for seq in dataset[1]]))
        self.assertTrue(all([all([seq[0] == 171 for seq in b]) for b in dataset]))
        self.assertTrue(all([all([seq[-1] in (170, 172) for seq in b]) for b in dataset]))
        self.assertEqual(172, dataset[0][1][-2])
        self.assertEqual(6, original_sequence_lengths[1][1])

    def test_batch_sorted(self):
        sequences = [el.split() for el in \
                     ['I love it', 'My name is Earl', 'Whose line is it anyway', 'As you like it', 'Everybody']]
        words = list(set([el for lis in sequences for el in lis]))
        word_index = {wd: ix for ix, wd in enumerate(words)}
        index_word = {ix: wd for wd, ix in word_index.items()}
        word_index[data.PAD_TOKEN] = 170
        word_index[data.START_OF_VERSE_TOKEN] = 171
        word_index[data.END_OF_VERSE_TOKEN] = 172
        dataset, _ = data.batch(sequences, 2, word_index)
        self.assertEqual('My', index_word[dataset[0][0][1]])

    def test_pad_batch(self):
        sequences = [el.split() for el in ['I love it', 'My name is Earl']]
        padded = data.pad_batch(sequences)
        self.assertEqual(2, len(padded))
        self.assertTrue(all([len(el) == 4 for el in padded]))
        self.assertEqual(data.PAD_TOKEN, padded[0][-1])

    def test_join_texts(self):
        texts = ['something', 'else', 'is', 'here']
        self.assertEqual(
            '\n\nsomething else is here EOS',
            data.join_texts(texts, prompt='\n\n', separator=' ', eot_token='EOS')
        )

    def test_join_by_hierarchy(self):
        comments = """# language_name:        English
# closest_ISO_639-3:    eng
# ISO_15924:            Latn
# year_short:           1997
# year_long:
# vernacular_title:
# english_title:        World English Bible
# URL:                  http://biblehub.com/web/matthew/1.htm
# copyright_short:      Public Domain 1997
# copyright_long:
# notes:
"""
        comment_lines = comments.split('\n')
        lines = comment_lines + ['40001001\tFirst verse', '40001002\tSecond verse', '40002001\tNext chapter', '41001001\tAnother book',
                 '67001001\tAnother testament']
        bible = data.parse_pbc_bible_lines(lines, True, 'eng')
        _, by_testament, by_book, by_chapter, _ = bible.join_by_toc()
        self.assertTrue('old' not in by_testament)
        self.assertEqual('First verse_Second verse_Next chapter_Another book'.split('_'),
                         by_testament['new'])
        self.assertEqual(['Another testament'],
                         by_testament['apocryphal'])
        self.assertEqual('First verse_Second verse_Next chapter'.split('_'), by_book[40])
        self.assertEqual(['Another book'], by_book[41])
        self.assertEqual('Another testament'.split('_'), by_book[67])
        self.assertEqual('First verse_Second verse'.split('_'), by_chapter[40001])
        self.assertEqual('Next chapter'.split('_'), by_chapter[40002])
        self.assertEqual('Another book'.split('_'), by_chapter[41001])
        self.assertEqual('Another testament'.split('_'), by_chapter[67001])

    def test_to_dictionaries_repeated_commented_out_lines(self):
        comment_lines = []
        content_lines = [(1, "some lines", False),
                         (2, "some other line", False),
                         (3, "this line is commented out", True),
                         (3, "again but with the same ID", True),
                         (4, "some other line", False)]
        _, _, hidden_content = data.PbcBible.to_dictionaries(comment_lines, content_lines)
        self.assertEqual({3: 'again but with the same ID'}, hidden_content)

if __name__ == "__main__":
    unittest.main()


import sys
# from PyQt4 import QtGui
# from PyQt4 import QtCore
# from PyQt4.QtCore import Qt

from PyQt5.QtGui import *
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *

class TitleBar(QWidget):
    def __init__(self, parent=None):
        QWidget.__init__(self, parent)
        self.box = parent
        self.box.setWindowFlags(Qt.FramelessWindowHint)
        # self.setAutoFillBackground(True)
        # self.setBackgroundRole(QPalette.Highlight)
        self.minimize=QPushButton(self)
        self.minimize.setIcon(QIcon('img/min.png'))
        self.maximize=QPushButton(self)
        self.maximize.setIcon(QIcon('img/max.png'))
        close=QPushButton(self)
        close.setIcon(QIcon('img/close.png'))
        self.minimize.setMinimumHeight(10)
        close.setMinimumHeight(10)
        self.maximize.setMinimumHeight(10)
        label=QLabel(self)
        label.setText(self.box.windowTitle())
        self.setWindowTitle("Window Title")
        hbox=QHBoxLayout(self)
        hbox.addWidget(label)
        hbox.addWidget(self.minimize)
        hbox.addWidget(self.maximize)
        hbox.addWidget(close)
        hbox.insertStretch(1,500)
        hbox.setSpacing(0)
        self.setSizePolicy(QSizePolicy.Expanding,QSizePolicy.Fixed)
        self.maxNormal=False
        close.clicked.connect(self.close)
        self.minimize.clicked.connect(self.showSmall)
        self.maximize.clicked.connect(self.showMaxRestore)

    def showSmall(self):
        self.box.showMinimized()

    def showMaxRestore(self):
        if(self.maxNormal):
            self.box.showNormal()
            self.maxNormal= False
            self.maximize.setIcon(QIcon('img/max.png'))
            print ('1')
        else:
            self.box.showMaximized()
            self.maxNormal=  True
            print ('2')
            self.maximize.setIcon(QIcon('img/max2.png'))

    def close(self):
        self.box.close()

    def mousePressEvent(self,event):
        if event.button() == Qt.LeftButton and not self.maxNormal:
            self.box.moving = True
            self.box.offset = event.pos()

    def mouseMoveEvent(self,event):
        if not self.maxNormal:
            if self.box.moving: self.box.move(event.globalPos()-self.box.offset)

class Frame(QFrame):
    def __init__(self, parent=None):
        QFrame.__init__(self, parent)
        self.m_mouse_down= False
        self.setFrameShape(QFrame.StyledPanel)
        css = """
        QFrame{
            Background:  #D700D7
            color:white
            font:13px
            font-weight:bold
            }
        """
        self.setStyleSheet(css)
        self.setWindowFlags(Qt.FramelessWindowHint)
        self.setMouseTracking(True)
        self.m_titleBar= TitleBar(self)
        self.m_content= QWidget(self)
        vbox=QVBoxLayout(self)
        vbox.addWidget(self.m_titleBar)
        # vbox.setMargin(0)
        vbox.setSpacing(0)
        layout=QVBoxLayout(self)
        layout.addWidget(self.m_content)
        # layout.setMargin(5)
        layout.setSpacing(0)
        vbox.addLayout(layout)
        # Allows you to access the content area of the frame
        # where widgets and layouts can be added

    def contentWidget(self):
        return self.m_content

    def titleBar(self):
        return self.m_titleBar

    def mousePressEvent(self,event):
        self.m_old_pos = event.pos()
        self.m_mouse_down = event.button()== Qt.LeftButton

    def mouseMoveEvent(self,event):
        x=event.x()
        y=event.y()

    def mouseReleaseEvent(self,event):
        m_mouse_down=False

if __name__ == '__main__':
    app = QApplication(sys.argv)
    box = Frame()
    box.move(60,60)
    box.show()
    app.exec_()


import matplotlib.pyplot as plt
import numpy as np
import tensorflow as tf
from sklearn import metrics
import pandas as pd
import pickle

from keras.optimizers import Adam
from keras.models import Model
from keras.layers import Dense
from keras.layers import Input
from keras.layers import Flatten
from keras.layers import Conv2D
from keras.layers.normalization.batch_normalization import BatchNormalization
from keras.layers import Dropout

def define_CNN(in_shape, n_keypoints):

    in_one = Input(shape=in_shape)
    conv_one_1 = Conv2D(16, kernel_size=(3, 3), activation='relu', strides=(1, 1), padding = 'same')(in_one)
    conv_one_1 = Dropout(0.3)(conv_one_1)
    conv_one_2 = Conv2D(32, kernel_size=(3, 3), activation='relu', strides=(1, 1), padding = 'same')(conv_one_1)
    conv_one_2 = Dropout(0.3)(conv_one_2)

    conv_one_2 = BatchNormalization(momentum=0.95)(conv_one_2)

    fe = Flatten()(conv_one_2)
    # dense1
    dense_layer1 = Dense(512, activation='relu')(fe)
    dense_layer1 = BatchNormalization(momentum=0.95)(dense_layer1)
    # # dropout

    # dropout
    dense_layer1 = Dropout(0.4)(dense_layer1)

    out_layer = Dense(n_keypoints, activation = 'linear')(dense_layer1)

    # model
    model = Model(in_one, out_layer)
    opt = Adam(lr=0.001, beta_1=0.5)

    # compile the model
    model.compile(loss='mse', optimizer=opt, metrics=['mae', 'mse', 'mape', tf.keras.metrics.RootMeanSquaredError()])
    return model

def main():
    # #load the feature and labels, 24066, 8033, and 7984 frames for train, validate, and test
    # featuremap_train = np.load('feature/featuremap_train.npy')
    # featuremap_validate = np.load('feature/featuremap_validate.npy')
    # featuremap_test = np.load('feature/featuremap_test.npy')

    # labels_train = np.load('feature/labels_train.npy')
    # labels_validate = np.load('feature/labels_validate.npy')
    # labels_test = np.load('feature/labels_test.npy')
    # remove the arms up one
    training_data_file_names = ["arms-up.bin", "t-pose.bin", "arms-down.bin"]
    # training_data_file_names = ["squat.bin"]
    # fig = plt.figure()
    # ax = fig.add_subplot(projection='3d')
    for name in training_data_file_names:
        with open(f"training_data/{name}", "rb") as f:
            training_features = pickle.load(f)
            for i in range(500):
                ax.clear()
                # ax.scatter(landmark.x, landmark.y, landmark.z)
                x = []
                y = []
                z = []
                for landmark in training_features[i].landmark:
                    x.append(landmark.x)
                    y.append(0)
                    z.append(landmark.y)
                    # ax.scatter(landmark.x, landmark.y, landmark.z)
                ax.scatter(x, y, z)
                ax.set_xlabel("X")
                ax.set_ylabel("Y")
                ax.set_zlabel("Z")
                ax.axes.set_xlim3d(left=-0.5, right=0.5)
                ax.axes.set_ylim3d(bottom=-0.5, top=0.5)
                ax.axes.set_zlim3d(bottom=1, top=0)

                plt.pause(0.05)

    # plt.show()
    #         # print(training_features[0].landmark[0])

    # # Initialize the result array
    # paper_result_list = []

    # # define batch size and epochs
    # batch_size = 128
    # epochs = 150

    # # load model
    # keypoint_model = tf.keras.models.load_model("model/MARS.h5")
    # # Repeat i iteration to get the average result
    # # for i in range(10):
    # # instantiate the model
    # keypoint_model = tf.keras.models.load_model("model/MARS.h5")

    # # save and print the metrics
    # # score_train = keypoint_model.evaluate(featuremap_train, labels_train,verbose = 1)
    # # print('train MAPE = ', score_train[3])
    # # score_test = keypoint_model.evaluate(featuremap_test, labels_test,verbose = 1)
    # # print('test MAPE = ', score_test[3])
    # print(len(featuremap_test))
    # result_test = keypoint_model.predict(np.array([featuremap_test[2735]]))

    # x = result_test[0][0:19]
    # y = result_test[0][19:38]
    # z = result_test[0][38:57]
    # # print(pts)

    # fig = plt.figure()
    # ax = fig.add_subplot(projection='3d')
    # ax.scatter(x, y, z)
    # ax.set_xlabel('X Label')
    # ax.set_ylabel('Y Label')
    # ax.set_zlabel('Z Label')
    # plt.show()

    # # df = pd.DataFrame(result_test)
    # # print(df)
    # # print(featuremap_test)
    # # print(featuremap_test[0])
    # # print(result_test)
    # # print(result_test[0])
    # exit()

    # # instantiate the model
    # # keypoint_model = define_CNN(featuremap_train[0].shape, 57)

    # # # # initial maximum error
    # # # score_min = 10
    # # history = keypoint_model.fit(featuremap_train, labels_train,
    # #                             batch_size=batch_size, epochs=epochs, verbose=1,
    # #                             validation_data=(featuremap_validate, labels_validate))
    # # result_test = keypoint_model.predict(featuremap_test)

if __name__ == "__main__":
    main()


# Main file to run the program
import Game

# Creating game object
g = Game.Game()
g.Initialization()

# Main game loop
while g.isRunning():
    g.handleEvent()
    g.Render()

# After game closed, quits all libraries
g.Clean()


import tkinter as tk
import random

class MathQuizApp:
    def __init__(self, root):
        self.root = root
        self.root.title("Math Quiz")

        self.color_themes = {
            "Light": {"bg": "white", "fg": "black"},
            "Dark": {"bg": "black", "fg": "white"}
        }

        self.language_options = {
            "English": {"start": "Start Quiz", "select_difficulty": "Select Difficulty:", "num_operations": "Number of Operations:", "min_number": "Min Number:", "max_number": "Max Number:", "color_theme": "Select Color Theme:", "language": "Select Language:"},
            "Estonian": {"start": "Alusta Testi", "select_difficulty": "Vali Raskustase:", "num_operations": "Tehtete Arv:", "min_number": "Minimaalne Arv:", "max_number": "Maksimaalne Arv:", "color_theme": "Vali Värviteema:", "language": "Vali Keel:"}
        }

        self.language_var = tk.StringVar()
        self.language_var.set("English")

        self.color_theme_var = tk.StringVar()
        self.color_theme_var.set("Light")

        self.difficulty_var = tk.StringVar()
        self.num_operations_var = tk.IntVar()
        self.min_number_var = tk.IntVar()
        self.max_number_var = tk.IntVar()

        self.difficulty_var.set("Easy")
        self.num_operations_var.set(5)
        self.min_number_var.set(1)
        self.max_number_var.set(10)

        self.difficulty_label = tk.Label(root, text=self.language_options[self.language_var.get()]["select_difficulty"], bg=self.color_themes[self.color_theme_var.get()]["bg"], fg=self.color_themes[self.color_theme_var.get()]["fg"])
        self.difficulty_label.pack()

        self.difficulty_menu = tk.OptionMenu(root, self.difficulty_var, "Easy", "Medium", "Hard")
        self.difficulty_menu.config(bg=self.color_themes[self.color_theme_var.get()]["bg"], fg=self.color_themes[self.color_theme_var.get()]["fg"])
        self.difficulty_menu.pack()

        self.num_operations_label = tk.Label(root, text=self.language_options[self.language_var.get()]["num_operations"], bg=self.color_themes[self.color_theme_var.get()]["bg"], fg=self.color_themes[self.color_theme_var.get()]["fg"])
        self.num_operations_label.pack()

        self.num_operations_entry = tk.Entry(root, textvariable=self.num_operations_var, bg=self.color_themes[self.color_theme_var.get()]["bg"], fg=self.color_themes[self.color_theme_var.get()]["fg"])
        self.num_operations_entry.pack()

        self.min_number_label = tk.Label(root, text=self.language_options[self.language_var.get()]["min_number"], bg=self.color_themes[self.color_theme_var.get()]["bg"], fg=self.color_themes[self.color_theme_var.get()]["fg"])
        self.min_number_label.pack()

        self.min_number_entry = tk.Entry(root, textvariable=self.min_number_var, bg=self.color_themes[self.color_theme_var.get()]["bg"], fg=self.color_themes[self.color_theme_var.get()]["fg"])
        self.min_number_entry.pack()

        self.max_number_label = tk.Label(root, text=self.language_options[self.language_var.get()]["max_number"], bg=self.color_themes[self.color_theme_var.get()]["bg"], fg=self.color_themes[self.color_theme_var.get()]["fg"])
        self.max_number_label.pack()

        self.max_number_entry = tk.Entry(root, textvariable=self.max_number_var, bg=self.color_themes[self.color_theme_var.get()]["bg"], fg=self.color_themes[self.color_theme_var.get()]["fg"])
        self.max_number_entry.pack()

        self.start_button = tk.Button(root, text=self.language_options[self.language_var.get()]["start"], command=self.start_quiz, bg=self.color_themes[self.color_theme_var.get()]["bg"], fg=self.color_themes[self.color_theme_var.get()]["fg"])
        self.start_button.pack()

        self.color_theme_label = tk.Label(root, text=self.language_options[self.language_var.get()]["color_theme"], bg=self.color_themes[self.color_theme_var.get()]["bg"], fg=self.color_themes[self.color_theme_var.get()]["fg"])
        self.color_theme_label.pack()

        self.color_theme_menu = tk.OptionMenu(root, self.color_theme_var, *self.color_themes.keys(), command=self.change_color_theme)
        self.color_theme_menu.config(bg=self.color_themes[self.color_theme_var.get()]["bg"], fg=self.color_themes[self.color_theme_var.get()]["fg"])
        self.color_theme_menu.pack()

        self.language_label = tk.Label(root, text=self.language_options[self.language_var.get()]["language"], bg=self.color_themes[self.color_theme_var.get()]["bg"], fg=self.color_themes[self.color_theme_var.get()]["fg"])
        self.language_label.pack()

        self.language_menu = tk.OptionMenu(root, self.language_var, *self.language_options.keys(), command=self.change_language)
        self.language_menu.config(bg=self.color_themes[self.color_theme_var.get()]["bg"], fg=self.color_themes[self.color_theme_var.get()]["fg"])
        self.language_menu.pack()

        self.quiz_frame = tk.Frame(root, bg=self.color_themes[self.color_theme_var.get()]["bg"])
        self.quiz_frame.pack()

        self.question_labels = []
        self.answer_entries = []
        self.questions = []
        self.answers = []

    def generate_question(self):
        num1 = random.randint(self.min_number_var.get(), self.max_number_var.get())
        num2 = random.randint(self.min_number_var.get(), self.max_number_var.get())
        operator = random.choice(["+", "-", "*", "/"])
        question = f"{num1} {operator} {num2}"
        answer = eval(question)
        return question, answer

    def start_quiz(self):
        self.questions = []
        self.answers = []
        for _ in range(self.num_operations_var.get()):
            question, answer = self.generate_question()
            self.questions.append(question)
            self.answers.append(answer)

        self.quiz_frame.destroy()
        self.quiz_frame = tk.Frame(root, bg=self.color_themes[self.color_theme_var.get()]["bg"])
        self.quiz_frame.pack()

        for idx, question in enumerate(self.questions):
            question_label = tk.Label(self.quiz_frame, text=f"Question {idx + 1}: {question}", fg=self.color_themes[self.color_theme_var.get()]["fg"], bg=self.color_themes[self.color_theme_var.get()]["bg"])
            question_label.pack()
            answer_entry = tk.Entry(self.quiz_frame, bg=self.color_themes[self.color_theme_var.get()]["bg"], fg=self.color_themes[self.color_theme_var.get()]["fg"])
            answer_entry.pack()
            self.question_labels.append(question_label)
            self.answer_entries.append(answer_entry)

        self.submit_button = tk.Button(root, text=self.language_options[self.language_var.get()]["start"], command=self.submit_answers, bg=self.color_themes[self.color_theme_var.get()]["bg"], fg=self.color_themes[self.color_theme_var.get()]["fg"])
        self.submit_button.pack()

    def submit_answers(self):
        correct_answers = 0
        for idx, answer_entry in enumerate(self.answer_entries):
            user_answer = answer_entry.get()
            correct_answer = self.answers[idx]
            if user_answer == str(correct_answer):
                correct_answers += 1

        total_questions = len(self.questions)
        percentage_correct = (correct_answers / total_questions) * 100

        if percentage_correct < 60:
            grade = "Hinne 2"
        elif 60 <= percentage_correct < 75:
            grade = "Hinne 3"
        elif 75 <= percentage_correct < 90:
            grade = "Hinne 4"
        else:
            grade = "Hinne 5"

        result_label = tk.Label(root, text=f"Your grade: {grade}", bg=self.color_themes[self.color_theme_var.get()]["bg"], fg=self.color_themes[self.color_theme_var.get()]["fg"])
        result_label.pack()

    def change_color_theme(self, theme):
        self.root.config(bg=self.color_themes[theme]["bg"])
        for label in self.question_labels:
            label.config(bg=self.color_themes[theme]["bg"], fg=self.color_themes[theme]["fg"])
        for entry in self.answer_entries:
            entry.config(bg=self.color_themes[theme]["bg"], fg=self.color_themes[theme]["fg"])
        self.color_theme_label.config(bg=self.color_themes[theme]["bg"], fg=self.color_themes[theme]["fg"])
        self.start_button.config(bg=self.color_themes[theme]["bg"], fg=self.color_themes[theme]["fg"])
        if hasattr(self, "submit_button"):
            self.submit_button.config(bg=self.color_themes[theme]["bg"], fg=self.color_themes[theme]["fg"])
        self.difficulty_label.config(bg=self.color_themes[theme]["bg"], fg=self.color_themes[theme]["fg"])
        self.num_operations_label.config(bg=self.color_themes[theme]["bg"], fg=self.color_themes[theme]["fg"])
        self.min_number_label.config(bg=self.color_themes[theme]["bg"], fg=self.color_themes[theme]["fg"])
        self.max_number_label.config(bg=self.color_themes[theme]["bg"], fg=self.color_themes[theme]["fg"])
        self.language_label.config(bg=self.color_themes[theme]["bg"], fg=self.color_themes[theme]["fg"])
        self.color_theme_menu.config(bg=self.color_themes[theme]["bg"], fg=self.color_themes[theme]["fg"])
        self.language_menu.config(bg=self.color_themes[theme]["bg"], fg=self.color_themes[theme]["fg"])
        self.difficulty_menu.config(bg=self.color_themes[theme]["bg"], fg=self.color_themes[theme]["fg"])

    def change_language(self, language):
        self.difficulty_label.config(text=self.language_options[language]["select_difficulty"])
        self.num_operations_label.config(text=self.language_options[language]["num_operations"])
        self.min_number_label.config(text=self.language_options[language]["min_number"])
        self.max_number_label.config(text=self.language_options[language]["max_number"])
        self.start_button.config(text=self.language_options[language]["start"])
        self.color_theme_label.config(text=self.language_options[language]["color_theme"])
        self.language_label.config(text=self.language_options[language]["language"])

if __name__ == "__main__":
    root = tk.Tk()
    app = MathQuizApp(root)
    root.mainloop()


import nidaqmx
import torch
import numpy as np
import time
from nidaqmx.constants import AcquisitionType, TerminalConfiguration
from collections import deque
from sklearn.preprocessing import StandardScaler
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
from LSTMmodel import GaitLSTM
from utils import buffer_data

# The number of IMU (It can only 1, 2, 4)
num_IMU = 1

Gyro = True
Acc = False

# Define ML model parameter
input_size = num_IMU*(Gyro+Acc)*3
hidden_size = 128
num_layers = 3
output_size = 1
dropout_prob = 0.4

# Load the trained LSTM model
model = GaitLSTM(input_size, hidden_size, num_layers, output_size, dropout_prob)
model.load_state_dict(torch.load('LSTMmodel_'+str(num_IMU)+'IMU_gyro.pth'))
model.eval()
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
model.to(device)

# Buffer to store the incoming data
window_size = 200
buffer = deque(maxlen=window_size)

# Replace device_name is the name of your device, and channel_name is the name of your input channel.
device_name = "Dev1"
channel_names = ["ai7", "ai8", "ai9"]

ylabel = ['Gyro X', 'Gyro Y', 'Gyro Z']

gyro_range = 2000 # Choose the range you are using: 250 dps, 500 dps, 1000 dps, 2000 dps
analog_output_range = 5
gyro_sensitivity = gyro_range / (2 * analog_output_range)

# Create a task
with nidaqmx.Task() as task:
    # Configure the analog input channel
    for channel_name in channel_names:
        task.ai_channels.add_ai_voltage_chan(f'{device_name}/{channel_name}',
                                             terminal_config=TerminalConfiguration.RSE)

    # Set the sample rate and number of samples
    sample_rate = 1000  # 1000 samples per second
    num_samples = 100  # Acquire 10 samples
    task.timing.cfg_samp_clk_timing(sample_rate, samps_per_chan=num_samples,
                                     sample_mode=AcquisitionType.CONTINUOUS)

    while True:
        try:
            start = time.time()

            data = np.array(task.read(number_of_samples_per_channel=num_samples, timeout=1)) * gyro_sensitivity

            # Preprocess the incoming data
            scaler = StandardScaler()
            preprocessed_data = scaler.fit_transform(data)

            # Buffer the preprocessed data and create segments when the buffer is full
            segment = buffer_data(buffer, preprocessed_data, window_size)

            if segment is not None:
                # Reshape the segment to match the input shape of the LSTM model
                segment = segment.reshape(1, window_size, -1)

                # Convert the segment to a PyTorch tensor
                input_data = torch.tensor(segment, dtype=torch.float32).to(device)
                # Estimate gait speed using the LSTM model
                with torch.no_grad():
                    estimated_speed = model(input_data).item()

                print(f"Estimated gait speed: {estimated_speed}")

        except KeyboardInterrupt:
            print("Stopping data acquisition...")
            task.stop()
            break


import numpy as np
import pandas as pd

from sqlalchemy import create_engine, MetaData, Table, Column, Integer, \
                       String, Float, DateTime, ForeignKeyConstraint, ForeignKey,\
                       Enum, UniqueConstraint, Boolean
from geoalchemy2 import Geometry

import website.models as m

# Pandas to human readable mapping
type_mappings = {
    'int': 'integer',
    'float': 'float',
    'datetime': 'datetime',
    'object': 'string'
}

# Human readable to alchemy mapping
alchemy_types = {
    'integer': Integer,
    'float': Float,
    'datetime': DateTime,
    'string': String
}

def to_sql(df, datatypes, table_name, schema, geospatial_columns=None):
    """
    Create a database table based on a DataFrame and load it with data

    Parameters:
    df (pandas.DataFrame) - The DataFrame the table will be generated based on.
                            The data found in this DataFrame will be loaded into the table
    datatypes (list) - A list of SQLAlchemy column datatypes
    table_name (str) - The name the table will be given
    schema (str) - The schema the table will be created into
    geospatial_columns(list) - A list of geospatial columns of the type returned
                               by get_geospatial_columns()

    Returns:
    table - The SQLAlchemy table object that was generated
    """
    create_table(df, datatypes, table_name, schema, geospatial_columns)
    table = getattr(m.Base.classes, table_name)
    insert_df(df, table, geospatial_columns)
    return table

def create_table(df, datatypes, table_name, schema, geospatial_columns=None):
    """
    Create a database table based on a DataFrame

    Parameters:
    df (pandas.DataFrame) - The dataframe the table will be generated for
    datatypes (list) - A list of SQLAlchemy column datatypes
    table_name (str) - The name the table will be given
    schema (str) - The schema the table will be created into
    geospatial_columns (list) - A list of geospatial columns of the type returned
                                from get_geospatial_columns()

    Returns:
    table - The generated SQLAlchemy table object
    """
    datatypes = get_alchemy_types(datatypes)
    columns = [Column('id', Integer, primary_key=True)]
    for i, c in enumerate(df.columns):
        columns.append(
            Column(c, datatypes[i])
        )
    if geospatial_columns is not None:
        for c in geospatial_columns:
            if c['type'] == 'latlon':
                columns.append(
                    Column(c['name'], Geometry('POINT', srid=c['srid']))
                )
    table = Table(table_name, m.m, *columns, schema=schema)
    m.m.create_all(m.engine)
    m.refresh()
    return table

def insert_df(df, table, geospatial_columns=None):
    """
    Load a DataFrame into an autogenerated database table

    Arguments:
    table - The SQLAlchemy table object into which data will be loaded
    geospatial_columns (list) - A list of geospatial columns found in the dataset.
                                Should be of the form returned by get_geospatial_columns()

    Returns:
    Nothing
    """
    insert_dict = df.to_dict('records')
    for row in insert_dict:
        for c in row:
            if pd.isnull(row[c]):
                row[c] = None
        if geospatial_columns is not None:
            for c in geospatial_columns:
                row[c['name']] = 'SRID=%s;POINT(%s %s)' % (c['srid'], row[c['lon_col']], row[c['lat_col']])
    m.engine.execute(
        table.__table__.insert(),
        insert_dict
    )
    return

def get_geospatial_columns(table_uuid):
    """
    Get a list of geospatial column definitions from the geospatial_columnns table
    for a given table

    Parameters:
    table_uuid (str) - The uuid of an autogenerated database table

    Retruns:
    columns (list) - A list of geospatial column definitions where each element
                     is of the type returned by parse_geospatial_column_string()
    """
    session = m.get_session()
    res = session.query(m.GEOSPATIAL_COLUMNS.column_definition).filter(
        m.GEOSPATIAL_COLUMNS.dataset_uuid == table_uuid
    )
    columns = []
    for col in res:
        columns.append(parse_geospatial_column_string(col[0]))
    session.close()
    return columns

def parse_geospatial_column_string(geospatial_column_string):
    """
    Convert a geospatial column definition String into a dictionary to be used
    by the database generation functions.

    Parameters:
    geospatial_column_string (str) - A string defining a geospatial column.
                                     probably either returned from the upload_file page
                                     or pulled from the column_definition column of the
                                     geospatial_columns table.
        example: name=geom&lat_col=LATITUDE&lon_col=LONGITUDE&srid=4326&type=latlon

    Returns:
    geospatial_column (dict) - A dictionary containing all the information foud in the defintion string
    """
    # For each geospatial column, create a dictionary using fields as keys to store values
    for column in geospatial_column_string.split(','):
        # Create the dictionary
        geospatial_column = {'column_definition': column}

        for field in column.split('&'):
            field = field.split('=')
            # "exampleone=7&exampletwo=8" -> {"exampleone":7, "exampletwo":8}
            geospatial_column[field[0]] = field[1]

        # Append the dictionary to geospatial_columns (for the to_sql function)
    return geospatial_column

def get_alchemy_types(mapped_types):
    """
    Get SQLAlchemy column datatype objects from a list of human readable datatypes.
    This converts a verified list human readable types from the frontend to objects
    for database generation on the backend

    Parameters:
    mapped_types (list) -  a list of human readable datatypes like those generated
                           by get_readable_types_from_dataframe().

    Returns:
    rt (list) - A list of SQLAlchemy column datatype objects
    """
    rt = []
    for t in mapped_types:
        rt.append(alchemy_types[t])
    return rt

def get_readable_types_from_dataframe(df):
    """
    Get human readable datatypes for the columns in a pandas.DataFrame. This is
    used to help the user verify that the system is auto-generating the correct
    database column types

    Parameters:
    df (pandas.DataFrame) - The DataFrame the human readable datatype list will
                            be generated from.

    Returns:
    readable_types (list) - a list of human readable datatypes
    """
    readable_types = []
    for d in df.dtypes:
        readable_types.append(convert_type(d))
    return readable_types

def convert_type(dtype):
    """
    Convert a pandas dtype to a human readable database type.

    Parameters:
    dtype - a dtype from the column of a pandas.Dataframe or a pandas.Series

    Returns:
    type_mapping (str) - the human readable equivalent of the dtype
    """
    d = str(dtype)
    for t in type_mappings:
        if t in d:
            return type_mappings[t]
    return None