# スパイラルデータセットの可視化
import sys
# 親ディレクトリのインポート⇨dataset_nlpディレクトリのインポート
sys.path.append('..')
from dataset_nlp import spiral
import matplotlib.pyplot as plt

if __name__ == '__main__':
    x, t = spiral.load_data()
    print('x:', x.shape)
    print('t:', t.shape)

    N = 100
    CLS_NUM = 3
    markers = ['o', 'x', '^']
    for i in range(CLS_NUM):
        plt.scatter(x[i * N:(i + 1) * N, 0], x[i * N:(i + 1) * N, 1], s=40, marker=markers[i])
    plt.show()
    plt.close()


from utils.google_drive import download, upload

import os

if __name__ == '__main__':
    file_name = 'test.xlsx'
    file_save_dir = './result/google_drive_download/'

    f = os.path.join(file_save_dir, file_name)
    download.down('1Ko-qeL8zCk4AxKmT00Nw2pO_0uFRZ7d2OH_UhIXqxzM', f)  # 다운로드 파일

    f = os.path.join(file_save_dir, 'somefile.txt')  # 업로드 파일
    upload.up(f)


# -*- coding: utf-8 -*-
"""
Created on Sun Apr 25 21:53:17 2021

@author: GKSch
"""
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.patches import Ellipse
import matplotlib.transforms as transforms
import pickle
from scipy import integrate
from scipy.optimize import minimize_scalar

if __name__ == "__main__":

    ## INPUTS ##
    ## ====================================================================================================================================================================================================== ##
    # Define load and save paths
    combined_path = "../results/Energy"
    path = "../results/Energy"
    save_path = "../results/Energy"
    files = [["1.2_1", "1.2_2", "1.2_3", "1.2_4", "1.2_5", "1.2_6", "1.2_7", "1.2_8", "1.2_9", "1.2_10", "1.2_11", "1.2_12", "1.2_13", "1.2_14", "1.2_15", "1.2_16", "1.2_17", "1.2_18", "1.2_19", "1.2_20"],
             ["1.3_1", "1.3_2", "1.3_3", "1.3_4", "1.3_5", "1.3_6", "1.3_7", "1.3_8", "1.3_9", "1.3_10", "1.3_11", "1.3_12", "1.3_13", "1.3_14", "1.3_15", "1.3_16", "1.3_17", "1.3_18", "1.3_19", "1.3_20"],
             ["1.4_1", "1.4_2", "1.4_3", "1.4_4", "1.4_5", "1.4_6", "1.4_7", "1.4_8", "1.4_9", "1.4_10", "1.4_11", "1.4_12", "1.4_13", "1.4_14", "1.4_15", "1.4_16", "1.4_17", "1.4_18", "1.4_19", "1.4_20"],
             ["1.5_1", "1.5_2", "1.5_3", "1.5_4", "1.5_5", "1.5_6", "1.5_7", "1.5_8", "1.5_9", "1.5_10", "1.5_11", "1.5_12", "1.5_13", "1.5_14", "1.5_15", "1.5_16", "1.5_17", "1.5_18", "1.5_19", "1.5_20"],
             ["1.6_1", "1.6_2", "1.6_3", "1.6_4", "1.6_5", "1.6_6", "1.6_7", "1.6_8", "1.6_9", "1.6_10", "1.6_11", "1.6_12", "1.6_13", "1.6_14", "1.6_15", "1.6_16", "1.6_17", "1.6_18", "1.6_19", "1.6_20"],
             ["1.7_1", "1.7_2", "1.7_3", "1.7_4", "1.7_5", "1.7_6", "1.7_7", "1.7_8", "1.7_9", "1.7_10", "1.7_11", "1.7_12", "1.7_13", "1.7_14", "1.7_15", "1.7_16", "1.7_17", "1.7_18", "1.7_19", "1.7_20"]]
    colors = ['tab:blue', 'tab:orange', 'tab:green', 'tab:red', 'tab:purple', 'tab:brown']
    labels = ["1.2 mm/s", "1.3 mm/s", "1.4 mm/s", "1.5 mm/s", "1.6 mm/s", "1.7 mm/s"]

    ## DEFINE HELPER FUNCTIONS ##
    ## ====================================================================================================================================================================================================== ##
    # Load all previous simulations, store their trajectory, front shape, and energy consumption
    def get_err(T, a0, v_target):
        return abs(v_target - (0.813723-5.12462*a0+0.0202144*T+9.54447*a0*a0-0.1646*a0*T+0.000808146*T*T+0.463609*a0*a0*T-0.00295865*a0*T*T))

    def get_speed(T0, a0):
        return (0.813723-5.12462*a0+0.0202144*T0+9.54447*a0*a0-0.1646*a0*T0+0.000808146*T0*T0+0.463609*a0*a0*T0-0.00295865*a0*T0*T0)

    def confidence_ellipse(x, y, ax, n_std=3.0, facecolor='none', **kwargs):
        """
        Create a plot of the covariance confidence ellipse of *x* and *y*.

        Parameters
        ----------
        x, y : array-like, shape (n, )
            Input data.

        ax : matplotlib.axes.Axes
            The axes object to draw the ellipse into.

        n_std : float
            The number of standard deviations to determine the ellipse's radiuses.

        **kwargs
            Forwarded to `~matplotlib.patches.Ellipse`

        Returns
        -------
        matplotlib.patches.Ellipse
        """
        if x.size != y.size:
            raise ValueError("x and y must be the same size")

        cov = np.cov(x, y)
        pearson = cov[0, 1]/np.sqrt(cov[0, 0] * cov[1, 1])
        # Using a special case to obtain the eigenvalues of this
        # two-dimensionl dataset.
        ell_radius_x = np.sqrt(1 + pearson)
        ell_radius_y = np.sqrt(1 - pearson)
        ellipse = Ellipse((0, 0), width=ell_radius_x * 2, height=ell_radius_y * 2,
                          facecolor=facecolor, **kwargs)

        # Calculating the stdandard deviation of x from
        # the squareroot of the variance and multiplying
        # with the given number of standard deviations.
        scale_x = np.sqrt(cov[0, 0]) * n_std
        mean_x = np.mean(x)

        # calculating the stdandard deviation of y ...
        scale_y = np.sqrt(cov[1, 1]) * n_std
        mean_y = np.mean(y)

        transf = transforms.Affine2D() \
            .rotate_deg(45) \
            .scale(scale_x, scale_y) \
            .translate(mean_x, mean_y)

        ellipse.set_transform(transf + ax.transData)
        return ax.add_patch(ellipse)

    ## LOAD PRE-COMBINED DATA ##
    ## ====================================================================================================================================================================================================== ##
    # Load previously generated combined data
    print("Loading...")

    if combined_path != "":
        with open(combined_path+"/combined_data", 'rb') as file:
            data = pickle.load(file)

        for entry in data:
            globals()[entry] = data[entry]

    ## LOAD CONTROLLED SIMULATION DATA ##
    ## ====================================================================================================================================================================================================== ##
    # Load all previous simulations, store their trajectory, front shape, and energy consumption
    if combined_path == "":
        print("Loading simulation data...")

        ind = -1
        T0_list = []
        a0_list = []
        time_list = []
        front_speed_list = []
        target_list = []
        energy_list = []
        bulk_heating_energy_list = []
        ideal_energy_list = []

        for target in files:
            ind = ind + 1
            T0_list.append([])
            a0_list.append([])
            time_list.append([])
            front_speed_list.append([])
            target_list.append([])
            energy_list.append([])
            bulk_heating_energy_list.append([])
            ideal_energy_list.append([])

            for file in target:
                with open(path+"/"+file+"/output", 'rb') as load:
                    print(path+"/"+file+"/output")
                    dat = pickle.load(load)

                    # Store time and frotn speed data
                    time_list[ind].append(dat['time'])
                    front_speed_list[ind].append(dat['front_velocity'])

                    # Simulation constants
                    adiabatic_rxn_temp = dat['adiabatic_rxn_temp']
                    initial_temperature = dat['initial_temperature']
                    specific_heat = dat['specific_heat']
                    density = dat['density']
                    volume = dat['volume']
                    heat_transfer_coeff = dat['heat_transfer_coeff']
                    surface_area = dat['surface_area']
                    ambient_temp = dat['ambient_temp']
                    interpolated_temp_field = dat['interpolated_temp_field']
                    interpolated_cure_field = dat['interpolated_cure_field']

                    # Energy and power calculations
                    T0 = np.mean(interpolated_temp_field[0]) * (adiabatic_rxn_temp - initial_temperature) + initial_temperature
                    a0 = np.mean(interpolated_cure_field[0])
                    T0_list[ind].append(T0)
                    a0_list[ind].append(a0)
                    v_target = 1000.0*np.mean(dat['target'])
                    target_temp = minimize_scalar(get_err, args=(a0, v_target), bounds=(T0-273.15, 2.0*(T0-273.15)), method='bounded', options={'xatol':0.001}).x + 273.15
                    v_actual = 1000.0*np.mean(dat['front_velocity'][np.argmin(abs(dat['time']-5.0)):np.argmin(abs(dat['time']-25.0))])
                    actual_temp = minimize_scalar(get_err, args=(a0, v_actual), bounds=(T0-273.15, 2.0*(T0-273.15)), method='bounded', options={'xatol':0.001}).x + 273.15
                    power = dat['source_power'] + dat['trigger_power']
                    energy = integrate.trapz(power, x=dat['time'])
                    trigger_energy = integrate.trapz(dat['trigger_power'], x=dat['time'])
                    bulk_heating_energy = specific_heat*density*volume*(actual_temp - T0) + heat_transfer_coeff*surface_area*(actual_temp - ambient_temp)*(dat['time'][-1]-dat['time'][0]) + trigger_energy
                    ideal_energy = specific_heat*density*volume*(actual_temp - T0) + trigger_energy

                    # Store calculated energy and power data
                    target_list[ind].append(v_target)
                    energy_list[ind].append(energy)
                    bulk_heating_energy_list[ind].append(bulk_heating_energy)
                    ideal_energy_list[ind].append(ideal_energy)

        # Time data calculation and formatting
        time = np.mean(np.array(time_list),axis=(0,1))

        # Energy data calculation and formatting
        energy = np.array(energy_list)
        bulk_heating_energy = np.array(bulk_heating_energy_list)
        ideal_energy = np.array(ideal_energy_list)
        energy_reduction = 100.0*(bulk_heating_energy - energy) / bulk_heating_energy
        ideal_energy_reduction = 100.0*(bulk_heating_energy - ideal_energy) / bulk_heating_energy
        efficiency = energy_reduction/ideal_energy_reduction

        # Time reduction data calculation and formatting
        a0 = np.array(a0_list)
        T0 = np.array(T0_list)
        open_loop_speed = get_speed(T0-273.15, a0)
        closed_loop_speed = 1000.0*np.mean(np.array(front_speed_list)[:,:,np.argmin(abs(time-5.0)):np.argmin(abs(time-25.0))], axis=2)
        time_reduction = 100.0*open_loop_speed * (open_loop_speed**-1 - closed_loop_speed**-1)
        ideal_time_reduction = 100.0*open_loop_speed * (open_loop_speed**-1 - np.array(target_list)**-1)

        # Front speed data calculation and formatting
        mean_front_speed = np.mean(np.array(front_speed_list),axis=1)
        std_front_speed = np.std(np.array(front_speed_list),axis=1)
        targets = np.array(target_list)
        mean_targets = np.mean(np.array(target_list),axis=1)
        mean_front_speed_err = np.mean(closed_loop_speed - targets,axis=1)
        std_front_speed_err = np.std(closed_loop_speed - targets,axis=1)

    ## PLOT TRAJECTORIES ##
    ## ====================================================================================================================================================================================================== ##
    # Plot speed trajectory
    print("Plotting trajectories...")
    plt.clf()
    fig, ax = plt.subplots()
    fig.set_size_inches(8.5, 5.5)
    ax.set_title("(a) Mean controlled front speed over " + str(len(files[0]))+" simulations",fontsize=20, y=-0.25)
    ax.set_xlabel("Time [s]",fontsize=16)
    ax.set_ylabel("Front Speed [mm/s]",fontsize=16)
    markers = ['o', 'D', 'X', '^', 's', '*']
    ms = 0.0 * np.array([1.0, 1.0, 1.4, 1.1, 1.0, 1.7])
    colors_1 = ['g', 'g', 'g', 'g', 'g', 'g']
    colors_2 = ['r', 'r', 'r', 'r', 'r', 'r']
    lws = 2.0*np.ones(6)
    lines = []
    fills = []
    for i in range(len(mean_front_speed)):
        if i == 0:
            f2 = ax.fill_between(time, np.ones(time.shape)*mean_targets[i], 1000.0*mean_front_speed[i], where=np.ones(time.shape)*mean_targets[i]>1000.0*mean_front_speed[i], color='indigo', alpha=0.3, label='Below Target',lw=0)
            f1 = ax.fill_between(time, np.ones(time.shape)*mean_targets[i], 1000.0*mean_front_speed[i], where=np.ones(time.shape)*mean_targets[i]<1000.0*mean_front_speed[i], color='tab:orange', alpha=0.3, label='Above Target',lw=0)
        else:
            ax.fill_between(time, np.ones(time.shape)*mean_targets[i], 1000.0*mean_front_speed[i], where=np.ones(time.shape)*mean_targets[i]>1000.0*mean_front_speed[i], color='indigo', alpha=0.3,lw=0)
            ax.fill_between(time, np.ones(time.shape)*mean_targets[i], 1000.0*mean_front_speed[i], where=np.ones(time.shape)*mean_targets[i]<1000.0*mean_front_speed[i], color='tab:orange', alpha=0.3,lw=0)
        if i == 0:
            l1, = ax.plot(time, np.ones(time.shape)*mean_targets[i], color=colors_1[i], lw=lws[i], ls="--", label='Targets', marker=markers[i], markevery=50, mfc='k', mew=0.0, ms=ms[i])
        else:
            ax.plot(time, np.ones(time.shape)*mean_targets[i], color=colors_1[i], lw=lws[i], ls="--", marker=markers[i], markevery=50, mfc='k', mew=0.0, ms=ms[i])
        if i == 0:
            l2, = ax.plot(time, 1000.0*mean_front_speed[i],c=colors_2[i], lw=lws[i], label="Controlled Speeds", marker=markers[i], markevery=50, mfc='k', mew=0.0, ms=ms[i])
        else:
            ax.plot(time, 1000.0*mean_front_speed[i],c=colors_2[i], lw=lws[i], marker=markers[i], markevery=50, mfc='k', mew=0.0, ms=ms[i])

    ax.set_ylim(1.1, (np.max(1000.0*mean_front_speed+500.0*std_front_speed)//0.10+2.0)*0.10)
    ax.set_xlim(5,25)
    ax.tick_params(axis='x',  labelsize=16)
    ax.tick_params(axis='x', labelsize=16)
    plt.xticks(fontsize=16)
    plt.yticks(np.mean(targets,axis=1), fontsize=16)
    lines = ax.get_lines()
    legend1 = plt.legend(handles=[l1,l2], loc='upper left',fontsize=14)
    legend2 = plt.legend(handles=[f1,f2], loc='upper right',fontsize=14)
    ax.add_artist(legend1)
    ax.add_artist(legend2)
    plt.tight_layout()
    plt.savefig(save_path+"/speed.svg", dpi = 500)
    plt.close()

    # Plot speed aherence
    plt.clf()
    plt.gcf().set_size_inches(8.5, 5.5)
    plt.title("(b) Mean controlled error over " + str(len(files[0]))+" simulations",fontsize=20, y=-0.25)
    plt.xlabel("Target Front Speed [mm/s]",fontsize=16)
    plt.ylabel("Absolute Error [mm/s]",fontsize=16)
    plt.errorbar(mean_targets, mean_front_speed_err, yerr=std_front_speed_err, c='r',lw=2.0,elinewidth=2.0,marker="o",ms=7.0,capsize=4.0)
    plt.axhline(y=0, c='g', lw=0.75)
    plt.xticks(fontsize=16)
    plt.yticks(fontsize=16)
    plt.tight_layout()
    plt.savefig(save_path+"/speed_error.svg", dpi = 500)
    plt.close()

    ## PLOT ENERGIES ##
    ## ====================================================================================================================================================================================================== ##
    print("Plotting energies...")
    plt.clf()
    fig, ax = plt.subplots(figsize=(8.5, 5.5))
    plt.title("(c) Energy consumed by controller",fontsize=20, y=-0.25)
    ax.set_xlabel("Front Speed [mm/s]",fontsize=16)
    ax.set_ylabel("Energy Consumed [J]",fontsize=16)
    ax.plot(np.mean(closed_loop_speed,axis=1), np.mean(bulk_heating_energy,axis=1),c='k',lw=2.0)
    ax.plot(np.mean(closed_loop_speed,axis=1), np.mean(ideal_energy,axis=1),c='k',lw=2.0)
    for i in range(len(closed_loop_speed)):
        ax.scatter(closed_loop_speed[i], energy[i], c='r', marker=".", s=2.0)
        confidence_ellipse(closed_loop_speed[i], energy[i], ax, n_std=3, edgecolor='r', lw=2.0)
    ax.tick_params(axis='x',labelsize=16)
    ax.tick_params(axis='y',labelsize=16)
    plt.tight_layout()
    plt.savefig(save_path+"/energy.svg", dpi = 500)
    plt.close()

    # Plot energy savings as function of cure time reduction
    plt.clf()
    fig, ax = plt.subplots(figsize=(8.5, 5.5))
    plt.title("(d) Energy used by controller compared to bulk heating",fontsize=20.0, y=-0.25)
    ax.set_xlabel("Cure Time Reduction Compared to Uncontrolled [%]",fontsize=16)
    ax.set_ylabel("Energy Reduction Compared to Bulk Heating [%]",fontsize=16, y=0.39)
    ax.plot(np.mean(ideal_time_reduction,axis=1), np.mean(ideal_energy_reduction,axis=1), c='k', lw=2.0, label="Ideal Local Heating")
    for i in range(len(time_reduction)):
        if i==0:
            ax.scatter(time_reduction[i], energy_reduction[i], c='r', marker=".", s=2.0, label='Controlled')
        else:
            ax.scatter(time_reduction[i], energy_reduction[i], c='r', marker=".", s=2.0)
        confidence_ellipse(time_reduction[i], energy_reduction[i], ax, n_std=3, edgecolor='r', lw=2.0)
    ax.tick_params(axis='x', labelsize=16)
    ax.tick_params(axis='y', labelsize=16)
    ax.set_ylim(0, 70)
    ax.legend(loc='upper right',fontsize=14)
    plt.tight_layout()
    plt.savefig(save_path+"/energy_saving.svg", dpi = 500)
    plt.close()

    ## SAVE ALL DATA USED TO GENERATE GRAPHS ##
    ## ====================================================================================================================================================================================================== ##
    print("Saving...")
    data = {
        'files' : files,
        'colors' : colors,
        'labels' : labels,
        'a0' : a0,
        'closed_loop_speed' : closed_loop_speed,
        'efficiency' : efficiency,
        'energy' : energy,
        'energy_reduction' : energy_reduction,
        'ideal_energy' : ideal_energy,
        'ideal_energy_reduction' : ideal_energy_reduction,
        'ideal_time_reduction' : ideal_time_reduction,
        'mean_front_speed' : mean_front_speed,
        'mean_front_speed_err' : mean_front_speed_err,
        'mean_targets' : mean_targets,
        'open_loop_speed' : open_loop_speed,
        'bulk_heating_energy' : bulk_heating_energy,
        'std_front_speed' : std_front_speed,
        'std_front_speed_err' : std_front_speed_err,
        'T0' : T0,
        'targets' : targets,
        'time' : time,
        'time_reduction' : time_reduction
    }
    with open(save_path + "/combined_data", 'wb') as file:
            pickle.dump(data, file)

    print("Done!")


import random
import math

class Player:
    def __init__(self, move_function):
        """
        Class to handle player
        :param move_function: Reference to function which determines which move to make next
        """

        self.player_index = 0
        self.game_manager = None
        self.move_function = move_function

        # Information known about other players (ignore element corresponding to self)
        self.number_of_resource_cards = [0, 0, 0, 0]
        self.number_of_development_cards = [0, 0, 0, 0]

        """
        Power Cards:

        - self.development_cards is a list of number of each type of card
         - List order is: [Knight, Take 2 Resources, Construct 2 Roads, Monopoly, Victory Point]]
        """
        self.development_cards = [0] * 5

        """
        Resources:

        - self.resource_cards is a list of number of each type of class
        - list order is: [Wheat, Stone, Brick, Sheep, Wood]
        - self.resource_dice_rolls is a list of which rolls get each resource
        """
        self.resource_cards = [0] * 5

        """
        Initialise road, settlement and city pieces:

         - self.building_pieces is list of quantities of each type of piece
         - List is in order: [Road, Settlement, City]
        """
        self.building_pieces = [15, 5, 4]

        # List of best trade deals via ports / 4:1 for each resource
        self.best_trade_type = [4, 4, 4, 4, 4]

    def setup(self):
        """
        Defines player logic for set-up phase of game (Turn 0)
        :return: node_index of settlement, edge_index of road
        """
        print('\nPlayer ' + str(self.player_index) + ':')
        print('Placing settlement')
        # Evaluate network to get output vector and dictionary
        network_output, vector_output = self.evaluateNetwork(self.assembleInputVector())
        settlements_vector = network_output['Settlements']

        # Whilst settlement hasn't been placed, find maximum node in settlements_vector and try and build there. If can't, choose next best
        settlement_built = False
        nodes_tested = 0
        while not settlement_built:
            nodes_tested += 1
            desired_node = settlements_vector.index(max(settlements_vector))
            if self.game_manager.buildSettlement(self, desired_node):
                settlement_built = True
            else:
                settlements_vector[desired_node] = 0

            if nodes_tested == 53:
                break

        print('Placing road')
        # Evaluate network to get output vector and dictionary
        network_output, vector_output = self.evaluateNetwork(self.assembleInputVector())
        roads_vector = network_output['Roads']

        # Get list of connected edges which player has built settlement on
        available_edges = self.game_manager.game_board.nodes[desired_node].connected_edges

        # Find edge from available edges with highest value of roads vector
        road_location = available_edges[0].ID
        max_output = roads_vector[road_location]
        for edge in available_edges:
            if roads_vector[edge.ID] > max_output:
                road_location = edge.ID
                max_output = roads_vector[edge.ID]

        self.game_manager.buildRoad(self, road_location)

        return desired_node, road_location

    def action(self):
        """
        Wrapper around controller for player. Continuously makes decisions until pass decision made
        """

        # Evaluate network and return decision
        network_output, vector_output = self.evaluateNetwork(self.assembleInputVector())

        # Go through output from decision corresponding to highest output to lowest until valid move found
        while True:

            # Find highest decision
            key, element = getHighestAcrossDictionaries(network_output)

            # Check for ending turn
            if key == 'EndTurn':
                return
            else:
                # If not ending turn, attempt action or set corresponding element to 0 if not possible
                self.game_manager.action_functions[key](self, element)
                network_output[key][element] = 0

        # If not returned, call action again to make next decision
        self.action()

    def endGame(self, points):
        pass

    def updateOtherPlayers(self):
        pass

    def assembleInputVector(self):
        """
        Assembles input vector for network based on current state of board
        :return: input vector
        """
        # Assemble all input values
        board_vector = self.game_manager.game_board.getInputValues()
        return board_vector + self.number_of_resource_cards + self.number_of_development_cards + self.development_cards + self.resource_cards

    def evaluateNetwork(self, input_vector):
        return self.move_function(input_vector)

    def hasResources(self, resources):
        """
        Checks player has resources
        :param resources: Vector of quantity of resources required in order [Wheat, Stone, Brick, Sheep, Wood]
        :return: Bool - True if player has enough resources
        """
        if (self.resource_cards[0] >= resources[0]) and (self.resource_cards[1] >= resources[1]) and (
                self.resource_cards[2] >= resources[2]) and (self.resource_cards[3] >= resources[3]) and (
                self.resource_cards[4] >= resources[4]):
            return True

        return False

    def discardHalfCards(self):
        """
        Currently discards random choice of cards
        """

        # Get number of cards to discard
        total_cards_in_hand = sum(self.resource_cards)
        number_to_discard = math.ceil(total_cards_in_hand / 2.0)

        # Discard cards
        while number_to_discard != 0:
            index_to_discard = random.randint(0, 4)
            if self.resource_cards[index_to_discard] != 0:
                self.resource_cards[index_to_discard] -= 1
                number_to_discard -= 1

    def moveRobber(self):
        """
        Moves robber and takes card from player
        """

        # Now random!
        self.game_manager.robber_location = random.randint(0, 17)

    def choosePlayerToStealFrom(self, list_of_players):
        """
        Choose which player to steal from when player must choose to steal resource card from another player (ie robber)
        """

        # Currently random
        random.shuffle(list_of_players)
        return list_of_players[0]

def getHighestAcrossDictionaries(output_dictionary):
    """
    Given a dictionary of lists, find the dictionary key and element index of the highest valued element in the dictionary
    :param output_dictionary: Dictionary to search
    :return: key - Key of dictionary with highest valued element, index - index of highest valued element in key
    """
    max_key = None
    element_index = None
    current_max = 0

    # Check through each key in dictionary
    for key in output_dictionary.keys():

        # Return index of max value in key
        max_value_in_key = max(output_dictionary[key])
        index_of_max_value_in_key = output_dictionary[key].index(max_value_in_key)

        # If larger than existing largest, update max_key and element_index
        if max_value_in_key > current_max:
            max_key = key
            element_index = index_of_max_value_in_key
            current_max = max_value_in_key

    return max_key, element_index

def randomAction(inputVector):
    """
    Sample wrapper function for network
    :param inputVector: vector containing all player knowledge of the game state
    :return: dictionary made up of vectors containing the choices made by the network broken up by category for convenience
    """

    # Generate random values for choices of settlement placement
    settlements = [0] * 54
    cities = [0] * 54
    for i in range(54):
        settlements[i] = random.uniform(0, 1)
        cities[i] = random.uniform(0, 1)

    # Generate random values for choices of settlement placement
    roads = [0] * 72
    for i in range(72):
        roads[i] = random.uniform(0, 1)

    # Trading
    trade_with_game = [0] * 20
    for i in range(20):
        trade_with_game[i] = random.uniform(0, 1)

    # Ending turn
    end_turn = [random.uniform(0, 1)]

    # Purchasing development card
    buy_development_card = [random.uniform(0, 1)]

    # Use development card
    knight = [random.uniform(0, 1)]

    output_dictionary = {'Settlements': settlements, 'Cities': cities, 'Roads': roads,
                         'EndTurn': end_turn, 'TradeWithGame': trade_with_game,
                         'BuyDevelopmentCard': buy_development_card,
                         'Knight': knight}
    output_vector = settlements + cities + roads + end_turn + trade_with_game + buy_development_card + knight

    return output_dictionary, output_vector


import importlib
import torch
import numpy as np
import random
from torch.utils.data import DataLoader, Subset

class PytorchDataset:
    """Base class defining pytorch datasets."""
    def __init__(self, dataset_name) -> None:
        """ Constructor method.

            Parameters:
            dataset_name    (str): Name of dataset to use.
        """
        module = importlib.import_module(f"torchvision.datasets")
        self.data_class = getattr(module, dataset_name)
        self.client_data_indices = []
        self.train_data = None
        self.test_data = None
        self.public_data = None
        self.num_workers = 0

    def _split_train_public(self, public_fraction, transform, split=None):
        """
        """
        if split is None:
            train_data = self.data_class(
                root='data',
                train=True,
                transform=transform,
                download=True)
        else:
            train_data = self.data_class(
                root='data',
                train=True,
                transform=transform,
                download=True,
                split=split)
            train_data.targets = train_data.targets - 1

        if not torch.is_tensor(train_data.targets):
            train_data.targets = torch.tensor(train_data.targets)

        idx_split = int(len(train_data) * public_fraction)

        return Subset(train_data, np.arange(idx_split)), Subset(train_data, np.arange(idx_split, len(train_data)))

    def generate_client_data(self, n_clients, distribution, alpha):
        """ Generate iid client data or non-iid by sampling from Dirichlet distribution.

            Parameters:
            n_clients       (int): Number of clients.
            distribution    (str): Indicator to sample iid or non-iid.
            alpha           (float): Concentration parameter for Dirichlet distribution.
        """
        labels = np.array([self.train_data[i][1] for i in range(len(self.train_data))])
        n_classes = len(np.unique(labels))
        partition_matrix = np.ones((n_classes, n_clients))

        # iid: Sample from each class until no samples left.
        if distribution == "iid":
            partition_matrix /= n_clients
            local_sets_indices = [np.array([], dtype=int) for _ in range(n_clients)]
            clients_iter = np.arange(n_clients)

            for i in range(n_classes):
                class_indices = np.where(labels == i)[0]

                clients_iter = clients_iter[::-1]
                samples_left = True
                while samples_left:
                    for j in clients_iter:
                        if len(class_indices) == 0:
                            samples_left = False
                            break
                        else:
                            sample_idx = np.random.choice(len(class_indices))
                            local_sets_indices[j] = np.append(local_sets_indices[j], self.train_data.indices[class_indices[sample_idx]])
                            class_indices = np.delete(class_indices, sample_idx)

        # non-iid: Sample from dirichlet distribution.
        else:
            class_indices = []
            for i in range(n_classes):
                class_indices.append(np.array(range(len(labels)))[labels == i])
            valid_pm = False
            while not valid_pm:
                partition_matrix = np.random.dirichlet((alpha, )*n_clients, n_classes)
                valid_pm = all(np.sum(partition_matrix, axis=0) > 0.01)

            local_sets_indices = [[] for _ in range(n_clients)]
            for each_class in range(n_classes):
                sample_size = len(class_indices[each_class])
                for client in range(n_clients):
                    np.random.shuffle(class_indices[each_class])
                    local_size = int(partition_matrix[each_class, client] * sample_size)
                    local_sets_indices[client] += list(self.train_data.indices[class_indices[each_class][:local_size]])
                    class_indices[each_class] = class_indices[each_class][local_size:]

        self.local_sets_indices = local_sets_indices

    def get_train_data_loaders(self, batch_size):
        """ Get list of client training data loaders.

            Parameters:
            n_clients       (int): Number of clients.
            distribution    (str): iid/non-iid distributed data.
            alpha           (float): Concentration parameter for dirichlet distribution.
            batch_size      (int): Batch size for loading training data.

            Returns List[torch.utils.data.DataLoader]
        """
        client_data_loaders = []
        for client_indices in self.local_sets_indices:
                np.random.shuffle(client_indices)
                client_data_loaders.append(DataLoader(Subset(self.train_data.dataset, client_indices), batch_size, num_workers=self.num_workers))
        return client_data_loaders

    def get_test_data_loader(self, batch_size):
        """ Get test data loader.

            Parameters:
            batch_size      (int): Batch size for loading test data.
        """
        return DataLoader(self.test_data, batch_size, num_workers=self.num_workers)

    def get_public_data_loader(self, batch_size):
        """ Get test data loader.

            Parameters:
            batch_size      (int): Batch size for loading test data.
        """
        return DataLoader(self.public_data, batch_size, num_workers=self.num_workers)

    def get_local_sets_indices(self):
        """
        """
        return self.local_sets_indices

    def get_test_indices(self):
        """
        """
        return self.test_data.indices

    def get_public_indices(self):
        """
        """
        return self.public_data.indices

    def set_local_sets_indices(self, local_sets_indices):
        """
        """
        self.local_sets_indices = local_sets_indices

    def set_test_indices(self, test_indices):
        """
        """
        self.test_data.indices = test_indices

    def set_public_indices(self, public_indices):
        """
        """
        self.public_data.indices = public_indices


"""trt_mtcnn.py

This script demonstrates how to do real-time face detection with
Cython wrapped TensorRT optimized MTCNN engine.
"""

import sys
import time
import argparse
import json

import cv2
from utils.camera import add_camera_args, Camera
from utils.display import open_window, set_display, show_fps
from utils.mtcnn import TrtMtcnn

WINDOW_NAME = 'TrtMtcnnDemo'
WINDOW_NAME2 = 'TrtMtcnnExtracted'
BBOX_COLOR = (0, 255, 0)  # green

import paho.mqtt.client as mqtt
LOCAL_MQTT_HOST="tx2broker"
LOCAL_MQTT_PORT=1883
LOCAL_MQTT_TOPIC="/facedetect/local/faces"
keepalive=1200 #set MQTT time out to 20 minutes

def parse_args():
    """Parse input arguments."""
    desc = ('Capture and display live camera video, while doing '
            'real-time face detection with TrtMtcnn on Jetson '
            'Nano')
    parser = argparse.ArgumentParser(description=desc)
    # print(f"desc: {desc}")
    parser = add_camera_args(parser)
    parser.add_argument('--minsize', type=int, default=40,
                        help='minsize (in pixels) for detection [40]')
    args = parser.parse_args()
    # print(f"args: {args}")
    return args

def show_faces(img, boxes, landmarks):
    """Draw bounding boxes and face landmarks on image."""
    for bb, ll in zip(boxes, landmarks):
        x1, y1, x2, y2 = int(bb[0]), int(bb[1]), int(bb[2]), int(bb[3])
        cv2.rectangle(img, (x1, y1), (x2, y2), BBOX_COLOR, 2)
        send_face(img[y1:y2, x1:x2, : ])
        for j in range(5):
            cv2.circle(img, (int(ll[j]), int(ll[j+5])), 2, BBOX_COLOR, 2)
    return img

def send_face(img):
    # Display the extracted face on the window
    cv2.imshow(WINDOW_NAME2, img)

    # first member is a tuple showing the resolution of the captured face
    json_string = json.dumps( ( img.shape, img.tolist()) )
    local_mqttclient.publish(LOCAL_MQTT_TOPIC, payload=json_string, qos=0, retain=False)

    return img

def loop_and_detect(cap, mtcnn, minsize):
    """Continuously capture images from camera and do face detection."""
    full_scrn = False
    fps = 0.0
    tic = time.time()

    fps_count=10

    while True:
        if cv2.getWindowProperty(WINDOW_NAME, 0) < 0:
            break
#         img = cam.read()
        ret,img = cap.read()
        if img is not None:
            dets, landmarks = mtcnn.detect(img, minsize=minsize)
            print('{} face(s) found'.format(len(dets)))
            img = show_faces(img, dets, landmarks)
            img = show_fps(img, fps)
            cv2.imshow(WINDOW_NAME, img)
            toc = time.time()
            curr_fps = 1.0 / (toc - tic)
            # calculate an exponentially decaying average of fps number
            fps = curr_fps if fps == 0.0 else (fps*0.95 + curr_fps*0.05)
            tic = toc
        fps_count -= 1
        if fps_count == 0:
            print(f"frames: {fps}")
            fps_count = 10
        key = cv2.waitKey(1)
        if key == 27:  # ESC key: quit program
            break
        elif key == ord('F') or key == ord('f'):  # Toggle fullscreen
            full_scrn = not full_scrn
            set_display(WINDOW_NAME, full_scrn)

def main():
    args = parse_args()

    cap = cv2.VideoCapture(0)

    # Attach to messaging
    global local_mqttclient
    local_mqttclient = mqtt.Client("facedetect")
    local_mqttclient.connect(LOCAL_MQTT_HOST, LOCAL_MQTT_PORT,keepalive)

    mtcnn = TrtMtcnn()

    open_window(WINDOW_NAME, args.image_width, args.image_height,
                'Image with Identified Faces')
    open_window(WINDOW_NAME2, int(args.image_width / 4) , int(args.image_height / 4),
                'Extracted Face')
    loop_and_detect(cap, mtcnn, args.minsize)

    cv2.destroyAllWindows()

    del(mtcnn)

if __name__ == '__main__':
    main()


"""Config flow for Google Photos integration."""
from __future__ import annotations

from collections.abc import Mapping
import logging
from typing import Any, List
import voluptuous as vol

from google.oauth2.credentials import Credentials
from googleapiclient.discovery import build
from googleapiclient.errors import HttpError as GoogleApiError

from homeassistant import config_entries
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import CONF_ACCESS_TOKEN, CONF_TOKEN
from homeassistant.core import callback
from homeassistant.data_entry_flow import FlowResult
from homeassistant.helpers import config_entry_oauth2_flow

from .api_types import PhotosLibraryService, Album
from .const import (
    DEFAULT_ACCESS,
    DOMAIN,
    CONF_WRITEMETADATA,
    WRITEMETADATA_DEFAULT_OPTION,
    CONF_ALBUM_ID,
    CONF_ALBUM_ID_FAVORITES,
)

class OAuth2FlowHandler(
    config_entry_oauth2_flow.AbstractOAuth2FlowHandler, domain=DOMAIN
):
    """Config flow to handle Google Photos OAuth2 authentication."""

    DOMAIN = DOMAIN
    VERSION = 2

    reauth_entry: ConfigEntry | None = None

    @property
    def logger(self) -> logging.Logger:
        """Return logger."""
        return logging.getLogger(__name__)

    @property
    def extra_authorize_data(self) -> dict[str, Any]:
        """Extra data that needs to be appended to the authorize url."""
        return {
            "scope": " ".join(DEFAULT_ACCESS),
            # Add params to ensure we get back a refresh token
            "access_type": "offline",
            "prompt": "consent",
        }

    async def async_step_reauth(self, entry_data: Mapping[str, Any]) -> FlowResult:
        """Perform reauth upon an API authentication error."""
        self.reauth_entry = self.hass.config_entries.async_get_entry(
            self.context["entry_id"]
        )
        return await self.async_step_reauth_confirm()

    async def async_step_reauth_confirm(
        self, user_input: dict[str, Any] | None = None
    ) -> FlowResult:
        """Confirm reauth dialog."""
        if user_input is None:
            return self.async_show_form(step_id="reauth_confirm")
        return await self.async_step_user()

    async def async_oauth_create_entry(self, data: dict[str, Any]) -> FlowResult:
        """Create an entry for the flow, or update existing entry."""
        if self.reauth_entry:
            self.hass.config_entries.async_update_entry(self.reauth_entry, data=data)
            await self.hass.config_entries.async_reload(self.reauth_entry.entry_id)
            return self.async_abort(reason="reauth_successful")

        credentials = Credentials(data[CONF_TOKEN][CONF_ACCESS_TOKEN])

        def _get_profile() -> dict[str, Any]:
            """Get profile from inside the executor."""
            lib = build("oauth2", "v2", credentials=credentials)
            userinfo = lib.userinfo().get().execute()  # pylint: disable=no-member
            return userinfo

        def _check_photoslibrary_access() -> PhotosLibraryService:
            lib = build(
                "photoslibrary",
                "v1",
                credentials=credentials,
                static_discovery=False,
            )
            albums = (
                lib.albums().list(pageSize=1).execute()  # pylint: disable=no-member
            )
            return albums

        try:
            (await self.hass.async_add_executor_job(_check_photoslibrary_access))
            email = (await self.hass.async_add_executor_job(_get_profile))["email"]
        except GoogleApiError as ex:
            return self.async_abort(
                reason="access_error", description_placeholders={"reason": ex.reason}
            )

        await self.async_set_unique_id(email)
        self._abort_if_unique_id_configured()

        options = dict()
        options[CONF_ALBUM_ID] = [CONF_ALBUM_ID_FAVORITES]
        return self.async_create_entry(title=email, data=data, options=options)

    @staticmethod
    @callback
    def async_get_options_flow(
        config_entry: config_entries.ConfigEntry,
    ) -> OptionsFlowHandler:
        """Get the options flow for this handler."""
        return OptionsFlowHandler(config_entry)

class OptionsFlowHandler(config_entries.OptionsFlow):
    """Handle a option flow for google photos."""

    def __init__(self, config_entry: config_entries.ConfigEntry) -> None:
        """Initialize options flow."""
        self.config_entry = config_entry

    @property
    def logger(self) -> logging.Logger:
        """Return logger."""
        return logging.getLogger(__name__)

    async def _get_albumselect_schema(self) -> vol.Schema:
        """Return album selection form"""

        credentials = Credentials(self.config_entry.data[CONF_TOKEN][CONF_ACCESS_TOKEN])

        def get_photoslibrary() -> PhotosLibraryService:
            return build(
                "photoslibrary",
                "v1",
                credentials=credentials,
                static_discovery=False,
            )

        def get_albums() -> List[Album]:
            service: PhotosLibraryService = get_photoslibrary()
            albums = service.albums()  # pylint: disable=no-member
            fields = "albums(id,title,mediaItemsCount),nextPageToken"
            request = albums.list(pageSize=50, fields=fields)
            album_list = []
            while request is not None:
                result = request.execute()
                album_list = album_list + result.get("albums", [])
                request = albums.list_next(request, result)

            sharedAlbums = service.sharedAlbums()  # pylint: disable=no-member
            fields = "sharedAlbums(id,title,mediaItemsCount),nextPageToken"
            request = sharedAlbums.list(pageSize=50, fields=fields)
            while request is not None:
                result = request.execute()
                album_list = album_list + result.get("sharedAlbums", [])
                request = sharedAlbums.list_next(request, result)
            return list(filter(lambda a: ("id" in a and "title" in a), album_list))

        albums = await self.hass.async_add_executor_job(get_albums)
        album_selection = dict({CONF_ALBUM_ID_FAVORITES: "Favorites"})
        for album in albums:
            album_selection[album.get("id")] = "{0} ({1} items)".format(
                album.get("title"), album.get("mediaItemsCount", "?")
            )

        return vol.Schema(
            {
                vol.Required(CONF_ALBUM_ID): vol.In(album_selection),
            }
        )

    async def async_step_init(self, user_input=None):
        """Handle options flow."""
        return self.async_show_menu(
            step_id="init",
            menu_options=["albumselect", "settings"],
            description_placeholders={
                "model": "Example model",
            },
        )

    async def async_step_albumselect(
        self, user_input: dict[str, Any] = None
    ) -> FlowResult:
        """Set the album used."""
        self.logger.debug(
            "async_albumselect_confirm called with user_input: %s", user_input
        )

        # user input was not provided.
        if user_input is None:
            data_schema = await self._get_albumselect_schema()
            return self.async_show_form(step_id="albumselect", data_schema=data_schema)

        album_id = user_input[CONF_ALBUM_ID]
        albums = self.config_entry.options.get(CONF_ALBUM_ID, []).copy()
        if album_id not in albums:
            albums.append(album_id)
        data = self.config_entry.options.copy()
        data.update({CONF_ALBUM_ID: albums})
        return self.async_create_entry(title="", data=data)

    async def async_step_settings(self, user_input=None):
        """Handle options flow."""
        if user_input is not None:
            data = self.config_entry.options.copy()
            data.update(user_input)
            return self.async_create_entry(title="", data=data)

        data_schema = vol.Schema(
            {
                vol.Optional(
                    CONF_WRITEMETADATA,
                    default=self.config_entry.options.get(
                        CONF_WRITEMETADATA, WRITEMETADATA_DEFAULT_OPTION
                    ),
                ): bool,
            }
        )
        return self.async_show_form(step_id="settings", data_schema=data_schema)


# File Handle as a Sequence

file = open('test.txt')
for line in file:
    print(line)

fhand = open('test.txt')
inp = fhand.read()  # Reads the whole file into a var that can be iterated over etc.

print(len(inp))
for char in inp:
    print(char)

# print(inp[:20])

# Searching through a file w/ continue

file = open('test.txt')
for line in file:
    line = line.rstrip()  # The newline char is considered as whitespace so if we .rstrip() we remove the whitespace
    if not line.startswith('line'):  # If the line it reads does not start with 'line' it is skipped
        continue
    print(line)


import os
from imutils import paths
from tensorflow.keras.models import load_model
import pickle
import numpy as np
import base64
from imageio import imread
import API_KERAS.processing_lab as processing_lab
from tqdm import tqdm
import cv2

CAPTCHA_IMAGE_FOLDER = r"C:\Users\DANIEL BEMERGUY\OneDrive\CaptchaML\Data\test_set\7"
MODEL_FILENAME = r"C:\Users\DANIEL BEMERGUY\OneDrive\CaptchaML\API_KERAS\result_model_letter.h5"
MODEL_LABELS_FILENAME = r"C:\Users\DANIEL BEMERGUY\OneDrive\CaptchaML\API_KERAS\model_labels.dat"

# Load up the model labels (so we can translate model predictions to actual letters)
with open(MODEL_LABELS_FILENAME, "rb") as f:
    lb = pickle.load(f)

# Load the trained neural network
model = load_model(MODEL_FILENAME)

# captcha_image_files = list(paths.list_images(CAPTCHA_IMAGE_FOLDER))

def predict_text(path):
    img = cv2.imread(path)
    img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
    predictions = []
    img = processing_lab.model2(img)
    for letter in img:
        # rgb = cv2.cvtColor(letter, cv2.COLOR_BGR2RGB)
        # Re-size the letter image to 20x20 pixels to match training data
        letter_image = processing_lab.resize_to_fit(letter, 20, 20)

        # Turn the single image into a 4d list of images to make Keras happy
        letter_image = np.expand_dims(letter_image, axis=2)
        letter_image = np.expand_dims(letter_image, axis=0)

        # Ask the neural network to make a prediction
        prediction = model.predict(letter_image)

        # Convert the one-hot-encoded prediction back to a normal letter
        letter = lb.inverse_transform(prediction)[0]
        predictions.append(letter)

        # Get captcha's text
        captcha_text = "".join(predictions)
        captcha_text = captcha_text.replace("_","")
        # filename = name1.filename
        # Find real captcha name
        # end = filename.rfind('.')  # last occurence of '.'
        # real = filename[:end]
    return str(captcha_text)

# teste = predict_text(captcha_image_files[0]) == '010E3'
# print('Predicted:',teste)
# print('Real:',captcha_image_files[0])

'''
1 = caxias
2 = barueri
3 = niteroi
4 = aparecido de goiania
'''
correct = 0
folder = 7

path = r"C:\Users\DANIEL BEMERGUY\OneDrive\CaptchaML\Data\test_set\{}".format(folder)
captcha_image_files = list(paths.list_images(path))
# print(captcha_image_files)
wrongs = []
for file in tqdm(captcha_image_files):
    name = os.path.basename(file).split('.')[0]
    predicted = predict_text(file)
    if predicted == name: #check right predictions
        correct += 1
    if predicted != name: #check wrong predictions
        wrongs.append(os.path.basename(file).split('.')[0])
print('Acc:',correct/len(captcha_image_files)*100)
print("wrong captchas:",len(wrongs))
print(wrongs)


import pandas as pd  # for data manipulation
from django.conf import settings
from pathlib import Path

import numpy as np
from sklearn import svm, metrics, datasets
from sklearn.utils import Bunch
from sklearn.model_selection import GridSearchCV, train_test_split

from skimage.io import imread
from skimage.transform import resize
import skimage

def load_image_files(container_path, dimension=(104, 104)):
    image_dir = Path(container_path)
    folders = [directory for directory in image_dir.iterdir() if directory.is_dir()]
    categories = [fo.name for fo in folders]
    descr = "A Rice Disease detection using Machine Learning"
    images = []
    flat_data = []
    target = []
    for i, direc in enumerate(folders):
        for file in direc.iterdir():
            img = skimage.io.imread(file)
            img_resized = resize(img, dimension, anti_aliasing=True, mode='reflect')
            flat_data.append(img_resized.flatten())
            images.append(img_resized)
            target.append(i)

    flat_data = np.array(flat_data)
    target = np.array(target)
    images = np.array(images)
    return Bunch(data=flat_data,
                 target=target,
                 target_names=categories,
                 images=images,
                 DESCR=descr)

path = settings.MEDIA_ROOT + "//" + "rice_leaf_diseases"
image_dataset = load_image_files(path)  # Load here dataset
print(image_dataset.target_names)

X_train, X_test, y_train, y_test = train_test_split(image_dataset.data, image_dataset.target, test_size=0.3,
                                                    random_state=109)
param_grid = [
    {'C': [1, 10, 100, 1000], 'kernel': ['linear']},
    {'C': [1, 10, 100, 1000], 'gammatt': [0.001, 0.0001], 'kernel': ['rbf']},
]

def process_randomForest():
    from sklearn.ensemble import RandomForestClassifier
    clf = RandomForestClassifier()
    clf.fit(X_train, y_train)
    y_pred = clf.predict(X_test)
    # import pickle
    # # now you can save it to a file
    # with open(r'rice_pred.pkl', 'wb') as f:
    #     pickle.dump(clf, f)
    print(clf.score(X_test, y_test))
    rf_report = metrics.classification_report(y_test, y_pred,output_dict=True)
    print("Classification report for - \n{}:\n{}\n".format(clf, rf_report))
    return rf_report

def process_decesionTree():
    from sklearn.tree import DecisionTreeClassifier
    clf = DecisionTreeClassifier()
    clf.fit(X_train, y_train)
    y_pred = clf.predict(X_test)
    print(clf.score(X_test, y_test))
    dt_report = metrics.classification_report(y_test, y_pred,output_dict=True)
    print("Classification report for - \n{}:\n{}\n".format(clf, dt_report))
    return dt_report

def process_naiveBayes():
    from sklearn.naive_bayes import GaussianNB
    clf = GaussianNB()
    clf.fit(X_train, y_train)
    y_pred = clf.predict(X_test)
    print(clf.score(X_test, y_test))
    nb_report = metrics.classification_report(y_test, y_pred,output_dict=True)
    print("Classification report for - \n{}:\n{}\n".format(clf, nb_report))
    return nb_report

def process_gradientBoosting():
    from sklearn.ensemble import GradientBoostingClassifier
    clf = GradientBoostingClassifier()
    clf.fit(X_train, y_train)
    y_pred = clf.predict(X_test)
    print(clf.score(X_test, y_test))
    gb_report = metrics.classification_report(y_test, y_pred,output_dict=True)
    print("Classification report for - \n{}:\n{}\n".format(clf, gb_report))
    return gb_report


import machine
import ili9XXX
import lvgl as lv
from machine import Pin,UART,PWM
import time
import gc
import device

lv.init()

uart = UART(2,9600,tx=1,rx=2)
bl=PWM(Pin(36), freq=5000, duty_u16=65535)

dispp = lv.disp_get_default()
theme = lv.theme_default_init(dispp, lv.palette_main(lv.PALETTE.BLUE), lv.palette_main(lv.PALETTE.RED), True, lv.font_default())
dispp.set_theme(theme)
#----------------------------SCREEN_SETTINGS--------------------------------------
def Button2_eventhandler(event_struct):
    event = event_struct.code
    if event == lv.EVENT.CLICKED and True:
        lv.scr_load_anim(ui_Screen2, lv.SCR_LOAD_ANIM.FADE_ON, 300, 0,False)
        screen_group(2)
    return

def slider_event_cb(evt):
    slider = evt.get_target()
    bl.duty_u16(int(slider.get_value())*6550)

def event_dropdown(e):
    code = e.get_code()
    obj = e.get_target()
    if code == lv.EVENT.VALUE_CHANGED:
        option1 = [9600,57600,14400,115200]
        option2 = [8,7,9]
        option3 = [1,2]
        o1=option1[ui_DDbaudrate.get_selected()]
        o2=option2[ui_DDdatabits.get_selected()]
        o3=option3[ui_DDstopbits.get_selected()]
        print(o1,o2,o3)
#         uart.deinit()
#         uart = UART(2, 9600)
        uart.init(o1, bits=o2, parity=None, stop=o3)

ui_Screen1 = lv.obj()

ui_DDbaudrate = lv.dropdown(ui_Screen1)
ui_DDbaudrate.set_options("9600\n57600\n14400\n115200")
ui_DDbaudrate.set_width(96)
ui_DDbaudrate.set_height(lv.SIZE_CONTENT)   # 1
ui_DDbaudrate.set_x(61)
ui_DDbaudrate.set_y(-50)
ui_DDbaudrate.set_align(lv.ALIGN.CENTER)
ui_DDbaudrate.add_event_cb(event_dropdown, lv.EVENT.ALL, None)

ui_DDdatabits = lv.dropdown(ui_Screen1)
ui_DDdatabits.set_options("8\n7\n9")
ui_DDdatabits.set_width(96)
ui_DDdatabits.set_height(lv.SIZE_CONTENT)   # 1
ui_DDdatabits.set_x(60)
ui_DDdatabits.set_y(-4)
ui_DDdatabits.set_align( lv.ALIGN.CENTER)
ui_DDdatabits.add_event_cb(event_dropdown, lv.EVENT.ALL, None)

ui_DDstopbits = lv.dropdown(ui_Screen1)
ui_DDstopbits.set_options("1\n2")
ui_DDstopbits.set_width(96)
ui_DDstopbits.set_height(lv.SIZE_CONTENT)   # 1
ui_DDstopbits.set_x(61)
ui_DDstopbits.set_y(42)
ui_DDstopbits.set_align( lv.ALIGN.CENTER)
ui_DDstopbits.add_event_cb(event_dropdown, lv.EVENT.ALL, None)

ui_DATABITS = lv.label(ui_Screen1)
ui_DATABITS.set_text("DATABITS")
ui_DATABITS.set_width(lv.SIZE_CONTENT)	# 1
ui_DATABITS.set_height(lv.SIZE_CONTENT)   # 1
ui_DATABITS.set_x(-66)
ui_DATABITS.set_y(-1)
ui_DATABITS.set_align( lv.ALIGN.CENTER)

ui_Label2 = lv.label(ui_Screen1)
ui_Label2.set_text("BAUDRATE")
ui_Label2.set_width(lv.SIZE_CONTENT)	# 1
ui_Label2.set_height(lv.SIZE_CONTENT)   # 1
ui_Label2.set_x(-70)
ui_Label2.set_y(-47)
ui_Label2.set_align( lv.ALIGN.CENTER)
ui_Label2.set_flex_flow(lv.FLEX_FLOW.ROW)
ui_Label2.set_flex_align(lv.FLEX_ALIGN.START, lv.FLEX_ALIGN.START, lv.FLEX_ALIGN.START)

ui_Label3 = lv.label(ui_Screen1)
ui_Label3.set_text("STOPBITS")
ui_Label3.set_width(lv.SIZE_CONTENT)	# 1
ui_Label3.set_height(lv.SIZE_CONTENT)   # 1
ui_Label3.set_x(-63)
ui_Label3.set_y(40)
ui_Label3.set_align( lv.ALIGN.CENTER)

ui_BTback = lv.btn(ui_Screen1)
ui_BTback.set_width(71)
ui_BTback.set_height(37)
ui_BTback.set_x(-2)
ui_BTback.set_y(87)
ui_BTback.set_align( lv.ALIGN.CENTER)
ui_BTback.add_event_cb(Button2_eventhandler, lv.EVENT.ALL, None)

ui_Label4 = lv.label(ui_BTback)
ui_Label4.set_text("BACK")
ui_Label4.set_width(lv.SIZE_CONTENT)	# 1
ui_Label4.set_height(lv.SIZE_CONTENT)   # 1
ui_Label4.set_align( lv.ALIGN.CENTER)

ui_Label1 = lv.label(ui_Screen1)
ui_Label1.set_text("BACKLIGHT")
ui_Label1.set_width(lv.SIZE_CONTENT)	# 1
ui_Label1.set_height(lv.SIZE_CONTENT)   # 1
ui_Label1.set_x(-92)
ui_Label1.set_y(-87)
ui_Label1.set_align( lv.ALIGN.CENTER)
ui_Label1.set_flex_flow(lv.FLEX_FLOW.ROW)
ui_Label1.set_flex_align(lv.FLEX_ALIGN.START, lv.FLEX_ALIGN.START, lv.FLEX_ALIGN.START)

ui_Slider1 = lv.slider(ui_Screen1)
ui_Slider1.set_width(150)
ui_Slider1.set_height(10)
ui_Slider1.set_x(55)
ui_Slider1.set_y(-87)
ui_Slider1.set_align( lv.ALIGN.CENTER)
ui_Slider1.add_event_cb(slider_event_cb, lv.EVENT.VALUE_CHANGED, None) # Assign an event function
ui_Slider1.set_range(0,10)
ui_Slider1.set_value(10, lv.ANIM.OFF)

#----------------------------SCREEN_MAIN--------------------------------------
def Button1_eventhandler(event_struct):
    event = event_struct.code
    if event == lv.EVENT.CLICKED:
        lv.scr_load_anim(ui_Screen1, lv.SCR_LOAD_ANIM.FADE_ON, 300, 0,False)
        screen_group(1)
    return

def uart_send(event_struct):
    event = event_struct.code
    if event == lv.EVENT.CLICKED:
        data=ui_TextArea1.get_text()
        print(data," send!")
        uart.write(data.encode())
    return

ui_Screen2 = lv.obj()

ui_TextArea1 = lv.textarea(ui_Screen2)
ui_TextArea1.set_width(200)
ui_TextArea1.set_height(36)
ui_TextArea1.set_x(20)
ui_TextArea1.set_y(138)
ui_TextArea1.set_align( lv.ALIGN.CENTER)
ui_TextArea1.set_one_line(True)

ui_TextArea2 = lv.textarea(ui_Screen2)
ui_TextArea2.set_placeholder_text("UART data received")
ui_TextArea2.set_width(280)
ui_TextArea2.set_height(110)
ui_TextArea2.set_x(20)
ui_TextArea2.set_y(15)
ui_TextArea2.set_align( lv.ALIGN.CENTER)
ui_TextArea2.add_state(lv.STATE.DISABLED)

ui_BTsend = lv.btn(ui_Screen2)
ui_BTsend.set_width(71)
ui_BTsend.set_height(37)
ui_BTsend.set_x(107)
ui_BTsend.set_y(35)
ui_BTsend.set_align( lv.ALIGN.CENTER)
ui_BTsend.add_event_cb(uart_send, lv.EVENT.ALL, None)

ui_Label6 = lv.label(ui_BTsend)
ui_Label6.set_text("SEND")
ui_Label6.set_width(lv.SIZE_CONTENT)	# 1
ui_Label6.set_height(lv.SIZE_CONTENT)   # 1
ui_Label6.set_align( lv.ALIGN.CENTER)

ui_BTsetting = lv.btn(ui_Screen2)
ui_BTsetting.set_width(100)
ui_BTsetting.set_height(37)
ui_BTsetting.set_x(75)
ui_BTsetting.set_y(85)
ui_BTsetting.set_align( lv.ALIGN.CENTER)
ui_BTsetting.add_event_cb(Button1_eventhandler, lv.EVENT.ALL, None)

ui_Label5 = lv.label(ui_BTsetting)
ui_Label5.set_text("SETTINGS")
ui_Label5.set_width(lv.SIZE_CONTENT)
ui_Label5.set_height(lv.SIZE_CONTENT)
ui_Label5.set_align( lv.ALIGN.CENTER)

ui_Switch1 = lv.switch(ui_Screen2)
ui_Switch1.set_width(109)
ui_Switch1.set_height(25)
ui_Switch1.set_x(-60)
ui_Switch1.set_y(85)
ui_Switch1.set_align( lv.ALIGN.CENTER)
ui_Switch1.add_state(lv.STATE.CHECKED)

ui_Label8 = lv.label(ui_Switch1)
ui_Label8.set_text("FRESH")
ui_Label8.set_width(lv.SIZE_CONTENT)
ui_Label8.set_height(lv.SIZE_CONTENT)
ui_Label8.set_align( lv.ALIGN.CENTER)

#------------------------------MAIN-----------------------------------------------------

def screen_group(scr):
    if scr==1:
        device.group.remove_all_objs()
        device.group.add_obj(ui_Slider1)
        device.group.add_obj(ui_DDbaudrate)
        device.group.add_obj(ui_DDdatabits)
        device.group.add_obj(ui_DDstopbits)
        device.group.add_obj(ui_BTback)
    elif scr==2:
        device.group.remove_all_objs()
        device.group.add_obj(ui_TextArea1)
        device.group.add_obj(ui_BTsend)
        device.group.add_obj(ui_Switch1)
        device.group.add_obj(ui_BTsetting )

lv.scr_load(ui_Screen2)
screen_group(2)

while 1:
    if ui_Switch1.has_state(lv.STATE.CHECKED):
        if uart.any():
            data=uart.read()
            ui_TextArea2.add_text(data)


import tkinter as tk
from tkinter import PhotoImage, messagebox
import subprocess

def play_game():
    root.destroy()  # Close the main window
    subprocess.run(["python", "play_game.py"])

def play_table_driven():
    root.destroy()  # Close the main window
    subprocess.run(["python", "snake_game.py"])

def play_intelligent_agent():
    root.destroy()  # Close the main window
    subprocess.run(["python", "agent.py"])

# Create the main window
root = tk.Tk()
root.title("Snake Game")

# Set window size
w, h = 640, 480
root.geometry(f"{w}x{h}")

# Load background image
background_image = PhotoImage(file="background.png")  # Replace "background.png" with your image file
background_label = tk.Label(root, image=background_image)
background_label.place(relwidth=1, relheight=1)

# Create buttons with some styling
btn_play = tk.Button(root, text="Play Game", command=play_game, font=("Helvetica", 14), bd=5, bg="lightgreen", padx=20, pady=10)
btn_table_driven = tk.Button(root, text="Play with Table-Driven Agent", command=play_table_driven, font=("Helvetica", 14), bd=5, bg="lightblue", padx=20, pady=10)
btn_intelligent_agent = tk.Button(root, text="Play with Intelligent Agent", command=play_intelligent_agent, font=("Helvetica", 14), bd=5, bg="lightcoral", padx=20, pady=10)

# Place buttons in the window
btn_play.place(relx=0.5, rely=0.3, anchor="center")
btn_table_driven.place(relx=0.5, rely=0.5, anchor="center")
btn_intelligent_agent.place(relx=0.5, rely=0.7, anchor="center")

# Center the main window on the screen
root.eval('tk::PlaceWindow . center')

# Run the main loop
root.mainloop()


import numpy as np
import random
import math
from environment import *
import matplotlib.pyplot as plt
import matplotlib.animation as animation

class MountainCar():

	def __init__(self,position,velocity):
		self.position = position
		self.velocity = velocity
		self.action = np.array([0,1,2])

	def bound(self, x, x_min, x_max):
		if x < x_min:
			return x_min
		else:
			return min(x, x_max)

	def move(self, a, x_bound, v_bound):
		v = self.velocity + 0.001*a - 0.0025*(math.cos(3*self.position))
		x = self.position + v
		self.position = self.bound(x, x_bound[0], x_bound[1])
		self.velocity = self.bound(v, v_bound[0], v_bound[1])
		return self.position, self.velocity

	def get_state(self):
		return (self.position, self.velocity)

	def reset(self, x0_min, x0_max):
		self.position = random.uniform(x0_min, x0_max)
		self.velocity = 0

	def render(self,S,file_path='/Users/Miri/RL-Practice/MountainCar/mountain_car.mp4', mode='mp4'):
		fig = plt.figure()
		ax = fig.add_subplot(111, autoscale_on=False, xlim=(-1.2, 0.5), ylim=(-1.1, 1.1))
		ax.grid(False)  # disable the grid
		x_sin = np.linspace(start=-1.2, stop=0.5, num=100)
		y_sin = np.sin(3 * x_sin)
		ax.plot(x_sin, y_sin)  # plot the sine wave
		dot, = ax.plot([], [], 'ro')
		time_text = ax.text(0.05, 0.9, '', transform=ax.transAxes)

		def _init():
			dot.set_data([], [])
			time_text.set_text('')
			return dot, time_text

		def animate(i):
			x = S[i]
			y = np.sin(3 * x)
			dot.set_data(x, y)
			time_text.set_text("Time: " + str(np.round(i*0.1, 1)) + "s" + '\n' + "Frame: " + str(i))
			return dot, time_text

		ani = animation.FuncAnimation(fig, animate, frames =np.arange(1,len(S)),
                                      blit=True, init_func=_init, repeat=False)

		writervideo = animation.FFMpegWriter(fps=60)

		ani.save(file_path, writer= writervideo) #,codec='libx264')
		fig.clear()
		plt.close(fig)

def Policy(s,w):
	a = np.argmax((qvalue(s,-1,w), qvalue(s,0,w), qvalue(s,1,w)))
	return a-1


import pytest

from nhl_data.models.utils import camel_to_snake_case, convert_keys_to_snake_case

@pytest.mark.parametrize(
    "test_value, expected",
    [
        ("", ""),
        ("is_snake_case", "is_snake_case"),
        ("camelCase", "camel_case"),
        ("simpletextthatisalllower", "simpletextthatisalllower"),
        ("snake_thenCamelCase", "snake_then_camel_case"),
        ("camelCaseWithNums12345", "camel_case_with_nums12345"),
    ],
)
def test_camel_to_snake_case(test_value, expected):
    result = camel_to_snake_case(test_value)
    assert expected == result

@pytest.mark.parametrize(
    "test_value, expected",
    [
        (dict(), dict()),
        (
            {"helloWorld": None, "fine_world": None},
            {"hello_world": None, "fine_world": None},
        ),
        (
            {"hiThere": {"nestedHiThere": None, "nested_fine": None}},
            {"hi_there": {"nested_hi_there": None, "nested_fine": None}},
        ),
    ],
    ids=["empty_dict", "normal_level", "nested_dict"],
)
def test_convert_keys_to_snake_case(test_value, expected):
    result = convert_keys_to_snake_case(test_value)
    assert expected == result


import numpy as np
import matplotlib.pyplot as plt
from BasicFunctions.NeuralNetwork import *
# def update_adline
class BASE:
    """
    @param
    net : np.darray
    hx(net)

    @param
    t: int32
    a: int32
    x1: np.darray
    update_weights(t, a, x1)

    call self.train(epoch) for custom epochs

    """
    def __init__(self, inputFile, hx, update_weights,outputFile="output_MCP.txt", learning_rate = 2):
        self.inputFile = inputFile
        self.outputFile = outputFile
        self.X, self.Y = takeInput(self.inputFile)
        print('Parameters entered!', self.Y)
        self.test_cases = len(self.X)
        self.num_attributes = len(self.X[0])
        self.theta = self.num_attributes - 0.1
        self.weights =  setRandomWeights(*[self.num_attributes, 1])
        self.hx = hx
        self.update_weights = update_weights
        self.learning_rate = learning_rate
        self.train()

    def get_net(self, x_mini):
        net = np.dot(x_mini, self.weights)
        return net

    def set_x(self, x1):
        x_mini = x1.reshape(1, self.num_attributes)
        return x_mini

    def train(self, epoch = 10):
        print('Training Begin')
        for _ in range(epoch):
            ch = 0
            for i in range(self.test_cases):
                print('weights - ', self.weights.T)
                t = self.Y[i, 0]
                x1 = self.set_x(self.X[i])
                net = self.get_net(x1)
                a = self.hx(net)
                print('x - {}, net = {}, threshold - {}'.format(x1, net, a))
                # update weights
                if t!=a:
                    ch+=1
                    self.weights = self.update_weights(t, a, x1)
            if ch==0:
                break
        print('END of Training for {} epochs'.format(epoch))

    def test(self, x1):
        x1 = np.array([1] + x1)
        print('TESt INPut - ', x1)
        net = self.get_net(x1)
        a = self.hx(net) # winnow

        return a

"""
Winnow model
wi+1 = wi*(alpha^(t-a))
"""

class Winnow(BASE):
    def __init__(self, inputFile, outputFile='output_MCP.txt', learning_rate=2):
        self.Alpha = 2
        super().__init__(inputFile, self.hx, self.update_weights, outputFile=outputFile, learning_rate=learning_rate)
        print(dir(Winnow))

    def hx(self, net):
        a =  np.sum((net>self.theta) + 0)
        return a
    def update_weights(self, t, a, x1):
        w1 = self.weights*(self.Alpha**(t-a + 0.0))
        return w1

"""
Hebbian
wi+1 = wi + t*xi
"""

class Hebbian(BASE):
    """
    It supports bipolar outputs (ex - 1, -1)
    other will not train this model
    """
    def __init__(self, inputFile, outputFile='output_MCP.txt', learning_rate=2):
        super().__init__(inputFile, self.hx, self.update_weights, outputFile=outputFile, learning_rate=learning_rate)

    def hx(self, net):
        a =  sum([1 if i else -1 for i in (net>0).flatten()])
        return a

    def update_weights(self, t, a, x1):
        # print('HB - ', t, x1)
        w1 = self.weights + t*(x1.T)
        return w1

"""
ADLINE
wi+1 = wi + learning_rate*(t-net)*x
"""

class ADLINE(BASE):
    def __init__(self, inputFile, outputFile='output_MCP.txt', learning_rate=0.003):
        super().__init__(inputFile, self.hx, self.update_weights, outputFile=outputFile, learning_rate=learning_rate)

    def hx(self, net):
        return np.sum(net)

    def update_weights(self, t, a, x1):
        w1 = self.weights + self.learning_rate*(t-a)*(x1.T)
        return w1

inputFile = "INPUT.txt"
classification_test(ADLINE, inputFile, type=int)


from settings import MEDIA_ROOT
from django.conf.urls.defaults import *

from django.contrib import admin
admin.autodiscover()

urlpatterns = patterns('',
    # static files
    url(r'^static/javascripts/(?P<path>.*)$', 'django.views.static.serve',
        {'document_root': MEDIA_ROOT + '/javascripts'}, name='javascripts'),
    url(r'^static/images/(?P<path>.*)$', 'django.views.static.serve',
        {'document_root': MEDIA_ROOT + '/images'}, name='images'),
    url(r'^static/stylesheets/(?P<path>.*)$', 'django.views.static.serve',
        {'document_root': MEDIA_ROOT + '/stylesheets'}, name='stylesheets'),
    url(r'^static/(?P<path>.*)$', 'django.views.static.serve',
        {'document_root': MEDIA_ROOT}, name='static'),

    url(r'^$', 'maps.views.new', name='root'),
    (r'^admin/', include(admin.site.urls)),
    (r'^mapy/', include('maps.urls')),
    (r'^czas/', include('stats.urls')),
    (r'^profil/', include('profiles.urls')),
    (r'^punkt/', include('points.urls')),
    (r'^zdjecie/', include('avatar.urls')),

    (r'^komentarze/', include('comments.urls')),

    url(r'^nowy/$', 'profiles.views.new', name='new-profile'),
    url(r'^edytuj/$', 'profiles.views.edit', name='edit-profile'),
    url(r'^zaloguj/$', 'profiles.views.login', name='login'),
    url(r'^wyloguj/$', 'profiles.views.logout', name='logout'),
)


from django.shortcuts import render
from rest_framework import viewsets
from rest_framework.permissions import IsAuthenticated, IsAdminUser

from .serializers import BookSerializer, LibrarySerializer, BookInfoSerializer
from .models import Book, Library, BookInfo

class BookViewSet(viewsets.ModelViewSet):
    serializer_class = BookSerializer

    def get_queryset(self):
        books = Book.objects.all()

        library = self.request.query_params.get('library')
        title = self.request.query_params.get('title')
        author = self.request.query_params.get('author')
        publisher = self.request.query_params.get('publisher')
        published_year = self.request.query_params.get('year')

        if library:
            books = books.filter(library__name__icontains=library)
        if title:
            books = books.filter(book_info__title__icontains=title)
        if author:
            books = books.filter(book_info__author__icontains=author)
        if publisher:
            books = books.filter(book_info__publisher__icontains=publisher)
        if published_year:
            books = books.filter(book_info__published_year=published_year)

        return books

    def get_permissions(self):
        if self.action == 'list' or self.action == 'retrieve' or self.action == 'update':
            permission_classes = [IsAuthenticated]
        else:
            permission_classes = [IsAdminUser]

        return [permission() for permission in permission_classes]

class LibraryViewSet(viewsets.ModelViewSet):
    queryset = Library.objects.all()
    serializer_class = LibrarySerializer

    def get_permissions(self):
        if self.action == 'list' or self.action == 'retrieve':
            permission_classes = [IsAuthenticated]
        else:
            permission_classes = [IsAdminUser]

        return [permission() for permission in permission_classes]

class BookInfoViewSet(viewsets.ModelViewSet):
    queryset = BookInfo.objects.all()
    serializer_class = BookInfoSerializer

    def get_permissions(self):
        if self.action == 'list' or self.action == 'retrieve':
            permission_classes = [IsAuthenticated]
        else:
            permission_classes = [IsAdminUser]

        return [permission() for permission in permission_classes]


# -*- coding: utf-8 -*-
"""
Created on Tue Aug 16 16:08:31 2016

@author: timothee.boulet
"""

alphabet = [chr(letter) for letter in range(ord('A'), ord('Z')+1)]

lower = list(range(97,123)) #a à z
lower = [bin(letter)[2:] for letter in lower]

f = open('Probleme059_cipher.txt', "r")

text=f.read().split(',')
text=[bin(int(letter))[2:] for letter in text]

def xor(a,b):
    lena=len(a)
    lenb=len(b)
    diff=lena-lenb
    if diff<0:
        a=abs(diff)*'0'+a
    elif diff>0:
        b=abs(diff)*'0'+b
    result=''
    for a,b in zip(a,b):
        if a!=b:
            result+='1'
        else:
            result+='0'
    return result

def decypher(text, key):
    """ key must be length 3"""
    result=[]
    for i, letter in enumerate(text):
        if i%3==0:
            decrypt=xor(letter, key[0])
            result.append(chr(int(decrypt,2)))
        if i%3==1:
            decrypt=xor(letter, key[1])
            result.append(chr(int(decrypt,2)))
        if i%3==2:
            decrypt=xor(letter, key[2])
            result.append(chr(int(decrypt,2)))
    return ''.join(result)

forbidden=['#', 'µ', '¤', '§', '\\', '[', ']', '\\', '{', '}' ]
mandatory=['the', 'and', 'to', 'be', 'of']
for i,letter1 in enumerate(lower):
    for j,letter2 in enumerate(lower):
        for k,letter3 in enumerate(lower):
            test=decypher(text, [letter1, letter2, letter3])
            if all(carac not in test for carac in forbidden):
                if all(word in test for word in mandatory):
                    print(i,j,k)
#6,14,3
test=decypher(text, [lower[6], lower[14], lower[3]])
ascii=[ord(letter) for letter in test]
print(sum(ascii))


import httpx
import pytest
from bilix.sites.hanime1 import api

client = httpx.AsyncClient(**api.dft_client_settings)

@pytest.mark.asyncio
async def test_get_video_info():
    data = await api.get_video_info(client, "https://hanime1.me/watch?v=39123")
    assert data.title
    data = await api.get_video_info(client, "https://hanime1.me/watch?v=13658")
    assert data.title


# -*- coding: utf-8 -*-
from pyAudioAnalysis import audioFeatureExtraction
from pyAudioAnalysis import audioBasicIO
import matplotlib.pyplot as plt
from boto.s3.connection import S3Connection
from django.conf import settings
import scipy.io.wavfile as wav

def extract_features(song):
    # Init amazon S3 to get the songs.
    conn = S3Connection(settings.AWS_ACCESS_KEY_ID, settings.AWS_SECRET_ACCESS_KEY)
    # Connect to bucket
    bucket = conn.get_bucket('music-emotions')
    k = bucket.get_key(song.key)
    # Get the contents of the key into a file
    k.get_contents_to_filename("song-wavs/"+song.name)
    [Fs, x] = audioBasicIO.readAudioFile("song-wavs/"+song.name)
    x = audioBasicIO.stereo2mono(x)  # convert to MONO if required
    F = audioFeatureExtraction.stFeatureExtraction(x, Fs, round(0.050 * Fs), round(0.050 * Fs))
    F_M = a
    plt.subplot(2, 1, 1)
    plt.plot(F[0, :])
    plt.xlabel('Frame no')
    plt.ylabel('ZCR')
    plt.subplot(2, 1, 2)
    plt.plot(F[1, :])
    plt.xlabel('Frame no')
    plt.ylabel('Energy')
    plt.show()


"""
json2yolo：将Honeybee2d的json转为适合yolo的txt格式
"""
import json

for i in range(480):
    # 读取JSON文件
    with open(f'annotation/{i:06}.json', 'r') as f:
        data = json.load(f)

    # 解析JSON文件并处理结果
    results = []
    for shape in data['shapes']:
        # 提取label、points、width、height信息
        points = shape['points']
        x = points[1][0] + points[0][0]
        x /= 2
        y = points[1][1] + points[0][1]
        y /= 2
        w = points[1][0] - points[0][0]
        h = points[1][1] - points[0][1]
        # 归一化坐标和尺寸到[0, 1]范围内
        x /= 1920
        y /= 1080
        w /= 1920
        h /= 1080
        # 将矩形信息添加到结果列表中
        results.append([0, abs(x), abs(y), abs(w), abs(h)])

    # 将结果保存到txt文件中
    with open(f'labels/{i:06}.txt', 'w') as f:
        for line in results:
            f.write(' '.join(map(str, line)) + '\n')


''' takes a multi level dict and flattens it into a single level dict
    > cant handle lists of dicts within dicts'''
import collections
from pprint import pprint

def flatten_dict(dctnry, parent_key='', sep='_'):
    ''' takes a multi level dict and flattens it into a single level dict
    > cant handle lists of dicts within dicts'''
    items = []
    for k, v in dctnry.items():
        new_key = parent_key + sep + k if parent_key else k
        if isinstance(v, collections.MutableMapping):
            items.extend(flatten_dict(v, new_key, sep=sep).items())
        else:
            items.append((new_key, v))
    return dict(items)

if __name__ == '__main__':
    diction = {'a': 1, 'b': {'c':2, 'd':3}}
    pprint(flatten_dict(diction))


import numpy as np
from bs4 import BeautifulSoup
import urllib.request
import pandas as pd
from icecream import ic
from pandas import read_table
from context.domains import Reader, File
from matplotlib import rc, font_manager, pyplot as plt
rc('font', family=font_manager.FontProperties(fname='C:/Windows/Fonts/malgunsl.ttf').get_name())
import matplotlib
matplotlib.rcParams['axes.unicode_minus'] = False

class Solution(Reader):
    def __init__(self, k=0.5):
        self.movie_comments = pd.DataFrame
        self.file = File()
        self.file.context = './data/'
        # 나이브베이즈 설정값
        self.k = k
        self.word_probs = []

    def hook(self):
        def print_menu():
            print('0. Exit')
            print('1. 크롤링(텍스트 마이닝)')
            print('2. 정형화(객체)')
            print('3. 다음 영화 댓글이 긍정인지 부정인지 ratio 값으로 판단하시오\n'
                  '너무 좋아요. 내 인생의 최고의 명작 영화\n'
                  '이렇게 졸린 영화는 처음이야')
            return input('메뉴 선택 \n')

        while 1:
            menu = print_menu()
            if menu == '0':
                break
            elif menu == '1':
                self.crawling()
            elif menu == '2':
                self.preprocess()
            elif menu == '3':
                doc = None
                self.naviaBayesClassifier(doc)

    def preprocess(self):  # 데이터를 수집해서 가져오는 일
        self.stereotype()
        df = self.movie_comments
        # ic(df.head(5))
        # 코멘트가 없는 리뷰 데이터(nan) 제거
        df = df.dropna()
        # 중복 리뷰 제거
        df_reviews = df.drop_duplicates(['comment'])
        # self.review_info(df)
        # 긍정, 부정 리뷰 수
        df.label.value_counts()
        top10 = self.top_10_movies(df)
        avg_score = self.get_avg_score(top10)
        self.visualization(top10, avg_score)

    def crawling(self):
        file = self.file
        file.fname = 'movie_reviews.txt'
        path = self.new_file(file)
        f = open(path, 'w', encoding='UTF-8')

        # -- 500페이지까지 크롤링
        for no in range(1, 501):
            url = 'https://movie.naver.com/movie/point/af/list.naver?&page=%d' % no
            html = urllib.request.urlopen(url)
            soup = BeautifulSoup(html, 'html.parser')

            reviews = soup.select('tbody > tr > td.title')
            for rev in reviews:
                title = rev.select_one('a.movie').text.strip()
                score = rev.select_one('div.list_netizen_score > em').text.strip()
                comment = rev.select_one('br').next_sibling.strip()

                # -- 긍정/부정 리뷰 레이블 설정
                if int(score) >= 8:
                    label = 1  # -- 긍정 리뷰 (8~10점)
                elif int(score) <= 4:
                    label = 0  # -- 부정 리뷰 (0~4점)
                else:
                    label = 2

                f.write(f'{title}\t{score}\t{comment}\t{label}\n')
        f.close()

    def stereotype(self):
        file = self.file
        file.context = './save/'
        file.fname = 'movie_reviews.txt'
        path = self.new_file(file)
        self.movie_comments = pd.read_csv(path, delimiter='\t',
                           names=['title', 'score', 'comment', 'label'])  # -- 본인 환경에 맞게 설치 경로 변경할 것

    def review_info(self, df):
        # 영화 리스트 확인
        movie_lst = df.title.unique()
        ic('전체 영화 편수 =', len(movie_lst))
        ic(movie_lst[:10])
        # 각 영화 리뷰 수 계산
        cnt_movie = df.title.value_counts()
        ic(cnt_movie[:20])
        # 각 영화 평점 분석
        # info_movie = df.groupby('title')['score'].describe() lambda 로 변환
        ic((lambda a, b: df.groupby(a)[b].describe())('title', 'score').sort_values(by=['count'], axis=0,
                                                                                ascending=False))

    def top_10_movies(self, df):
        top10 = df.title.value_counts().sort_values(ascending=False)[:10]
        top10_title = top10.index.tolist()
        return df[df['title'].isin(top10_title)]

    def get_avg_score(self, top10):
        movie_title = top10.title.unique().tolist()  # -- 영화 제목 추출
        avg_score = {}  # -- {제목 : 평균} 저장
        for t in movie_title:
            avg = top10[top10['title'] == t]['score'].mean()
            avg_score[t] = avg
        return avg_score

    def visualization(self, top10, avg_score):
        plt.figure(figsize=(10, 5))
        plt.title('영화 평균 평점 (top 10: 리뷰 수)\n', fontsize=17)
        plt.xlabel('영화 제목')
        plt.ylabel('평균 평점')
        plt.xticks(rotation=20)

        for x, y in avg_score.items():
            color = np.array_str(np.where(y == max(avg_score.values()), 'orange', 'lightgrey'))
            plt.bar(x, y, color=color)
            plt.text(x, y, '%.2f' % y,
                     horizontalalignment='center',
                     verticalalignment='bottom')

        plt.show()
        self.rating_distribution(top10, avg_score)
        self.circle_chart(top10, avg_score)

    def rating_distribution(self, top10, avg_score):
        fig, axs = plt.subplots(5, 2, figsize=(15, 25))
        axs = axs.flatten()

        for title, avg, ax in zip(avg_score.keys(), avg_score.values(), axs):
            num_reviews = len(top10[top10['title'] == title])
            x = np.arange(num_reviews)
            y = top10[top10['title'] == title]['score']
            ax.set_title('\n%s (%d명)' % (title, num_reviews), fontsize=15)
            ax.set_ylim(0, 10.5, 2)
            ax.plot(x, y, 'o')
            ax.axhline(avg, color='red', linestyle='--')  # -- 평균 점선 나타내기

        plt.show()

    def circle_chart(self, top10, avg_score):
        fig, axs = plt.subplots(5, 2, figsize=(15, 25))
        axs = axs.flatten()
        colors = ['pink', 'gold', 'whitesmoke']
        labels = ['1 (8~10점)', '0 (1~4점)', '2 (5~7점)']

        for title, ax in zip(avg_score.keys(), axs):
            num_reviews = len(top10[top10['title'] == title])
            values = top10[top10['title'] == title]['label'].value_counts()
            ax.set_title('\n%s (%d명)' % (title, num_reviews), fontsize=15)
            ax.pie(values,
                   autopct='%1.1f%%',
                   colors=colors,
                   shadow=True,
                   startangle=90)
            ax.axis('equal')
        plt.show()

    def naviaBayesClassifier(self, doc):
        file = self.file
        file.context = './save/'
        file.fname = 'movie_reviews.txt'
        path = self.new_file(file)
        self.load_corpus(path)

        training_set = None
        self.count_words(training_set)
        counts = 0
        total_class0 = 0
        total_class1 = 0
        k = self.k
        word_probs = 0
        trainfile_path = ''
        self.word_probabilities(counts, total_class0, total_class1, doc)
        self.class0_probabilities(word_probs, doc)
        self.train(trainfile_path)
        self.classify(doc)

    def load_corpus(self, path):
        corpus = pd.read_table(path)
        ic(corpus)
        return corpus

    def count_words(self, training_set):
        counts = 0
        return counts

    def inNumber(self, s):
        try:
            float(s)
            return True
        except ValueError:
            return False

    def word_probabilities(self, counts, total_class0, total_class1, k):
        # 단어의 빈도수를 [단어, p(w| 긍정), p(w| 부정)] 형태로 변환
        return []

    def class0_probabilities(self, word_probs, doc):
        return None

    def train(self, trainfile_path):
        pass

    def classify(self, doc):
        return self.class0_probabilities(self.word_probs, doc)

if __name__ == '__main__':
    Solution().hook()


import math
#Nhập input

n = 6
x = []
x = toa_do = [0,0,0,1,2,1]
#tương ứng [Ax, Ay, Bx, By, Cx, Cy]

a1 = math.sqrt(((x[2] - x[0])**2 + (x[3] - x[1])**2)) #a1 là độ dài cạnh AB
a2 = math.sqrt(((x[4] - x[0])**2 + (x[5] - x[1])**2)) #a2 là độ dài cạnh AC
a3 = math.sqrt(((x[4] - x[2])**2 + (x[5] - x[3])**2)) #a3 là độ dài cạnh BC

#a. Kiểm tra xem 3 điểm A, B, C có đủ điều kiện hợp thành tam giác ABC hay không

def kiemtra_tamgiac(input):
    if a1 + a2 < a3 and a1 + a3 < a2 and a2 + a3 < a1:
        return False
    else:
        return True

#b. Tính toán các cạnh và góc của tam giác ABC:

def goccanh_tamgiac(input):

    #Độ dài cạnh AB, AC, BC:
    a = round(a1,2)
    b = round(a2,2)
    c = round(a3,2)
    print(f'Độ dài cạnh AB: {a}')
    print(f'Độ dài cạnh AC: {b}')
    print(f'Độ dài cạnh BC: {c}')

    #Số đo các góc của tam giác ABC(cos => radian => degrees):
    cosA = (a**2 + b**2 - c**2) / (2*a*b)
    gocA = round(math.degrees(math.acos(cosA)),2)
    print(f'Goc A : {gocA}')

    cosB = (a**2 + c**2 - b**2) / (2*a*c)
    gocB = round(math.degrees(math.acos(cosB)),2)
    print(f'Goc B : {gocB}')

    cosC = (b**2 + c**2 - a**2) / (2*b*c)
    gocC = round(math.degrees(math.acos(cosC)),2)
    print(f'Goc C : {gocC}')

    return (a, b, c, gocA, gocB, gocC)

#Xác định lại biến cho các tham số trên để sử dụng cho các yêu cầu về sau:
cosA = (a1**2 + a2**2 - a3**2) / (2*a1*a2)
cosB = (a1**2 + a3**2 - a2**2) / (2*a1*a3)
cosC = (a2**2 + a3**2 - a1**2) / (2*a2*a3)

#Độ dài cạnh AB, AC, BC:
a = round(a1,2)
b = round(a2,2)
c = round(a3,2)

gocA = round(math.degrees(math.acos(cosA)),2)
gocB = round(math.degrees(math.acos(cosB)),2)
gocC = round(math.degrees(math.acos(cosC)),2)

#c. Xét xem tam giác ABC thuộc loại tam giác nào:

def xet_tamgiac(input):

    #Xét xem tam giác ABC là tam giác vuông, tam giác nhọn hay tam giác tù, tại đỉnh nào:
    if gocA == 90 and a1 == a2:
        print(f'ABC la tam giac vuong can tai dinh A : {gocA}')
    elif gocB == 90 and a1 == a3:
        print(f'ABC la tam giac vuong can tai dinh B : {gocB}')
    elif gocC == 90 and a2 == a3:
        print(f'ABC la tam giac vuong can tai dinh C : {gocC}')

    elif a1 == a2 and a2 == a3:
        print("ABC la tam gia deu")

    elif gocA == 60 and gocB == 60 and gocC == 60:
        print("ABC la tam gia deu")

    elif gocA > 90 and a1 == a2:
        print(f'ABC la tam giac tu va can tai dinh A : {gocA}')
    elif gocB > 90 and a1 == a3:
        print(f'ABC la tam giac tu va can tai dinh B : {gocB}')
    elif gocC > 90 and a2 == a3:
        print(f'ABC la tam giac tu va can tai dinh C : {gocC}')

    if gocA == 90 and a2 != a3:
        print(f'ABC la tam giac vuong tai dinh A : {gocA}')
    elif gocB == 90 and a1 != a3:
        print(f'ABC la tam giac vuong tai dinh B : {gocB}')
    elif gocC == 90 and a2 != a3:
        print(f'ABC la tam giac vuong tai dinh C : {gocC}')

    elif a1 == a2 or a1 == a3 or a2 == a3:
        print("ABC la tam giac can")

    elif gocA > 90 and a1 != a2:
        print(f'ABC la tam giac tu tai dinh A : {gocA}')
    elif gocB > 90 and a1 != a3:
        print(f'ABC la tam giac tu tai dinh B : {gocB}')
    elif gocC > 90 and a2 != a3:
        print(f'ABC la tam giac tu tai dinh C : {gocC}')

    else:
        print("ABC la tam giac binh thuong")

#d. Tinh dien tich tam giac ABC:
area = round((0.5 * a1 * a2 * math.sin(gocA)), 2)
def dientich_tamgiac(input):
    return round(area, 2)

#e. Tính độ dài của các đường cao của tam giác ABC:

# nửa chu vi tam giác ABC:
p = (a1 + a2 + a3) / 2

dcA = round(2*(math.sqrt(p * (p - a1) * (p - a2) * (p - a3)))/a3, 2)
dcB = round(2*(math.sqrt(p * (p - a1) * (p - a2) * (p - a3)))/a2, 2)
dcC = round(2*(math.sqrt(p * (p - a1) * (p - a2) * (p - a3)))/a1, 2)

def duongcao_tamgiac(input):
    list = ["dcA", "dcB", "dcC"]
    for h in list :
        if h == True :
            print("\"h\" la duong cao cua tam giac ABC");

    return (dcA, dcB, dcC)

#f. Tính độ dài từ các đỉnh A, B, C đến trọng tâm tam giác ABC:

mA = round(math.sqrt(((a2**2 + a3**2)/2) - (a1**2)/4), 2)
mB = round(math.sqrt(((a1**2 + a3**2)/2) - (a2**2)/4), 2)
mC = round(math.sqrt(((a1**2 + a2**2)/2) - (a3**2)/4), 2)

def trungtuyen_tamgiac(input):
    list = ["ttA", "ttB", "ttC"]
    for t in list :
        if t == True :
            print("t la trung tuyen tam giac ABC");

    return (mA, mB, mC)

# g. Tọa độ trọng tâm và trực tâm của tam giác ABC

trongtam_x = round((x[0] + x[2] + x[4]) /3, 2)
trongtam_y = round((x[1] + x[3] + x[5]) /3, 2)

def trongtam_tamgiac(input):
    list = ["trongtam_x", "trongtam_y", "tructam_x", "tructam_y"]
    for T in list :
        if T == True :
            print("T la trong tam tam giac ABC");

    return [trongtam_x, trongtam_y]

#Tọa độ BC(a1;a2); AC(a3;a4); AH(xH - x[0]; yH - x[1]); BH(xH - x[2]; yH - x[3])
a1 = x[4] - x[2]
a2 = x[5] - x[3]
a3 = x[4] - x[0]
a4 = x[5] - x[4]

#Tam giác ABC có trực tâm H
#Vecto(AH).vecto(BC) = 0
#Vecto(BH).vecto(AC) = 0

#Tính các định thức
D = a1*a4 - a2*a3
Dx = a4*(a1*x[0] + a2*x[1]) - a2*(a3*x[2] + a4*x[3])
Dy = a1*(a3*x[2] + a4*x[3]) - a3*(a1*x[0] + a2*x[1])

#Công thức Cramer
xH = Dx/D
yH = Dy/D

def tructam_tamgiac(input):
    return [xH, yH]

# h.Trả về tất cả các kết quả ở trên:
def giaima_tamgiac(input):
    if kiemtra_tamgiac(input):
        print ("A, B, C hop thanh mot tam giac")

    else:
        from sys import exit
        exit("A, B, C khong hop thanh mot tam giac")

print ("1. So do co ban cua tam giac:")
print ("Chieu dai canh AB:", a)
print ("Chieu dai canh AC:", b)
print ("Chieu dai canh BC:", c)
print ("Goc A:", gocA)
print ("Goc B:", gocB)
print ("Goc C:", gocC)
xet_tamgiac (input)
print ("2. Dien tich cua tam giac ABC:", area)
print ("3. So do nang cao tam giac ABC:")
print ("Do dai duong cao tu dinh A:", dcA)
print ("Do dai duong cao tu dinh B:", dcB)
print ("Do dai duong cao tu dinh C:", dcC)
print ("Khoang cach den trong tam tu dinh A:", mA)
print ("Khoang cach den trong tam tu dinh B:", mB)
print ("Khoang cach den trong tam tu dinh C:", mC)
print("4. Toa do mot so diem dac biet cua tam giac ABC:")
print("Toa do trong tam:", trongtam_tamgiac(input))
print("Toa do truc tam:", tructam_tamgiac(input))

giaima_tamgiac(input)


def solution(answers):
    MAX_Q = 10000
    p1 = [[1, 2, 3, 4, 5, ] for i in range(MAX_Q)]
    # p1 = [1, 2, 3, 4, 5, ] * MAX_Q
    # p2 = [2, 1, 2, 3, 2, 4, 2, 5,] * MAX_Q
    p2 = [[2, 1, 2, 3, 2, 4, 2, 5, ] for i in range(MAX_Q)]
    # p2 = [1, 2, 3, 4, 5, ] * MAX_Q
    # p3 = [3, 3, 1, 1, 2, 2, 4, 4, 5, 5, ] * MAX_Q
    p3 = [[3, 3, 1, 1, 2, 2, 4, 4, 5, 5, ] for i in range(MAX_Q)]
    print(len(p1), len(p2), len(p3))
    re1 = 0
    re2 = 0
    re3 = 0
    result = []
    answer = answers * MAX_Q
    for i in range(MAX_Q):
        if p1[i] == answer[i]:
            re1 += 1
        if p2[i] == answer[i]:
            re2 += 1
        if p3[i] == answer[i]:
            re3 += 1
    result.append(re1)
    result.append(re2)
    result.append(re3)
    # result = sorted(result)
    print(result)
    # print(max(result))
    MAX = max(result)
    rresult = []
    for i, v in enumerate(result):
        if v == MAX:
            rresult.append(i + 1)
    print(rresult)
    return sorted(rresult)
    # print(result.index(max(result)))
    # return result

answers1 = [1, 2, 3, 4, 5]
answers2 = [1, 3, 2, 4, 2]
solution(answers1)
solution(answers2)

프로그래머스/레벨1/모의고사.py


__credits__ = ["Evan Bolyen"]

import sys
from unittest import TestCase, main

if sys.version_info.major == 2:
    from StringIO import StringIO
else:
    from io import StringIO

from pyqi.core.exception import IncompetentDeveloperError
from pyqi.core.interfaces.html.input_handler import (load_file_lines,
        load_file_contents)

class HTMLInputHandlerTests(TestCase):
    def setUp(self):
        self.file_like_object = StringIO()
        #Note the whitespace, this tests strip()
        self.file_like_object.write("This is line 1\n")
        self.file_like_object.write(" This is line 2\n")
        self.file_like_object.write("This is line 3 \n")
        #Place it at the beginning of the file again
        self.file_like_object.seek(0)

    def tearDown(self):
        self.file_like_object.close()

    def test_load_file_lines(self):
        """Correctly returns file lines as a list of strings"""
        # can't load a string, etc...
        self.assertRaises(IncompetentDeveloperError, load_file_lines, 'This is not a file')
        result = load_file_lines(self.file_like_object)
        self.assertEqual(result,
                         ["This is line 1",
                          "This is line 2",
                          "This is line 3"])

    def test_load_file_contents(self):
        """Correctly returns file contents"""
        # can't load a string, etc...
        self.assertRaises(IncompetentDeveloperError, load_file_contents, 'This is not a file')

        result = load_file_contents(self.file_like_object)
        #Note the whitespace
        self.assertEqual(result, "This is line 1\n This is line 2\nThis is line 3 \n")

if __name__ == '__main__':
    main()


# Definition for singly-linked list.

class ListNode(object):
    def __init__(self, x):
        self.val = x
        self.next = None

class Solution(object):

    def addTwoNumbers(self, l1, l2):
        """
        :type l1: ListNode
        :type l2: ListNode
        :rtype: ListNode
        """

        def oneListToInt(l):
            res = 0
            multiplier = 1
            while l is not None:
                res += l.val * multiplier
                multiplier = multiplier * 10
                l = l.next
            return res

        res = 0
        carry_over = 0
        multiplier = 1

        while l1 is not None and l2 is not None:
            # print(l1.val * l2.val + carry_over)
            res += multiplier * ((l1.val + l2.val + carry_over) % 10)
            carry_over = (l1.val + l2.val + carry_over) // 10
            multiplier = multiplier * 10
            # print("RES: " + str(res))
            l1 = l1.next
            l2 = l2.next

        l1_extra = oneListToInt(l1)
        l2_extra = oneListToInt(l2)
        res = (l1_extra + l2_extra + carry_over) * multiplier + res
        print("RES: " + str(res))

        head = ListNode(res % 10)
        res_ll = head
        res = res // 10
        print("INIT RES " + str(res))

        while res > 0:
            new_node = ListNode(res%10)
            res_ll.next = new_node
            res_ll = new_node
            res = res // 10
            print("ITER RES " + str(res))

        return head

l1_1 = ListNode(2)
l1_2 = ListNode(4)
l1_3 = ListNode(3)
l1_1.next = l1_2
l1_2.next = l1_3

l2_1 = ListNode(5)
l2_2 = ListNode(6)
l2_3 = ListNode(4)
l2_1.next = l2_2
# l2_2.next = l2_3

sol = Solution()
sol.addTwoNumbers(l1_1,l2_1)


money = int(input())
stocks = list(map(int, input().split()))

# bnp 주식 개수
bnp = 0
# timing 주식 개수
timing = 0

# bnp
bnp_money = money
bnp_dap = 0
for stock in stocks:
    if stock <= bnp_money:
        bnp += (bnp_money//stock)
        bnp_money -= (bnp_money//stock)*stock

bnp_dap = (stocks[13]*bnp) + bnp_money

# timing

# 연속으로 내려간 날
down_count = 0
# 연속으로 올라간 날
up_count = 0
# 현재 stock과 비교할 그 전날 stock
before_stock = 0
# 현재 stock
now_stock = 0

timing_money = money
timing_dap = 0
for i in range(1, len(stocks)):
    before_stock = stocks[i-1]
    now_stock = stocks[i]
    # 매수
    if before_stock > now_stock:
        down_count += 1
        up_count = 0
        if down_count >= 3:
            timing += (timing_money // stocks[i])
            timing_money -= (timing_money//stocks[i])*stocks[i]

    # 매도
    if before_stock < now_stock:
        up_count += 1
        down_count = 0
        if up_count >= 3:
            timing_money += timing * stocks[i]
            timing = 0

    # 초기화
    if before_stock == now_stock:
        down_count = 0
        up_count = 0

timing_dap = (stocks[13] * timing) + timing_money

if bnp_dap > timing_dap:
    print('BNP')
elif bnp_dap < timing_dap:
    print('TIMING')
else:
    print('SAMESAME')

백준/Silver/20546. 🐜 기적의 매매법 🐜/🐜 기적의 매매법 🐜.py

🐜 기적의 매매법 🐜.py


from django.contrib.auth import get_user_model
from django.test import TestCase
from django.urls import reverse, reverse_lazy
from rest_framework import status
from rest_framework.test import APIClient

from books.models import Book
from books.serializers import BookSerializer

BOOK_URL = reverse_lazy("books:book-list")

def sample_book(**params) -> Book:
    defaults = {
        "title": "title",
        "author": "author",
        "cover": "H",
        "inventory": 100,
        "daily_fee": 25,
    }
    defaults.update(params)

    return Book.objects.create(**defaults)

class UnauthenticatedBookApiTests(TestCase):
    def setUp(self) -> None:
        self.client = APIClient()

    def test_auth_requirement(self):
        response = self.client.get(BOOK_URL)
        self.assertEqual(response.status_code, status.HTTP_200_OK)

class AuthenticatedBookApiTests(TestCase):
    def setUp(self) -> None:
        self.client = APIClient()
        self.user = get_user_model().objects.create_user(
            "test@test.com",
            "test12345",
        )
        self.client.force_authenticate(self.user)

    def test_list_book(self):
        sample_book()

        response = self.client.get(BOOK_URL)

        book = Book.objects.all()
        serializer = BookSerializer(book, many=True)

        self.assertEqual(response.status_code, status.HTTP_200_OK)
        self.assertEqual(response.data, serializer.data)

    def test_retrieve_book_detail(self):
        book = sample_book()
        url = reverse("books:book-list") + f"{book.pk}/"

        response = self.client.get(url)
        self.assertEqual(response.status_code, status.HTTP_200_OK)

    def test_delete_book_not_allowed(self):
        book = sample_book()
        url = reverse("books:book-list") + f"{book.pk}/"

        res = self.client.delete(url)

        self.assertEqual(res.status_code, status.HTTP_403_FORBIDDEN)

class AdminBookApiTests(TestCase):
    def setUp(self) -> None:
        self.client = APIClient()
        self.user = get_user_model().objects.create_user(
            "test@admin.com",
            "test12345",
            is_staff=True,
        )
        self.client.force_authenticate(self.user)

    def test_book_create(self):
        payload = {
            "title": "Test title",
            "author": "Test author",
            "cover": "H",
            "inventory": 25,
            "daily_fee": 100,
        }

        response = self.client.post(BOOK_URL, payload)
        book = Book.objects.get(id=response.data["id"])

        self.assertEqual(response.status_code, status.HTTP_201_CREATED)
        self.assertEqual(payload["title"], getattr(book, "title"))
        self.assertEqual(payload["author"], getattr(book, "author"))

    def test_book_update(self):
        data = {
            "title": "Test",
            "author": "Test",
            "cover": "H",
            "inventory": 250,
            "daily_fee": 50,
        }
        book = sample_book()
        url = reverse("books:book-list") + f"{book.pk}/"

        response = self.client.put(url, data)
        self.assertEqual(response.status_code, status.HTTP_200_OK)

    def test_delete_book(self):
        book = sample_book()
        url = reverse("books:book-list") + f"{book.pk}/"

        res = self.client.delete(url)

        self.assertEqual(res.status_code, status.HTTP_204_NO_CONTENT)