# %%
import matplotlib.pyplot as plt
import matplotlib.font_manager as fm
import matplotlib.ticker as ticker
import matplotlib.patheffects as path_effects
import matplotlib.patches as patches
from matplotlib import rcParams
from highlight_text import ax_text, fig_text
import pandas as pd

from PIL import Image
import urllib
import os

# --- Use this only if you have already downloaded fonts into your
# --- local directory.

# Add pretty fonts

font_path = r"" #Set the path to where the fonts are located

for x in os.listdir(font_path):
    for y in os.listdir(f"{font_path}/{x}"):
        if y.split(".")[-1] == "ttf":
            fm.fontManager.addfont(f"{font_path}/{x}/{y}")
            try:
                fm.FontProperties(weight=y.split("-")[-1].split(".")[0].lower(), fname=y)
            except Exception as e:
                print(f"Font {y} could not be added.")
                continue

rcParams['font.family'] = 'Karla'

# --- Read and transform the data

df = pd.read_csv("data/08012022_womens_euro.csv", index_col = 0)

# ----------------------------------------------------------------
# -- Declare a function to group the shots into bins

def shot_map_bins(match_id, team_id, grid_x = 6, grid_y = 2, data = df):
    '''
    This function takes a playerId and returns the list of
    percentages (in order) to map the values into our shot map plot.

    Args:
        grid_x (int): the number of divisions to be made to the goal aross the x-axis. Must be an even number.
        grid_y (int): the number of divisions to be made to the goal aross the y-axis. Must be an even number.
    '''

    data = data.copy()
    width = 24
    height = 8

    if (grid_x % 2 != 0) | (grid_y % 2 != 0):
        raise Exception('grid_x and grid_y must be even integers.')

    increment_x = int(width / grid_x)
    increment_y = int(height / grid_y)

    # The data's scale is 2 units wide and .666 high.

    data['x'] = [((x*width)/2.1) for x in data['x']]
    data['y'] = [((y*height)/.7) for y in data['y']]

    # Assign intervals
    bins_x = range(0, width + 1, increment_x)
    bins_y = range(0, height + 1, increment_y)

    data['bins_x'] = pd.cut(data['x'], bins_x)
    data['bins_y'] = pd.cut(data['y'], bins_y)

    # -- We add an auxiliary column to help us count the number of shots.
    data['shot_aux'] = 1

    data_bins = (
        data
        .groupby(['bins_x','bins_y','team_id', 'match_id'])
        ['shot_aux'].sum().
        reset_index()
    )

    # -- Count all shots on target.
    total_shots = data.groupby(['team_id', 'match_id'])['shot_aux'].sum().reset_index()
    total_shots.columns = ['team_id', 'match_id', 'total']

    # -- Merge it back & calculate the percentage
    data_bins = pd.merge(data_bins, total_shots, how = 'left', on = ['match_id', 'team_id'])
    data_bins['shot_pct'] = data_bins['shot_aux']/data_bins['total']

    # -- Order data_bins first by x and then by y
    team_bins = data_bins[(data_bins['team_id'] == team_id) & (data_bins['match_id'] == match_id)].reset_index()
    team_bins = team_bins.sort_values(by = ['bins_x', 'bins_y'])

    return team_bins['shot_pct'].to_list()

# -------------------------------------------------------------------------
# Declare a function that plots the shotmap

def shot_map_plot(match_id, team_id, ax, grid_x = 6, grid_y = 2, data = df, main_color = '#005377'):
    '''
    This function takes a team, match_id and axes to plot a shot map.

    Args:
    ax (obj): a Matplotlib axes.
    grid_x (int): the number of divisions to be made to the goal aross the x-axis. Must be an even number.
    grid_y (int): the number of divisions to be made to the goal aross the y-axis. Must be an even number.
    main_color (str): a hex color code for the heat-map.
    '''

    scatter_df = data.copy()
    scatter_df = scatter_df[
        (scatter_df["match_id"] == match_id) &
        (scatter_df["team_id"] == team_id)
    ]

    ax.axis('equal')

    # -- The size of the goal
    width = 24
    height = 8

    # -- The left & right post
    ax.plot([0,0],[0,height], color = 'black', lw = 1.25)
    ax.plot([width,width],[0,height], color = 'black', lw = 1.25)

    # -- The top post
    ax.plot([0,width],[height,height], color = 'black', lw = 1.25)

    # -- The data

    data = shot_map_bins(match_id = match_id, team_id = team_id, grid_x = grid_x, grid_y = grid_y, data = data)
    try:
        max_data = max(data)
        scaled_data = [x/max_data for x in data]
        scatter_df['x'] = [((x*width)/2.1) for x in scatter_df['x']]
        scatter_df['y'] = [((y*height)/.7) for y in scatter_df['y']]
        ax.scatter(scatter_df['x'], scatter_df['y'], ec = "black", color = "white", alpha = 0.5, s = 10)
    except:
        scaled_data = [0]*grid_x*grid_y
        data = scaled_data

    # -- The Grid

    increment_x = int(width / grid_x)
    increment_y = int(height / grid_y)

    i = 0
    x = 0
    while x < width:
        for y in range(0, height, increment_y):
            rect = patches.Rectangle(
                    (x, y),  # bottom left starting position (x,y)
                    increment_x,  # width
                    increment_y,  # height
                    ec= main_color,
                    fc= main_color,
                    alpha = scaled_data[i], # <---- the transparency
                    zorder=-1
                )

            ax.add_patch(rect)

            # -- Anotate the counter (i) and choose color depending on value
            if scaled_data[i] < .5:
                color_text = 'black'
                fore_color ='white'
            else:
                color_text = 'white'
                fore_color = 'black'
            label_ = ax.text(
                    x = x + increment_x/2, y = y + increment_y/2,
                    s = f'{data[i]:.0%}', # <----- the data label
                    color = color_text,
                    va = 'center',
                    ha = 'center',
                    size = 7
                    )
            # Set path effects to ensure readability
            label_.set_path_effects(
                [path_effects.Stroke(linewidth=1, foreground=fore_color),
                path_effects.Normal()]
            )

            i += 1
        # -- Once we've placed the top & bottom rectangles we move right.
        x = x + increment_x

    # -- Set axes limits and remove ticks
    ax.set_xlim(-.5,width + .5)
    ax.set_ylim(-.5,height + 1)
    ax.set_axis_off()

    # -- Draw the lower border
    ax.plot([-2,width + 2],[0,0], color = 'black', marker = 'None', lw = 1.25, zorder = 3)

    return ax

# ----------------------------------------------------------------
# The final visual
# ----------------------------------------------------------------

# ----------------------------------------------------------------
# --- Define the grid we'll be using to plot all of the matches.
# %%
layout = [
    ["q1logo_h", ".", "q1logo_a", ".", ".", "q2logo_h", ".", "q2logo_a", "."],
    ["q1goal_h", "q1goal_h", "q1goal_a", "q1goal_a", ".", "q2goal_h", "q2goal_h", "q2goal_a", "q2goal_a"],
    ["."] * 9,
    [".", ".", "s1logo_h", ".", ".", "s1logo_a", ".", ".", "."],
    [".", ".", "s1goal_h", "s1goal_h", ".", "s1goal_a", "s1goal_a", ".", "."],
    ["."] * 9,
    [".", ".", "flogo_h", ".", ".", "flogo_a", ".", ".", "."],
    [".", ".", "fgoal_h", "fgoal_h", ".", "fgoal_a", "fgoal_a", ".", "."],
    ["."] * 9,
    [".", ".", "s2logo_h", ".", ".", "s2logo_a", ".", ".", "."],
    [".", ".", "s2goal_h", "s2goal_h", ".", "s2goal_a", "s2goal_a", ".", "."],
    ["."] * 9,
    ["q3logo_h", ".", "q3logo_a", ".", ".", "q4logo_h", ".", "q4logo_a", "."],
    ["q3goal_h", "q3goal_h", "q3goal_a", "q3goal_a", ".", "q4goal_h", "q4goal_h", "q4goal_a", "q4goal_a"],
]

# -- Fotmob url for logos
fotmob_url = "https://images.fotmob.com/image_resources/logo/teamlogo/"

# Hieght ratios (logo, shotmap, space)
h_ratios = [.35, 1., .25] * 4 + [.35, 1.]

fig = plt.figure(figsize=(12, 8), dpi = 200)
axs = fig.subplot_mosaic(
    layout,
    gridspec_kw = {
        "height_ratios" : h_ratios,
        "width_ratios" : [1]*4 + [0.25] + [1]*4
    }
)

# --- This could have been a function, but was already too invested to change it :(
# --- Sorry for being lazy...

# -------------------- Quarter Finals
# --------------
# England vs. Spain
shot_map_plot(3552651, 5811, axs["q1goal_h"], main_color = "#6fa3e6")
club_icon = Image.open(urllib.request.urlopen(f"{fotmob_url}{5811:.0f}.png"))
axs["q1logo_h"].imshow(club_icon)
x_ = axs["q1logo_h"].get_xlim()[1]
y_ = axs["q1logo_h"].get_ylim()[0]
axs["q1logo_h"].annotate(
    xy = (x_,y_),
    xytext = (5, 0),
    textcoords = "offset points",
    text = "England (2)",
    ha = "left",
    va = "bottom",
    weight = "bold"
)
axs["q1logo_h"].axis("off")
# --
shot_map_plot(3552651, 244165, axs["q1goal_a"], main_color = "#cd4201")
club_icon = Image.open(urllib.request.urlopen(f"{fotmob_url}{244165:.0f}.png"))
axs["q1logo_a"].imshow(club_icon)
x_ = axs["q1logo_a"].get_xlim()[1]
y_ = axs["q1logo_a"].get_ylim()[0]
axs["q1logo_a"].annotate(
    xy = (x_,y_),
    xytext = (5, 0),
    textcoords = "offset points",
    text = "Spain (1)",
    ha = "left",
    va = "bottom"
)
axs["q1logo_a"].axis("off")

# --------------
# Sweden vs. Belgium
shot_map_plot(3552653, 5814, axs["q2goal_h"], main_color = "#3060a8")
club_icon = Image.open(urllib.request.urlopen(f"{fotmob_url}{5814:.0f}.png"))
axs["q2logo_h"].imshow(club_icon)
x_ = axs["q2logo_h"].get_xlim()[1]
y_ = axs["q2logo_h"].get_ylim()[0]
axs["q2logo_h"].annotate(
    xy = (x_,y_),
    xytext = (5, 0),
    textcoords = "offset points",
    text = "Sweden (1)",
    ha = "left",
    va = "bottom",
    weight = "bold"
)
axs["q2logo_h"].axis("off")
# --
shot_map_plot(3552653, 394233, axs["q2goal_a"], main_color = "#333333")
club_icon = Image.open(urllib.request.urlopen(f"{fotmob_url}{394233:.0f}.png"))
axs["q2logo_a"].imshow(club_icon)
x_ = axs["q2logo_a"].get_xlim()[1]
y_ = axs["q2logo_a"].get_ylim()[0]
axs["q2logo_a"].annotate(
    xy = (x_,y_),
    xytext = (5, 0),
    textcoords = "offset points",
    text = "Belgium (0)",
    ha = "left",
    va = "bottom"
)
axs["q2logo_a"].axis("off")

# --------------
# France vs. Netherlands
shot_map_plot(3552654, 6325, axs["q3goal_h"], main_color = "#284898")
club_icon = Image.open(urllib.request.urlopen(f"{fotmob_url}{6325:.0f}.png"))
axs["q3logo_h"].imshow(club_icon)
x_ = axs["q3logo_h"].get_xlim()[1]
y_ = axs["q3logo_h"].get_ylim()[0]
axs["q3logo_h"].annotate(
    xy = (x_,y_),
    xytext = (5, 0),
    textcoords = "offset points",
    text = "France (1)",
    ha = "left",
    va = "bottom",
    weight = "bold"
)
axs["q3logo_h"].axis("off")
# --
shot_map_plot(3552654, 159980, axs["q3goal_a"], main_color = "#ff6d41")
club_icon = Image.open(urllib.request.urlopen(f"{fotmob_url}{159980:.0f}.png"))
axs["q3logo_a"].imshow(club_icon)
x_ = axs["q3logo_a"].get_xlim()[1]
y_ = axs["q3logo_a"].get_ylim()[0]
axs["q3logo_a"].annotate(
    xy = (x_,y_),
    xytext = (5, 0),
    textcoords = "offset points",
    text = "Netherlands (0)",
    ha = "left",
    va = "bottom"
)
axs["q3logo_a"].axis("off")

# --------------
# Germany vs. Austria
shot_map_plot(3552652, 5812, axs["q4goal_h"], main_color = "#000000")
club_icon = Image.open(urllib.request.urlopen(f"{fotmob_url}{5812:.0f}.png"))
axs["q4logo_h"].imshow(club_icon)
x_ = axs["q4logo_h"].get_xlim()[1]
y_ = axs["q4logo_h"].get_ylim()[0]
axs["q4logo_h"].annotate(
    xy = (x_,y_),
    xytext = (5, 0),
    textcoords = "offset points",
    text = "Germany (2)",
    ha = "left",
    va = "bottom",
    weight = "bold"
)
axs["q4logo_h"].axis("off")
# --
shot_map_plot(3552652, 394231, axs["q4goal_a"], main_color = "#EF3340")
club_icon = Image.open(urllib.request.urlopen(f"{fotmob_url}{394231:.0f}.png"))
axs["q4logo_a"].imshow(club_icon)
x_ = axs["q4logo_a"].get_xlim()[1]
y_ = axs["q4logo_a"].get_ylim()[0]
axs["q4logo_a"].annotate(
    xy = (x_,y_),
    xytext = (5, 0),
    textcoords = "offset points",
    text = "Austria (0)",
    ha = "left",
    va = "bottom"
)
axs["q4logo_a"].axis("off")

# -------------------- Semi Finals
# --------------
# England vs. Sweden
shot_map_plot(3552655, 5811, axs["s1goal_h"], main_color = "#6fa3e6")
club_icon = Image.open(urllib.request.urlopen(f"{fotmob_url}{5811:.0f}.png"))
axs["s1logo_h"].imshow(club_icon)
x_ = axs["s1logo_h"].get_xlim()[1]
y_ = axs["s1logo_h"].get_ylim()[0]
axs["s1logo_h"].annotate(
    xy = (x_,y_),
    xytext = (5, 0),
    textcoords = "offset points",
    text = "England (4)",
    ha = "left",
    va = "bottom",
    weight = "bold"
)
axs["s1logo_h"].axis("off")
# --
shot_map_plot(3552655, 5814, axs["s1goal_a"], main_color = "#3060a8")
club_icon = Image.open(urllib.request.urlopen(f"{fotmob_url}{5814:.0f}.png"))
axs["s1logo_a"].imshow(club_icon)
x_ = axs["s1logo_a"].get_xlim()[1]
y_ = axs["s1logo_a"].get_ylim()[0]
axs["s1logo_a"].annotate(
    xy = (x_,y_),
    xytext = (5, 0),
    textcoords = "offset points",
    text = "Sweden (1)",
    ha = "left",
    va = "bottom"
)
axs["s1logo_a"].axis("off")

# --------------
# France vs. Germany
shot_map_plot(3552656, 6325, axs["s2goal_h"], main_color = "#284898")
club_icon = Image.open(urllib.request.urlopen(f"{fotmob_url}{6325:.0f}.png"))
axs["s2logo_h"].imshow(club_icon)
x_ = axs["s2logo_h"].get_xlim()[1]
y_ = axs["s2logo_h"].get_ylim()[0]
axs["s2logo_h"].annotate(
    xy = (x_,y_),
    xytext = (5, 0),
    textcoords = "offset points",
    text = "France (1)",
    ha = "left",
    va = "bottom"
)
axs["s2logo_h"].axis("off")
# --
shot_map_plot(3552656, 5812, axs["s2goal_a"], main_color = "#000000")
club_icon = Image.open(urllib.request.urlopen(f"{fotmob_url}{5812:.0f}.png"))
axs["s2logo_a"].imshow(club_icon)
x_ = axs["s2logo_a"].get_xlim()[1]
y_ = axs["s2logo_a"].get_ylim()[0]
axs["s2logo_a"].annotate(
    xy = (x_,y_),
    xytext = (5, 0),
    textcoords = "offset points",
    text = "Germany (2)",
    ha = "left",
    va = "bottom",
    weight = "bold"
)
axs["s2logo_a"].axis("off")

# ----------- THE FINAL
# England vs. Germany
shot_map_plot(3552657, 5811, axs["fgoal_h"], main_color = "#6fa3e6")
club_icon = Image.open(urllib.request.urlopen(f"{fotmob_url}{5811:.0f}.png"))
axs["flogo_h"].imshow(club_icon)
x_ = axs["flogo_h"].get_xlim()[1]
y_ = axs["flogo_h"].get_ylim()[0]
axs["flogo_h"].annotate(
    xy = (x_,y_),
    xytext = (5, 0),
    textcoords = "offset points",
    text = "England (2)",
    ha = "left",
    va = "bottom",
    weight = "bold"
)
axs["flogo_h"].axis("off")
# --
shot_map_plot(3552657, 5812, axs["fgoal_a"], main_color = "#000000")
club_icon = Image.open(urllib.request.urlopen(f"{fotmob_url}{5812:.0f}.png"))
axs["flogo_a"].imshow(club_icon)
x_ = axs["flogo_a"].get_xlim()[1]
y_ = axs["flogo_a"].get_ylim()[0]
axs["flogo_a"].annotate(
    xy = (x_,y_),
    xytext = (5, 0),
    textcoords = "offset points",
    text = "Germany (1)",
    ha = "left",
    va = "bottom"
)
axs["flogo_a"].axis("off")

trophy_ax = fig.add_axes([0.22, 0.46, 0.06, 0.06])
trophy_icon = Image.open(urllib.request.urlopen(f"https://cdn-icons-png.flaticon.com/512/3112/3112946.png"))
trophy_ax.imshow(trophy_icon)
trophy_ax.axis("off")

fig_text(
    x = 0.15, y = .95,
    s = "Shotmap of the Euro's Knockout Stage",
    va = "bottom", ha = "left",
    fontsize = 16, color = "black", font = "DM Sans", weight = "bold"
)
fig_text(
	x = 0.15, y = .92,
    s = "<Shot-on-target> locations for each match in the <Euro's knockout stage> | 2022 | Viz by @sonofacorner",
    highlight_textprops=[{"weight": "bold", "color": "black"}, {"weight": "bold", "color": "black"}],
	va = "bottom", ha = "left",
	fontsize = 12, color = "#4E616C", font = "Karla"
)

plt.savefig(
	"figures/08012022_womens_euro.png",
	dpi = 600,
	facecolor = "#EFE9E6",
	bbox_inches="tight",
    edgecolor="none",
	transparent = False
)

plt.savefig(
	"figures/08012022_womens_euro_tr.png",
	dpi = 600,
	facecolor = "none",
	bbox_inches="tight",
    edgecolor="none",
	transparent = True
)


from searching.medium_problems.swap_nodes.classes.Node import Node
from searching.medium_problems.swap_nodes.classes.Tree import Tree

class TreeFactory:

    def __init__(self):
        self.tree_root = None
        self.partitioned_indices: list = []
        self.tree_levels: list = []

    def get_constructed_tree(self) -> Tree:
        constructed_tree: Tree = Tree()
        constructed_tree.root = self.tree_root
        constructed_tree.tree_levels = self.tree_levels.copy()
        constructed_tree.depth = len(self.tree_levels) - 1
        return constructed_tree

    def construct_tree_with(self, partitioned_indices: list):

        self.tree_root: Node = Node(1)
        self.partitioned_indices = partitioned_indices
        self.construct_tree_levels_with_partitioned_indices()
        self.connect_levels()

    def construct_tree_levels_with_partitioned_indices(self):
        self.tree_levels.append([self.tree_root])
        for indices_partition in self.partitioned_indices:
            nodes: list = self.construct_nodes_with(indices_partition)
            self.tree_levels.append(nodes)

    @staticmethod
    def construct_nodes_with(indices_partition) -> list:
        nodes: list = []
        for data in indices_partition:
            node: Node = Node(data) if data != -1 else None
            nodes.append(node)
        return nodes

    def connect_levels(self):
        connection_i: int = 0
        connection_j: int = 1
        number_of_connection_steps: int = len(self.tree_levels) - 1
        for _ in range(number_of_connection_steps):
            parents: list = self.tree_levels[connection_i]
            children: list = self.tree_levels[connection_j]
            self.connect(parents, children)
            connection_i += 1
            connection_j += 1

    @staticmethod
    def connect(parents: list, children: list):
        left_child_index: int = 0
        right_child_index: int = 1
        for parent in parents:
            if parent is not None:
                parent.left = children[left_child_index]
                parent.right = children[right_child_index]
                left_child_index += 2
                right_child_index += 2


from django.db import models
import re
from apps.login_app.models import User
import datetime

# Create your models here.
class TripManager(models.Manager):
    def basic_validator(self, postData):
        errors = {}
        # add keys and values to errors dictionary for each invalid field
        if len(postData['destination'])<3:
            errors['destination'] = "Destination should be at least 3 characters"
        if len(postData['plan'])<3:
            errors['plan'] = "Plan should be at least 3 characters"
        if len(postData['start_date'])<7:
            errors['start_date'] = "Please enter a valid date"
        if len(postData['end_date'])<7:
            errors['end_date'] = "Please enter a valid date"
        now = datetime.datetime.now()
        try:
            start = datetime.datetime.strptime(postData['start_date'], '%Y-%m-%d')
            if start<now:
                errors['start_date'] = "Please enter a date in the future"
        except ValueError:
            errors['start_date'] = "Please a valid date format"
        try:
            end = datetime.datetime.strptime(postData['end_date'], '%Y-%m-%d')
            if end<now:
                errors['end_date'] = "Please ensure end date is after start date"
        except ValueError:
            errors['end_date'] = "Please a valid date format"

        print(postData['start_date'])
        print(type(postData['start_date']))

        return errors

class Trip(models.Model):
    destination = models.CharField(max_length=255)
    start_date = models.DateField()
    end_date = models.DateField()
    plan = models.TextField()
    created_by = models.ForeignKey(User, related_name="trips_created")
    members = models.ManyToManyField(User, related_name="trips_joined")
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)
    objects = TripManager()


import numpy as np
import joblib
import os
from ctrls.controller import Controller
import threading
from multiprocessing import Process
import shutil

class InterleavedTestEpochController(Controller):
    """A controller that interleaves a test epoch between training epochs of the agent.

    Parameters
    ----------
    id : int
        The identifier (>= 0) of the mode each test epoch triggered by this controller will belong to.
        Can be used to discriminate between datasets in your Environment subclass (this is the argument that
        will be given to your environment's reset() method when starting the test epoch).
    epoch_length : float
        The total number of transitions that will occur during a test epoch. This means that
        this epoch could feature several episodes if a terminal transition is reached before this budget is
        exhausted.
    controllers_to_disable : list of int
        A list of controllers to disable when this controller wants to start a
        test epoch. These same controllers will be reactivated after this controller has finished dealing with
        its test epoch.
    periodicity : int
        How many epochs are necessary before a test epoch is ran (these controller's epochs
        included: "1 test epoch on [periodicity] epochs"). Minimum value: 2.
    show_score : bool
        Whether to print an informative message on stdout at the end of each test epoch, about
        the total reward obtained in the course of the test epoch.
    summarize_every : int
        How many of this controller's test epochs are necessary before the attached agent's
        summarizeTestPerformance() method is called. Give a value <= 0 for "never". If > 0, the first call will
        occur just after the first test epoch.
    """
    """

    """
    def __init__(self, id=0, epoch_length=500, controllers_to_disable=[], periodicity=2, show_score=True, summarize_every=10, number_tests=10,path_files=".",prefix_file=""):
        """Initializer.
        """

        super(self.__class__, self).__init__()
        self._periodicity = max(2,int(periodicity))
        id = int(id)
        self._epoch_length = int(epoch_length)
        self._to_disable = list(map(int,controllers_to_disable.split(",")))
        self._show_score = show_score
        self._epoch_count = 0
        self._id = int(id)

        self._summary_counter = 0
        self._summary_periodicity = int(summarize_every)

        self._number_tests = int(number_tests)
        self._path_files=path_files
        self._prefix_file = prefix_file

    def onStart(self, agent):
        if (self._active == False):
            return

        self._epoch_count = 0
        self._summary_counter = 0

        try:
            shutil.rmtree(self._path_files + "/", ignore_errors=True)
            os.makedirs(self._path_files)
        except:
            pass

        f = open(self._path_files + "/" + self._prefix_file + "_summary.csv", "w+")
        f.write("epoch;nb_episodes;r_mean;r_var;r_std\n")
        f.close()

    def onEpochEnd(self, agent):
        if (self._active == False):
            return

        mod = self._epoch_count % self._periodicity
        self._epoch_count += 1
        if mod == 0:
            agent.startMode(self._id, self._epoch_length,self._number_tests)
            agent.setControllersActive(self._to_disable, False)
        elif mod == 1:
            self._summary_counter += 1

            scores = []
            nb_episodes = 0
            mean_score,var_score,std_score,nbr_episodes=agent.statRewardsOverLastTests()
            f = open(self._path_files + "/" + self._prefix_file + "_summary.csv", "a+")
            f.write(str(self._epoch_count) + ";" + str(nbr_episodes) + ";" + str(mean_score)+";"+str(var_score)+";"+str(std_score)+"\n")
            f.close()
            if self._show_score:

                print(("Testing" if self._id == 1 else "Validating") + " score per episode (id: {}) is {} (average over {} episode(s) with standard deviation of {})".format(self._id, mean_score, nbr_episodes,std_score))
            if self._summary_periodicity > 0 and self._summary_counter % self._summary_periodicity == 0:
                try:
                    os.makedirs(self._path_files + "/" + "epoch_" + str(self._epoch_count))
                except:
                    pass
                Process(None, agent.summarizeTestPerformance, kwargs={"path_dump" : self._path_files + "/" + "epoch_" + str(self._epoch_count),"prefix_file" : self._prefix_file}).start()
                #agent.summarizeTestPerformance(path_dump=self._path_files + "/" + "epoch_" + str(self._epoch_count),prefix_file=self._prefix_file)

            agent.resumeTrainingMode()
            agent.setControllersActive(self._to_disable, True)


import matplotlib.pyplot as plt
import numpy as np
import re, os, argparse

parser = argparse.ArgumentParser()
parser.add_argument('path', nargs='+')
args = parser.parse_args()

val_re = re.compile('^Validation averagesBCE: (\d+\.\d+)$')
loss_re = re.compile('^loss: (\d+\.\d+)$')
epoch_re = re.compile('^Train epoch (\d+)$')

class Log:
    def __init__(self, name):
        self.name = name
        self.vals = []
        self.losses = []
        self.epochs = []

    def update(self, val, loss, epoch):
        self.vals.append(val)
        self.losses.append(loss)
        self.epochs.append(epoch)

    def get(self):
        vals = np.array(self.vals)
        losses = np.array(self.losses)
        epochs = np.array(self.epochs)

        return vals, losses, epochs

def parse_file(fname):
    log = Log(fname)
    losses = []
    for line in open(fname, 'r'):
        m_epoch = epoch_re.match(line)
        if m_epoch:
            epoch = int(m_epoch.group(1))

        m_val = val_re.match(line)
        if m_val:
            mean_loss = np.array(losses).mean()
            val = float(m_val.group(1))
            log.update(val, mean_loss, epoch)
            losses = []

        m_loss = loss_re.match(line)
        if m_loss:
            losses.append(float(m_loss.group(1)))

    return log

log_re = re.compile('^log(\d+).log$')

def parse_files(search_paths=['.']):
    parsed = dict()

    for base in search_paths:
        for root, dirs, files in os.walk(base):
            for file in files:
                m = log_re.match(file)
                if not m:
                    continue

                path = os.path.join(root, file)
                try:
                    log = parse_file(path)
                except Exception as e:
                    print(f'Exception {e} happened when processing {path}')
                    continue

                if len(log.epochs) > 1:
                    parsed[path] = log

    return parsed

parsed = parse_files(args.path)

fig, (train_ax, test_ax) = plt.subplots(2, 1)
train_ax.set_title('training')
test_ax.set_title('testing')

for i, path in enumerate(parsed):
    color = f'C{i % 10}'

    log = parsed[path]
    train_ax.plot(log.epochs, log.losses, color, label=path)
    test_ax.plot(log.epochs, log.vals, color)

handles, labels = train_ax.get_legend_handles_labels()
fig.legend(handles, labels, loc='upper right')

plt.show()


import cv2 as cv
import os as os
import skimage as skimage
from random import randint
import numpy as np

class DataAugmentation:
	def random_crop(self, img):
		width, height, chanel = img.shape
		x1 = randint(0, int(width*0.7))
		y1 = randint(0, int(height*0.7))

		edge_size = randint(10, width)
		x2 = min(width-1, x1 + edge_size)
		y2 = min(height-1, y1 + edge_size)
		temp = img[x1:x2, y1:y2, :]
		return cv.resize(temp, (height, width))

	def random_erasing(self, img):
		temp = img.copy()
		width, height, chanel = temp.shape
		x1 = randint(0, width)
		y1 = randint(0, height)

		x2 = randint(x1, width)
		y2 = randint(y1, height)

		temp[x1:x2, y1:y2, :] = 0
		return temp

	def contrast(self, img):
		# alpha value [1.0-3.0], beta value [0-100]
		return cv.convertScaleAbs(img, alpha=randint(100, 300) / 100, beta=randint(0, 100))

	def flip_horizontal(self, img):
		return cv.flip(img, 1)

	def flip_vertical(self, img):
		return cv.flip(img, 0)

	def flip_origin(self, img):
		return cv.flip(img, -1)

	def noise(self, img):
		out = skimage.util.random_noise(img, mode="gaussian")
		norm_image = cv.normalize(out, None, alpha=0, beta=255, norm_type=cv.NORM_MINMAX, dtype=cv.CV_32F)

		return norm_image.astype(np.uint8)

	def rotate_90_clockwise(self, img):
		return cv.rotate(img, cv.ROTATE_90_CLOCKWISE)

	def rotate_90_counter_clockwise(self, img):
		return cv.rotate(img, cv.ROTATE_90_COUNTERCLOCKWISE)

	def random_rotation(self, img):
		angle = randint(30, 330)
		height, width = img.shape[:2]
		rotate_matrix = cv.getRotationMatrix2D(center=(width / 2, height / 2), angle=angle, scale=1)
		return cv.warpAffine(src=img, M=rotate_matrix, dsize=(width, height))

	def translation(self, img):
		height, width, _ = img.shape
		x = int(width * 0.3)
		y = int(height * 0.3)
		M = np.float32([[1, 0, randint(-x, x)], [0, 1, randint(-y, y)]])
		return cv.warpAffine(img, M, (width, height))

	def brightness(self, img):
		value = randint(-100, 100)
		hsv = cv.cvtColor(img, cv.COLOR_BGR2HSV)
		h, s, v = cv.split(hsv)
		v = cv.add(v, value)
		v[v > 255] = 255
		v[v < 0] = 0
		final_hsv = cv.merge((h, s, v))
		img = cv.cvtColor(final_hsv, cv.COLOR_HSV2BGR)
		return img

	def saturation(self, img):
		value = randint(-100, 100)
		hsv = cv.cvtColor(img, cv.COLOR_BGR2HSV)
		h, s, v = cv.split(hsv)
		s = cv.add(s, value)
		s[s > 255] = 255
		s[s < 0] = 0
		final_hsv = cv.merge((h, s, v))
		img = cv.cvtColor(final_hsv, cv.COLOR_HSV2BGR)
		return img

	def hue(self, img):
		value = randint(-100, 100)
		hsv = cv.cvtColor(img, cv.COLOR_BGR2HSV)
		h, s, v = cv.split(hsv)
		h = cv.add(h, value)
		h[h > 255] = 255
		h[h < 0] = 0
		final_hsv = cv.merge((h, s, v))
		img = cv.cvtColor(final_hsv, cv.COLOR_HSV2BGR)
		return img

	def grayScale(self, img):
		return cv.cvtColor(img, cv.COLOR_BGR2GRAY)

class Other:
	@staticmethod
	def file_extentions(directory):
		fileExts = set()
		_, _, filenames = next(os.walk(directory))

		for f in filenames:
			_, ext = os.path.splitext(f)
			fileExts.add(ext)

		if '' in fileExts:  # deleting directory extension if exists
			fileExts.remove('')

		return fileExts

	@staticmethod
	def get_method_with_its_name(func_name):
		return getattr(DataAugmentation, func_name)


# -*- coding: utf-8 -*-
"""
    Straply
    ~~~~~~~~

    Main views
"""

import requests

from pprint import pprint

from flask import Blueprint, render_template, flash, redirect, url_for, request, abort, jsonify
from flask_security import login_required, current_user, login_user, logout_user

from . import route
from ..core import db
from ..services import _User
from ..models import User, Card
from ..forms import userSettingsForm

bp = Blueprint('main', __name__)

@route(bp, '/')
def index():
    """Returns the index."""
    return render_template('index.html')

@route(bp, '/trello-router', methods=['GET', 'POST'])
def trello_router():
    """Routes updates to a trello card to the right message on Slack."""
    # pprint(request.json)
    webhook_resp = request.json
    if not webhook_resp:
        return jsonify(dict(OK=True))
    delta = webhook_resp.get('action')
    card_id = delta['data']['card']['id']
    pprint(request.json)

    if delta['type'] in ["createCard", "copyCommentCard"]:
        card = Card(trello_card_id=card_id)
        db.session.add(card)
        db.session.commit()
        print("card id", card_id)

    # Fetch the card from the database
    card = Card.query.filter_by(trello_card_id=card_id).first()

    if delta['type'] == "addLabelToCard":
        # Check to see if it's the weekly commit label
        details = delta['data']
        if "label" in details:
            if details['label']['name'] == "Weekly Commits":
                card = Card.query.filter_by(trello_card_id=card_id).first()
                card.weekly_commits = True
                db.session.commit()

    if delta['type'] == "removeLabelFromCard":
        # Check to see if it's the weekly commit label
        details = delta['data']
        if "label" in details:
            if details['label']['name'] == "Weekly Commits":
                card = Card.query.filter_by(trello_card_id=card_id).first()
                card.weekly_commits = False
                db.session.commit()

    if delta['type'] in ['createCheckItem', 'deleteCheckItem', 'updateCheckItemStateOnCard', 'updateCheckItem']:
        # Is this a weekly commit card?
        if card.weekly_commits:
            print("This is a weekly commit card")
            # Fetch the whole card
            r = requests.get("https://trello.com/1/cards/" + card_id, params={
                "key": "TRELLO_KEY",
                "token": "TRELLO_USER_TOKEN",
                "checklists": "all"
            })
            if r.status_code != 200:
                abort(500)
            full_card = r.json()
            # Send a message to Slack
            pprint(full_card)
            checklist = full_card['checklists'][0]
            text = ""
            for i in checklist['checkItems']:
                if i['state'] == "incomplete":
                    text = text + ":white_square: " + i['name'] + "\n"
                else:
                    text = text + ":white_check_mark:  " + i['name'] + "\n"
            print(text)
            if not card.slack_message_id:
                url = "https://slack.com/api/chat.postMessage"
                data = {
                    "token": "SLACK_TOKEN",
                    "channel": "SLACK_CHANNEL",
                    "as_user": "true",
                    "text": text
                }
            else:
                url = "https://slack.com/api/chat.update"
                data = {
                    "token": "SLACK_TOKEN",
                    "channel": "SLACK_CHANNEL",
                    "as_user": "true",
                    "text": text,
                    "ts": card.slack_message_id
                }
            # Add the message on Slack
            print("Sending this card to slack!")
            sr = requests.post(url, data)
            smessage = sr.json()
            pprint(smessage)
            if 'message' in smessage:
                card.slack_message_id = smessage['message']['ts']
            elif 'ts' in smessage:
                card.slack_message_id = smessage['ts']
            db.session.commit()
        else:
            print("Not a weekly commit card!")

    else:
        card = Card.query.filter_by(trello_card_id=card_id).first()
        if card:
            print("found card", card.trello_card_id, card.slack_message_id)

    return render_template('index.html')

@route(bp, '/preferences', methods=['GET', 'POST'])
@login_required
def preferences():
    """Allows user to change account prefs"""
    form = userSettingsForm(obj=current_user)
    if form.validate_on_submit():
        form.populate_obj(current_user)
        db.session.commit()
        flash('Successfully updated your profile', 'success')
    return render_template('preferences.html', form=form)


import sys
import json
import time
import spacy
#from spacy.tokens import Doc
import random
import logging
import argparse
from collections import defaultdict
from noise.Noiser import Noiser
#from utils.FlaubertTok import FlaubertTok
#from utils.Lexicon import Lexicon
from utils.Utils import create_logger#, MAX_IDS_LEN, KEEP, get_linear, shape_of_word, reshape, build_sentence, Word, PUNCTUATION
#from noise.LemRules import LemRules
#from noise.Misspell import Misspell
#from model.Vocab import Vocab

if __name__ == '__main__':

    parser = argparse.ArgumentParser()
    parser.add_argument('--lex', type=str, default=None, help='Lexicon (pickle) file [required]', required=True)
    parser.add_argument('--pho', type=str, default=None, help='Homophones (pickle) file [required]', required=True)
    parser.add_argument('--lem', type=str, default=None, help='LemRules config file [required]', required=True)
    #
    parser.add_argument('--errors', type=str, default=None, help='Error vocabulary (None) [required]', required=True)
    parser.add_argument('--correc',  type=str, default=None, help='Correction vocabulary (None) [required]', required=True)
    parser.add_argument('--lfeats', type=str, default=None, help='Linguistic features vocabulary (None) [required]', required=True)
    parser.add_argument('--shapes', type=str, default=None, help='Shape vocabulary (None) [required]', required=True)
    parser.add_argument('--inlexi', type=str, default=None, help='Inlexicon vocabulary (None) [required]', required=True)
    #
    parser.add_argument('--max_n', type=int, default=7, help='Maximum number of noises per sentence (7)')
    parser.add_argument('--max_r', type=float, default=0.3, help='Maximum ratio of noises/words per sentence (0.3)')
    parser.add_argument('--p_cor', type=float, default=0.5, help='probability of using cor layer without err (0.5)')
    parser.add_argument('--p_lng', type=float, default=0.5, help='probability of using lng layer without err (0.5)')
    #
    parser.add_argument('--w_phon', type=int, default=4, help='Weight of PHON noise [err/cor] (4)')
    parser.add_argument('--w_lemm', type=int, default=6, help='Weight of LEMM noise [err/cor] (6)')
    parser.add_argument('--w_spel', type=int, default=2, help='Weight of SPEL noise [err/cor] (2)')
    parser.add_argument('--w_apnd', type=int, default=1, help='Weight of APND noise [err/cor] (1)')
    parser.add_argument('--w_splt', type=int, default=1, help='Weight of SPLT noise [err/cor] (1)')
    parser.add_argument('--w_dele', type=int, default=1, help='Weight of DELE noise [err] (1)')
    parser.add_argument('--w_mrge', type=int, default=1, help='Weight of MRGE noise [err] (1)')
    parser.add_argument('--w_hyph', type=int, default=5, help='Weight of HYPH noise [err] (5)')
    parser.add_argument('--w_swap', type=int, default=1, help='Weight of SWAP noise [err] (1)')
    parser.add_argument('--w_case', type=int, default=1, help='Weight of CASE noise [err] (1)')
    #
    parser.add_argument('--seed', type=int, default=0, help='Seed for randomness (0)')
    parser.add_argument('--log', type=str, default="info", help='Log level (info)')
    args = parser.parse_args()
    create_logger(None, args.log)
    logging.info("Options = {}".format(args.__dict__))

    noises = []
    for k,v in args.__dict__.items():
        if k.startswith('w_'):
            noises.append([k[2:], v])

    noiser = Noiser(noises,args.lem,args.lex,args.pho,args.errors,args.correc,args.lfeats,args.shapes,args.inlexi,args.max_n,args.max_r,args.p_cor,args.p_lng,args.seed)

    n_sents = 0
    tic = time.time()
    for l in sys.stdin:
        ldict = noiser(json.loads(l))
        print(json.dumps(ldict, ensure_ascii=False))
        n_sents += 1
        if n_sents%10000 == 0:
            noiser.debug(tic)
    logging.info('Done')
    noiser.debug(tic)


import tensorflow as tf
import numpy as np
import os
import time
import argparse
import cv2
import json
import sys
#import matplotlib.pyplot as plt
#import scipy.ndimage
#import scipy.io
import csv
from UCI.UCIGeneral import UCIDatasetGeneral
import uci_models as model_generator

def parseArguments():
    # Create argument parser
    parser = argparse.ArgumentParser()

    # Positional mandatory arguments
    parser.add_argument("--architecture", type=str, default='reg', help="architecture")
    parser.add_argument("--bn", type=int, default=0, help="batch normalization")
    parser.add_argument("--bn_full", type=int, default=0, help="batch bn_full")
    parser.add_argument("--norm_start", type=int, default=0, help="norm_start")
    parser.add_argument("--norm_end", type=int, default=0, help="norm_end")
    parser.add_argument("--drop", type=int, default=0, help="dropout")
    parser.add_argument("--dataset_index", type=int, default=7, help="index_of_dataset")
    parser.add_argument("--batchsize", type=int, default=50, help="batchsize")
    parser.add_argument("--epochs", type=int, default=100, help="num_of_epochs")
    parser.add_argument("--depth", type=int, default=8, help="net depth")
    parser.add_argument("--dim", type=int, default=362, help="layer_width")
    parser.add_argument("--lr", type=float, default=0.01, help="learning_rate")
    parser.add_argument("--activation", type=str, default='relu', help="activation_type")
    parser.add_argument("--data_path", type=str, default='/path_to_data/data', help="path_of_all_datasets")
    args = parser.parse_args()

    return args

args = parseArguments()

def identity(x):
    return x

norm_start = args.norm_start
norm_end = args.norm_end
drop = args.drop
batchsize = args.batchsize
depth = args.depth
dim = args.dim
lr = args.lr
epochs = args.epochs
architecture = args.architecture
if args.activation=='id':
    activation = identity
if args.activation=='elu':
    activation = tf.nn.elu
if args.activation=='relu':
    activation = tf.nn.relu
if args.activation=='selu':
    activation = tf.nn.selu
bn = args.bn
bn_full = args.bn_full
data_path = args.data_path
datasets = os.listdir(data_path)
dataset_idx = args.dataset_index

sets = ['cardiotocography-3clases','contrac','mushroom','pendigits','magic','chess-krvk','led-display','plant-margin','steel-plates','statlog-vehicle',
        'statlog-heart','waveform','bank','waveform-noise','statlog-shuttle','plant-shape','statlog-landsat','plant-texture','twonorm','connect-4',
        'page-blocks','wall-following','thyroid','oocytes_merluccius_nucleus_4d','hill-valley','semeion','oocytes_merluccius_states_2f','miniboone',
        'ozone','wine-quality-white','letter','chess-krvkp','adult','yeast','cardiotocography-10clases','statlog-image','optical','titanic','ringnorm','abalone']
trainset = UCIDatasetGeneral(dataset = datasets[datasets.index(sets[dataset_idx])], root=data_path, train=True, fold = 0)

train_data = trainset.train_data
val_data = trainset.validation_data
test_data = trainset.test_data
num_of_labels = trainset.num_classes
input_dim = trainset.input_dim()

data_node  = tf.placeholder(tf.float32, shape=[None, input_dim], name='data')
labels_node = tf.placeholder(tf.int32, shape=[None], name='labels')
lr_node = tf.placeholder(tf.float32,shape=(), name='learning_rate')
isTrain_node = tf.Variable(False, name='istrainvar', trainable = False)
tf.add_to_collection('istrainvar',isTrain_node)

train_data = trainset.train_data
val_data = trainset.validation_data
test_data = trainset.test_data

train_labels = trainset.train_labels
val_labels = trainset.validation_labels
test_labels = trainset.test_labels

current_depth = [8,16,32]
#current_depth = [8]
logits = []
loss = []
trainable_vars = []
train_op = []
predictions = []
correct_prediction = []
err = []
optimizer = tf.train.MomentumOptimizer(lr_node, 0.9)
for i in range(len(current_depth)):
    with tf.variable_scope("depth_"+str(current_depth[i])) as scope:
        if architecture=='ml':
            activation = tf.nn.relu
            logits.append(model_generator.model(data_node, input_dim, dim, num_of_labels, current_depth[i], isTrain_node, bn, norm_start, norm_end))

        if architecture=='mlorth':
            activation = tf.nn.relu
            logits.append(model_generator.model2(data_node, input_dim, dim, num_of_labels, current_depth[i], isTrain_node, bn, norm_start, norm_end))

        if architecture=='reg':
                logits.append(model_generator.reg_architecture(data_node, input_dim, dim, num_of_labels, current_depth[i], isTrain_node, activation, bn, bn_full, norm_start, norm_end))
        if architecture=='rel':
                logits.append(model_generator.rel_architecture(data_node, input_dim, dim, num_of_labels, current_depth[i], isTrain_node, activation, bn, bn_full, norm_start, norm_end))

        if architecture=='res':
            logits.append(model_generator.res_architecture(data_node, dim, num_of_labels, activation, current_depth[i], isTrain_node, bn))
        if architecture=='res2':
            logits.append(model_generator.res_architecture2(data_node, dim, num_of_labels, activation, current_depth[i], isTrain_node, bn))

        loss.append(tf.reduce_mean(tf.nn.sparse_softmax_cross_entropy_with_logits(logits = logits[-1],labels = labels_node)))
        trainable_vars.append(tf.get_collection(tf.GraphKeys.TRAINABLE_VARIABLES,"depth_"+str(current_depth[i])))
        train_op.append(optimizer.minimize(loss[-1], var_list = trainable_vars[-1]))

        predictions.append(logits[-1])
        correct_prediction.append(tf.equal(tf.cast(tf.argmax(predictions[-1], 1), tf.int32), labels_node))
        err.append(1 - tf.reduce_mean(tf.cast(correct_prediction[-1], 'float')))

lr_schedule = [0.1,0.01,0.001]
#lr_schedule = [0.01]
session = tf.Session()
feed_dict = {}
ini = tf.global_variables_initializer()
print("dataset: %s, dataset_index: [%5d], dim: [%5d], activation: %s, bn: [%5d], bn_full: [%5d], norm_start: [%5d], norm_end: [%5d], architecture: %s"  % (str(sets[dataset_idx]), datasets.index(sets[dataset_idx]), dim, activation, bn, bn_full, norm_start, norm_end, architecture))

agg_test_errors = []
agg_smoothed_val_errors = []
for depth_loop in range(len(current_depth)):
    for lr_loop in range(len(lr_schedule)):
        lr = lr_schedule[lr_loop]
        depth = current_depth[depth_loop]
        train_op_net = train_op[depth_loop]
        error = err[depth_loop]
        feed_dict[lr_node] = lr
        test_error_folds = []
        smoothed_val_error_folds = []

        for outer_outer in range(1):
            print(outer_outer)
            for outer in range(4):
                trainset = UCIDatasetGeneral(dataset = datasets[datasets.index(sets[dataset_idx])], root=data_path, train=True, fold = outer)
                train_data = trainset.train_data

                val_data = trainset.validation_data
                test_data = trainset.test_data

                train_labels = trainset.train_labels
                val_labels = trainset.validation_labels
                test_labels = trainset.test_labels

                session.run(ini)
                error_plot_train = []
                error_plot_test = []
                error_plot_val = []

                for i in range(epochs):
                    if i>50:
                        feed_dict[lr_node] = lr/10

                    avg_error = 0
                    perm = np.random.permutation(train_data.shape[0])
                    perm = np.concatenate((perm,perm),0)
                    itter = 0
                    session.run(isTrain_node.assign(True))
                    for idx in range(0,train_data.shape[0],batchsize):
                        batch_idx = perm[idx:idx + batchsize]
                        perm_val = np.random.permutation(test_data.shape[0])
                        feed_dict[data_node] = train_data[batch_idx,:]
                        feed_dict[labels_node] = train_labels[batch_idx]
                        time_end_h5 = time.time()
                        _, error_val = session.run([train_op_net, error], feed_dict = feed_dict)
                        time_end_run    = time.time()
                        avg_error+=error_val
                        itter+=1
                    error_plot_train.append(avg_error/(itter))

                    avg_test_error = 0
                    session.run(isTrain_node.assign(False))
                    for idx in range(test_data.shape[0]):
                        feed_dict[data_node] = test_data[idx:idx+1,:]
                        feed_dict[labels_node] = test_labels[idx:idx+1]
                        error_test = session.run(error, feed_dict = feed_dict)
                        avg_test_error+=error_test
                    error_plot_test.append(avg_test_error/(test_data.shape[0]))

                    avg_val_error = 0
                    for idx in range(val_data.shape[0]):
                        feed_dict[data_node] = val_data[idx:idx+1,:]
                        feed_dict[labels_node] = val_labels[idx:idx+1]
                        error_val = session.run(error, feed_dict = feed_dict)
                        avg_val_error+=error_val
                    error_plot_val.append(avg_val_error/(val_data.shape[0]))

#                    print('_______________________________________________________________')
#                    print("dataset: %s, dataset_index: [%5d], dim: [%5d], depth: [%5d], lr: %.8f, activation: %s, bn: [%5d], architecture: %s"  % (str(sets[dataset_idx]), datasets.index(sets[dataset_idx]), dim, current_depth[depth_loop], lr_schedule[lr_loop], activation, bn, architecture))
#                    print("Testing: epoch [%5d], train error: %.8f, test error: %.8f, val_error: %.8f" % (i, error_plot_train[i], error_plot_test[i], error_plot_val[i]))

                min_smoothed_val = 1
                for i in range(5,len(error_plot_val)):
                    smoothed_val = np.mean(error_plot_val[i - 5:i])
                    if smoothed_val<min_smoothed_val:
                        min_smoothed_val = smoothed_val
                        test_error = error_plot_test[i - 3]
                test_error_folds.append(test_error)
                smoothed_val_error_folds.append(min_smoothed_val)

        agg_test_errors.append(np.mean(test_error_folds))
        agg_smoothed_val_errors.append(np.mean(smoothed_val_error_folds))
        print("depth: [%5d], lr: %.8f, test_error_mean: %.8f, test_error_std: %.8f, smoothed_val_error_mean: %.8f, smoothed_val_error_std: %.8f"  % (current_depth[depth_loop], lr_schedule[lr_loop], np.mean(test_error_folds), np.std(test_error_folds), np.mean(smoothed_val_error_folds),np.std(smoothed_val_error_folds)))
final_test_error =  agg_test_errors[agg_smoothed_val_errors.index(min(agg_smoothed_val_errors))]
print("final_test_error: %.8f"  % (final_test_error))


"""
We referred to the examples provided by
https://github.com/pytorch/examples/tree/master/vae and
https://github.com/wiseodd/generative-models/tree/master/VAE/conditional_vae
"""
import torch as th
import torch.nn as nn
import torch.nn.functional as F
from torch.autograd import Variable

class Value(nn.Module):
    """
    Define a value network for estimating state values.
    """
    def __init__(self):
        super(Value, self).__init__()
        self.fc1 = nn.Linear(6, 600)
        self.fc2 = nn.Linear(600, 1)

    def forward(self, s):
        """

        Parameters
        ----------
        s: Variable whose data is Tensor of shape n x 6 with requires_grad=False
            state signal sent by the environment

        Returns
        -------
        v: Variable whose data is Tensor of shape n x 1 with requires_grad=True
            This estimates the state value at s.
        """
        return self.fc2(F.tanh(self.fc1(s)))

class Fnn(nn.Module):
    """
    Define a feedforward neural network which will be used as the feedforward policy.
    """
    def __init__(self):
        super(Fnn, self).__init__()
        self.fc1 = nn.Linear(6, 600)
        self.fc2 = nn.Linear(600, 3)

    def forward(self, s):
        """

        Parameters
        ----------
        s: Variable whose data is Tensor of shape 1 x 6 with requires_grad=False
            state signal sent by the environment

        Returns
        -------
        p: Variable whose data is Tensor of shape 1 x 3 with requires_grad=True
           The data of p may be interpreted as probability of taking discrete
           action 1, 2, 3 separately.
        """
        s_ = F.tanh(self.fc1(s))
        p = F.softmax(F.tanh(self.fc2(s_)))
        return p

class Cvae(nn.Module):
    """
    Define a CVAE model which will be used as the CVAE policy.
    """
    def __init__(self):
        super(Cvae, self).__init__()
        self.fc1 = nn.Linear(9, 500)
        self.fc21 = nn.Linear(500, 24)
        self.fc22 = nn.Linear(500, 24)
        self.fc3 = nn.Linear(30, 3)

    def encode(self, x):
        """

        Parameters
        ----------
        x: Variable whose data is Tensor of shape n x 9 with requires_grad=False
            x = (s, a) with a one-hot representation of a. Note when we are collecting
            real-time experience, where the corresponding actions are unknown, simply set
            a = [0, 0, 0].

        Returns
        -------
        mu_h: Variable whose data is Tensor of shape n x 24 with requires_grad=True
            mean of the modeled gaussian distribution for h
        log_var_h: Variable whose data is Tensor of shape n x 24 with requires_grad=True
            logarithm of the covariance of the modeled gaussian distribution for h
        """
        x_ = F.tanh(self.fc1(x))
        return F.tanh(self.fc21(x_)), F.tanh(self.fc22(x_))

    @staticmethod
    def reparameterize(mu_h, log_var_h):
        """
        Perform the reparametrization trick. The reparametrization trick in VAE
        makes it tractable for BP to improve the distribution of h.

        Parameters
        ----------
        mu_h: Variable whose data is Tensor of shape n x 24 with requires_grad=True
            mean of the modeled gaussian distribution for h
        log_var_h: Variable whose data is Tensor of shape n x 24 with requires_grad=True
            logarithm of the covariance of the modeled gaussian distribution for h

        Returns
        -------
        h_sampled: Variable whose data is Tensor of shape n x 24 with requires_grad=True
            h_sampled = mu_h + epsilon x covariance, where epsilon is sampled from a
            standard normal distribution
        """
        std = log_var_h.mul(0.5).exp_()
        epsilon = th.Tensor(std.size()).normal_()
        epsilon = Variable(epsilon, requires_grad=False).type(th.Tensor)
        return epsilon.mul(std).add_(mu_h)

    def forward(self, x):
        """
        Reconstruct a given (s,a).

        Parameters
        ----------
        x: Variable whose data is Tensor of shape n x 9 with requires_grad=False
            x = (s, a) with a one-hot representation of a. Note when we are collecting
            real-time experience, where the corresponding actions are unknown, simply set
            a = [0, 0, 0].

        Returns
        -------
        p: Variable whose data is Tensor of shape n x 3 with requires_grad=True
           The data of p may be interpreted as probability of taking discrete
           action 1, 2, 3 separately.
        """
        mu_h, log_var_h = self.encode(x)
        indices = th.arange(0, 6).type(th.LongTensor)
        h = self.reparameterize(mu_h, log_var_h)
        p = F.softmax(F.tanh(self.fc3(th.cat([x.index_select(1, indices), h], 1))))
        # Note we return the mean and covariance of the modeled Gaussian and they will be
        # used to calculate the closed form KL divergence between the distribution of
        # p(h|s,a) and the distribution of p(h|s).
        return mu_h, log_var_h, p


import logging
import sys
from redis import Redis
from botocore.exceptions import ClientError
import json
import time
from threading import Timer
import boto3
import uuid
import os
# Setup logging to stdout
logger = logging.getLogger(__name__)
logging.basicConfig(stream=sys.stdout, level=logging.DEBUG)

DYNAMO_DB = "Raspberry_Car_Object"
S3_BUCKET = "iot-raspberry-car"
S3_KEY = "camera_images/"

def s3_upload(img_local_path):
    try:
        logging.debug("s3_upload: entry")
        file_name = os.path.basename(img_local_path)
        s3 =boto3.resource('s3')
        logging.debug("s3_upload: client loaded.")
        s3.meta.client.upload_file(img_local_path, S3_BUCKET, S3_KEY+file_name)
        #s3_client.upload_file(img_local_path, S3_BUCKET, S3_KEY+file_name)
        logging.debug("s3_upload: success: ")
        logging.debug("s3_upload: %s"%img_local_path)
        logging.debug("s3_upload: %s"%S3_BUCKET)
        logging.debug("s3_upload: %s"%file_name)
    except ClientError as e:
        logging.error(e)
        return False
    return True

def upload_img_to_cloud():
    try:
        cli = Redis('localhost')
        while True:
            item = cli.lpop('car')
            if not item:
                logger.info("car queue is empty")
                break
            dt = json.loads(item)
            img_local_path = str(dt['img_local_path'])
            detection_time = str(dt['detection_time'])
            position = str(dt['position'])
            rfid_pos = str(dt['rfid_pos'])
            logging.debug("redis data is below: ")
            logging.debug(dt)
            if s3_upload(img_local_path):
                uniqueid = uuid.uuid4().hex
                file_name = os.path.basename(img_local_path)
                try:
                    logging.debug("dynamodb: entry")
                    dynamodb_client = boto3.client('dynamodb')
                    dynamodb_client.put_item(TableName=DYNAMO_DB,
                                Item={'detection_time': {'S':detection_time},
                                    'position':{'S': position},
                                    'rfid_pos':{'S': rfid_pos},
                                    's3_path':{'S': S3_KEY+file_name},
                                    'hash_tag':{'S': uniqueid} })
                    logging.debug("dynamodb: success")
                except ClientError as e:
                    logger.error(e)

    except Exception as e:
        logger.error("upload_img_to_cloud error: " + repr(e))

    # Asynchronously schedule this function to be run again in 5 seconds
    Timer(10, upload_img_to_cloud).start()

# Start executing the function above
upload_img_to_cloud()

# This is a dummy handler and will not be invoked
# Instead the code above will be executed in an infinite loop for our example
def function_handler(event, context):
    return


#!/usr/bin/env python

import socket
import sys
import os

# host to listen on
host = '0.0.0.0'

# create raw socket and bind to public iface
if os.name == 'nt':
	socket_protocol = socket.IPPROTO_IP
else:
	socket_protocol = socket.IPPROTO_ICMP

sniffer = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket_protocol)

sniffer.bind((host, 0))

# want the IP headers included in capture
sniffer.setsockopt(socket.IPPROTO_IP, socket.IP_HDRINCL, 1)

# if we're using Windows we need to send an IOCTL to set up
# promiscuous mode
if os.name == "nt":
	sniffer.ioctl(socket.SIO_RCVALL, socket.RCVALL_ON)

# Read a single packet capture
print(sniffer.recvfrom(65565))

# If we're using Windows, turn off promiscuous mode
if os.name == "nt":
	sniffer.ioctl(socket.SIO_RCVALL, socket.RCVALL_OFF)


from pylab import *

figure(figsize = (8, 6), dpi = 80) # set the size and dpi of this plot
subplot(1, 1, 1)

X = np.linspace(-np.pi, np.pi, 256, endpoint = True)
C = np.cos(X)
S = np.sin(X)

plot(X, C, color = "blue", linewidth = 2.0, linestyle = "-", label = "cosine")
plot(X, S, color = "red", linewidth = 2.0, linestyle = "-", label = "sine")
legend(loc = "upper left")

xlim(-4.0, 4.0) # set x limits

xticks([-np.pi, -np.pi / 2, 0, np.pi /2 , np.pi],
       [r'$-\pi$', r'$-\pi/2$', r'$0$', r'$+\pi/2$', r'$+\pi$'])
# set x ticks in LaTeX format

ylim(-1.1, 1.1) # set y limits
yticks([-1, 1],
       [r'$-1$', r'$+1$'])
# set y ticks in LaTeX format

# set spines' location
ax = gca()
ax.spines['right'].set_color('none')
ax.spines['top'].set_color('none')
ax.spines['bottom'].set_position(('data', 0))
ax.spines['left'].set_position(('data', 0))
ax.xaxis.set_ticks_position('bottom')
ax.yaxis.set_ticks_position('left')

# add annotate points
t = 2 * np.pi / 3
ax.plot([t, t], [0, np.cos(t)], color = "blue", linewidth = 2.0, linestyle = "--")
ax.plot([t, t], [0, np.sin(t)], color = "red", linewidth = 2.0, linestyle =
"--")

ax.scatter([t, ], [np.cos(t), ], 50, color = "blue")
ax.scatter([t, ], [np.sin(t), ], 50, color = "red")

ax.annotate(r'$\cos(\frac{2\pi}{3})=-\frac{1}{2}$',
            xy = (t, np.cos(t)),
            xycoords = "data",
            xytext = (-90, -50),
            textcoords = "offset points",
            fontsize = 16,
            arrowprops = dict(arrowstyle = "->", connectionstyle =
                "arc3,rad=.0"))

ax.annotate(r'$\sin\frac{2\pi}{3})=\frac{\sqrt{3}}{2}$',
            xy = (t, np.sin(t)),
            xycoords = "data",
            xytext = (10, 30),
            textcoords = "offset points",
            fontsize = 16,
            arrowprops = dict(arrowstyle = "->", connectionstyle =
                "arc3,rad=.0"))

savefig("Example_1", dpi = 200)

show()


from odoo import api, fields, models, _
from odoo.exceptions import UserError
import logging

class SaleOrder(models.Model):
    _inherit = "sale.order"

    state = fields.Selection([
        ('draft', 'Quotation'),
        ('waiting', 'Waiting for Approval'),
        ('sent', 'Quotation Sent'),
        ('sale', 'Sales Order'),
        ('done', 'Locked'),
        ('cancel', 'Cancelled'),
        ], string='Status', readonly=True, copy=False, index=True, track_visibility='onchange', default='draft')

    @api.multi
    def check_limit(self):
        self.ensure_one()
        if self._context.get('bypass_check_limit'):
            return True
        partner = self.partner_id
        moveline_obj = self.env['account.move.line']
        movelines = moveline_obj.search(
            [('partner_id', '=', partner.id),
             ('account_id.user_type_id.name', 'in', ['Receivable']),
             ('amount_residual', '>', 0)
            ]
        )
        confirm_sale_order = self.search([('partner_id', '=', partner.id), ('state', '=', 'sale')])
        debit, credit = 0.0, 0.0
        amount_total = 0.0
        for status in confirm_sale_order:
            amount_total += status.amount_total
        for line in movelines:
            credit += line.credit
            debit += line.debit
        partner_credit_limit = (partner.credit_limit - debit) + credit
        available_credit_limit = ((partner_credit_limit - (amount_total - debit)) + self.amount_total)

        msg = False
        if (amount_total - debit) > partner_credit_limit:
            if not partner.over_credit:
                msg = 'You can not confirm Sale Order.
 Your available credit limit'\
                      ' Amount = %s
Check "%s" Accounts or Credit ' \
                      'Limits.' % (available_credit_limit,
                                   self.partner_id.name)
            partner.write({'credit_limit': credit - debit + self.amount_total})

        if not msg:
            return True

        view = self.env.ref('pcla_via_telegram.view_send_approval')
        start = view.arch.index('
') + 3
        end = view.arch.index('
') - 1
        sentence = view.arch[start:end]
        view.arch = view.arch.replace(sentence, msg)
        wiz = self.env['send.approval'].create({'sale_ids': [(4, s.id) for s in self]})
        return {
            'name': _('Credit Limit Approval'),
            'type': 'ir.actions.act_window',
            'view_type': 'form',
            'view_mode': 'form',
            'res_model': 'send.approval',
            'views': [(view.id, 'form')],
            'view_id': view.id,
            'target': 'new',
            'res_id': wiz.id,
            'context': dict(self.env.context, available_credit_limit=available_credit_limit),
        }

    @api.multi
    def confirm_sale(self):
        for order in self:
            res = order.check_limit()
            if isinstance(res, dict):
                return res
        return self.action_confirm()

    def process_sale_order(self, approve):
        if approve:
            return self.with_context({'bypass_check_limit': True}).action_confirm()
        else:
            return self.action_cancel()


# CH3 Greedy 92p <2> 큰 수의 법칙

if __name__=='__main__':
    # N: 배열의 크기
    # M: 숫자가 더해지는 횟수
    # K: 연속으로 수를 더할 수 있는 횟수
    N, M, K = map(int, input("N(2<=N<=1000), M(1<=M<=10000), K(1<=K<=10000) 입력:").split())

    data = list(map(int, input("list 원소 입력(1<x<10000):").split()))

    data.sort()

    result = 0
    while M!=0:
        if M < K:
            result += M * data[N-1]
            M = 0
            break
        else:
            result += K * data[N-1]
            M = M-K

        N -= 1

    print("Output: {}".format(result))


"""Implementation of the binary tree maze."""
from random import choice, random

from mazes.primitives import Grid

def binary_tree(grid: Grid) -> None:
    """Just a basic bitch binary tree."""
    # since we are moving from the north west point instead
    # of the south west point, this basic walk flips the options
    # from north/east to south/east
    for position, cell in grid.each_cell():
        possible_directions = {}

        # account for the south direction
        if position[0] < grid.inner.shape[0] - 1:
            possible_directions["south"] = (position[0] + 1, position[1])

        # account for the east direction
        if position[1] < grid.inner.shape[1] - 1:
            possible_directions["east"] = (position[0], position[1] + 1)

        if not possible_directions:
            # this happens when we are at the corner
            # which means we're done
            return

        random_direction = choice(list(possible_directions.keys()))

        setattr(cell, random_direction, grid[possible_directions[random_direction]])


# qr_decomposition.py
"""Volume 1A: QR 1 (Decomposition).
<Juan>
<M345GL>
<October the last>
"""

import numpy as np
import scipy
from scipy import linalg as la

# Problem 1
def qr_gram_schmidt(A):
    """Compute the reduced QR decomposition of A via Modified Gram-Schmidt.

    Inputs:
        A ((m,n) ndarray): A matrix of rank n.

    Returns:
        Q ((m,n) ndarray): An orthonormal matrix.
        R ((n,n) ndarray): An upper triangular matrix.
    """
    m,n = np.shape(A)
    Q = np.copy(A)
    R = np.zeros((n,n))
    for i in xrange(n):
        R[i,i] = scipy.linalg.norm(Q[:,i])
        Q[:,i] = Q[:,i]/R[i,i]
        for j in xrange(i+1,n):
            R[i,j] = Q[:,j].T.dot(Q[:,i])
            Q[:,j] = Q[:,j] - R[i,j]*(Q[:,i])
    return Q,R

# Problem 2
def abs_det(A):
    """Use the QR decomposition to efficiently compute the absolute value of
    the determinant of A.

    Inputs:
        A ((n,n) ndarray): A square matrix.

    Returns:
        (float) the absolute value of the detetminant of A.
    """
    return np.absolute(np.prod(np.diag(qr_gram_schmidt(A)[1])))

# Problem 3
def solve(A, b):
    """Use the QR decomposition to efficiently solve the system Ax = b.

    Inputs:
        A ((n,n) ndarray): An invertible matrix.
        b ((n, ) ndarray): A vector of length n.

    Returns:
        x ((n, ) ndarray): The solution to the system Ax = b.
    """
    Q,R = la.qr(A, mode="economic")
    Y = Q.T.dot(b)

    m = len(Y)
    X = [0]*(m)
    for k in xrange(m-1,-1,-1):             #k represents the row
        sumb = 0
        for l in xrange(m-1, k, -1):         #l represents the column
            sumb += R[k,l]*X[l]
        X[k]=(Y[k]-sumb)*(1/R[k][k])
    return X

# Problem 4
def qr_householder(A):
    """Compute the full QR decomposition of A via Householder reflections.

    Inputs:
        A ((m,n) ndarray): A matrix of rank n.

    Returns:
        Q ((m,m) ndarray): An orthonormal matrix.
        R ((m,n) ndarray): An upper triangular matrix.
    """
    sign = lambda x: 1 if x >= 0 else -1

    m,n = np.shape(A)
    R = np.copy(A)
    Q = np.identity(m)

    for k in xrange(n):

        u = np.copy(R[k:,k])
        u[0] = u[0] + sign(u[0])*scipy.linalg.norm(u)
        u = u/scipy.linalg.norm(u)
        R[k:,k:] = R[k:,k:] - 2*np.outer(u,(u.T.dot(R[k:,k:])))
        Q[k:,:] = Q[k:,:] - 2*np.outer(u,(u.T.dot(Q[k:,:])))

    return Q.T, R

# Problem 5
def hessenberg(A):
    """Compute the Hessenberg form H of A, along with the orthonormal matrix Q
    such that A = QHQ^T.

    Inputs:
        A ((n,n) ndarray): An invertible matrix.

    Returns:
        H ((n,n) ndarray): The upper Hessenberg form of A.
        Q ((n,n) ndarray): An orthonormal matrix.
    """
    m,n = np.shape(A)
    H = np.copy(A)
    Q = np.identity(n)
    for k in xrange(n-2):
        u = np.copy(H[(k+1):, k])
        u[0] = u[0] + scipy.linalg.norm(u)
        u = u/scipy.linalg.norm(u)

        H[(k+1):, k:] = H[(k+1):, k:] - np.outer(2*u,(np.dot(np.transpose(u),(H[(k+1):, k:]))))
        H[:,k+1:] = H[:,k+1:] - 2*np.outer((H[:,(k+1):].dot(u)), (u.T))
        Q[k+1:,:] = Q[k+1:,:] - 2*np.outer(u,(u.T.dot(Q[(k+1):,:])))

    return H, np.transpose(Q)

    """

if __name__ == "__main__":
    #prob4
    A = np.random.random((5, 3))
    Q,R = la.qr(A)
    q,r = qr_householder(A)
    print A.shape, q.shape, r.shape
    print np.allclose(q.dot(r), A)

    #prob5
    A = np.random.random((8,8))
    H, Q = la.hessenberg(A, calc_q=True)
    h, q = hessenberg(A)

    print np.allclose(np.triu(h, -1), h)
    print np.allclose(np.dot(np.dot(q, h), q.T), A)

    #Problem 1 tester
    B = np.copy(A)
    Q,R = la.qr(A, mode="economic")
    S,T = qr_gram_schmidt(B)
    print Q
    print S
    print R

    print T
    print np.allclose(np.dot(S, T), B)

    #problem 3 tester
    A_ = np.copy(A)
    b_ = np.copy(b)
    print solve(A,b)
    print la.solve(A_,b_)
    """


string = list(input())
stack = []
num = 0
# 레이저 나오면 스택 길이 num에 저장, 닫는괄호나오면 +1
for i in range(len(string)):
    if string[i] == '(':
        stack.append(string[i])
    elif string[i] == ')':
        if string[i-1] =='(':
            stack.pop(-1)
            num += len(stack)
        else:
            stack.pop(-1)
            num += 1
print(num)


from django.core.mail import send_mail, EmailMultiAlternatives
from django.conf import settings
from django.template.loader import get_template

def email_confirmation(email, conf_number, url, first_name, last_name):
    subject=f'STAUD Agent Confirmation'
    body=f""
    from_email=settings.EMAIL_HOST_USER
    recipient_list=[email]
    message = EmailMultiAlternatives(subject=subject, body=body, from_email=from_email, to=recipient_list)
    html_template = get_template('accounts/agent_confirmation.html').render(context={'email': email, "conf_number": conf_number, "url": url,
                                                                                'first_name':first_name, 'last_name': last_name})
    message.attach_alternative(html_template, 'text/html')
    message.send()


# 문자열 word가 주어질 때, 해당 문자열에서 모음의 갯수를 출력하시오.
# 모음 : a, e, i, o, u
# count() 사용 금지

A = input()
cnt = 0
a = []
for i in range(len(A)):
    letter = A[i]
    a.append(letter)
for i in range(len(A)):
    if a[i] == 'a' or a[i] == 'e' or a[i] == 'i' or a[i] == 'o' or a[i] == 'u':
        cnt += 1
print(cnt)

# 리스트가 필요할까
b = input()
cnt1 = 0
for i in b:
    if i=='a' or i=='e' or i=='i' or i=='o' or i=='u':
        cnt1 += 1
print(cnt1)

#수업추가풀이
c = input()
cnt2 = 0
for i in c:
    if i in 'aeiou':
        cnt2 += 1
print(cnt2)

#한줄샷
d = input()
print(''in d)


"""
SQLite managing class definition
"""
import sqlite3
import os
import traceback
from sqlite3 import Error, DatabaseError
from app_lib.utils.files_utils import transform_path

class DataBase:
    """
    Main class to manage SQLite database
    """

    insert_query = "INSERT INTO {table_name} VALUES (?, ? ,? ,?)"
    table_name = ''

    def __init__(self):
        db_location = str(os.getcwd()).split('app_lib')[0] + transform_path('/app_lib/DDBB/sqlite/crypto_database')
        self.connection = sqlite3.connect(db_location)
        self.cursor = self.connection.cursor()

    def close(self) -> None:
        """
        Close the current open connection
        :return:
        """
        self.connection.close()

    def create_table(self) -> None:
        """
        Create table if it does not exist
        :return:
        """
        self.cursor.execute(
            f"CREATE TABLE {self.table_name} (DATE INTEGER, CLOSE REAL, MAXIMUM REAL, MINIMUM REAL)"
        )

    def check_if_table_exists(self) -> bool:
        """
        Checks if selected table already exists
        :return:
        """
        self.cursor.execute(
            f"SELECT name FROM sqlite_master WHERE name == '{self.table_name}'"
        )
        db_result = self.cursor.fetchone()
        if db_result and self.table_name in db_result:
            return True
        return False

    def set_array_data(self, tuples_array: list) -> None:
        """
        Insert many rows into the database
        :param tuples_array:
        :return:
        """
        self.cursor.executemany(
            self.insert_query.format(table_name=self.table_name),
            tuples_array
        )
        self.connection.commit()

    def set_data(self, tuple_data: tuple) -> None:
        """
        Insert a row into the database
        :param tuple_data:
        :return:
        """
        self.cursor.execute(
            self.insert_query.format(table_name=self.table_name),
            tuple_data
        )
        self.connection.commit()

    def get_data(self, date_init: int = None, date_end: int = None, select_columns: str = '*'):
        """
        Search and return data between given dates
        :param date_init: integer with YYYYMMDD form
        :param date_end: integer with YYYYMMDD form
        :param select_columns: columns to select from database
        :return:
        """
        get_query = f"SELECT {select_columns} FROM {self.table_name}"
        if date_init or date_end:
            get_query = get_query + " WHERE "
            if date_init:
                get_query = get_query + f"date >= {date_init}"
            if date_end:
                if date_init:
                    get_query = get_query + " AND "
                get_query = get_query + f"date <= {date_end}"
        get_query += " ORDER BY DATE DESC"
        self.cursor.execute(get_query)
        return self.cursor.fetchall()

    def get_close_prices(self, date_init: int = None, date_end: int = None):
        return_data = []
        try:
            return_data = self.get_data(
                date_init=date_init, date_end=date_end, select_columns='DATE, CLOSE'
            )
        except Error as ex:
            print('%s\n%s', ex, traceback.format_exc())
        except Exception as ex:
            print('%s\n%s', ex, traceback.format_exc())
        finally:
            return return_data


from flask import Blueprint, request, jsonify
from flask_jwt_extended import jwt_required
from flask_cors import CORS

from http import HTTPStatus

from .controller import MachineController

machine_api_v1 = Blueprint('machine_api_v1', 'machine_api_v1', url_prefix='/api/v1/machine')
CORS(machine_api_v1)

@machine_api_v1.route('/', methods=['GET'])
@jwt_required()
def api_get_machines():
    try:
        response, status = MachineController.get_machines()
        return jsonify(response), status
    except Exception as e:
        return jsonify({'error': str(e)}), HTTPStatus.BAD_REQUEST

@machine_api_v1.route('/<id>', methods=['GET'])
@jwt_required()
def api_get_machine_by_id(id):
    try:
        response, status = MachineController.get_machine_by_id(id)
        return jsonify(response), status
    except Exception as e:
        return jsonify({'error': str(e)}), HTTPStatus.BAD_REQUEST

@machine_api_v1.route('/create', methods=['POST'])
@jwt_required()
def api_add_machine():
    req = request.get_json()
    try:
        user_id = req.get('user_id')
        receiver_ip = req.get('receiver_ip')
        receiver_port = req.get('receiver_port')
        package_capture_time = req.get('package_capture_time')
        package_capture_interval = req.get('package_capture_interval')
        inactivity_threshold = req.get('inactivity_threshold')

        response, status = MachineController.add_machine(user_id, receiver_ip, receiver_port, package_capture_time, package_capture_interval, inactivity_threshold)
        return jsonify(response), status
    except Exception as e:
        return jsonify({'error': str(e)}), HTTPStatus.BAD_REQUEST

@machine_api_v1.route('/<id>', methods=['DELETE'])
@jwt_required()
def api_delete_machine(id):
    try:
        response, status = MachineController.delete_machine(id)
        return jsonify(response), status
    except Exception as e:
        return jsonify({'error': str(e)}), HTTPStatus.BAD_REQUEST


import re
from PyQt5.Qt import QObject
from PyQt5.QtWebEngineWidgets import QWebEngineProfile
from mc.common import const
from mc.app.Settings import Settings

class UserAgentManager(QObject):
    def __init__(self, parent=None):
        super().__init__(parent)
        self._globalUserAgent = ''
        self._defaultUserAgent = ''

        self._usePerDomainUserAgent = False
        self._userAgentsList = {}  # QHash<QString, QString>

        self._defaultUserAgent = QWebEngineProfile.defaultProfile().httpUserAgent()
        self._defaultUserAgent = re.sub(r'QtWebEngine/[^\s]+', 'App/%s' % const.VERSION, self._defaultUserAgent)

    def loadSettings(self):
        settings = Settings()
        settings.beginGroup('Web-Browser-Settings')
        self._globalUserAgent = settings.value('UserAgent', '', type=str)
        settings.endGroup()

        settings.beginGroup('User-Agent-Settings')
        self._usePerDomainUserAgent = settings.value('UsePerDomainUA', False, type=bool)
        domainList = settings.value('DomainList', [], type=list)
        userAgentsList = settings.value('UserAgentsList', [], type=list)
        settings.endGroup()

        self._usePerDomainUserAgent = self._usePerDomainUserAgent and domainList.count() == userAgentsList.count()

        if self._usePerDomainUserAgent:
            for idx in range(domainList.count()):
                self._userAgentsList[domainList[idx]] = userAgentsList[idx]

        if not self._globalUserAgent:
            userAgent = self._defaultUserAgent
        else:
            userAgent = self._globalUserAgent

        QWebEngineProfile.defaultProfile().setHttpUserAgent(userAgent)

    def globalUserAgent(self):
        return self._globalUserAgent

    def defaultUserAgent(self):
        return self._defaultUserAgent

    def usePerDomainUserAgents(self):
        '''
        @return: bool
        '''
        return self._usePerDomainUserAgent

    def perDomainUserAgentsList(self):
        '''
        @return: QHash<QString, QString>
        '''
        return self._userAgentsList


comment = []

def AddEdge(end, to):
	comment.append( (end, to) )

def PrintDeep(point,depth):
	for a,b in comment:
		if(point == a):
			indent = "\t"*depth; print(indent, end="")
			print(a,"-->",b)
			PrintDeep(b,depth+1)

AddEdge('a', 'b')
AddEdge('b', 'c')
AddEdge('b', 'd')
AddEdge('b', 'e')
AddEdge('c', 'e')
AddEdge('c', 'f')
AddEdge('d', 'g')
AddEdge('g', 'h')
AddEdge('h', 'j')
AddEdge('h', 'k')
AddEdge('h','l')

PrintDeep('a',0)


#!/usr/bin/env python

# setup for FisherExact library packages

from __future__ import absolute_import
from __future__ import print_function
import os
import sys
from distutils import spawn
try:
    from setuptools import find_packages
except ImportError:
    import ez_setup
    ez_setup.use_setuptools()
    from setuptools import find_packages

from numpy.distutils.core import Extension as Ext
from numpy.distutils.core import setup

__version__ = "1.4"
__project__ = "FisherExact"
__author__ = "Emmanuel Noutahi"

sys.path.insert(0, os.path.realpath(os.path.join(os.path.dirname(__file__), "python")))

def configuration(top_path=''):
    fexact_sources = [
        'FisherExact/statlib/fexact.pyf',
        'FisherExact/statlib/FEXACT.F90',
        'FisherExact/statlib/prterr.f'
    ]

    fexact = Ext(name='FisherExact.statlib.fexact', sources=[
                 os.path.join(top_path, x) for x in fexact_sources])
    asa159 = Ext(name='FisherExact.statlib.asa159', sources=[
                 os.path.join(top_path, 'FisherExact/statlib', 'asa159.f90')])
    asa205 = Ext(name='FisherExact.statlib.asa205', sources=[
                 os.path.join(top_path, 'FisherExact/statlib', 'asa205.f90')])
    return [fexact, asa205, asa159]

def setup_package():
    if os.path.exists('README.md'):
        README = open('README.md').read()
    else:
        README = ""  # a placeholder, readme is generated on release
    print("\nVersion : %s\n" % __version__)

    fortran_extnsion = configuration()

    setup(
        name=__project__,
        version=__version__,
        maintainer=__author__,
        description="Fishe's Exact test for mxn contingency table",
        url='https://github.com/maclandrol/FisherExact',
        download_url='https://github.com/maclandrol/FisherExact/archive/%s.tar.gz' % __version__,
        author= __author__,
        author_email='fmr.noutahi@umontreal.ca',
        scripts= ['bin/fexact'],
        packages=find_packages(),
        entry_points={'console_scripts': []},
        keywords="statistic fisher independence test",

        long_description=(README + '\n'),
        license='GPL',
        classifiers=[
            'Development Status :: 4 - Beta',
            'Environment :: Console',
            'Natural Language :: English',
            'Intended Audience :: Developers',
            'Intended Audience :: Science/Research',
            'License :: OSI Approved :: GNU General Public License (GPL)',
            'Operating System :: Microsoft :: Windows',
            'Operating System :: POSIX',
            'Operating System :: Unix',
            'Operating System :: MacOS',
            'Programming Language :: Python',
            'Programming Language :: Python :: 2',
            'Programming Language :: Python :: 2.7',
            'Programming Language :: Python :: 3',
            'Programming Language :: Python :: 3.4',
            'Programming Language :: Python :: 3.5',
            'Programming Language :: Python :: 3.6',
        ],

        setup_requires=['numpy'],
        install_requires=[
            'future>=0.15.0',
            'numpy>=1.8.0',
            'scipy>=0.16.0',
        ],
        ext_modules=fortran_extnsion
    )

if __name__ == '__main__':
    setup_package()


from telebot.types import InlineKeyboardMarkup, InlineKeyboardButton

# Keyboard to list address
def keyboardNodes(nodes, prefix, button_return=True):
    # We get number of nodes and if it's even or odd
    list_nodes = list(nodes)
    i = len(list_nodes)
    modI = i % 2

    markup = InlineKeyboardMarkup()
    markup.row_width = 2

    if i == 1:
        markup.add(InlineKeyboardButton(list_nodes[0]['name'], callback_data=prefix + list_nodes[0]['address']))

    else:
        # If it's odd
        if modI == 1:
            k = 0
            for j in range(int((i - 1) / 2)):
                markup.add(InlineKeyboardButton(list_nodes[k]['name'], callback_data=prefix + list_nodes[k]['address']),
                           InlineKeyboardButton(list_nodes[k + 1]['name'],
                                                callback_data=prefix + list_nodes[k + 1]['address']))

                k = k + 2

            markup.add(
                InlineKeyboardButton(list_nodes[k]['name'], callback_data=prefix + list_nodes[k]['address']))

        # If it's even
        else:
            k = 0
            for j in range(int(i / 2)):
                markup.add(InlineKeyboardButton(list_nodes[k]['name'], callback_data=prefix + list_nodes[k]['address']),
                           InlineKeyboardButton(list_nodes[k + 1]['name'],
                                                callback_data=prefix + list_nodes[k + 1]['address']))

                k = k + 2

    # Button to return
    if button_return:
        markup.add(
            InlineKeyboardButton("« Return", callback_data="statsReturn"))

    return markup

# Keyboard with options for address (edit, delete, view...)
def keyboardOptionsNode(node_code):
    markup = InlineKeyboardMarkup()
    markup.row_width = 2
    markup.add(
        InlineKeyboardButton("View Stats", callback_data="stats-" + node_code),
        InlineKeyboardButton("Settings", callback_data="settings-" + node_code),
        InlineKeyboardButton("« Return", callback_data="myNodes"))

    return markup

# Keyboard with options for address (edit, delete,...)
def keyboardSettingsNode(node_code):
    markup = InlineKeyboardMarkup()
    markup.row_width = 3
    markup.add(
        InlineKeyboardButton("Edit Node", callback_data="editNode-" + node_code),
        InlineKeyboardButton("Delete Node", callback_data="delNode-" + node_code),
        InlineKeyboardButton("Notifications", callback_data="notNode-" + node_code),
        InlineKeyboardButton("« Back to Nodes List", callback_data="myNodes"))

    return markup

# Keyboard edit configuracion node (name, code)
def keyboardEditNode(node_code):
    markup = InlineKeyboardMarkup()
    markup.row_width = 2
    markup.add(
        InlineKeyboardButton("Edit name", callback_data="setNodeName-" + node_code),
        InlineKeyboardButton("Edit address", callback_data="setNodeAddr-" + node_code))

    return markup

# Keybpard return Node or Nodes List
def keyboardReturn(node_code):
    markup = InlineKeyboardMarkup()
    markup.row_width = 2
    markup.add(
        InlineKeyboardButton("« Back to Node", callback_data="mynode-" + node_code),
        InlineKeyboardButton("« Back to Nodes List", callback_data="myNodes"))

    return markup

# Keyboard confirm delete node
def keyboardDeleteNode(node_code):
    markup = InlineKeyboardMarkup()
    markup.row_width = 1
    markup.add(
        InlineKeyboardButton("Yes, delete the Node",
                             callback_data="yesDelNode-" + node_code),
        InlineKeyboardButton("No", callback_data="myNodes"))

    return markup

# Keyboard to return select stats for myNodes
def keyboardReturnMyNodes():
    markup = InlineKeyboardMarkup()
    markup.row_width = 1
    markup.add(
        InlineKeyboardButton("« Back to Nodes List", callback_data="myNodes"))

    return markup

# Keyboard notifications
def keyboardNotifications(node_code):
    markup = InlineKeyboardMarkup()
    markup.row_width = 2
    markup.add(
        InlineKeyboardButton("ON", callback_data="notON-" + node_code),
        InlineKeyboardButton("OFF", callback_data="notOFF-" + node_code),
        InlineKeyboardButton("Change Port", callback_data="changeport-" + node_code),
        InlineKeyboardButton("Change Downtime", callback_data="changedowntime-" + node_code)
    )

    return markup

# Keyboard nodeinfo
def keyboardNodeInfo(node_code):
    markup = InlineKeyboardMarkup()
    markup.row_width = 2
    markup.add(
        InlineKeyboardButton("Utilization & Remaning", callback_data="utilization-" + node_code),
        InlineKeyboardButton("Payout", callback_data="payout-" + node_code),
        InlineKeyboardButton("Other Info", callback_data="otherinf-" + node_code),
        InlineKeyboardButton("« Back to Nodes List", callback_data="myNodes"))

    return markup

# Keyboard return to last keyboard
def keyboardReturnCustom(prefix, node_code):
    markup = InlineKeyboardMarkup()
    markup.row_width = 1
    markup.add(
        InlineKeyboardButton("« Return", callback_data=prefix + node_code))

    return markup

# Keyboard return to node info o satellites
def keyboardNodeInfoSatellites(node_code):
    markup = InlineKeyboardMarkup()
    markup.row_width = 3
    markup.add(
        InlineKeyboardButton("« Return", callback_data="stats-" + node_code),
        InlineKeyboardButton("Satellites", callback_data="satellites-" + node_code),
        InlineKeyboardButton("Uptime & Audits", callback_data="uptimeaudits-" + node_code))
    return markup

# Keyboard list satellites
def keyboardSatellites(node_code, req):
    list_satellites = req["satellites"]
    markup = InlineKeyboardMarkup()
    markup.row_width = 1

    i = 0
    for satellite in list_satellites:

        if satellite["disqualified"] is not None or satellite["suspended"] is not None:
            markup.add(InlineKeyboardButton("⚠ " + satellite["url"], callback_data="sat-{0}#{1}".format(node_code, i)))

        else:
            markup.add(InlineKeyboardButton(satellite["url"], callback_data="sat-{0}#{1}".format(node_code, i)))

        i = i + 1

    return markup

# Keyboard select other satellite
def KeyboardOtherSatellite(node_code):
    markup = InlineKeyboardMarkup()
    markup.row_width = 2
    markup.add(
        InlineKeyboardButton("« Node Info", callback_data="stats-" + node_code),
        InlineKeyboardButton("« Return", callback_data="satellites-" + node_code))

    return markup

# Keyboard cancell command contact
def keyboardCancelContact():
    markup = InlineKeyboardMarkup()
    markup.row_width = 1
    markup.add(
        InlineKeyboardButton("« Return", callback_data="cancelcontact"))

    return markup