import numpy as np
from scipy import optimize

class KernelSVC:
    def __init__(self, C, kernel, epsilon=1e-3):
        self.type = 'non-linear'
        self.C = C
        self.kernel = kernel
        self.alpha = None
        self.support = None
        self.epsilon = epsilon
        self.norm_f = None

        self.Nfeval = 0
    def fit(self, X, y):
        y = 2 * (y - 0.5)

        N = len(y)
        self.support = X

        M = self.kernel(X, X)
        # Lagrange dual problem
        def loss(alpha):
            Y = np.diag(y)
            AY = Y @ alpha
            return -np.sum(alpha) + AY.T @ (M @ AY) / 2

        # Partial derivate of Ld on alpha
        def grad_loss(alpha):
            Y = np.diag(y)
            AY = Y @ alpha
            return -np.ones(len(alpha)) + Y @ (M @ AY)

        fun_eq = lambda alpha: np.sum(alpha * y)
        jac_eq = lambda alpha: y
        fun_ineq1 = lambda alpha: self.C - alpha
        jac_ineq1 = lambda alpha: -np.identity(len(alpha))
        fun_ineq2 = lambda alpha: alpha
        jac_ineq2 = lambda alpha: np.identity(len(alpha))

        constraints = ({'type': 'eq', 'fun': fun_eq, 'jac': jac_eq},
                       {'type': 'ineq', 'fun': fun_ineq1, 'jac': jac_ineq1},
                       {'type': 'ineq', 'fun': fun_ineq2, 'jac': jac_ineq2})

        optRes = optimize.minimize(fun=lambda alpha: loss(alpha),
                                   x0=np.ones(N),
                                   method='SLSQP',
                                   jac=lambda alpha: grad_loss(alpha),
                                   constraints=constraints,
                                   callback=self.callbackF,
                                   options={"maxiter":50, 'disp':True})
        self.alpha = optRes.x
        ## Assign the required attributes
        Y = np.diag(y)
        AY = Y @ self.alpha

        self.margin_points = [X[p] for p in np.where((self.alpha > self.epsilon) & (self.alpha < self.C - self.epsilon))[0]]
        self.b = np.mean(y[np.where((self.alpha > self.epsilon) & (self.alpha < self.C - self.epsilon))[0]]
                         - self.kernel(self.margin_points,X) @ AY)
        self.norm_f = np.sqrt(AY.T @ M @ AY)
        self.alpha = AY

    ### Implementation of the separting function $f$
    def separating_function(self, x):
        return self.kernel(x, self.support) @ self.alpha

    def predict(self, X):
        d = self.separating_function(X)
        # return 2 * (d + self.b > 0) - 1
        return 1 / (1 + np.exp(-(d+self.b)))

    def callbackF(self, Xi):
        print(self.Nfeval)
        self.Nfeval += 1


__revision__ = "src/engine/SCons/Tool/gs.py bee7caf9defd6e108fc2998a2520ddb36a967691 2019-12-17 02:07:09 bdeegan"

import SCons.Action
import SCons.Builder
import SCons.Platform
import SCons.Util

# Ghostscript goes by different names on different platforms...
platform = SCons.Platform.platform_default()

if platform == 'os2':
    gs = 'gsos2'
elif platform == 'win32':
    gs = 'gswin32c'
else:
    gs = 'gs'

GhostscriptAction = None

def generate(env):
    """Add Builders and construction variables for Ghostscript to an
    Environment."""
    global GhostscriptAction
    # The following try-except block enables us to use the Tool
    # in standalone mode (without the accompanying pdf.py),
    # whenever we need an explicit call of gs via the Gs()
    # Builder ...
    try:
        if GhostscriptAction is None:
            GhostscriptAction = SCons.Action.Action('$GSCOM', '$GSCOMSTR')

        from SCons.Tool import pdf
        pdf.generate(env)

        bld = env['BUILDERS']['PDF']
        bld.add_action('.ps', GhostscriptAction)
    except ImportError as e:
        pass

    gsbuilder = SCons.Builder.Builder(action = SCons.Action.Action('$GSCOM', '$GSCOMSTR'))
    env['BUILDERS']['Gs'] = gsbuilder

    env['GS']      = gs
    env['GSFLAGS'] = SCons.Util.CLVar('-dNOPAUSE -dBATCH -sDEVICE=pdfwrite')
    env['GSCOM']   = '$GS $GSFLAGS -sOutputFile=$TARGET $SOURCES'

def exists(env):
    if 'PS2PDF' in env:
        return env.Detect(env['PS2PDF'])
    else:
        return env.Detect(gs) or SCons.Util.WhereIs(gs)

# Local Variables:
# tab-width:4
# indent-tabs-mode:nil
# End:
# vim: set expandtab tabstop=4 shiftwidth=4:


# -*- coding: utf-8 -*-
"""
Created on Mon Sep 29 17:03:06 2014

@author: aaron
"""

import neblina as nb                ### Module for neblina interpreter.
import operators as op              ### Module for operators functions.
import ioFunctions as io            ### Module for write on disk functions.
import gnuplot as gnuplot  ### Module for Gnuplot functions.
import config as cfg                ### Module for global variables for Quantum Walk.
import standardDeviation as sd      ### Module for Standard Deviation functions.
import numpy as np
import testmode

def run():
    probabilities=[]

    if not cfg.OVERLAP:
        cfg.OVERLAPX=int(cfg.TESSELLATIONPOLYGONS[0])

    io.savetxt("HIPERWALK_TEMP_PSI.dat",cfg.STATE,float,'%1.16f')
    op.STAGGERED1D()

    sd.distances_vector_1D(cfg.RANGEX[0],cfg.RANGEX[1])
    cfg.DISTANCE_VECTOR_SIZE=cfg.GRAPHSIZE

#    nb.generating_STAGGERED1D_NBL()
    nb.runCore_STAGGERED1D()

    cfg.STATE=nb.neblina_state_to_vector("NEBLINA_TEMP_final_state.dat")
    probabilities=nb.neblina_distribution_to_vector("NEBLINA_TEMP_final_distribution.dat")

    output = open("final_distribution.dat",'w')
    output1 = open("final_state.dat",'w')
    output.write("#POSITION \t PROBABILITY\n")
    output1.write("#POSITION \t Re(amplitude) \t \t \t Im(amplitude)\n")

    for i in range(int(cfg.GRAPHSIZE)):

        output.write("%d \t \t \t%1.16f\n"%(cfg.RANGEX[0]+i,probabilities[i]))
        output1.write("%d \t \t \t%1.16f\t\t\t%1.16f\n"%(cfg.RANGEX[0]+i,cfg.STATE[i].real,cfg.STATE[i].imag))

    output.close()
    output1.close()

    if cfg.GNUPLOT:
        io.savetxt("HIPERWALK_TEMP_PROBABILITIES.dat",probabilities,float,'%1.16f')

        gnuplot.template_STAGGERED1D("HIPERWALK_TEMP_PROBABILITIES.dat","final_distribution.eps","EPS")
        if cfg.STEPS>1:
            gnuplot.plotStatistics1D()
        if cfg.ANIMATION == 1:
            gnuplot.plotAnimation1D()

    if cfg.TEST_MODE:
        modelVector=testmode.create_STAGGERED1D_test_vector()
        returnNeblina=nb.neblina_distribution_to_vector("NEBLINA_TEMP_final_distribution.dat")
        if np.linalg.norm(modelVector-returnNeblina,np.inf) == float(0):
            return 1
        else:
            return 0

    return 1


from bs4 import BeautifulSoup
import requests
import csv
import pandas as pd
import os

source = requests.get('https://www.centuryply.com/centurylaminates/')
soup = BeautifulSoup(source.content, 'lxml')

for main in soup.select('li.dropdown-submenu'):
    for a_link in main.find_all('a'):
        try:
            t_link = a_link['href'].replace('#','')
            f_name = t_link.replace('.php','')
            m_link = f'https://www.centuryply.com/centurylaminates/{t_link}'

            folder_location = f'./data/{f_name}'
            if not os.path.exists(folder_location):
                os.mkdir(folder_location)

            source = requests.get(m_link)
            soup = BeautifulSoup(source.content, 'lxml')

            for src in soup.find_all('div',class_='product-meta'):
                links = src.a
                link =links.find_next('a')['href']
                link = f'https://www.centuryply.com/centurylaminates/{link}'
                #print(link)

                source = requests.get(link)
                soup = BeautifulSoup(source.content, 'lxml')
                print(f'>> {link}')

                img = soup.find('div',class_='product-img').a['bg-image']
                prod_img = f'https://www.centuryply.com/centurylaminates/{img}'
                print(prod_img)

                name = soup.find('div',class_='product-heading').h1.text
                name = f' {name} '
                print(name)

                desc = soup.find('div',class_='product-description').p.text
                print(desc)

                f_name = name.replace(' ','_')
                filenames = f'{folder_location}/{f_name}.csv'
                with open(filenames , 'w') as csv_file:
                    csv_writer = csv.writer(csv_file)
                    csv_writer.writerow(['Prod_link ',' Name ',' Images ', ' Prod_Desc '])
                    csv_writer.writerow([link , name , prod_img , desc])
                print(csv_file.closed)

        except:
            print('')


"""
Twilio API NTS token
"""

import asyncio
from functools import partial

from twilio.rest import Client as TwilioRestClient

from server.config import config

class TwilioNTS:
    """
    Twilio NTS Token Service

    Creates new twilio NTS tokens
    """

    def __init__(self, sid=None, token=None):
        if sid is None:
            sid = config.TWILIO_ACCOUNT_SID  # pragma: no cover
        if token is None:
            token = config.TWILIO_TOKEN  # pragma: no cover

        self.twilio_account_sid = sid
        self.twilio_token = token
        self.client = TwilioRestClient(self.twilio_account_sid, self.twilio_token)

    async def server_tokens(self, ttl=None) -> list[dict[str]]:
        """
        Fetches token from Twilio

        # Params
        - `ttl`: ttl in seconds
        """
        if ttl is None:
            ttl = config.TWILIO_TTL  # pragma: no cover

        loop = asyncio.get_running_loop()
        token = await loop.run_in_executor(None, partial(self.client.tokens.create, ttl))
        return token.ice_servers


"""MAIN MODULE TO RUN"""
from datetime import datetime
import stonk_functions as func

#gets the top sector for the week
sectorOG = func.get_sector()
sector = (sectorOG.replace(' ','')).lower()

#gets todays date
day = datetime.today().strftime('%A')
if day.lower() in ("saturday", "sunday"):
    day = "Friday"
today = datetime.now()
date = (f"{today.strftime('%B')} {today.day}")

"""Add Link for Criteria Here using https://finviz.com/screener.ashx"""
#the urls for stock criteria
win_sector = f"https://finviz.com/screener.ashx?v=111&f=sec_{sector},sh_avgvol_o1000,sh_price_o5,sh_relvol_o1.5,targetprice_above&ft=4"
rsi = "https://finviz.com/screener.ashx?v=211&f=sh_avgvol_o1000,sh_price_o5,ta_rsi_os30,ta_sma200_pa,targetprice_above&ft=4"

"""Add New Criteria Variable to urls Dict and assign a label"""
#dict of criteria urls and there label
urls = {win_sector: f"{sectorOG} Winners", rsi : "Oversold"}

#gets the stocks for each criteria and adds them to the stonks dict
stonks = func.get_stocks(urls)

#gets todays watchlist listing
main_str = func.get_main(day,stonks)

#gets current watchlist contents
with open("watchlist.txt", 'r') as file:
     contents = file.read()

#if its Monday, start a new watchlist
if day == 'Monday':
    with open("watchlist.txt", 'w') as file:
        file.write(main_str + '\n')

#if its not Monday, add todays stocks to the current watchlist
else:
    content_list = contents.split('\n\n')
    #remove the current days entry if its there to make space for updated entry
    with open("watchlist.txt", "w") as f:
        for i in content_list:
            if day not in i:
                f.write(f"{i}\n")
        f.truncate()

    #add todays entry
    with open("watchlist.txt", 'a') as file:
        file.write(main_str + '\n')

#gets weeks updated wathlist and prints it
with open("watchlist.txt", 'r') as file:
     contents = file.read()
print('Watchlist', date)

print(contents)


import sqlite3

__author__ = 'marcelo_garay'
import os

class DBManager(object):
    db_name = os.path.abspath(
        os.path.join(os.path.dirname(__file__), '../../../db/sicarios'))

    def __init__(self):
        """
        Make connection to an SQLite database file
        :param db:
        :return:
        """
        self.conn = sqlite3.connect(self.db_name)
        self.conn.execute('pragma foreign_keys = on')
        self.conn.commit()
        self.cur = self.conn.cursor()

    def query(self, arg):
        """
        Execute a query using the arg
        :return
        """
        self.cur.execute(arg)
        self.conn.commit()
        return self.cur

    def close(self):
        """
        Close connection to the database
        """
        self.conn.close()


import sys

sys.path.append('../')

import numpy as np
import matplotlib.pyplot as plt
from GroupingAlgorithm import groupingWithOrder
from utils import Label2Chain, H2O, save_object
from joblib import delayed, Parallel
import networkx as nx
from itertools import permutations
from tqdm.auto import tqdm
import copy

sys.setrecursionlimit(10 ** 9)

def n_groups_shuffle(paulis, G, seed, shuffle_paulis=True, shuffle_qubits=True, x=1, n_max=10000, n_delete=0):
	G_new = copy.deepcopy(G)

	if x < 1 or n_delete > 0:
		edges = list(G_new.edges())

		if x < 1:
			n_delete = int((1 - x) * len(edges))

		indices_delete = np.random.default_rng().choice(len(edges), size=n_delete, replace=False)
		for index in indices_delete:
			G_new.remove_edge(*edges[index])

		if not nx.is_connected(G_new):
			if n_max == 0:
				return np.nan, None, None, G_new
			else:
				return n_groups_shuffle(paulis, G, seed, shuffle_paulis=shuffle_paulis,
				                        shuffle_qubits=shuffle_qubits, x=x, n_max=n_max - 1, n_delete=n_delete)

	np.random.seed(seed)
	order_paulis = np.arange(len(paulis))
	order_qubits = np.arange(num_qubits)
	if shuffle_paulis:
		np.random.shuffle(order_paulis)

	if shuffle_qubits:
		np.random.shuffle(order_qubits)

		temp = copy.deepcopy(paulis)
		for j in range(len(order_qubits)):
			paulis[:, j] = temp[:, order_qubits[j]]

	Groups_HEEM, _, _ = groupingWithOrder(paulis[order_paulis], G_new)
	return len(Groups_HEEM), order_paulis, order_qubits, G_new

qubit_op = H2O()
num_qubits = qubit_op.num_qubits
paulis, _, _ = Label2Chain(qubit_op)
print('There are {} Pauli strings of {} qubits.'.format(len(qubit_op), num_qubits))

WC_ideal = list(permutations(list(range(num_qubits)), 2))

G_ideal = nx.Graph()
G_ideal.add_nodes_from(range(num_qubits))
G_ideal.add_edges_from(WC_ideal)

backend_parallel = 'multiprocessing'

n = num_qubits
k = 2
total_edges = int(np.math.factorial(n) / (np.math.factorial(n - k) * 2))

n_x = 20
N = 3000
x_vec = np.linspace((num_qubits - 1) / total_edges, 1, n_x)

n_groups_list = []
optimal_order_paulis = []
optimal_order_qubits = []
optimal_graph = []

pbar_outer = tqdm(range(n_x), desc='Connectivity', file=sys.stdout, ncols=90,
                  bar_format='{l_bar}{bar}{r_bar}', position=0)

for i in pbar_outer:
	pbar_inner = tqdm(range(N), desc='Shuffling', file=sys.stdout, ncols=90,
	                  bar_format='{l_bar}{bar}{r_bar}', position=1)

	results = Parallel(n_jobs=-1, backend=backend_parallel)(
		delayed(n_groups_shuffle)(paulis, G_ideal, None, x=x_vec[i]) for j in
		pbar_inner)

	print('-' * 90)

	n_groups = [results[i][0] for i in range(N)]

	delete_indices = np.where(np.isnan(n_groups))[0]
	for j, index in enumerate(delete_indices):
		n_groups.pop(index - j)
		results.pop(index - j)

	n_groups_list.append(n_groups)

	index_min = np.argmin(n_groups)
	optimal_order_paulis.append(results[index_min][1])
	optimal_order_qubits.append(results[index_min][2])
	optimal_graph.append(results[index_min][3])

n_std = np.zeros(n_x)
n_avg = np.zeros(n_x)
n_min = np.zeros(n_x)
n_max = np.zeros(n_x)

for i in range(n_x):
	n_std[i] = np.std(n_groups_list[i])
	n_avg[i] = np.mean(n_groups_list[i])
	n_min[i] = np.min(n_groups_list[i])
	n_max[i] = np.max(n_groups_list[i])

fig, ax = plt.subplots()
ax.plot(x_vec, n_avg)
ax.fill_between(x_vec, n_avg - n_std, n_avg + n_std, alpha=0.25)
ax.plot(x_vec, n_min, '--')
ax.plot(x_vec, n_max, '--')
ax.set_xlabel('x')
ax.set_ylabel('# of groups')
ax.set_xlim([x_vec[0], x_vec[-1]])

fig.show()

file = 'H20_grouping_shuffle_ideal_vs_connectivity'

data_save = {'x_vec': x_vec, 'n_groups': n_groups_list, 'optimal_order_paulis': optimal_order_paulis,
             'optimal_order_qubits': optimal_order_qubits, 'optimal_graph': optimal_graph}

save_object(data_save, file, overwrite=True)


from gpiozero import Button, PWMLED, MotionSensor
from time import sleep, time
from signal import pause
from datetime import datetime, timedelta
import simpleaudio as sa
from models import Game, Goal, Team
from game_history import send_game_history
from constants import UI_GAME_CLOCK, UI_TEAM1_SCORE, UI_TEAM2_SCORE
import threading
import queue

def _play_sound_clip(sound_file, wait=False):
    wave_obj = sa.WaveObject.from_wave_file(sound_file)
    play_obj = wave_obj.play()
    if wait:
        play_obj.wait_done()

def _get_elapsed_time_string(elapsed_seconds):
    hours, rem = divmod(elapsed_seconds, 3600)
    minutes, seconds = divmod(rem, 60)
    return "{:0>2}:{:0>2}:{:0>2}".format(int(hours), int(minutes), int(seconds))

def _team_scored(team):
    _play_sound_clip("/home/pi/Projects/FoosTracks/resources/SoccerGoal.wav")

class AsyncMatch(threading.Thread):

    def __init__(self, ui_queue,
                team1_name, team1_members,
                team2_name, team2_members,
                games_per_match=1,
                points_to_win=5,
                next_game_callback=None,
                match_end_callback=None):
        super().__init__()
        self.ui_queue = ui_queue # queue for asyncrohonus updates to the tkinter UI
        self.team1_name = team1_name
        self.team2_name = team2_name
        self.team1_members = team1_members
        self.team2_members = team2_members
        self.games_per_match = games_per_match
        self.points_to_win = points_to_win
        self.next_game_callback = next_game_callback # function that determines whether the next game in the match should be played.  Takes no argments and returns boolean, True if game should be played, False if match shoiuld be ended.
        self.match_end_callback = match_end_callback # function that notifies UI that the match has ended, takkes no argments and returns nothing.

        self.cancelled = False
        self.devices = []

    def cancel(self):
        self.cancelled = True

    def run(self):
        if not self.cancelled:
            self._start_match()

    def _start_match(self):
        print("Starting match ...")

        team1 = Team(name=self.team1_name, members=self.team1_members, score_handler=_team_scored)
        team2 = Team(name=self.team2_name, members=self.team2_members, score_handler=_team_scored)

        dev = MotionSensor(16, pull_up=True, sample_rate=120, queue_len=1)
        goal_a = Goal(name="Goal A",
                    score_device=dev,
                    score_handler=None)

        dev = MotionSensor(19, pull_up=True, sample_rate=120, queue_len=1)
        goal_b = Goal(name="Goal B",
                    score_device=dev,
                    score_handler=None)

        self.devices = [goal_a.input_device, goal_b.input_device]

        games_played = 0
        while games_played < self.games_per_match:
            if games_played % 2 == 0:
                last_game = self._start_new_game(team1, goal_a, team2, goal_b, ui_queue=self.ui_queue)
            else:
                last_game = self._start_new_game(team1, goal_b, team2, goal_a, ui_queue=self.ui_queue)

            if self.cancelled:
                self._clean_up()
                print("Match was cancelled")
                return

            # Game has finished check if the next game in the match should be played
            games_played += 1
            if games_played < self.games_per_match:
                if not self._play_next_game(last_game):
                    self._clean_up()
                    if self.match_end_callback:
                        self.match_end_callback()
                    break
            else:
                # Match is over
                if self.match_end_callback:
                    self.match_end_callback()
                print("Match is over hope you had fun!")

    def _start_new_game(self, team1, goal_1, team2, goal_2, sound_fx=True, ui_queue=None):
        print("Starting new game ...")

        goal_1.set_on_score_handler(team1.did_score)
        goal_2.set_on_score_handler(team2.did_score)

        game = Game(team1=team1, team2=team2)
        game.start()

        if sound_fx:
            self._start_fx()

        start_time = time()
        while not game.finished:
            if self.cancelled:
                print("Game was cancelled")
                self._clean_up()
                return
            self._update_ui(ui_queue, start_time, game)
            self._check_game(game)
            sleep(0.1)

        # Game is finished
        self._report_game_stats(game)
        return game

    def _start_fx(self):
        sound_file = "/home/pi/Projects/FoosTracks/resources/SoccerCrowd.wav"
        wave_obj = sa.WaveObject.from_wave_file(sound_file)
        play_obj = wave_obj.play()

    def _stop_fx(self):
        sa.stop_all()

    def _update_ui(self, ui_queue, start_time, game):
        elapsed_time = _get_elapsed_time_string(time() - start_time)
        team1_score = game.team1.total_score()
        team2_score = game.team2.total_score()
        if ui_queue:
            ui_msg = {
                UI_GAME_CLOCK: elapsed_time,
                UI_TEAM1_SCORE: team1_score,
                UI_TEAM2_SCORE: team2_score
            }
            ui_queue.put(ui_msg)

    def _check_game(self, game):
        if game.team1.total_score() >= self.points_to_win and game.team2.total_score() >= self.points_to_win:
            assert False, "NOT POSSIBLE FOR BOTH TEAMS TO WIN"
        elif game.team1.total_score() >= self.points_to_win:
            game.finish()
        elif  game.team2.total_score() >= self.points_to_win:
            game.finish()

    def _clean_up(self):
        sa.stop_all()
        # unset goal score handlers
        for d in self.devices:
            d.close()

    def _report_game_stats(self, game):
        winner = game.get_winning_team()
        loser = game.get_losing_team()
        send_game_history(game)
        self._print_win_message(winning_team=winner, losing_team=loser)

    def _print_win_message(self, winning_team, losing_team):
        msg = "\n{0} has won!!!\n{0} - {1}, {2} - {3}".format(winning_team.name,
                                                            winning_team.total_score(),
                                                            losing_team.name,
                                                            losing_team.total_score())
        print(msg)

    def _play_next_game(self, last_game):
        if self.next_game_callback:
            winner = last_game.get_winning_team()
            loser = last_game.get_losing_team()
            msg = "{0} won!\n\nScore\n  {0} - {1}\n  {2} - {3}\n\nPlay next game?".format(winner.name, winner.total_score(), loser.name, loser.total_score())
            play_next = self.next_game_callback(message=msg, title="")
            return play_next
        else:
            input("Press enter to play next game ...")
            return True


import numpy as np

from sklearn.utils.validation import check_array, check_scalar
from scipy import stats

def z_test_one_sample(sample_data, mu_0, sigma, test_type="two-sided"):
    """Perform a one-sample z-test.

    Parameters
    ----------
    sample_data : array-like of shape (n_samples,)
        Sample data drawn from a population.
    mu_0 : float or int
        Population mean assumed by the null hypothesis.
    sigma: float
        True population standard deviation.
    test_type : {'right-tail', 'left-tail', 'two-sided'}
        Specifies the type of test for computing the p-value.
        left-tail: Intergral links bis pvalue
        right-tail: 1 - Integral links bis pvalue
        two-sided: min etc.

    Returns
    -------
    z_statistic : float
        Observed z-transformed test statistic.
    p : float
        p-value for the observed sample data.
    """
    # Check parameters.
    sample_data = check_array(sample_data, ensure_2d=False)
    mu_0 = check_scalar(mu_0, name="mu_0", target_type=(int, float))
    sigma = check_scalar(sigma, name="sigma", target_type=(int, float), min_val=0, include_boundaries="neither")
    if test_type not in ["two-sided", "left-tail", "right-tail"]:
        raise ValueError("`test_type` must be in `['two-sided', 'left-tail', 'right-tail']`")

    # empirical mean
    empirical_mean = np.mean(sample_data)

    # sample size
    sample_size = len(sample_data)

    # z_statistic
    # kommen empirical means aus gleichen Distributions?
    z_statistic = (empirical_mean - mu_0) / (sigma / np.sqrt(sample_size))

    # p-value
    # depends on test_type
    p_left = stats.norm.cdf(z_statistic)
    p_right = 1 - p_left
    if test_type == "left-tail":
        p = p_left
    elif test_type == "right-tail":
        p = p_right
    else:
        p = 2 * min(p_left, p_right)

    return z_statistic, p

def t_test_one_sample(sample_data, mu_0, test_type="two-sided"):
    """Perform a one-sample t-test.

    Parameters
    ----------
    sample_data : array-like of shape (n_samples,)
        Sample data drawn from a population.
    mu_0 : float or int
        Population mean assumed by the null hypothesis.
    test_type : {'right-tail', 'left-tail', 'two-sided'}
        Specifies the type of test for computing the p-value.

    Returns
    -------
    t_statistic : float
        Observed t-transformed test statistic.
    p : float
        p-value for the observed sample data.

    Variance is estimated from the sample data (not given like in z-test).
    """
    # Check parameters.
    sample_data = check_array(sample_data, ensure_2d=False)
    mu_0 = check_scalar(mu_0, name="mu_0", target_type=(int, float))
    if test_type not in ["two-sided", "left-tail", "right-tail"]:
        raise ValueError("`test_type` must be in `['two-sided', 'left-tail', 'right-tail']`")

    # empirical mean is test statistic
    empirical_mean = np.mean(sample_data)

    # empirical standard deviation
    # ddof=1: Delta degrees of freedom. The divisor used in calculations is N - ddof, where N represents the number of elements.-> N-1 = ddof
    empirical_sigma = np.std(sample_data, ddof=1)

    # sample size
    sample_size = len(sample_data)

    # t_statistic
    # kommen empirical means aus gleichen Distributions?
    # sigma is not given, has to be estimated from sample data
    # degrees of freedom = sample_size - 1; Letzter Datenpunkt ist aus N-1 anderen und mean berechenbar
    t_statistic = (empirical_mean - mu_0) / (empirical_sigma / np.sqrt(sample_size))

    # p-value
    # depends on test_type
    p_left = stats.t.cdf(t_statistic, df=sample_size - 1)    # df = degrees of freedom
    p_right = 1 - p_left
    if test_type == "left-tail":
        p = p_left
    elif test_type == "right-tail":
        p = p_right
    else:
        p = 2 * min(p_left, p_right)

    return t_statistic, p


from mpl_toolkits.axes_grid1 import make_axes_locatable
import matplotlib.pyplot as plt
import numpy as np

from collections.abc import Iterable

def colorbar(mappable, pad=0.1, side="right"):
    '''
    colorbar whose height (or width) in sync with the master axe
    https://matplotlib.org/mpl_toolkits/axes_grid/users/overview.html#colorbar-whose-height-or-width-in-sync-with-the-master-axes
    '''
    ax = mappable.axes
    fig = ax.figure
    divider = make_axes_locatable(ax)
    cax = divider.append_axes(side, size="5%", pad=pad)
    return fig.colorbar(mappable, cax=cax)

def colorbar2(mappable, shift=0.05, width=0.05, ax=None, trim_left=0, trim_right=0, side="right"):
    # creates a color bar that does not shrink the main plot or panel
    # only works for horizontal bars so far

    if ax is None:
        ax = mappable.axes

    # Get current figure dimensions
    try:
        fig = ax.figure
        p = np.zeros([1,4])
        p[0,:] = ax.get_position().get_points().flatten()
    except:
        fig = ax[0].figure
        p = np.zeros([ax.size,4])
        for k, a in enumerate(ax):
            p[k,:] = a.get_position().get_points().flatten()
    xmin = np.amin(p[:,0]) ; xmax = np.amax(p[:,2]) ; dx = xmax - xmin
    ymin = np.amin(p[:,1]) ; ymax = np.amax(p[:,3]) ; dy = ymax - ymin

    if side=="top":
        cax = fig.add_axes([xmin + trim_left, ymax + shift * dy, dx - trim_left - trim_right, width * dx])
        cax.xaxis.set_ticks_position('top')
        return fig.colorbar(mappable, cax=cax, orientation="horizontal")
    elif side=="right":
        cax = fig.add_axes([xmax + shift*dx, ymin, width * dx, dy])
        cax.xaxis.set_ticks_position('top')
        return fig.colorbar(mappable, cax=cax, orientation="vertical")

def shift_axes(axes,dx,dy):

    # only 1 axis, we make it iterable
    if not isinstance(axes, Iterable):
        axes = [axes]

    for ax in axes:
        pos = ax.get_position()
        pos = [pos.x0 + dx, pos.y0 + dy, pos.width, pos.height]
        ax.set_position(pos)

def L2R(L,Teff):
  '''
  L2R(Lstar/Lsun,Teff) renvoie Rstar/Rsun
   '''
  return np.sqrt(L * (5777./Teff)**4)

def R2L(R,Teff):
  '''
  R2L(Rstar/Rsun,Teff) renvoie Lstar/Lsun
  '''
  return R**2 * (Teff/5777.)**4

def pdf(filename):
    if (filename[-4:] != ".pdf"):
        filename += ".pdf"
    print(filename)
    plt.savefig(filename, bbox_inches='tight')


import numpy as np
import cv2
import glob
from matplotlib import pyplot as plt
import os
from mpl_toolkits.mplot3d import axes3d, Axes3D

base_folder = os.getcwd() +'/parameters/'

s = cv2.FileStorage(base_folder + 'left_camera_intrinsics.xml', cv2.FileStorage_READ)

mtx_left = s.getNode('mtx_left').mat()
distCoeffs_left = s.getNode('distCoeffs_left').mat()
s.release()

s = cv2.FileStorage(base_folder + 'right_camera_intrinsics.xml', cv2.FileStorage_READ)
mtx_right = s.getNode('mtx_right').mat()
distCoeffs_right = s.getNode('distCoeffs_right').mat()
s.release()

s = cv2.FileStorage(base_folder + 'stereo_rectification.xml', cv2.FileStorage_READ)

R1 = s.getNode('R1').mat()
R2 = s.getNode('R2').mat()
Q = s.getNode('Q').mat()
s.release()

s = cv2.FileStorage(base_folder + 'P1.xml', cv2.FileStorage_READ)
P1 = s.getNode('P1').mat()
s = cv2.FileStorage(base_folder + 'P2.xml', cv2.FileStorage_READ)
P2 = s.getNode('P2').mat()
s.release()

img_folder = os.getcwd() + '/'

img_folder = os.getcwd() + '/'

img_l = cv2.imread(img_folder + 'images/task_3_and_4/left_4.png')

img_r= cv2.imread(img_folder + 'images/task_3_and_4/right_4.png')

height,width = img_l.shape[:2]

mapx1, mapy1 = cv2.initUndistortRectifyMap(mtx_left, distCoeffs_left, R1, mtx_left, (width,height), 5)
rectified_img_left = cv2.remap(img_l,mapx1, mapy1, cv2.INTER_LINEAR)

mapx2, mapy2 = cv2.initUndistortRectifyMap(mtx_right, distCoeffs_right,R2, mtx_right, (width,height), 5)
rectified_img_right = cv2.remap(img_r,mapx2, mapy2, cv2.INTER_LINEAR)
output_path = os.getcwd() + '/output/task_4'
cv2.imshow('rectified_img_l',rectified_img_left)
cv2.imwrite(output_path + '/rectified_img_left.png', rectified_img_left)
cv2.imshow('rectified_img_r',rectified_img_right)
cv2.imwrite(output_path + '/rectified_img_right.png', rectified_img_right)

window_size = 3
# Best parameter
left_matcher = cv2.StereoSGBM_create( minDisparity=0, numDisparities=160,blockSize=5, P1=8 * 3 * window_size ** 2,P2=32 * 3 * window_size ** 2,disp12MaxDiff=1,uniquenessRatio=15,speckleWindowSize=0,speckleRange=2, preFilterCap=63,mode=cv2.STEREO_SGBM_MODE_SGBM_3WAY)
#left_matcher = cv2.StereoSGBM_create(numDisparities=16, blockSize=15)
right_matcher = cv2.ximgproc.createRightMatcher(left_matcher)

# FILTER Parameters
lmbda = 10000
sigma = 1.2
visual_multiplier = 0.5

wls_filter = cv2.ximgproc.createDisparityWLSFilter(matcher_left=left_matcher)
wls_filter.setLambda(lmbda)
wls_filter.setSigmaColor(sigma)
displ = left_matcher.compute(img_l, img_r)
dispr = right_matcher.compute(img_r, img_l)
displ = np.int16(displ)
dispr = np.int16(dispr)
filteredImg = wls_filter.filter(displ, img_l, None, dispr)

filteredImg = cv2.normalize(src=filteredImg, dst=filteredImg, beta=0, alpha=255, norm_type=cv2.NORM_MINMAX)
filteredImg = np.uint8(filteredImg)
cv2.imshow('Disparity Map', filteredImg)
cv2.imwrite(output_path+'/Disparity.png', filteredImg)


import asyncio
import logging
import random
from enum import Enum
from uuid import uuid4

import websockets

from wired_exchange.kucoin import CandleStickResolution

from typing import Union

WS_OPEN_TIMEOUT = 10
WS_CONNECTION_TIMEOUT = 3

class WebSocketState(Enum):
    STATE_WS_READY = 1
    STATE_WS_CLOSING = 2

class WebSocketNotification(Enum):
    CONNECTION_LOST = 1

class WebSocketMessageHandler:

    def can_handle(self, message: str) -> bool:
        pass

    def handle(self, message: str) -> bool:
        """process received message and indicates if handler must be kept registered
        one time handler are useful when waiting for acknowledgement"""
        pass

    def on_notification(self, notification: WebSocketNotification):
        pass

class KucoinWebSocket:

    def __init__(self, endpoint, token, encrypt: bool,
                 ping_interval: int, ping_timeout: int, connect_id: str = None):
        self._encrypt = encrypt
        self._ping_timeout = ping_timeout
        self._ping_interval = ping_interval
        self._endpoint = endpoint
        self._token = token
        self._id = connect_id if connect_id is not None else str(uuid4()).replace('-', '')
        self._logger = logging.getLogger(type(self).__name__)
        self._ws = None
        self._connected = asyncio.Event()
        self._handlers = [PongMessageHandler(self, self._ping_interval, self._ping_timeout),
                          self.WelcomeMessageHandler(self._connected), SinkMessageHandler()]
        self._state: WebSocketState = WebSocketState.STATE_WS_READY

    async def open_async(self):
        uri = f"{self._endpoint}?token={self._token}&connectId={self._id}"
        try:
            if self._state != WebSocketState.STATE_WS_READY:
                return
            async for ws in websockets.connect(uri,
                                               logger=self._logger,
                                               ssl=self._encrypt,
                                               open_timeout=WS_OPEN_TIMEOUT,
                                               ping_interval=self._ping_interval,
                                               ping_timeout=self._ping_timeout):
                try:
                    if self._state == WebSocketState.STATE_WS_CLOSING:
                        break
                    self._ws = ws
                    self._disconnect()
                    await self._run_message_loop(ws)
                except websockets.ConnectionClosed:
                    continue
        finally:
            for handler in self._handlers:
                handler.on_notification(WebSocketNotification.CONNECTION_LOST)
            self._disconnect()
            self._ws = None
            self._state = WebSocketState.STATE_WS_READY

    async def _run_message_loop(self, ws: websockets):
        async for message in ws:
            try:
                if self._state == WebSocketState.STATE_WS_CLOSING:
                    break
                self._handle_message(message)
            except:
                self._logger.error(f'something goes wrong when processing message: {message}', exc_info=True)

    def insert_handler(self, handler: WebSocketMessageHandler):
        self._handlers.insert(0, handler)
        self._logger.debug(f'{type(handler).__name__}: handler registered')

    def _handle_message(self, message):
        for handler in self._handlers:
            if handler.can_handle(message):
                self._logger.debug(f'handler found: {type(handler).__name__}')
                handler.handle(message)
                return

    async def subscribe_klines_async(self, topics: list[tuple[str, str, CandleStickResolution]]):
        try:
            await self.wait_connection_async()
            subscription_id = random.randint(100000000, 1000000000)
            self.insert_handler(SubscriptionHandler(subscription_id))
            await self._ws.send(self._new_klines_subscription_message(subscription_id, topics))
            self._logger.debug('kline subscription completed')
        except TimeoutError:
            self._logger.error('kline subscription timeout', exc_info=True)

    async def subscribe_tickers_async(self, tickers: Union[list[tuple[str, str]], None]):
        try:
            await self.wait_connection_async()
            subscription_id = random.randint(100000000, 1000000000)
            self.insert_handler(SubscriptionHandler(subscription_id))
            await self._ws.send(self._new_tickers_subscription_message(subscription_id, tickers))
            self._logger.debug('ticker subscription completed')
        except TimeoutError:
            self._logger.error('ticker subscription timeout', exc_info=True)

    def _new_tickers_subscription_message(self, subscription_id: int,
                                          tickers: Union[list[tuple[str, str]], None]):
        if tickers is None:
            return f"""
            {{
            "id": {subscription_id},
                "type": "subscribe",
                "topic": "/market/ticker:all",
                "response": true
            }}
            """
        else:
            return f"""
            {{
            "id": {subscription_id},
                "type": "subscribe",
                "topic": "/market/ticker:{','.join([f'{bc}-{qc}' for bc, qc in tickers])}",
                "response": true
            }}
            """

    def _new_klines_subscription_message(self, subscription_id: int,
                                         topics: list[tuple[str, str, CandleStickResolution]]):
        return f"""
        {{
        "id": {subscription_id},
            "type": "subscribe",
            "topic": "/market/candles:{','.join([f'{bc}-{qc}_{res.value}' for bc, qc, res in topics])}",
            "response": true
        }}
        """

    def _disconnect(self):
        self._connected.clear()
        return self

    def is_connected(self):
        self._connected.is_set()

    def wait_connection_async(self, timeout: int = WS_CONNECTION_TIMEOUT):
        return asyncio.wait_for(self._connected.wait(), timeout)

    def close(self):
        self._state = WebSocketState.STATE_WS_CLOSING

    async def send(self, message):
        await self.wait_connection_async()
        await self._ws.send(message)

    class WelcomeMessageHandler(WebSocketMessageHandler):
        def __init__(self, event: asyncio.Event):
            self._connected = event
            self._logger = logging.getLogger(type(self).__name__)

        def can_handle(self, message):
            return not self._connected.is_set() and '"type":"welcome"' in message

        def handle(self, message):
            self._connected.set()
            self._logger.debug('connection acknowledged by server')
            return True

class PongMessageHandler(WebSocketMessageHandler):
    def __init__(self, ws: KucoinWebSocket, ping_interval: int, ping_timeout: int):
        self._ws = ws
        self._ping_interval = ping_interval / 1000 * .95
        self._ping_timeout = ping_timeout / 1000
        self._task = asyncio.create_task(self._loop())
        self._task.set_name('ping_pong')
        self._pong = asyncio.Event()
        self._logger = logging.getLogger(type(self).__name__)

    async def _loop(self):
        while True:
            try:
                await self._send_ping_message()
                await asyncio.wait_for(self._pong.wait(), self._ping_timeout)
                self._pong.clear()
                await asyncio.sleep(self._ping_interval)
            except TimeoutError:
                self._logger.warning('ping timeout reached without pong')
                continue
            except asyncio.CancelledError:
                self._logger.warning('ping handler stopped')
                break

    def can_handle(self, message):
        return f'"type":"pong"' in message

    def handle(self, message):
        self._pong.set()
        return True

    def on_notification(self, notification: WebSocketNotification):
        if notification == WebSocketNotification.CONNECTION_LOST:
            self._task.cancel()

    def _send_ping_message(self):
        message_id = random.randint(100000000, 1000000000)
        return self._ws.send(f'{{ "id":{message_id},"type":"ping" }}')

class SinkMessageHandler(WebSocketMessageHandler):
    def __init__(self):
        self._logger = logging.getLogger(type(self).__name__)

    def can_handle(self, message):
        return True

    def handle(self, message):
        self._logger.debug(f'unhandled message received: {message}')
        return True

class SubscriptionHandler(WebSocketMessageHandler):
    def __init__(self, subscription_id: int):
        self.subscription_id = subscription_id
        self._logger = logging.getLogger(type(self).__name__)

    def can_handle(self, message: str) -> bool:
        return f'"id":{self.subscription_id}' in message

    def handle(self, message: str) -> bool:
        if '"type":"ack"' in message:
            self._logger.info(f'subscription #{self.subscription_id} acknowledged')
        else:
            self._logger.warning(f'subscription #{self.subscription_id}: unexpected response: {message}')
        return False

class StrategyHandler(WebSocketMessageHandler):
    pass


import requests

def get_page(name):
    url = "https://fr.wikipedia.org/w/api.php?"
    try:
        response = requests.get(
            url,
            params={
                "action": "query",
                "list": "search",
                "srsearch": name,
                "format": "json",
            },
            headers={
                "Content-Type": "application/json",
            }
        )
        response.raise_for_status()
        return response.json()
    except requests.exceptions.RequestException as error:
        print(error)

def get_page_content(pageid):
    url = "https://fr.wikipedia.org/w/api.php?"
    try:
        response =  requests.get(
            url,
            params={
                "action": "parse",
                "pageid": pageid,
                "format": "json",
            },
            headers={
                "Content-Type": "application/json",
            }
        )
        response.raise_for_status()
        return  response.json()
    except requests.exceptions.RequestException as error:
        print(error)

from bs4 import BeautifulSoup

def get_information(name):
    try:
        result =  get_page(name)
        content =  get_page_content(result['query']['search'][0]['pageid'])
        html = content['parse']['text']['*']
        dom =  BeautifulSoup(html, "html.parser")
        th = dom.find_all('th')
        information = {}
        for i in range(len(th)):
            if th[i].text == "Siège":
                information["address"] = th[i].find_next_sibling('td').text.replace('\n', '').strip()
            if th[i].text == "SIREN":
                information["siren"] = th[i].find_next_sibling('td').text.replace('\n', '').strip()
            if th[i].text == "Site web" or th[i].text == "Sites web":
                link = th[i].find_next_sibling('td').find('a')
                if link:
                    information["website"] = link.get('href')
        return information
    except Exception as error:
        print(error)
    return None


import ply.yacc as yacc
from anytree import Node
from lex import Lexer

class Parser():
  # Tokens do processo de análise léxica
  tokens = Lexer.tokens

  def __init__(self, **kwargs):
    self.totalLines = 0
    self.result = True
    self.lexer = Lexer()
    self.parser = yacc.yacc(module=self, **kwargs)

  def f_column(self, token, pos):
    input = token.lexer.lexdata
    line_start = input.rfind('\n', 0, token.lexpos(pos)) + 1
    return (token.lexpos(pos) - line_start) + 1

  def p_programa(self, p):
    '''
      programa : lista_declaracoes
    '''

    p[0] = Node('programa', value = 'programa', children = [p[1]])

  def p_lista_declaracoes(self, p):
    '''
      lista_declaracoes : lista_declaracoes declaracao
                          | declaracao
    '''

    if(len(p) == 3):
      p[0] = Node('lista_declaracoes', value = 'lista_declaracoes', children = [p[1],p[2]])
    else:
      p[0] = Node('lista_declaracoes', value = 'lista_declaracoes', children = [p[1]])

  def p_declaracao(self, p):
    '''
      declaracao : declaracao_variaveis
                  | inicializacao_variaveis
                  | declaracao_funcao
    '''

    p[0] = Node('declaracao', value = 'declaracao', children = [p[1]])

  def p_declaracao_variaveis(self, p):
    '''
      declaracao_variaveis : tipo DOIS_PONTOS lista_variaveis
    '''

    p[0] = Node('declaracao_variaveis', value = 'declaracao_variaveis', children = [
      p[1],
      Node(str(p[2]), value = str(p[2]), line = (p.lineno(2) - (self.totalLines - 1)), column = self.f_column(p, 2)),
      p[3]
    ])

  def p_inicializacao_variaveis(self, p):
    '''
      inicializacao_variaveis : atribuicao
    '''

    p[0] = Node('inicializacao_variaveis', value = 'inicializacao_variaveis', children = [p[1]])

  def p_lista_variaveis(self, p):
    '''
      lista_variaveis : lista_variaveis VIRGULA var
                      | var
    '''

    if(len(p) == 4):
      p[0] = Node('lista_variaveis', value = 'lista_variaveis', children = [
        p[1],
        Node(str(p[2]), value = str(p[2]), line = (p.lineno(2) - (self.totalLines - 1)), column = self.f_column(p, 2)),
        p[3]
      ])
    else:
      p[0] = Node('lista_variaveis', value = 'lista_variaveis', children = [p[1]])

  def p_var(self, p):
    '''
      var : ID
          | ID indice
    '''

    if(len(p) == 3):
      p[0] = Node('var', value = 'var', children = [
        Node(str(p[1]), value = str(p[1]), line = (p.lineno(1) - (self.totalLines - 1)), column = self.f_column(p, 1)),
        p[2]
      ])
    else:
      p[0] = Node('var', value = 'var', children = [
        Node(str(p[1]), value = str(p[1]), line = (p.lineno(1) - (self.totalLines - 1)), column = self.f_column(p, 1))
      ])

  def p_indice(self, p):
    '''
      indice : indice ABRE_COLCHETE expressao FECHA_COLCHETE
              | ABRE_COLCHETE expressao FECHA_COLCHETE
    '''

    if(len(p) == 5):
      p[0] = Node('indice', value = 'indice', children = [
        p[1],
        Node(str(p[2]), value = str(p[2]), line = (p.lineno(2) - (self.totalLines - 1)), column = self.f_column(p, 2)),
        p[3],
        Node(str(p[4]), value = str(p[4]), line = (p.lineno(4) - (self.totalLines - 1)), column = self.f_column(p, 4))
      ])
    else:
      p[0] = Node('indice', value = 'indice', children = [
        Node(str(p[1]), value = str(p[1]), line = (p.lineno(1) - (self.totalLines - 1)), column = self.f_column(p, 1)),
        p[2],
        Node(str(p[3]), value = str(p[3]), line = (p.lineno(3) - (self.totalLines - 1)), column = self.f_column(p, 3))
      ])

  def p_tipo(self, p):
    '''
      tipo : INTEIRO
            | FLUTUANTE
    '''

    p[0] = Node('tipo', value = 'tipo', children = [
      Node(str(p[1]), value = str(p[1]), line = (p.lineno(1) - (self.totalLines - 1)), column = self.f_column(p, 1))
    ])

  def p_declaracao_funcao(self, p):
    '''declaracao_funcao : tipo cabecalho
                             | cabecalho'''

    if(len(p) == 3):
      p[0] = Node('declaracao_funcao', value = 'declaracao_funcao', children = [
        p[1],
        p[2]
      ])
    else:
      p[0] = Node('declaracao_funcao', value = 'declaracao_funcao', children = [p[1]])

  def p_cabecalho(self, p):
    '''cabecalho : ID ABRE_PARENTESE lista_parametros FECHA_PARENTESE corpo FIM'''

    p[0] = Node('cabecalho', value = 'cabecalho', children = [
      Node(str(p[1]), value = str(p[1]), line = (p.lineno(1) - (self.totalLines - 1)), column = self.f_column(p, 1)),
      Node(str(p[2]), value = str(p[2]), line = (p.lineno(2) - (self.totalLines - 1)), column = self.f_column(p, 2)),
      p[3],
      Node(str(p[4]), value = str(p[4]), line = (p.lineno(4) - (self.totalLines - 1)), column = self.f_column(p, 4)),
      p[5]
    ])

  def p_lista_parametros(self, p):
    '''
      lista_parametros : lista_parametros VIRGULA parametro
                        | parametro
                        | vazio
    '''

    if(len(p) == 4):
      p[0] = Node('lista_parametros', value = 'lista_parametros', children = [
        p[1],
        Node(str(p[2]), value = str(p[2]), line = (p.lineno(2) - (self.totalLines - 1)), column = self.f_column(p, 2)),
        p[3]
      ])
    else:
      if(p[1] is not None):
        p[0] = Node('lista_parametros', value = 'lista_parametros', children = [p[1]])
      else:
        p[0] = Node('lista_parametros', value = 'lista_parametros')

  def p_parametro(self, p):
    '''
      parametro : tipo DOIS_PONTOS ID
                |  parametro ABRE_COLCHETE FECHA_COLCHETE
    '''

    p[0] = Node('parametro', value = 'parametro', children = [
      p[1],
      Node(str(p[2]), value = str(p[2]), line = (p.lineno(2) - (self.totalLines - 1)), column = self.f_column(p, 2)),
      Node(str(p[3]), value = str(p[3]), line = (p.lineno(3) - (self.totalLines - 1)), column = self.f_column(p, 3))
    ])

  def p_corpo(self, p):
    '''
      corpo : corpo acao
            | vazio
    '''

    if(len(p) == 3):
      p[0] = Node('corpo', value = 'corpo', children = [
        p[1],
        p[2]
      ])
    else:
      p[0] = Node('corpo', value = 'corpo')

  def p_acao(self, p):
    '''
      acao : expressao
            | declaracao_variaveis
            | se
            | repita
            | leia
            | escreva
            | retorna
    '''

    p[0] = Node('acao', value = 'acao', children = [p[1]])

  def p_se(self, p):
    '''
      se : SE expressao ENTAO corpo FIM
          | SE expressao ENTAO corpo SENAO corpo FIM
    '''

    if(len(p) == 6):
      p[0] = Node('condicional', value = 'condicional', children = [
        Node(str(p[1]), value = str(p[1]), line = (p.lineno(1) - (self.totalLines - 1)), column = self.f_column(p, 1)),
        p[2],
        Node(str(p[3]), value = str(p[3]), line = (p.lineno(3) - (self.totalLines - 1)), column = self.f_column(p, 3)),
        p[4],
        Node(str(p[5]), value = str(p[5]), line = (p.lineno(5) - (self.totalLines - 1)), column = self.f_column(p, 5))
      ])
    else:
      p[0] = Node('condicional', value = 'condicional', children = [
        Node(str(p[1]), value = str(p[1]), line = (p.lineno(1) - (self.totalLines - 1)), column = self.f_column(p, 1)),
        p[2],
        Node(str(p[3]), value = str(p[3]), line = (p.lineno(3) - (self.totalLines - 1)), column = self.f_column(p, 3)),
        p[4],
        Node(str(p[5]), value = str(p[5]), line = (p.lineno(5) - (self.totalLines - 1)), column = self.f_column(p, 5)),
        p[6],
        Node(str(p[7]), value = str(p[7]), line = (p.lineno(7) - (self.totalLines - 1)), column = self.f_column(p, 7))
      ])

  def p_repita(self, p):
    '''
      repita : REPITA corpo ATE expressao
    '''

    p[0] = Node('repita', value = 'repita', children = [
      Node(str(p[1]), value = str(p[1]), line = (p.lineno(1) - (self.totalLines - 1)), column = self.f_column(p, 1)),
      p[2],
      Node(str(p[3]), value = str(p[3]), line = (p.lineno(3) - (self.totalLines - 1)), column = self.f_column(p, 3)),
      p[4]
    ])

  def p_atribuicao(self, p):
    '''
      atribuicao : var ATRIBUICAO expressao
    '''

    p[0] = Node('atribuicao', value = 'atribuicao', children = [
      p[1],
      Node(str(p[2]), value = str(p[2]), line = (p.lineno(2) - (self.totalLines - 1)), column = self.f_column(p, 2)),
      p[3]
    ])

  def p_leia(self, p):
    '''
      leia : LEIA ABRE_PARENTESE var FECHA_PARENTESE
    '''

    p[0] = Node('leia', value = 'leia', children = [
      Node(str(p[1]), value = str(p[2]), line = (p.lineno(1) - (self.totalLines - 1)), column = self.f_column(p, 1)),
      Node(str(p[2]), value = str(p[2]), line = (p.lineno(2) - (self.totalLines - 1)), column = self.f_column(p, 2)),
      p[3],
      Node(str(p[4]), value = str(p[4]), line = (p.lineno(4) - (self.totalLines - 1)), column = self.f_column(p, 4))
    ])

  def p_escreva(self, p):
    '''
      escreva : ESCREVA ABRE_PARENTESE expressao FECHA_PARENTESE
    '''

    p[0] = Node('escreva', value = 'escreva', children = [
      Node(str(p[1]), value = str(p[1]), line = (p.lineno(1) - (self.totalLines - 1)), column = self.f_column(p, 1)),
      Node(str(p[2]), value = str(p[2]), line = (p.lineno(2) - (self.totalLines - 1)), column = self.f_column(p, 2)),
      p[3],
      Node(str(p[4]), value = str(p[4]), line = (p.lineno(4) - (self.totalLines - 1)), column = self.f_column(p, 4))
    ])

  def p_retorna(self, p):
    '''
      retorna : RETORNA ABRE_PARENTESE expressao FECHA_PARENTESE
    '''

    p[0] = Node('retorna', value = 'retorna', children = [
      Node(str(p[1]), value = str(p[1]), line = (p.lineno(1) - (self.totalLines - 1)), column = self.f_column(p, 1)),
      Node(str(p[2]), value = str(p[2]), line = (p.lineno(2) - (self.totalLines - 1)), column = self.f_column(p, 2)),
      p[3],
      Node(str(p[4]), value = str(p[4]), line = (p.lineno(4) - (self.totalLines - 1)), column = self.f_column(p, 4))
    ])

  def p_expressao(self, p):
    '''
      expressao : expressao_logica
                | atribuicao
    '''

    p[0] = Node('expressao', value = 'expressao', children = [p[1]])

  def p_expressao_logica(self, p):
    '''
      expressao_logica : expressao_simples
                        | expressao_logica operador_logico expressao_simples
    '''

    if(len(p) == 4):
      p[0] = Node('expressao_logica', value = 'expressao_logica', children = [
        p[1],
        p[2],
        p[3]
      ])
    else:
      p[0] = Node('expressao_logica', value = 'expressao_logica', children = [p[1]])

  def p_expressao_simples(self, p):
    '''
      expressao_simples : expressao_aditiva
                        | expressao_simples operador_relacional expressao_aditiva
    '''

    if(len(p) == 4):
      p[0] = Node('expressao_simples', value = 'expressao_simples', children = [
        p[1],
        p[2],
        p[3]
      ])
    else:
      p[0] = Node('expressao_simples', value = 'expressao_simples', children = [p[1]])

  def p_expressao_aditiva(self, p):
    '''
      expressao_aditiva : expressao_multiplicativa
                        | expressao_aditiva operador_soma expressao_multiplicativa
    '''

    if(len(p) == 4):
      p[0] = Node('expressao_aditiva', value = 'expressao_aditiva', children = [
        p[1],
        p[2],
        p[3]
      ])
    else:
      p[0] = Node('expressao_aditiva', value = 'expressao_aditiva', children = [p[1]])

  def p_expressao_multiplicativa(self, p):
    '''
      expressao_multiplicativa : expressao_unaria
                                | expressao_multiplicativa operador_multiplicacao expressao_unaria
    '''

    if(len(p) == 4):
      p[0] = Node('expressao_multiplicativa', value = 'expressao_multiplicativa', children = [
        p[1],
        p[2],
        p[3]
      ])
    else:
      p[0] = Node('expressao_multiplicativa', value = 'expressao_multiplicativa', children = [p[1]])

  def p_expressao_unaria(self, p):
    '''
      expressao_unaria : fator
                        | operador_soma fator
                        | operador_negacao fator
    '''

    if(len(p) == 3):
      p[0] = Node('expressao_unaria', value = 'expressao_unitaria', children = [
        p[1],
        p[2]
      ])
    else:
      p[0] = Node('expressao_unaria', value = 'expressao_unitaria', children = [p[1]])

  def p_operador_relacional(self, p):
    '''
      operador_relacional : MENOR
                          | MAIOR
                          | IGUAL
                          | DIFERENTE
                          | MENOR_IGUAL
                          | MAIOR_IGUAL
    '''

    p[0] = Node('operador_relacional', value = 'operador_relacional', children = [
      Node(str(p[1]), value = str(p[1]), line = (p.lineno(1) - (self.totalLines - 1)), column = self.f_column(p, 1))
    ])

  def p_operador_soma(self, p):
    '''
      operador_soma : MAIS
                    | MENOS
    '''

    p[0] = Node('operador_soma', value = 'operador_soma', children = [
      Node(str(p[1]), value = str(p[1]), line = (p.lineno(1) - (self.totalLines - 1)), column = self.f_column(p, 1))
    ])

  def p_operador_logico(self, p):
    '''
      operador_logico : E_LOGICO
                      | OU_LOGICO
    '''

    p[0] = Node('operador_logico', value = 'operador_logico', children = [
      Node(str(p[1]), value = str(p[1]), line = (p.lineno(1) - (self.totalLines - 1)), column = self.f_column(p, 1))
    ])

  def p_operador_negacao(self, p):
    '''
      operador_negacao : NEGACAO
    '''

    p[0] = Node('operador_negacao', value = 'operador_negacao', children = [
      Node(str(p[1]), value = str(p[1]), line = (p.lineno(1) - (self.totalLines - 1)), column = self.f_column(p, 1))
    ])

  def p_operador_multiplicacao(self, p):
    '''
      operador_multiplicacao : MULTIPLICACAO
                              | DIVISAO
    '''

    p[0] = Node('operador_multiplicacao', value = 'operador_multiplicacao', children = [
      Node(str(p[1]), value = str(p[1]), line = (p.lineno(1) - (self.totalLines - 1)), column = self.f_column(p, 1))
    ])

  def p_fator(self, p):
    '''
      fator : ABRE_PARENTESE expressao FECHA_PARENTESE
            | var
            | chamada_funcao
            | numero
    '''

    if(len(p) == 4):
      p[0] = Node('fator', value = 'fator', children = [
        Node(str(p[1]), value = str(p[1]), line = (p.lineno(1) - (self.totalLines - 1)), column = self.f_column(p, 1)),
        p[2],
        Node(str(p[3]), value = str(p[3]), line = (p.lineno(3) - (self.totalLines - 1)), column = self.f_column(p, 3))
      ])
    else:
      p[0] = Node('fator', value = 'fator', children = [p[1]])

  def p_numero(self, p):
    '''
      numero : NUM_INTEIRO
              | NUM_PONTO_FLUTUANTE
              | NUM_NOTACAO_CIENTIFICA
    '''

    p[0] = Node('numero', value = 'numero', children = [
      Node(str(p[1]), value = p[1], line = (p.lineno(1) - (self.totalLines - 1)), column = self.f_column(p, 1))
    ])

  def p_chamada_funcao(self, p):
    '''
      chamada_funcao : ID ABRE_PARENTESE lista_argumentos FECHA_PARENTESE
    '''

    p[0] = Node('chamada_funcao', value = 'chamada_funcao', children = [
      Node(str(p[1]), value = str(p[1]), line = (p.lineno(1) - (self.totalLines - 1)), column = self.f_column(p, 1)),
      Node(str(p[2]), value = str(p[2]), line = (p.lineno(2) - (self.totalLines - 1)), column = self.f_column(p, 2)),
      p[3],
      Node(str(p[4]), value = str(p[4]), line = (p.lineno(4) - (self.totalLines - 1)), column = self.f_column(p, 4))
    ])

  def p_lista_argumentos(self, p):
    '''
      lista_argumentos : lista_argumentos VIRGULA expressao
                        | expressao
                        | vazio
    '''

    if(len(p) == 4):
      p[0] = Node('lista_argumentos', value = 'lista_argumentos', children = [
        p[1],
        Node(str(p[2]), value = str(p[2]), line = (p.lineno(2) - (self.totalLines - 1)), column = self.f_column(p, 2)),
        p[3]
      ])
    else:
      if(p[1] is not None):
        p[0] = Node('lista_argumentos', value = 'lista_argumentos', children = [p[1]])
      else:
        p[0] = Node('lista_argumentos', value = 'lista_argumentos')

  def p_vazio(self, p):
    '''
      vazio :
    '''
    pass

  def p_error(self, p):
    self.result = False

    if p:
      print('Sintaxe Inválida do token \'' + str(p.value) + '\' em ' + str(p.lineno) + ':' + str(self.lexer.f_column(p)))
    else:
      print('Sintaxe Inválida da saída')

  def syntactic(self, codeFile, numberOfLines):
    self.totalLines = numberOfLines
    self.tree = self.parser.parse(codeFile, tracking = True)

    return self.tree, self.result


################################################################################
# 1. Including files
################################################################################
import xlrd

################################################################################
# 2. Class definition
################################################################################
class testSuiteCollection:
    test_suite_name = ""
    testcases = []

    def __init__(self, test_suite_name):
        self.test_suite_name = str(test_suite_name)

class testcaseCollection:
    function_name = ""
    testcase_name = ""
    invoked_func_precondition = ""
    params = []
    global_vars = []

    def __init__(self, function_name, testcase_name):
        self.function_name = str(function_name)
        self.testcase_name = str(testcase_name)

class globalVarCollection:
    gen_name = ""
    type = ""
    expected = ""
    actual_mem = ""
    mask = ""
    def __init__(self, gen_name, type, expected, actual_mem, mask):
        self.gen_name = str(gen_name)
        self.type = str(type)
        self.expected = str(expected)
        self.actual_mem = str(actual_mem)
        self.mask = str(mask)

class paramCollection:
    gen_name = ""
    type = ""
    param_name = ""
    init_value = ""
    isStructType = "False"
    def __init__(self, gen_name, type, param_name, init_value, isStructType):
        self.gen_name = str(gen_name)
        self.type = str(type)
        self.param_name = str(param_name)
        self.init_value = str(init_value)
        self.isStructType = str(isStructType)

################################################################################
# 3. Function definition
################################################################################
def find_output_position(firstParamColumn):
    output_position = firstParamColumn # assume that there is no INPUT data,
    # and OUTPUT data begins at first param column.
    for i in range(sheet.ncols):
        if "Output" == sheet.cell_value(2, i):
            output_position = i
    return output_position

def isStructure(type):
    result = "True"

    # check if "type" exists in "basicTypes"
    try:
        type.index("Struct_")
    except ValueError:
        result = "False"

    return result

################################################################################
# 4. Main processing: XLS file parsing
################################################################################
loc = ("C:\\Users\\PC\\Documents\\GitHub\\STM32F4Discovery\\UT_TestSuite.xls")
# Open Workbook
testcaseSheetList = [6, 8, 9, 10]
firstParamColumn = 3
tcFirstLine = 5
tcNameColumn = 0
tcInvokedFuncColumn = 1
ioTypeRow = 4
ioNameRow = 3

testSuite = testSuiteCollection("ut_usart_driver")

# Open XLS file
wb = xlrd.open_workbook(loc)
for tcSheet in testcaseSheetList:
    # Open a sheet
    sheet = wb.sheet_by_index(tcSheet)

    noRows = sheet.nrows
    noCols = sheet.ncols
    func_name = sheet.cell_value(0, 1)
    output_position = find_output_position(firstParamColumn)

    for i in range(tcFirstLine, noRows):
        testcase_name = sheet.cell_value(i, tcNameColumn)
        testcase_invoked_func = sheet.cell_value(i, tcInvokedFuncColumn)
        noParams = (output_position - firstParamColumn) // 2 # division with result of integer number
        noGlobalVars = (noCols - output_position) // 2 # division with result of integer number

        testcase = testcaseCollection(func_name, testcase_name)
        testcase.invoked_func_precondition = testcase_invoked_func
        testcase.params = [None]*noParams
        testcase.global_vars = [None]*noGlobalVars

        # Collect all parameters
        index = 0
        for j in range(firstParamColumn, output_position, 2):
            gen_name = "param_" + str(index + 1)
            type = sheet.cell_value(ioTypeRow, j) # unchanged
            param_name = sheet.cell_value(ioNameRow, j) # unchanged
            init_value = sheet.cell_value(i, j)
            isStructType = isStructure(type)
            testcase.params[index] = \
            paramCollection(gen_name, type, param_name, init_value, isStructType)

            index += 1

        # Collect all global variables
        index = 0
        for j in range(output_position, noCols - 1, 2):
            gen_name = "global_var_" + str(index + 1)
            type = sheet.cell_value(ioTypeRow, j) # unchanged
            expected = sheet.cell_value(i, j)
            actual_mem = sheet.cell_value(ioNameRow, j) # unchanged
            mask = sheet.cell_value(i, j + 1)
            testcase.global_vars[index] = \
            globalVarCollection(gen_name, type, expected, actual_mem, mask)

            index += 1

        testSuite.testcases.append(testcase)


import collections

def number_of_islands(grid):
    # this problem can be approached by dfs/bfs approach

    # base case
    if not grid:
        return 0

    ROWS, COLS = len(grid), len(grid[0])

    visit = set()
    island = 0

    def bfs(r, c):
        # since bfs, need a queue
        # append r, c immediately
        queue = collections.deque()
        queue.append((r, c))
        visit.add((r,c))

        while queue: # check until queue is empty after popping left
            row, col = queue.popleft()
            directions = [[1, 0], [-1, 0], [0, 1], [0, -1]]

            for dr, dc in directions:
                # store current cell by directions
                r, c = row + dr, col + dc
                # check if satisfies conditions
                # 1. in bound
                # 2. current cell = 1
                # 3. (r,c) not visited yet
                if r in range(ROWS) and c in range(COLS) and grid[r][c] == "1" and (r, c) not in visit:
                    # add to visit & queue
                    visit.add((r, c))
                    queue.append((r,c))

        # outside of bfs, do nested loop and check if satisfies conditions cell = 1 & r, c not visited yet
        for r in range(ROWS):
            for c in range(COLS):
                if grid[r][c] == "1" and (r,c) not in visit:
                    bfs(r,c)
                    island += 1

        return island


import logging
from cterasdk import CTERAException

def suspend_filer_sync(self=None, device_name=None, tenant_name=None):
    """Suspend sync on a device"""
    logging.info("Starting suspend sync task.")
    try:
        device = self.devices.device(device_name, tenant_name)
        device.sync.suspend(wait=True)
        logging.info("Suspended sync on %s", device.name)
    except Exception as e:
        logging.warning(e)
        logging.error("Error suspending sync")


import os
import torch

def load_checkpoint(path):
  if os.path.isdir(path):
    path = os.path.join(path, 'checkpoint_best.pt')
  dst = f'cuda:{torch.cuda.current_device()}'
  print(f'Loading checkpoint from {path}')
  checkpoint = torch.load(path, map_location=dst)
  return checkpoint

ckpt = load_checkpoint("./LM-TFM/")

# # adaptive softmax / embedding
cutoffs, tie_projs = [], [False]
cutoffs = [19997, 39997, 199997]
tie_projs += [True] * len(cutoffs)

model_config_base = {
  'dropout'       : 0.1,
  'dropatt'       : 0.0,
  'tie_weight'    : False,
  'div_val'       : 1,
  'pre_lnorm'     : True,
  'cutoffs'       : cutoffs,
  'clamp_len'     : 400,
  }

from transformers import TransfoXLTokenizer, TransfoXLLMHeadModel, TransfoXLConfig

# Initializing a Transformer XL configuration
configuration = TransfoXLConfig.from_dict(model_config_base)
# To match with pre-trained model
configuration.d_embed, configuration.d_head  = 512, 64
configuration.d_inner, configuration.d_model = 2048, 512
configuration.mem_len, configuration.n_head = 192, 8
configuration.n_layer, configuration.tgt_len = 16, 192
configuration.vocab_size = 32000

model = TransfoXLLMHeadModel.from_pretrained(pretrained_model_name_or_path=None, state_dict=ckpt['model_state'], config=configuration)

from transformers import PreTrainedTokenizer
from utils.tokenization_sentencepiece import FullTokenizer
from collections import Counter, OrderedDict
from os.path import join, exists

class Vocab(TransfoXLTokenizer):
    def __init__(
        self,
        special=None,
        min_freq=0,
        max_size=None,
        lower_case=False,
        delimiter=None,
        vocab_file='./data/mn_cased.vocab',
        never_split=None,
        unk_token="<unk>",
        eos_token="</s>",
        additional_special_tokens=["<formula>"],
        **kwargs
        ):

        super().__init__(
            unk_token=unk_token, eos_token=eos_token, additional_special_tokens=additional_special_tokens, **kwargs
        )

        self.vocab_file = vocab_file
        if vocab_file is not None:
            self.build_vocab()

    def tokenize(self, line, add_eos=False, add_double_eos=False):
        tokenizer = FullTokenizer(model_file=join('./data', 'mn_cased.model'),
                          vocab_file=join('./data', 'mn_cased.vocab'), do_lower_case=False)
        line = line.strip()
        # convert to lower case
        if self.lower_case:
            line = line.lower()

        # empty delimiter '' will evaluate False
        if self.delimiter == '':
            symbols = line
        else:
            symbols = tokenizer.tokenize(line)

        if add_double_eos:  # lm1b
            return ['<S>'] + symbols + ['<S>']
        elif add_eos:
            return symbols + ['<eos>']
        else:
            return symbols

    def _build_from_file(self, vocab_file):
        self.idx2sym = []
        self.sym2idx = OrderedDict()

        with open(vocab_file, 'r') as f:
            for line in f:
                symb = line.strip().split()[0]
                self.add_symbol(symb)
        self.unk_idx = self.sym2idx['<unk>']

    def build_vocab(self):
        if self.vocab_file:
            print('building vocab from {}'.format(self.vocab_file))
            self._build_from_file(self.vocab_file)
            print('final vocab size {}'.format(len(self)))
        else:
            print('building vocab with min_freq={}, max_size={}'.format(
                self.min_freq, self.max_size))
            self.idx2sym = []
            self.sym2idx = OrderedDict()

            for sym in self.special:
                self.add_special(sym)

            for sym, cnt in self.counter.most_common(self.max_size):
                if cnt < self.min_freq: break
                self.add_symbol(sym)
            print('final vocab size {} from {} unique tokens'.format(
                len(self), len(self.counter)))

model.to('cuda')
model.eval()
model.half()
cool_tokenizer = Vocab()

# reference - https://github.com/huggingface/transformers/blob/2ba147ecffa28e5a4f96eebd09dcd642117dedae/examples/run_generation.py
def text_generation(prompt_text, temp, topk, topp, beams, penalty, do_sample):
    encoded_prompt = cool_tokenizer.encode(prompt_text, return_tensors="pt")
    encoded_prompt = encoded_prompt.to('cuda')

    output_sequences = model.generate(
        input_ids=encoded_prompt,
        max_length=20,
        temperature=temp,
        top_k=topk,
        top_p=topp,
        num_beams=beams,
        repetition_penalty=penalty,
        do_sample=do_sample,
    )

    # Batch size == 1. to add more examples please use num_return_sequences > 1
    generated_sequence = output_sequences[0].tolist()
    text = cool_tokenizer.decode(generated_sequence, skip_special_tokens=True, clean_up_tokenization_spaces=True)
    text = [word.replace("▁", " ") for word in text.split()]

    return ' '.join(text)

print(text_generation("УИХ ", temp=1.0, topk=5, topp=1, beams=1, penalty=1.0, do_sample=True))


from scripts.leet75.reverse_string import Solution

class Test:

    test_cases = [
        [["h", "e", "l", "l", "o"], ["o","l","l","e","h"]],
        [["H","a","n","n","a","h"], ["h","a","n","n","a","H"]],
        [["h"], ["h"]],
        [[], []],
    ]

    def test_reverse_string(self):
        soln = Solution()

        for case, expected in self.test_cases:
            assert soln.reverseString(case) == expected

    def test_reverse_string_recursive(self):
        soln = Solution()

        for case, expected in self.test_cases:
            assert soln.reverseStringRecursive(case) == expected

if __name__ == '__main__':
    soln = Solution()
    inp1 = ["h", "e", "l", "l", "o"]

    print(soln.reverseString(inp1))


from typing import Literal

import beaker as bk
from pyteal import (
    Expr,
    Global,
    InnerTxnBuilder,
    Int,
    Seq,
    Txn,
    TxnField,
    TxnType,
    abi,
)

app = bk.Application("EventTicket")

@app.external
def create_asset(
    assetName: abi.String,
    assetUrl: abi.String,
    assetTotal: abi.Uint64,
    managerAddress: abi.Address,
    metadataHash: abi.StaticBytes[Literal[32]],
) -> Expr:
    return Seq(  # Seq is used to group a set of operations with only the last returning a value on the stack
        # Start to build the transaction builder
        InnerTxnBuilder.Begin(),
        # This method accepts a dictionary of TxnField to value so all fields may be set
        InnerTxnBuilder.SetFields(
            {
                TxnField.type_enum: TxnType.AssetConfig,
                TxnField.config_asset_name: assetName.get(),
                TxnField.config_asset_url: assetUrl.get(),
                TxnField.config_asset_manager: managerAddress.get(),
                TxnField.config_asset_clawback: Global.current_application_address(),
                TxnField.config_asset_reserve: Global.current_application_address(),
                TxnField.config_asset_freeze: Global.current_application_address(),
                TxnField.config_asset_total: assetTotal.get(),
                TxnField.config_asset_metadata_hash: metadataHash.get(),
                TxnField.config_asset_decimals: Int(0),
            }
        ),
        # Submit the transaction we just built
        InnerTxnBuilder.Submit(),
    )

@app.external
def get_asset(asset: abi.Asset) -> Expr:
    return Seq(  # Seq is used to group a set of operations with only the last returning a value on the stack
        # Start to build the transaction builder
        InnerTxnBuilder.Begin(),
        # This method accepts a dictionary of TxnField to value so all fields may be set
        InnerTxnBuilder.SetFields(
            {
                TxnField.type_enum: TxnType.AssetTransfer,
                TxnField.xfer_asset: asset.asset_id(),
                TxnField.asset_amount: Int(1),
                TxnField.asset_receiver: Txn.sender(),
                TxnField.asset_sender: Global.current_application_address(),
            }
        ),
        # Submit the transaction we just built
        InnerTxnBuilder.Submit(),
    )

if __name__ == "__main__":
    spec = app.build()
    spec.export("artifacts")


"""
Your Library Page Testing

This script tests the Your Library Page functions and report the results to allure

This script requires `allure` and `pytest` be installed within the Python environment you are running this script in
"""
import time

import allure
import pytest

from Web_Testing.Pages.WebPlayerLibrary import WebPlayerLibrary
from Web_Testing.helperClasses import WebHelper
from Web_Testing.Pages.LoginPage import LoginPage
from Web_Testing.Pages.SignupPage import SignupPage
from Web_Testing.Pages.WebPlayerHome import WebPlayerHome
from Web_Testing.Pages.LoggedOutHome import LoggedOutHome
from selenium import webdriver
from Web_Testing.helperClasses import ConstantsClass

@allure.parent_suite("End to End testing")
@allure.suite("Your Library Page")
@allure.feature("Your Library Page")
@allure.severity(allure.severity_level.BLOCKER)
class TestWebPlayerLibrary:
    driver = WebHelper().firefox_driver_init()
    helper = WebHelper()
    helper.set_driver(driver)

    @pytest.yield_fixture
    def setup_initial(self):
        self.driver.get(WebHelper().get_login_url())
        self.driver.maximize_window()
        yield
        self.driver.refresh()

    @pytest.yield_fixture
    def setup(self):
        self.driver.get(self.helper.base_url + "webplayer/home")
        self.driver.maximize_window()
        yield
        # self.driver.close()

    @pytest.yield_fixture
    def setup_final(self):
        self.driver.get(self.helper.base_url + "webplayer/home")
        self.driver.maximize_window()
        yield
        self.driver.close()

    # Test #1 -> Your Library Button
    @allure.severity(allure.severity_level.BLOCKER)
    @allure.story("Testing Your Library Liked Songs Play Button")
    @allure.title("Liked Songs Play Button")
    @allure.description("Testing Your Library Liked Songs Play Button")
    @pytest.mark.Do
    @pytest.mark.YourLibrary
    def test_case_1(self, setup_initial):
        time.sleep(3)
        lp = LoginPage(self.driver)
        lp.login_to_spotify("test1@test.com", "test123")
        time.sleep(3)
        self.driver.get(self.helper.base_url + "webplayer/home")
        time.sleep(3)
        web_player_home = WebPlayerHome(self.driver)
        web_player_home.click_your_library()
        time.sleep(2)
        web_player_library = WebPlayerLibrary(self.driver)
        if web_player_library.check_liked_songs_click():
            self.helper.report_allure("SUCCESS: Your Library Liked songs cards are functional")
            assert True
        else:
            self.helper.report_allure("FAILURE: Your Library Liked songs cards are not functional")
            assert False

    # Test #2 -> Playlists Cards
    @allure.severity(allure.severity_level.BLOCKER)
    @allure.story("Testing Your Library playlists cards")
    @allure.title("Playlists cards")
    @allure.description("Testing Your Library Playlists cards")
    @pytest.mark.Do
    @pytest.mark.YourLibrary
    def test_case_2(self, setup):
        time.sleep(2)
        web_player_home = WebPlayerHome(self.driver)
        web_player_home.click_your_library()
        time.sleep(2)
        web_player_library = WebPlayerLibrary(self.driver)
        if web_player_library.check_card_click(0, True):
            self.helper.report_allure("SUCCESS: Your Library page playlist cards are functional")
            assert True
        else:
            self.helper.report_allure("FAILURE: Your Library page playlist cards are not functional")
            assert False

    # Test #3 -> Liked Songs Text Button
    @allure.severity(allure.severity_level.BLOCKER)
    @allure.story("Clicking on the Liked Songs Text in the card in Your Library Page")
    @allure.title("Clicking Liked Songs Card text")
    @allure.description("Clicking on the Liked Songs Text in the card in Your Library Page")
    @pytest.mark.Do
    @pytest.mark.YourLibrary
    def test_case_3(self, setup):
        time.sleep(2)
        web_player_home = WebPlayerHome(self.driver)
        web_player_home.click_your_library()
        time.sleep(2)
        web_player_library = WebPlayerLibrary(self.driver)
        web_player_library.click_liked_songs_txt()
        if self.helper.url_has("webplayer/likedplay"):
            self.helper.report_allure("SUCCESS: The Liked Songs Card button in your Library page is functional")
            assert True
        else:
            self.helper.report_allure("FAILURE: The Liked Songs Card button in your Library page is not functional")
            assert False

    # Test #4 -> Your Library Button with empty playlist
    @allure.severity(allure.severity_level.BLOCKER)
    @allure.story("Testing Your Library Liked Songs Play Button with empty playlist")
    @allure.title("Liked Songs Play Button with empty playlist")
    @allure.description("Testing Your Library Liked Songs Play Button with empty playlist")
    @pytest.mark.Do
    @pytest.mark.YourLibrary
    def test_case_4(self, setup_final):
        web_player_home = WebPlayerHome(self.driver)
        web_player_home.click_logout()
        time.sleep(2)
        web_player_home.click_login()
        time.sleep(3)
        lp = LoginPage(self.driver)
        lp.login_to_spotify("abdallah@gmail.com", "1234567")
        time.sleep(3)
        self.driver.get(self.helper.base_url + "webplayer/home")
        time.sleep(3)
        web_player_home = WebPlayerHome(self.driver)
        web_player_home.click_your_library()
        time.sleep(2)
        web_player_library = WebPlayerLibrary(self.driver)
        if web_player_library.check_liked_songs_click():
            assert True
        else:
            assert False


#README
'''
buka file dengan cara mengetikan:
    python main.py "folder_yang_berisi_data_csv"
selama fungsi login belum jadi, cara keluar program adalah control + "c"
'''

#import modul yang dibuat
from read_csv import load
from add_data import *
from write_csv import save
from login import login
from caritahun import cari_tahun
from see_history import see_gadget_return_history,see_consumable_history,see_gadget_borrow_history
from interface import *
import argparse
import os,time

#inisialisasi Data (Loading Data dari CSV)
parser = argparse.ArgumentParser()
parser.add_argument("folder_location", help="Location of the folder that contains all the data.",nargs='?', const='')
args = parser.parse_args()
if args.folder_location is None:
    print("Tidak ada folder yang dimasukkan")
    exit()
current_path=os.getcwd()
new_path=os.path.join(current_path,args.folder_location)
if os.path.exists(new_path):
    data=load(args.folder_location)
else:
    print("Folder tidak ada")
    exit()
loaded,user,gadget,consumable,consumable_history,gadget_borrow_history,gadget_return_history=data

#Algoritma Program
#User diminta untuk login
valid=False
while not valid:
    valid,curret_id,curret_role=login(user)

while valid:
    pilihan=input("Masukkan Pilihan Menu: ")

    #Masukkan Fungsi-Fungsi Yang Sudah dibuat disini (F01-F17)
    #F01 - Register
    if pilihan=='register':
        if curret_role=='admin':
            add_data_user(user)
        else:
            print("Fungsi Hanya diperbolehkan untuk Admin")
    #F02 - Login
        #Sudah di atas
    #F03 - Pencarian Gadget Berdasarkan Rarity
    if pilihan == "carirarity":
        rarity=input("Masukkan rarity yang akan dicari: ")
        if rarity=='S' or rarity=='A' or rarity=='B' or rarity=='C':
            found=False
            for j in range(len(gadget)):
                if rarity==gadget[j][4]:
                    found=True
                    print("Nama Gadget      : ",gadget[j][1])
                    print("Deskripsi        : ",gadget[j][2])
                    print("Jumlah           : ",gadget[j][3])
                    print("Rarity           : ",gadget[j][4])
                    print("Tahun Ditemukan  : ",gadget[j][5])
                    print("")
            if not found:
                print("Tidak ada gadget dengan rarity tersebut")
        else:
            print("Rarity tidak valid")
    #F04 - Pencarian Gadget Berdasarkan Tahun
    if pilihan=='caritahun':
        cari_tahun(gadget)
    #F05 - Menambah Item
    if pilihan == "tambahitem":
        if curret_role=='admin':
            cek = 0 #untuk mengecek apakah id_item sudah ada
            id_item = input("Masukkan ID: ")

            if id_item[0] == 'G':
                for i in range(1,len(gadget)):
                    if gadget[i][0] == id_item:
                        cek += 1
                if cek > 0:
                    print("Gagal menambahkan item karena ID sudah ada.")
                else: #cek == 0 atau id_item belum ada
                    add_data_gadget(id_item,gadget)

            elif id_item[0] == 'C':
                for i in range(1,len(consumable)):
                    if consumable[i][0] == id_item:
                        cek += 1
                if cek > 0:
                    print("Gagal menambahkan item karena ID sudah ada.")
                else: #cek == 0 atau id_item belum ada
                    add_data_consumable(id_item,consumable)

            else:
                print("Gagal menambahkan item karena ID tidak valid")
        else:
            print("Fungsi Hanya diperbolehkan untuk Admin")
    #F06 - Menghapus Item
    if pilihan=='hapusitem':
        if curret_role=='admin':
            id_item_yang_akan_dihapus=input("Masukkan ID item yang akan dihapus : ")
            if id_item_yang_akan_dihapus[0]=='G':
                delete_gadget(id_item_yang_akan_dihapus,gadget)
            elif id_item_yang_akan_dihapus[0]=='C':
                delete_consumable(id_item_yang_akan_dihapus,consumable)
            else:
                print("ID tidak cocok")
        else:
            print("Fungsi Hanya diperbolehkan untuk Admin")
    #F07 - Mengubah jumlah pada inventory
    if pilihan == "ubahjumlah":
        if curret_role=='admin':
            id_item_yang_akan_diubah = input("Masukan ID: ")
            if id_item_yang_akan_diubah[0]=='G':
                ubah_jumlah_gadget(id_item_yang_akan_diubah, gadget)
            elif id_item_yang_akan_diubah[0]=='C':
                ubah_jumlah_consumable(id_item_yang_akan_diubah, consumable)
            else:
                print("Tidak ada item dengan ID tersebut!")
        else:
            print("Fungsi Hanya diperbolehkan untuk Admin")
    #F08 - Meminjam Gadget
    if pilihan=='pinjam':
        if curret_role=='user':
            add_data_gadget_borrow_history(curret_id,gadget,gadget_borrow_history)
        else:
            print("Fungsi Hanya diperbolehkan untuk User")
    #F09 - Mengembalikan Gadget
    if pilihan=='kembalikan':
        if curret_role=='user':
            add_data_gadget_return_history(curret_id,gadget,gadget_borrow_history,gadget_return_history)
        else:
            print("Fungsi Hanya diperbolehkan untuk User")
    #F10 - Meminta Consumable
    if pilihan=='minta':
        if curret_role=='user':
            add_data_consumable_history(curret_id,consumable,consumable_history)
        else:
            print("Fungsi Hanya diperbolehkan untuk user")
    #F11 - Melihat Riwayat Peminjaman Gadget
    if pilihan=='riwayatpinjam':
        if curret_role=='admin':
            see_gadget_borrow_history(user,gadget,gadget_borrow_history)
    #F12 - Melihat Riwayat Pengembalian Gadget
    if pilihan=='riwayatkembali':
        if curret_role=='admin':
            see_gadget_return_history(user,gadget,gadget_return_history)
        else:
            print("Fungsi Hanya diperbolehkan untuk Admin")
    #F13 - Melihat Riwayat Pengambilan Consumable
    if pilihan=='riwayatambil':
        if curret_role=='admin':
            see_consumable_history(user,consumable,consumable_history)
        else:
            print("Fungsi Hanya diperbolehkan untuk Admin")
    #F14 - Load Data
        #Sudah pada baigan awal bersama dengan argparse
    #F15 - Save Data
    if pilihan=='save':
        os.system("cls")
        path=input("Masukkan Folder tempat file akan di save: ")
        save(path,user,gadget,consumable,consumable_history,gadget_borrow_history,gadget_return_history)
        r=50
        for i in range (r):
            progressBar(i, r)
            time.sleep(.02)
        time.sleep(1.5)
        data=load(path)
        loaded,user,gadget,consumable,consumable_history,gadget_borrow_history,gadget_return_history=data
    #F16 - Help
    if pilihan == 'help':
        print("================================= HELP =================================")
        print("register             - untuk melakukan registrasi user baru")
        print("login                - untuk melakukan login ke dalam sistem")
        print("carirarity           - untuk mencari gadget dengan rarity tertentu")
        print("caritahun            - untuk mencari gadget berdasarkan tahun ditemukan")
        if curret_role=='admin':
            print("tambahitem           - untuk menambahkan item ke dalam inventori")
            print("hapusitem            - untuk menghapus suatu item pada database")
            print("ubahjumlah           - untuk mengubah jumlah gadget dan consumable dalam sistem")
            print("riwayatkembali       - untuk melihat riwayat pengembalian gadget")
            print("riwayatambil         - untuk melihat riwayat pengambilan consumable")
        else:#curret_role=='user'
            print("pinjam               - untuk melakukan peminjaman gadget")
            print("kembalikan           - untuk mengembalikan gadget")
            print("minta                - untuk meminta consumable yang tersedia")
        print("save                 - untuk melakukan penyimpanan data")
        print("help                 - untuk panduan penggunaan penggunaan sistem")
        print("exit                 - untuk keluar dari aplikasi")

    #F17 - Exit
    if pilihan == 'exit':
        pil = input("Apakah anda mau melakukan penyimpanan file yang sudah diubah? (y/n)")
        if pil == "y" or pil == "Y":
            path = input("Masukkan Folder tempat file akan di save: ")
            save(path, user, gadget, consumable, consumable_history, gadget_borrow_history, gadget_return_history)
        break
    #FB01 - Hashing
        #Done pada hashing.py
    #FB02 - Mengembalikan Gadget Secara Parsial
        #Done
    #FB03 - Gacha
    if pilihan=='gacha':
        #Validasi User
        #Sementara id digenerate otomatis. Nantinya current id
        id=1
        gacha(id,consumable,consumable_history)


import argparse
import os
import uuid

import numpy as np

import torch
from torch import optim
from torch.nn import functional
from torch.utils.data import DataLoader

from datasets import load_metric

import albumentations
from albumentations.pytorch import ToTensorV2

from tqdm import tqdm

from utils import set_seed, load_config
from dataset import HarborClassificationDataset, HarborSegmentationDataset
from model import TwinHeadSegformerForSemanticSegmentation

parser = argparse.ArgumentParser(description="Train twin head segformer")
parser.add_argument("--seed", type=int, default=None)
parser.add_argument("--id", type=str, default=None)
parser.add_argument("--num_epochs", type=int, default=None)

args = parser.parse_args()

if args.seed is not None:
    set_seed(args.seed)

train_id = args.id
if train_id is None:
    train_id = uuid.uuid4().hex

device = torch.device("cuda" if torch.cuda.is_available() else "cpu")

config = load_config(os.path.join(os.path.dirname(__file__), "config.yaml"))
train_config = config["train"]["twin_head"]

model_name = config["pretrained_model_name"]

label2id = {k: v + 1 for k, v in config["label2id"].items()}
label2id["background"] = 0

id2label = {v: k for k, v in label2id.items()}

transform = albumentations.Compose([
    albumentations.CoarseDropout(
        max_holes=16, max_height=0.1, max_width=0.1, min_height=0.05, min_width=0.05, p=0.5
    ),
    albumentations.HorizontalFlip(p=0.5),
    albumentations.SafeRotate(15, p=0.5),
    albumentations.GaussNoise(p=0.5),
    albumentations.OpticalDistortion(p=0.5),
    albumentations.OneOf([
        albumentations.RGBShift(),
        albumentations.RandomToneCurve(),
        albumentations.InvertImg(),
        albumentations.ToGray()
    ]),
    ToTensorV2()
])

classifier_train_dataset = HarborClassificationDataset.from_config(config)
classifier_train_dataset.set_transform(transform)

train_dataset = HarborSegmentationDataset.from_config(config)
train_dataset.set_transform(transform)

classifier_train_dataloader = DataLoader(
    classifier_train_dataset, batch_size=train_config["classifier_batch_size"], shuffle=True
)
train_dataloader = DataLoader(
    train_dataset, batch_size=train_config["batch_size"], shuffle=True
)

model = TwinHeadSegformerForSemanticSegmentation.from_pretrained(
    model_name,
    num_labels=len(id2label),
    id2label=id2label,
    label2id=label2id,
    ignore_mismatched_sizes=True
)
model.to(device)

optimizer = optim.AdamW(
    model.parameters(),
    lr=float(train_config["learning_rate"]),
    weight_decay=float(train_config["weight_decay"])
)

accumulation_steps = train_config["accumulation_steps"]

losses = []
f1_metric = load_metric("f1")
miou_metric = load_metric("mean_iou")

model.train()

num_epochs = args.num_epochs
if num_epochs is None:
    num_epochs = train_config["num_epochs"]

step = 0
for epoch in range(1, num_epochs + 1):
    for (classifier_pixel_values, classifier_labels), segmenter_batch in tqdm(
        zip(classifier_train_dataloader, train_dataloader),
        train_id,
        total=min(len(classifier_train_dataloader), len(train_dataloader))
    ):
        step += 1

        classifier_pixel_values = classifier_pixel_values.to(device)
        classifier_labels = classifier_labels.to(device)
        pixel_values = segmenter_batch["pixel_values"].to(device)
        labels = segmenter_batch["labels"].to(device)

        outputs = model(
            classifier_pixel_values=classifier_pixel_values,
            classifier_labels=classifier_labels,
            pixel_values=pixel_values,
            labels=labels
        )
        classifier_logits, logits = outputs.classifier_logits, outputs.logits

        loss = (outputs.classifier_loss + outputs.loss) / 2
        loss /= accumulation_steps

        losses.append(loss.item())

        loss.backward()

        if step % accumulation_steps == 0:
            optimizer.step()
            optimizer.zero_grad()

        f1_metric.add_batch(
            predictions=classifier_logits.argmax(dim=-1).detach().cpu().numpy(),
            references=classifier_labels.detach().cpu().numpy()
        )

        if epoch % train_config["eval_frequency"] == 0:
            with torch.no_grad():
                upsampled_logits = functional.interpolate(
                    logits,
                    size=labels.shape[-2:],
                    mode="bilinear",
                    align_corners=False
                )
                predicted = upsampled_logits.argmax(dim=1)

                miou_metric.add_batch(
                    predictions=predicted.detach().cpu().numpy(),
                    references=labels.detach().cpu().numpy()
                )

    micro_f1 = f1_metric.compute(average="micro")["f1"]

    if epoch % train_config["eval_frequency"]:
        print(
            f"epoch: {epoch}\n"
            f"├─ loss: {np.mean(losses[-100:]):.6f}\n"
            f"└─ micro f1: {micro_f1:.4f}\n"
        )
    else:
        miou_metrics = miou_metric.compute(
            num_labels=len(id2label), ignore_index=label2id["background"], reduce_labels=False
        )

        print(
            f"epoch: {epoch}\n"
            f"├─ loss: {np.mean(losses[-100:]):.6f}\n"
            f"├─ micro f1: {micro_f1:.4f}\n"
            f"├─ mIoU: {miou_metrics['mean_iou']:.4f}\n"
            f"└─ mAcc: {miou_metrics['mean_accuracy']:.4f}\n"
        )

    torch.save(model, os.path.join(os.path.dirname(__file__), "checkpoints", f"{train_id}_{epoch}.pt"))


#%%
import numpy as np
import pandas as pd
from sklearn import metrics
from matplotlib import pyplot as plt
import glob
#%%
class Takens:

	'''
	constant
	'''
	tau_max = 30

	'''
	initializer
	'''
	def __init__(self, data,tau=None):
		self.data           = data
		if tau is None:
			self.tau, self.nmi  = self.__search_tau()
		else:
			self.tau = tau

	'''
	reconstruct data by using searched tau
	'''
	def reconstruct(self):
		_data1 = self.data[:-2]
		_data2 = np.roll(self.data, -1 * self.tau)[:-2]
		_data3 = np.roll(self.data, -2 * self.tau)[:-2]
		return np.array([_data1, _data2, _data3])

	'''
	find tau to use Takens' Embedding Theorem
	'''
	def __search_tau(self):

		# Create a discrete signal from the continunous dynamics
		hist, bin_edges = np.histogram(self.data, bins=200, density=True)
		bin_indices = np.digitize(self.data, bin_edges)
		data_discrete = self.data[bin_indices]

		# find usable time delay via mutual information
		before     = 1
		nmi        = []
		res        = None

		for tau in range(1, self.tau_max):
			unlagged = data_discrete[:-tau]
			lagged = np.roll(data_discrete, -tau)[:-tau]
			nmi.append(metrics.normalized_mutual_info_score(unlagged, lagged))

			if res is None and len(nmi) > 1 and nmi[-2] < nmi[-1]:
				res = tau - 1

		if res is None:
			res = 50

		return res, nmi

class Dataset:
	def __init__(self,dir_list):
		self.root_path_list = dir_list
		for dir in self.root_path_list:
			path_list = glob.glob(os.path.join(dir, "*.csv"), recursive=True)
			if len(path_list)==0:
				print(f"Cannot find any files inside {dir}")
				self.exp_path_list.extend(path_list)
        # self.exp_path_list = [p.replace('./', '') for p in self.exp_path_list if 'old' not in p]
		# print(self.exp_path_list)
		for path in self.exp_path_list:
			df = pd.read_csv(path)
			self.eigenworm_exp_list.append(np.array(df.loc[:,self.var_name]))
			[self.behavior_label_dict[k].append(df.loc[:,k].values) for k in self.behavior_label_name]
			self.stimulus_list.append(np.array(df.loc[:,'led']))

#%%
import itertools
import os

var_name = ['a_1','a_2','a_3','a_4','a_5','VelocityTailToHead']

root_path_list = ['data/141_ASH_02/']
exp_path_list = []
for dir in root_path_list:
	path_list = glob.glob(os.path.join(dir, "*.csv"), recursive=True)
	if len(path_list)==0:
		print(f"Cannot find any files inside {dir}")
	exp_path_list.extend(path_list)

	dataset = {}
	for i, name in enumerate(var_name):
		eigenworm_exp_list = []
		d = []
		for path in exp_path_list:
			df = pd.read_csv(path)
			d.append(np.array(df.loc[:,name]))
		d_1D = list(itertools.chain.from_iterable(d))

		dataset[name] = d_1D

#%%
# eigenworm_exp_list =  np.array(eigenworm_exp_list)
#
fig, axs = plt.subplots(6,2, figsize=(15,30))
plt_sample_size = 30000
for i, name in enumerate(var_name):
	takens = Takens(dataset[name],tau=10)
	emd = takens.reconstruct()
	tau = takens.tau

	axs[i,0].scatter(emd[0,:plt_sample_size],emd[1,:plt_sample_size],s=1,c=dataset["VelocityTailToHead"][:plt_sample_size])
	axs[i,1].plot(emd[0,:10000],emd[1,:10000],lw=0.2)
	axs[i,0].set_title(name+'\n'+'tau:'+str(tau))
	axs[i,1].set_title(name+'\n'+'tau:'+str(tau))

plt.show()

#%%
fig.savefig("tde.png",dpi=150)

#%%
position = np.array(df.loc[:,["posCentroidX","posCentroidY"]])
velocity = np.array(df.loc[:,["VelocityTailToHead"]])

#%%
# plt.plot(emd[0,:1000],emd[1,:1000],'gray',lw=0.1)
plt.scatter(emd[0,:60000],emd[2,:60000],s=1,c=dataset["VelocityTailToHead"][:60000])
plt.savefig('tde_velocity_all.png',dpi=150)

#%%