#!/usr/bin/python3

"""
Script used when we only base on encoders to tell our absolute position.
It can nonetheless return the absolute position of the opponent robots.

"""

import os
import shutil
import time
import datetime
import queue

from lidarproc.main.constants import *
from lidarproc import HOME
import lidarproc.main.output_rendering as outr
import lidarproc.main.data_retrieval as datr
import lidarproc.main.data_cleansing as dacl
import lidarproc.main.communication as comm
import lidarproc.main.clustering as clus
# import lidarproc.main.tracking as trac
import lidarproc.main.enemy_locator as eloc

__author__ = ["Clément Besnier", ]

# region logs
log_folder = os.path.join(HOME, "lidar-processor", "logs")
last_log_folder = os.path.join(log_folder, "last")
history_log_folder = os.path.join(log_folder, "history")

if not os.path.exists(log_folder):
    os.mkdir(log_folder)

if not os.path.exists(last_log_folder):
    os.mkdir(last_log_folder)

if not os.path.exists(history_log_folder):
    os.mkdir(history_log_folder)

if len(os.listdir(last_log_folder)) != 0:
    shutil.move(last_log_folder+"/*", os.path.join(HOME, "lidar-processor", "logs", "hitory"))

# log_filename = "lidar_logs" + datetime.datetime.today().ctime().replace(":", "")
log_filename = ""
if log_filename:
    logging.basicConfig(filename=os.path.join(HOME, "lidar-processor", "logs", "last",
                                              log_filename + ".txt"), level=15)
else:
    logging.basicConfig(stream=sys.stdout, level=5)
# endregion

def main():
    logger = logging.getLogger(log_filename)
    logger.info("On a lancé le script de match")

    # region # thread initialisation
    t_lidar = datr.LidarThread(log_filename)
    t_lidar.start()

    t_ll = datr.EncoderThread(log_filename)
    t_ll.start()

    t_hl = comm.HLThread(log_filename)
    t_hl.start()

    logger.info("Fils de communication lancés")

    time.sleep(3)
    # endregion

    # region # variable initialisation
    start_enemy_positions = []
    own_colour_team = None
    computed_opponent_robot_position = False
    previous_beacons = []
    previous_self_positions = []
    previous_clusters = []
    previous_opponent_robots = []
    # endregion

    # region # before the match
    one_turn_points = dacl.filter_points(t_lidar.get_measures(), 50)
    one_turn_clusters = clus.clusterize(one_turn_points)

    while not t_hl.has_match_begun():
        # team colour
        if t_hl.get_team_colour() is not None:
            # computes the position
            if t_hl.get_team_colour() == TeamColor.purple:
                start_enemy_positions = eloc.find_robots_in_purple_zone(one_turn_clusters)
                computed_opponent_robot_position = True
                own_colour_team = TeamColor.purple
                logger.info("On est violet")

            elif t_hl.get_team_colour() == TeamColor.orange:
                start_enemy_positions = eloc.find_robot_in_orange_zone(one_turn_clusters)
                computed_opponent_robot_position = True
                own_colour_team = TeamColor.orange
                logger.info("On est orange")

            # retrieves and filters measures
            one_turn_points = dacl.filter_points(t_lidar.get_measures(), 50)
            cartesian_one_turn_points = outr.one_turn_to_cartesian_points(one_turn_points)
            one_turn_clusters = clus.clusterize(cartesian_one_turn_points)

            # send the positions of the opponent robots
            if computed_opponent_robot_position:
                for enemy_position in start_enemy_positions:
                    t_hl.send_robot_position(*enemy_position)
    # endregion

    logger.info("Le match vient de commencer")

    # region # match
    while not t_hl.has_match_stopped():
        # region # measures
        one_turn_points = dacl.filter_points(t_lidar.get_measures(), THRESHOLD_QUALITY)
        cartesian_one_turn_measure = outr.one_turn_to_cartesian_points(one_turn_points)
        clusters = clus.clusterize(cartesian_one_turn_measure)
        # endregion

        # region # retrieves position from encoders
        proprioceptive_position = datr.from_encoder_position_to_lidar_measure(*t_ll.get_measures())
        # endregion

        # region # estimations of positions
        robots = eloc.find_robots(clusters)
        # endregion

        # region history management
        previous_clusters.append(clusters.copy())
        if len(previous_clusters) > 3:
            previous_clusters.pop(0)

        previous_opponent_robots.append(robots.copy())
        if len(previous_opponent_robots) > 3:
            previous_opponent_robots.pop(0)
        # endregion

        time.sleep(1)
    # endregion
    logger.info("Le match est fini")
    # region # end of match

    t_lidar.close_connection()
    t_hl.close_connection()
    t_ll.close_connection()
    time.sleep(3)
    logger.info("On a fermé les connexions")
    # sys.exit(0)
    # endregion

if __name__ == "__main__":
    main()


import os
import math
import time
import textwrap

import wx
import wx.xrc as xrc
from wx.lib.pubsub import pub

import gpxpy
import gpxpy.gpx

import pymaplib
from mapsevolved import util

def _(s): return s

class GPSPointStatistics:
    def __init__(self, point_list):
        self.num_points = 0
        self.ele_gps_min = None
        self.ele_gps_max = None
        self.ele_dhm_min = None
        self.ele_dhm_max = None

        self.time_secs_min = None
        self.time_secs_max = None
        self.point_distances = [0]
        self.cumulative_point_distances = [0]

        prev_point = None
        for point in point_list:
            self.num_points += 1
            self.ele_gps_min = self.min(self.ele_gps_min, point.elevation)
            self.ele_gps_max = self.max(self.ele_gps_max, point.elevation)
            self.ele_dhm_min = self.min(self.ele_dhm_min, point.dhm_elevation)
            self.ele_dhm_max = self.max(self.ele_dhm_max, point.dhm_elevation)
            self.time_secs_min = self.min(self.time_secs_min,
                                          point.secs_after_start)
            self.time_secs_max = self.max(self.time_secs_max,
                                          point.secs_after_start)

            if prev_point is not None:
                distance = point.distance_2d(prev_point)
                self.point_distances.append(distance)
                self.cumulative_point_distances.append(
                        self.cumulative_point_distances[-1] + distance)
            prev_point = point

        self.total_distance = self.cumulative_point_distances[-1]
        self.ele_gps_delta = self.ele_gps_max - self.ele_gps_min
        self.ele_dhm_delta = self.ele_dhm_max - self.ele_dhm_min
        self.time_secs_elapsed = self.time_secs_max - self.time_secs_min

    def min(self, result, value):
        if result is None:
            return value
        return min(result, value)

    def max(self, result, value):
        if result is None:
            return value
        return max(result, value)

    def sum(self, result, value):
        if result is None:
            return value
        return result + value

class XAxis_NPoints:
    axis_name = 'N'
    def __init__(self, points, point_stats):
        self.val_min = 0
        self.val_max = point_stats.npoints

    def get_x(self, point_num, point):
        return point_num

    def stringify(self, val):
        return "{}".format(int(round(val)))

    def get_suggested_subticks(self, max_ticks):
        tick_distance = util.round_up_reasonably(self.val_max / max_ticks)
        if tick_distance == 0:
            return []
        return list(range(tick_distance, self.val_max, tick_distance))

class XAxis_Time:
    def __init__(self, points, point_stats):
        self.val_min = point_stats.time_secs_min
        self.val_max = point_stats.time_secs_max

        delta = self.val_max - self.val_min
        if delta > 3600:  # > one hour
            self.axis_name = 't [h]'
            self.display = 'h'
        elif delta > 60:
            self.axis_name = 't [m]'
            self.display = 'm'
        else:
            self.axis_name = 't [s]'
            self.display = 's'

    def get_x(self, point_num, point):
        return point.secs_after_start

    def stringify(self, val):
        if self.display == 's':
            return "{}s".format(val)

        m, s = divmod(val, 60)
        if self.display == 'm':
            if s == 0:
                return "{}m".format(m)
            elif m == 0:
                return "{}s".format(s)
            else:
                return "{}m{}s".format(m, s)

        h, m = divmod(m, 60)
        if self.display == 'h':
            if m == 0:
                return "{}h".format(h)
            elif h == 0:
                return "{}m".format(m)
            else:
                return "{}h{}m".format(h, m)

        raise NotImplementedError('Unknown XAxis_Time.display value: %s',
                                  self.display)

    def get_suggested_subticks(self, max_ticks):
        tick_distance = (self.val_max - self.val_min) / max_ticks
        if tick_distance == 0:
            return []
        m, s = divmod(tick_distance, 60)
        h, m = divmod(m, 60)
        if h:
            tick_distance = util.round_up_reasonably(h) * 3600
        elif m:
            tick_distance = util.round_up_reasonably(m) * 60
        else:
            tick_distance = util.round_up_reasonably(s)
        tick_min = self.val_min + tick_distance
        return list(range(tick_min, self.val_max, tick_distance))

class XAxis_Distance:
    def __init__(self, points, point_stats):
        self._point_stats = point_stats
        self.val_min = 0
        self.val_max = point_stats.total_distance

        if self.val_max <= 1000:
            self.axis_name = 'd [m]'
            self.factor = 1
        else:
            self.axis_name = 'd [km]'
            self.factor = 1000

    def stringify(self, val):
        fmt = "{:.0f}" if self.factor == 1 else "{:.1f}"
        return fmt.format(val / self.factor)

    def get_suggested_subticks(self, max_ticks):
        if self.val_max == 0:
            return []
        tick_distance = util.round_up_reasonably(self.val_max / max_ticks)
        return list(range(tick_distance, self.val_max, tick_distance))

class YAxis_GPSElevation:
    axis_name = 'Ele [m]'
    legend_name = 'GPS Ele'
    def __init__(self, points, point_stats, val_min=None, val_max=None):
        if val_min is None:
            self.val_min = point_stats.ele_gps_min
        else:
            self.val_min = val_min
        if val_max is None:
            self.val_max = point_stats.ele_gps_max
        else:
            self.val_max = val_max

    def get_y(self, point_num, point):
        return point.elevation

    def stringify(self, val):
        return "{}".format(int(round(val)))

    def get_suggested_subticks(self, max_ticks):
        tick_distance = (self.val_max - self.val_min) / max_ticks
        if tick_distance == 0:
            return []
        tick_distance = util.round_up_reasonably(tick_distance)
        tick_min = util.round_up_to_multiple(self.val_min, tick_distance)
        tick_min += tick_distance
        return list(range(tick_min, int(self.val_max), tick_distance))

class YAxis_DHMElevation:
    axis_name = 'Ele [m]'
    legend_name = 'DHM Ele'
    def __init__(self, points, point_stats, val_min=None, val_max=None):
        if val_min is None:
            self.val_min = point_stats.ele_gps_min
        else:
            self.val_min = val_min
        if val_max is None:
            self.val_max = point_stats.ele_gps_max
        else:
            self.val_max = val_max

    def get_y(self, point_num, point):
        return point.dhm_elevation

    def stringify(self, val):
        return "{}".format(int(round(val)))

    def get_suggested_subticks(self, max_ticks):
        tick_distance = (self.val_max - self.val_min) / max_ticks
        if tick_distance == 0:
            return []
        tick_distance = util.round_up_reasonably(tick_distance)
        tick_min = util.round_up_to_multiple(self.val_min, tick_distance)
        tick_min += tick_distance
        return list(range(tick_min, int(self.val_max), tick_distance))

class GPSTrackGrapher:
    def __init__(self, points):
        self.points = points

        self.bg_color = wx.Colour(250, 250, 250)
        self.gridline_color = wx.Colour(230, 230, 230)
        self.border_px = 10
        self.tick_px = 3
        self.colors = [wx.BLUE, wx.RED, wx.Colour(79, 47, 79)]

        self.draw_gps_ele = True
        self.draw_dhm_ele = True
        self.x_axis_class = XAxis_Time

    @staticmethod
    def _value_to_pixel(value, axis, pixel_width_height):
        return round(pixel_width_height *
                     (value - axis.val_min) / (axis.val_max - axis.val_min))

    @staticmethod
    def _round_boundaries(min_val, max_val):
        """Calculate display bounderies from min/max values

        Calculate a display window where the min/max values fit nicely.
        The window will be round-numbered:

        >>> _round_boundaries(1032, 1538)
            (1000, 1600)
        """

        delta = max_val - min_val
        if delta != 0:
            magnitude = int(math.log10(delta))
        else:
            magnitude = 0
        round_adj = 10**magnitude / 2
        rounded_min = round(min_val - round_adj, -magnitude)
        rounded_max = round(max_val + round_adj, -magnitude)
        return rounded_min, rounded_max

    def calc_value_boundaries(self, point_stats):
        """Find appropriate x/y min/max boundaries for graphing"""

        x_axis = self.x_axis_class(self.points, point_stats)
        if self.draw_gps_ele and self.draw_dhm_ele:
            gps_min, gps_max = self._round_boundaries(point_stats.ele_gps_min,
                                                      point_stats.ele_gps_max)
            dhm_min, dhm_max = self._round_boundaries(point_stats.ele_dhm_min,
                                                      point_stats.ele_dhm_max)
            y_val_min = min(gps_min, dhm_min)
            y_val_max = max(gps_max, dhm_max)
            y_axes = [YAxis_GPSElevation(self.points, point_stats,
                                         y_val_min, y_val_max),
                      YAxis_DHMElevation(self.points, point_stats,
                                         y_val_min, y_val_max)]
        elif self.draw_gps_ele:
            y_val_min, y_val_max = self._round_boundaries(
                   point_stats.ele_gps_min, point_stats.ele_gps_max)
            y_axes = [YAxis_GPSElevation(self.points, point_stats,
                                         y_val_min, y_val_max)]
        elif self.draw_dhm_ele:
            y_val_min, y_val_max = self._round_boundaries(
                   point_stats.ele_dhm_min, point_stats.ele_dhm_max)
            y_axes = [YAxis_DHMElevation(self.points, point_stats,
                                         y_val_min, y_val_max)]
        else:
            y_axes = []

        return x_axis, y_axes

    def draw_one_function(self, dc, coosys_tl, coosys_br,
                          x_axis, y_axis):
        chart_size = coosys_br - coosys_tl
        line_points = []
        for idx, point in enumerate(self.points):
            x_val = x_axis.get_x(idx, point)
            y_val = y_axis.get_y(idx, point)
            x = self._value_to_pixel(x_val, x_axis, chart_size.x)
            y = self._value_to_pixel(y_val, y_axis, chart_size.y)
            line_points.append(wx.Point(coosys_tl.x + x, coosys_br.y - y))
        dc.DrawLines(line_points, 0, 0)

    def draw_all_functions(self, dc, coosys_tl, coosys_br, point_stats,
                           x_axis, y_axes):
        for i, y_axis in enumerate(y_axes):
            dc.Pen = wx.Pen(self.colors[i], 1)
            self.draw_one_function(dc, coosys_tl, coosys_br, x_axis, y_axis)

    def vertical_tick(self, dc, text, pos, tickmark=True):
        dc.Pen = wx.BLACK_PEN
        if tickmark:
            dc.DrawLine(pos.x, pos.y, pos.x - self.tick_px, pos.y)

        util.draw_text(dc, text, wx.Point(pos.x - self.tick_px, pos.y),
                       alignment=wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL)

    def horizontal_tick(self, dc, text, pos, tickmark=True):
        dc.Pen = wx.BLACK_PEN
        if tickmark:
            dc.DrawLine(pos.x, pos.y, pos.x, pos.y + self.tick_px)

        util.draw_text(dc, text, wx.Point(pos.x, pos.y + self.tick_px),
                       alignment=wx.ALIGN_CENTER_HORIZONTAL|wx.ALIGN_TOP)

    def vertical_label(self, dc, text, pos):
        base_point = wx.Point(pos.x - self.tick_px, self.border_px)
        util.draw_text(dc, text, base_point,
                       alignment=wx.ALIGN_RIGHT|wx.ALIGN_TOP)

    def horizontal_label(self, dc, text, pos):
        base_point = wx.Point(dc.Size.width - 1 - self.border_px,
                              pos.y + self.tick_px)
        util.draw_text(dc, text, base_point,
                       alignment=wx.ALIGN_RIGHT|wx.ALIGN_TOP)

    def legend_label(self, dc, text, pos, color):
        base_point = wx.Point(pos.x, self.border_px)
        util.draw_text(dc, text, base_point,
                       alignment=wx.ALIGN_RIGHT|wx.ALIGN_TOP)
        label_width, label_height, label_descent, label_external_lead = \
                                                     dc.GetFullTextExtent(text)
        new_x = pos.x - label_width - 15
        new_y = self.border_px + label_height // 2
        dc.Pen = wx.Pen(color, 1)
        dc.DrawLine(new_x, new_y, new_x + 10, new_y)

        return wx.Point(new_x - self.border_px, pos.y)

    def draw_coordinate_system(self, dc, coosys_tl, coosys_br):
        dc.Pen = wx.TRANSPARENT_PEN
        dc.Brush = wx.WHITE_BRUSH
        dc.DrawRectangle(coosys_tl, coosys_br - coosys_tl)

        coosys_bl = wx.Point(coosys_tl.x, coosys_br.y)
        dc.Pen = wx.BLACK_PEN
        dc.DrawLine(coosys_tl, coosys_bl)
        dc.DrawLine(coosys_bl, coosys_br)

    def gridline_x(self, dc, x_coord, coosys_tl, coosys_br):
        dc.Pen = wx.Pen(self.gridline_color, 1)
        dc.DrawLine(x_coord, coosys_tl.y, x_coord, coosys_br.y)

    def gridline_y(self, dc, y_coord, coosys_tl, coosys_br):
        # Use coosys_tl.x + 1 to avoid painting over the coordinate axis.
        dc.Pen = wx.Pen(self.gridline_color, 1)
        dc.DrawLine(coosys_tl.x + 1, y_coord, coosys_br.x, y_coord)

    def draw_tickmarks_gridlines(self, dc, coosys_tl, coosys_bl, coosys_br,
                                 x_est_tick_width, y_est_tick_height,
                                 x_axis, y_axis):

        chart_size = coosys_br - coosys_tl

        # Draw the outermost tickmarks first (i.e. begin/end of axis).
        self.vertical_tick(dc, y_axis.stringify(y_axis.val_max), coosys_tl)
        self.vertical_tick(dc, y_axis.stringify(y_axis.val_min), coosys_bl)
        self.horizontal_tick(dc, x_axis.stringify(x_axis.val_min), coosys_bl)
        self.horizontal_tick(dc, x_axis.stringify(x_axis.val_max), coosys_br)

        # [xy]_est_tick_[wh] estimates the size of a tick label and we can
        # infer how many ticks we can fit. The factors (1.*) ensure that we
        # have some room for larger labels and also bring sensible spacing.
        #
        # Y is tighter as heights vary less, and vertically close text doesn't
        # look as bad as horizontally close text.
        x_tick_spacing = int(x_est_tick_width * 1.7)
        x_tick_space_avail = (coosys_br.x - coosys_bl.x - x_est_tick_width)
        x_num_ticks = x_tick_space_avail / x_tick_spacing
        for x_tick in x_axis.get_suggested_subticks(x_num_ticks):
            x_tick_px = self._value_to_pixel(x_tick, x_axis, chart_size.x)
            x_tick_px += coosys_bl.x
            self.gridline_x(dc, x_tick_px, coosys_tl, coosys_br)
            # Avoid painting over the (manually drawn) last tick label.
            if x_tick_px < coosys_br.x - x_est_tick_width:
                self.horizontal_tick(dc, x_axis.stringify(x_tick),
                                     wx.Point(x_tick_px, coosys_bl.y))

        y_tick_spacing = int(y_est_tick_height * 1.3)
        y_tick_space_avail = (coosys_bl.y - coosys_tl.y - y_tick_spacing)
        y_num_ticks = y_tick_space_avail / y_tick_spacing
        for tick in y_axis.get_suggested_subticks(y_num_ticks):
            tick_px = self._value_to_pixel(tick, y_axis, chart_size.y)
            tick_px = coosys_bl.y - tick_px
            self.gridline_y(dc, tick_px, coosys_tl, coosys_br)
            # Avoid painting over the (manually drawn) last tick label.
            if tick_px > coosys_tl.y + y_est_tick_height:
                self.vertical_tick(dc, y_axis.stringify(tick),
                                   wx.Point(coosys_tl.x, tick_px))

    def draw_dc(self, dc):
        dc.BackgroundMode = wx.TRANSPARENT

        dc.Background = wx.Brush(self.bg_color)
        dc.Clear()

        if not dc.CanGetTextExtent():
            util.Error(self, _("Failed to draw GPS track:\n" +
                               "Can not calculate text size on this platform"))
            return
        label_width, label_height, label_descent, label_external_lead = \
                                             dc.GetFullTextExtent("+0000")

        point_stats = GPSPointStatistics(self.points)
        x_axis, y_axes = self.calc_value_boundaries(point_stats)

        if not y_axes:
            # No functions to draw: stop drawing alltogether.
            return

        y_axis = y_axes[0]
        x_last_tick_text = x_axis.stringify(x_axis.val_max)
        y_last_tick_text = y_axis.stringify(y_axis.val_max)

        x_label_width = dc.GetFullTextExtent(x_axis.axis_name)[0]
        y_label_height = dc.GetFullTextExtent(y_axis.axis_name)[1]
        x_last_tick_width = dc.GetFullTextExtent(x_last_tick_text)[0]
        y_last_tick_height = dc.GetFullTextExtent(y_last_tick_text)[1]

        coosys_tl = wx.Point(self.border_px + label_width + self.tick_px,
                             self.border_px + y_label_height +
                                              y_last_tick_height // 2)
        coosys_br = wx.Point(
                        dc.Size.width - 1 -
                            self.border_px - x_label_width -
                            self.border_px - x_last_tick_width // 2,
                        dc.Size.height - 1 -
                            self.border_px - label_height - self.tick_px)
        coosys_bl = wx.Point(coosys_tl.x, coosys_br.y)

        self.draw_coordinate_system(dc, coosys_tl, coosys_br)

        self.horizontal_label(dc, x_axis.axis_name, coosys_br)
        self.vertical_label(dc, y_axis.axis_name, coosys_tl)

        legend_pos = wx.Point(coosys_br.x, self.border_px)
        for i, axis in enumerate(y_axes):
            legend_pos = self.legend_label(dc, axis.legend_name, legend_pos,
                                           self.colors[i])

        self.draw_tickmarks_gridlines(
                dc, coosys_tl, coosys_bl, coosys_br,
                x_last_tick_width, y_last_tick_height, x_axis, y_axis)

        if len(self.points) <= 1:
            # Don't draw any functions if we only have 0 or 1 points.
            return

        # Note that we pass all y_axes, not just y_axis == y_axes[0].
        self.draw_all_functions(dc, coosys_tl, coosys_br,
                                point_stats,
                                x_axis, y_axes)

    def draw(self, bmp):
        with util.Bitmap_MemoryDC_Context(bmp) as dc:
            self.draw_dc(dc)

class GPSTrackAnalyzerFrame(wx.Frame):
    def __init__(self, parent, track, heightfinder):
        wx.Frame.__init__(self)
        # 3-argument LoadFrame() calls self.Create(), so skip 2-phase creation.
        res = util.get_resources("main")
        if not res.LoadFrame(self, parent, "GPSTrackAnalyzerFrame"):
            raise RuntimeError("Could not load track analyzer frame from XRC.")

        util.bind_decorator_events(self)

        self.parent = parent
        self.track = track
        self.heightfinder = heightfinder
        self.pointlistbox = xrc.XRCCTRL(self, 'PointList')
        self.hdist_per_hour_text = xrc.XRCCTRL(self, 'HDistPerHourText')
        self.ele_per_hour_text = xrc.XRCCTRL(self, 'ElePerHourText')
        self.graphbitmap = xrc.XRCCTRL(self, 'GraphBitmap')

        self.stat_texts = [
                xrc.XRCCTRL(self, 'TotalTimeText'),
                xrc.XRCCTRL(self, 'HorizDistanceText'),
                xrc.XRCCTRL(self, 'VertDistanceGPSText'),
                xrc.XRCCTRL(self, 'VertDistanceDHMText'),
                ]
        self.stat_texts = {st: st.LabelText for st in self.stat_texts}

        fname = self.track.GetFname()
        self.gpx_basename = os.path.basename(fname).split(':', 1)[0]
        self.gpx_fname = os.path.join(os.path.dirname(fname),
                                      self.gpx_basename)

        self.gpx = self.track.data.gpx
        if not self.gpx:
            # We take the GPX data from an already loaded track.
            # This really shouldn't happen.
            raise RuntimeError("GPS Analyzer couldn't get gpx from track.")
        self.augment_gpx_data()

        self.active_segments = []
        for track in self.gpx.tracks:
            for segment in track.segments:
                self.active_segments.append(segment)

        self.populate_pointlistbox()

        self.grapher = GPSTrackGrapher(list(self.walk_active_points()))
        self.update_display()

    @util.EVENT(wx.EVT_SIZE, id=xrc.XRCID('GraphBitmap'))
    def on_graph_resize(self, evt):
        evt.Skip()
        self.update_display()

    @util.EVENT(wx.EVT_LIST_ITEM_SELECTED, id=xrc.XRCID('PointList'))
    @util.EVENT(wx.EVT_LIST_ITEM_DESELECTED, id=xrc.XRCID('PointList'))
    def on_pointlist_selection_change(self, evt):
        self.update_display()
        point = self.point_list[evt.Index]
        point.highlight = self.pointlistbox.IsSelected(evt.Index)
        pub.sendMessage('gpsanalyzer.gps_point_hl_update',
                        track=self.track, gpx=self.gpx)

    @util.EVENT(wx.EVT_PAINT, id=xrc.XRCID('GraphBitmap'))
    def on_graph_paint(self, evt):
        evt.Skip()
        self.grapher.points = list(self.walk_active_points())
        dc = wx.PaintDC(self.graphbitmap)
        self.grapher.draw_dc(dc)

    @util.EVENT(wx.EVT_PAINT, id=xrc.XRCID('TotalTimeText'))
    def on_output_paint(self, evt):
        if not self.output_needs_update:
            return
        self.output_needs_update = False

        points = list(self.walk_active_points())
        stats = GPSPointStatistics(points)
        stats.time_elapsed = {
                "h": stats.time_secs_elapsed // 3600,
                "m": (stats.time_secs_elapsed // 60) % 60,
                "s": stats.time_secs_elapsed % 60,
                }
        for st, format_string in self.stat_texts.items():
            st.LabelText = format_string.format(stats=stats)
        self.stats = stats

    @util.EVENT(wx.EVT_TEXT_ENTER, id=xrc.XRCID('HDistPerHourText'))
    def on_hdist_per_hour_enter(self, evt):
        km_per_hour = float(self.hdist_per_hour_text.Value)
        h_total_km = self.stats.total_distance / 1000
        h_time_hours = h_total_km / km_per_hour

        v_time_hours = self.waytime_calc_inverse(h_time_hours)
        v_Hm_per_hour = self.stats.ele_dhm_delta / v_time_hours
        self.ele_per_hour_text.Value = "{:.0f}".format(v_Hm_per_hour)

    @util.EVENT(wx.EVT_TEXT_ENTER, id=xrc.XRCID('ElePerHourText'))
    def on_ele_per_hour_enter(self, evt):
        Hm_per_hour = float(self.ele_per_hour_text.Value)
        v_time_hours = self.stats.ele_dhm_delta / Hm_per_hour

        h_time_hours = self.waytime_calc_inverse(v_time_hours)
        h_total_km = self.stats.total_distance / 1000
        h_km_per_hour = h_total_km / h_time_hours
        self.hdist_per_hour_text.Value = "{:.0f}".format(h_km_per_hour)

    @util.EVENT(wx.EVT_CLOSE, id=xrc.XRCID('MainFrame'))
    def on_close_window(self, evt):
        evt.Skip()
        for point in self.walk_all_points():
            point.highlight = False
        pub.sendMessage('gpsanalyzer.gps_point_hl_update',
                        track=self.track, gpx=self.gpx)

    def waytime_calc(self, one_dimension_hours, other_dimension_hours):
        return max(one_dimension_hours, other_dimension_hours) + \
               min(one_dimension_hours, other_dimension_hours) / 2

    def waytime_calc_inverse(self, one_dimension_hours):
        total_hours = self.stats.time_secs_elapsed / 3600
        if one_dimension_hours >= total_hours * 2 / 3:
            # Contribution of this dimension is larger.
            return 2 * (total_hours - one_dimension_hours)
        else:
            # Contribution of the other dimension is larger.
            return total_hours - (one_dimension_hours / 2)

    def augment_gpx_data(self):
        first_point = self.gpx.tracks[0].segments[0].points[0]
        for point, track_idx, seg_idx, point_idx in self.gpx.walk():
            point.abs_name = "%s:%d:%d:%d" % (self.gpx_basename, track_idx,
                                              seg_idx, point_idx)

            latlon = pymaplib.LatLon(point.latitude, point.longitude)
            ok, terraininfo = self.heightfinder.calc_terrain(latlon)
            if not ok:
                terraininfo.height_m = -1
            point.dhm_elevation = terraininfo.height_m

            point.secs_after_start = point.time_difference(first_point)

    def populate_pointlistbox(self):
        self.pointlistbox.AppendColumn(_("Time"))
        self.pointlistbox.AppendColumn(_("Lat"))
        self.pointlistbox.AppendColumn(_("Lon"))
        self.pointlistbox.AppendColumn(_("GPS Ele"))
        self.pointlistbox.AppendColumn(_("Map Ele"))
        self.pointlistbox.AppendColumn(_("GPS Delta Ele"))
        self.pointlistbox.AppendColumn(_("Map Delta Ele"))

        self.point_list = list()
        last_gps_ele = last_dhm_ele = None
        for point in self.walk_all_points():
            if last_gps_ele is None:
                last_gps_ele = point.elevation
            if last_dhm_ele is None:
                last_dhm_ele = point.dhm_elevation

            tm_struct = time.gmtime(point.secs_after_start)
            self.pointlistbox.Append([
                      time.strftime("%H:%M:%S", tm_struct),
                      "{:1.06f}".format(point.latitude),
                      "{:1.06f}".format(point.longitude),
                      "{:1.01f}".format(point.elevation),
                      "{:1.01f}".format(point.dhm_elevation),
                      "{:1.01f}".format(point.elevation - last_gps_ele),
                      "{:1.01f}".format(point.dhm_elevation - last_dhm_ele),
                      ])
            index = self.pointlistbox.GetItemCount() - 1
            self.point_list.append(point)
            last_gps_ele = point.elevation
            last_dhm_ele = point.dhm_elevation

    def update_display(self):
        self.graphbitmap.Refresh()
        self.output_needs_update = True
        xrc.XRCCTRL(self, 'TotalTimeText').Refresh()

    def walk_all_points(self):
        for seg in self.active_segments:
            for point in seg.walk(only_points=True):
                yield point

    def walk_active_points(self):
        if self.pointlistbox.GetSelectedItemCount() == 0:
            yield from self.walk_all_points()

        for i, point in enumerate(self.point_list):
            if self.pointlistbox.IsSelected(i):
                yield point


from datetime import datetime, timedelta

from db.db_util import get_connection

def setup():
    create_tables()
    insert_users()
    insert_students()
    insert_faculties()
    insert_courses()
    insert_student_courses()
    # insert_classes()
    # insert_attendance()

def create_tables():
    connection = get_connection()
    cursor = connection.cursor()

    create_table = 'CREATE TABLE IF NOT EXISTS user (id INTEGER PRIMARY KEY AUTOINCREMENT, username TEXT NOT NULL UNIQUE, password TEXT NOT NULL, is_student BOOLEAN DEFAULT FALSE)'
    cursor.execute(create_table)

    create_table = 'CREATE TABLE IF NOT EXISTS student (id INTEGER PRIMARY KEY, student_id TEXT NOT NULL UNIQUE, student_name TEXT NOT NULL, FOREIGN KEY (id) REFERENCES user (id))'
    cursor.execute(create_table)

    create_table = 'CREATE TABLE IF NOT EXISTS faculty (id INTEGER PRIMARY KEY, faculty_id TEXT NOT NULL UNIQUE, faculty_name TEXT NOT NULL, FOREIGN KEY (id) REFERENCES user (id))'
    cursor.execute(create_table)

    create_table = 'CREATE TABLE IF NOT EXISTS course (id INTEGER PRIMARY KEY AUTOINCREMENT, course_code TEXT NOT NULL UNIQUE, course_name TEXT NOT NULL, faculty_id INTEGER NOT NULL, FOREIGN KEY (faculty_id) REFERENCES faculty (id))'
    cursor.execute(create_table)

    create_table = 'CREATE TABLE IF NOT EXISTS student_course (student_id INTEGER NOT NULL, course_id INTEGER NOT NULL, PRIMARY KEY (student_id, course_id), FOREIGN KEY (student_id) REFERENCES student (id), FOREIGN KEY (course_id) REFERENCES course (id))'
    cursor.execute(create_table)

    create_table = 'CREATE TABLE IF NOT EXISTS class (id INTEGER PRIMARY KEY AUTOINCREMENT, course_id INTEGER, start_time TIMESTAMP NOT NULL, end_time TIMESTAMP, FOREIGN KEY (course_id) REFERENCES course (id))'
    cursor.execute(create_table)

    create_table = 'CREATE TABLE IF NOT EXISTS attendance (id INTEGER PRIMARY KEY AUTOINCREMENT, class_id INTEGER, student_id INTEGER, is_present BOOLEAN DEFAULT TRUE, UNIQUE (class_id, student_id, is_present) FOREIGN KEY (class_id) REFERENCES class (id), FOREIGN KEY (student_id) REFERENCES student (id))'
    cursor.execute(create_table)

    connection.close()

def insert_users():
    connection = get_connection()
    cursor = connection.cursor()

    insert_query = "INSERT INTO user (username, password, is_student) VALUES (?, ?, ?)"

    users = [
        ('nimisha', 'asdf', True),
        ('tanay', 'asdf', True),
        ('daksh', 'xyz', True),
        ('sumit', 'xyz', True),
        ('kavya', 'xyz', True),
        ('anisha', 'xyz', True),
        ('himanshu', 'xyz', True),
        ('ankita', 'xyz', True),
        ('stuti', 'xyz', True),
        ('parth', 'xyz', True),
        ('amit', 'xyz', False),
        ('kunal', 'xyz', False),
        ('pooja', 'xyz', False),
        ('manas', 'xyz', False),
        ('priya', 'xyz', False)
    ]
    cursor.executemany(insert_query, users)

    connection.close()

def insert_students():
    connection = get_connection()
    cursor = connection.cursor()

    insert_query = "INSERT INTO student (id, student_id, student_name) VALUES (?, ?, ?)"
    students = [
        (1, '19BCE1860', 'Nimisha Swain'),
        (2, '19BCE1563', 'Tanay Vaishnav'),
        (3, '19BCE1320', 'Daksh Sethi'),
        (4, '19BCE1600', 'Sumit Swain'),
        (5, '19BCE1426', 'Kavya Kapoor'),
        (6, '19BCE1123', 'Anisha Kaushik'),
        (7, '19BCE1024', 'Himanshu Barik'),
        (8, '19BCE1480', 'Ankita Bagaliker'),
        (9, '19BCE1725', 'Stuti Singh'),
        (10, '19BCE1670', 'Parth Singh')

    ]

    cursor.executemany(insert_query, students)

    connection.close()

def insert_faculties():
    connection = get_connection()
    cursor = connection.cursor()

    insert_query = "INSERT INTO faculty (id, faculty_id, faculty_name) VALUES (?, ?, ?)"
    faculties = [
        (11, '11FAC1078', 'Amit Tyagi'),
        (12, '12FAC1346', 'Kunal Kapoor'),
        (13, '12FAC1005', 'Pooja Johar'),
        (14, '16FAC1089', 'Manas Murli'),
        (15, '18FAC1234', 'Priya Bhatt')

    ]

    cursor.executemany(insert_query, faculties)

    connection.close()

def insert_courses():
    connection = get_connection()
    cursor = connection.cursor()

    insert_query = "INSERT INTO course (course_code, course_name, faculty_id) VALUES (?, ?, ?)"
    courses = [
        ('CSE2002', 'Data Structure And Algorithm', 12),
        ('CSE2004', 'Network And Communication', 12),
        ('CHE2003', 'Engineering Chemistry', 15),
        ('CSE3001', 'Software Engineering', 15),
        ('CSE3002', 'Internet And Web Programming', 12),
        ('PHY1002', 'Engineering Physics', 13),
        ('STS1106', 'Soft Skills', 15),
        ('PHY1105', 'Introduction to Innovative Projects', 13),
        ('CSE5002', 'Introduction to Machine Learning', 13)
    ]

    cursor.executemany(insert_query, courses)

    connection.close()

def insert_student_courses():
    connection = get_connection()
    cursor = connection.cursor()

    insert_query = "INSERT INTO student_course (student_id, course_id) VALUES (?, ?)"
    student_courses = [
        (1, 1),
        (1, 2),
        (1, 3),
        (1, 5),
        (1, 6),
        (2, 1),
        (2, 5),
        (2, 3),
        (2, 8),
        (2, 9),
        (3, 1),
        (3, 5),
        (3, 6),
        (3, 3),
        (4, 6),
        (4, 1),
        (4, 5),
        (5, 1),
        (5, 5),
        (6, 1),
        (6, 5),
        (7, 1),
        (7, 5),
        (8, 1),
        (8, 5),
        (9, 5),
        (10, 5)
    ]

    cursor.executemany(insert_query, student_courses)

    connection.close()

def insert_classes():
    connection = get_connection()
    cursor = connection.cursor()

    insert_query = "INSERT INTO class (course_id, start_time, end_time) VALUES (?, ?, ?)"
    classes = [
        (1, datetime.now() - timedelta(days=1), datetime.now()),
    ]

    cursor.executemany(insert_query, classes)

    connection.close()

def insert_attendance():
    connection = get_connection()
    cursor = connection.cursor()

    insert_query = "INSERT INTO attendance (student_id, class_id) VALUES (?, ?)"
    attendance = [
        (1, 1),
        (1, 2),
    ]

    cursor.executemany(insert_query, attendance)

    connection.close()

if __name__ == "__main__":
    setup()


import keyboard
import screeninfo
import pyautogui
import random
import time
import win32api
import win32con
from pyautogui import *

# Get the primary screen information
screen = screeninfo.get_monitors()[0]

# Instead of using PyAutoGUI (too slow) to click the tiles, we can use the win32api to click the tiles.
def click(coords):
    win32api.SetCursorPos(coords)
    win32api.mouse_event(win32con.MOUSEEVENTF_LEFTDOWN, 0, 0)
    time.sleep(0.01)  # This pauses the script for 0.01 seconds
    win32api.mouse_event(win32con.MOUSEEVENTF_LEFTUP, 0, 0)

def take_screenshot_from_region(region):
    """
        Takes a screenshot of the screen and saves it in the images folder
    """
    return pyautogui.screenshot(region=region)
    # iml.save(r"C:\Users\maxna\Exos Codage\Python\piano_tiles_bot\images\stickman.png")

def main():
    print("Program starting...")
    # Takes 2 seconds to launch the AimBooster game
    time.sleep(2)

    print("Press q to quit")
    while not keyboard.is_pressed("q"):
        region = (screen.width//2 + 100, 430, 742, 524)
        image = take_screenshot_from_region(region)

        width, height = image.size

        target = (255, 219, 195)

        prev = (0, 0)
        # We check every pixel of the image
        for i in range(0, width, 5):
            for j in range(0, height, 5):
                # If the pixel is the same color as the target, we click it
                if image.getpixel((i, j)) == target:
                    # We add the padding to the coordinates to click in the correct region
                    click((region[0] + i, region[1] + j))
                    time.sleep(0.04)
                    break

if __name__ == "__main__":
    main()


# File:          hydrocarbon_weight-progex3.3.py
# Date:          2019-09-26
# Author:        "Hannes Thiersen" <hannesthiersen@gmail.com>
# Exercise:      prog ex 3.3
# Description:
#   Write a program that dtermines the molocular weight of a hydrocarbon based
#   on the number of hydrogen, carbon, and oxygen atoms. You should use the
#   following weights:
#
#       Atom    Weight (grams/mole)
#        H       1.0079
#        C       12.011
#        O       15.994

#-----------------------------------------------------------------------------
# FUNCTIONS
#-----------------------------------------------------------------------------
def main():
    print("Calculate the molecular weight of a hydrocarbon.")
    hydrogen = eval(input("Enter the amount of hydrogen (H): "))
    carbon = eval(input("Enter the amount of carbon (C): "))
    oxygen = eval(input("Enter the amount of oxygen (O): "))

    mol_weight = hydrogen*1.0079 + carbon*12.011 + oxygen*15.994

    print("Hydrocarbon molecular weight: ", mol_weight)

#-----------------------------------------------------------------------------
# MAIN
#-----------------------------------------------------------------------------
if __name__ == "__main__":

    main()


import psdata
import os

from pylab import *

class FeeSpec(psdata.Detector):
    """General Camera implementation of Detector Class of psdata.Detector.
    """

    def __init__(self,*args,**kwargs):

        psdata.Detector.__init__(self,*args,**kwargs)

        cam_dict = {'ArrayData': 'CAMR:FEE1:441:IMAGE2:ArrayData',
                    'ArraySize0_RBV': 'CAMR:FEE1:441:IMAGE2:ArraySize0_RBV',
                    'ArraySize1_RBV': 'CAMR:FEE1:441:IMAGE2:ArraySize1_RBV'}

        self.add_device(**cam_dict)
        self.set_parameter(nx=self.ArraySize0_RBV.VAL)
        self.set_parameter(ny=self.ArraySize1_RBV.VAL)

    @property
    def image(self):
        """Create image from data_array.
        """
        return self.ArrayData.VAL[0:self.nx*self.ny].reshape(self.ny,self.nx)

    @property
    def xprojection(self):
        """X projection of image.
        """
        return self.image.sum(axis=1)

    @property
    def yprojection(self):
        """X projection of image.
        """
        return self.image.sum(axis=0)

    def new_plot(self, **kwargs):
        plt.ion()
        plt.imshow(self.image)
        plt.clim(**kwargs)
        plt.colorbar()
        plt.title(self.desc)

    def plot(self, nevents=1, projection=False, monitor=False, next_event=False):
        """Plot CSpad image.
        """
        ievent = 0
        try:
            plt.ion()
            plt.show()
            while ievent < nevents or monitor:
                if ievent > 0 or next_event or monitor:
                    self._data.next_event()

                if projection:
                    if projection in ['y', 'yprojection', 'Y']:
                        plotdata = self.yprojection
                    else:
                        plotdata = self.xprojection

                    plt.plot(plotdata)

                else:
                    plt.imshow(self.image)

                plt.draw()
                ievent += 1
        except KeyboardInterrupt:
            pass

    def publish(self, name=None, title=None,
                projection=None,
                start=True, stop=False, local=True, **kwargs):
        """Publish plot with psmon.
           Plot can be read on multiple machines with psplot.
        """
        if projection:
            if projection is 'y':
                plotdata = 'yprojection'
            else:
                plotdata = 'xprojection'

            if not name:
                name = self._name+'_'+plotdata

            if not title:
                if self._desc:
                    title = self._desc+' '+plotdata
                else:
                    title = self._name+' '+plotdata

        else:
            if not name:
                name = self._name+'_image'

            if not title:
                if self._desc:
                    title = self._desc
                else:
                    title = self._name

        if start:
            if projection:
                self.add_psplot(plotdata, plot_type='XYplot',
                                name=name, title=title, local=local, **kwargs)

            else:
                self.add_psplot('image', plot_type='Image',
                                name=name, tle=title, local=local, **kwargs)

        if stop:
            self.del_psplot(name)


# -*- coding: utf-8 -*-
"""
This test is performed on ledger subsystem with Ethereum, over 'development'
network of brownie. This test takes approximately 70 seconds to complete.
"""
import pytest
import hashlib
import os
import time

import sys
sys.path.extend(["../"])
import bbc1

TEST_CONFIG_FILE = 'test_config.json'

from bbc1.core import bbclib
from bbc1.core import ledger_subsystem, bbc_stats, bbc_network, bbc_config
from bbc1.core.ethereum import bbc_ethereum

domain_id1 = bbclib.get_new_id("test_domain1")
domain_id2 = bbclib.get_new_id("test_domain2")

class Args:

    def __init__(self):

        self.workingdir = bbc_config.DEFAULT_WORKING_DIR
        self.config = TEST_CONFIG_FILE

class DummyCore:
    class UserMessageRouting:
        def add_domain(self, domain_id):
            pass

        def remove_domain(self, domain_id):
            pass

    def __init__(self):
        self.user_message_routing = DummyCore.UserMessageRouting()
        self.stats = bbc_stats.BBcStats()

@pytest.fixture()
def default_config():

    args = Args()
    config = bbc_ethereum.setup_config(args.workingdir, args.config,
            'development')
    conf = config.get_config()

    db_conf = {
        "db_type": "sqlite",
        "db_name": "bbc_ledger.sqlite",
        "replication_strategy": "all",
        "db_servers": [
            {
                "db_addr": "127.0.0.1",
                "db_port": 3306,
                "db_user": "user",
                "db_pass": "pass"
            }
        ]
    }

    domain_id1_conf = {
        'storage': {
            'type': 'internal',
        },
        'db': db_conf,
        'use_ledger_subsystem': True,
        'ledger_subsystem': {
            'subsystem': 'ethereum',
            'max_transactions': 100,
            'max_seconds': 30,
        },
    }
    domain_id2_conf = {
        'storage': {
            'type': 'internal',
        },
        'db': db_conf,
        'use_ledger_subsystem': True,
        'ledger_subsystem': {
            'subsystem': 'ethereum',
            'max_transactions': 100,
            'max_seconds': 30,
        },
    }

    conf['domains'][domain_id1.hex()] = domain_id1_conf
    conf['domains'][domain_id2.hex()] = domain_id2_conf

    return config

def test_ledger_subsystem(default_config):

    bbc_ethereum.setup_deploy(default_config)

    prevdir = os.getcwd()
    os.chdir(bbc1.__path__[0] + '/core/ethereum')

    conf = default_config.get_config()

    os.chdir('..')

    networking = bbc_network.BBcNetwork(core=DummyCore(),
            config=default_config, p2p_port=6641)
    networking.create_domain(domain_id=domain_id1)

    ls = ledger_subsystem.LedgerSubsystem(default_config,
            networking=networking, domain_id=domain_id1, enabled=True)
    eth = bbc_ethereum.BBcEthereum(
        conf['ethereum']['network'],
        private_key=conf['ethereum']['private_key'],
        contract_address=conf['ethereum']['contract_address']
    )

    for i in range(150):
        ls.register_transaction(hashlib.sha256(i.to_bytes(4, 'big')).digest())

    print("\n30-second interval for trigger Merkle tree creation.")
    for i in range(6, 0, -1):
        print("continuing to sleep. countdown", i)
        time.sleep(5)

    i = 300
    j = ls.verify_transaction(hashlib.sha256(i.to_bytes(4, 'big')).digest())

    assert not j['result']

    for i in range(150):
        digest = hashlib.sha256(i.to_bytes(4, 'big')).digest()
        j = ls.verify_transaction(digest)
        assert j['result']
        assert eth.verify(digest, j['subtree']) > 0

    # -- test in another domain
    networking.create_domain(domain_id=domain_id2)
    ls = ledger_subsystem.LedgerSubsystem(default_config,
            networking=networking, domain_id=domain_id2, enabled=True)

    i = 100
    j = ls.verify_transaction(hashlib.sha256(i.to_bytes(4, 'big')).digest())

    assert not j['result']

    i = 99
    digest = hashlib.sha256(i.to_bytes(4, 'big')).digest()
    ls.register_transaction(digest)

    print("31-second interval for trigger Merkle tree creation.")
    time.sleep(1)
    for i in range(6, 0, -1):
        print("continuing to sleep. countdown", i)
        time.sleep(5)

    j = ls.verify_transaction(digest)
    assert j['result']
    assert eth.verify(digest, j['subtree']) > 0

    block_no, root = eth.verify_and_get_root(digest, j['subtree'])
    assert block_no == eth.test(root)

    os.chdir(prevdir)

# end of tests/test_ledger_subsystem_.py


##
## LogsAnalyserTool
## File description:
## functions1
##

import re
import threading

def print_step(step, id, line_nb): #print step in percentage -> if you do real time analysis, you should remove this functions
    if (int((id / line_nb) * 100) == step): #print the calculation progression
        step += 5
        print(step, "%")
    return (step)

def multiple_replace(banned_char, log_line, replace_with): # replace many characters in one time
    for i in range (0, len(banned_char)):
       log_line = log_line.replace(banned_char[i], replace_with)
    return (log_line.split())

def is_a_correct_front_log_line(log_line): # verify if a line is a real log's line(using IP)
    if (re.match(r'([0-9]{1,3}\.){3}[0-9]{1,3}', log_line)):
        return (1)
    return (0)

def is_a_correct_back_log_line(log_line): # verify if a line is a real log's line(using DATE)
    if (re.match(r'[0-9]{2}([:][0-9]{2}){2}[,][0-9]{3}', log_line)):
        return (1)
    return (0)

def count_lines(file): #count all lines
    i = 0
    fd = open(file, 'r')
    for line in fd:
	    i += 1
    fd.close()
    return (i)

def count_logs(sys_argv): # count all "true" log's lines
    nb_logs = 0
    fd = open(sys_argv[2], 'r')
    nb_lines = count_lines(sys_argv[2])
    for x in range (0, nb_lines):
        str = fd.readline()
        if (sys_argv[1] == "-backend"):
            if (is_a_correct_back_log_line(str[:12])):
                nb_logs += 1
        elif (sys_argv[1] == "-frontend"):
            if (is_a_correct_front_log_line(str[:12])):
                nb_logs += 1
    return (nb_logs)

def call_as_thread(function_name, options):
    thread = threading.Thread(target = function_name, args = options)
    thread.start()
    thread.join()


import os
import json
import time
from flask import request
from werkzeug.security import safe_join
from userConfig import compareVersion, VERSION
version = VERSION

cache = {}

getBrief = lambda item: dict(name=item['name'], notes=item.get('notes', []))

def loadPreset(path):
  def f(filename, raw=False):
    if not filename.endswith('.json'):
      return None
    name = filename.rpartition('.')[0]
    filename = safe_join(path, filename)
    if not os.path.exists(filename):
      return None
    mtime = cache[name][0] if name in cache else 0
    st_mtime = os.stat(filename).st_mtime
    if mtime < st_mtime:
      try:
        with open(filename, 'r', encoding='utf-8') as fp:
          text = fp.read()
          item = json.loads(text)
          name = item['name'] # should equals name
          if compareVersion(version, item['version']) < 0:
            return 'Incompatible version' if raw else None
          cache[name] = (st_mtime, text, getBrief(item))
      except Exception as e:
        return str(e) if raw else None
    return cache[name][1] if raw else cache[name][2]
  return f

def savePreset(path):
  def f(data):
    if not os.path.exists(path):
      os.mkdir(path)
    brief = getBrief(json.loads(data))
    name = brief['name']
    with open(safe_join(path, name + '.json'), 'w', encoding='utf-8') as fp:
      fp.write(data)
      cache[name] = (time.time(), data, brief)
    return name
  return f

def initPreset(config):
  global version
  if 'version' in config:
    version = config['version']

def preset():
  try:
    pType = request.values['path']
    if not pType in {'video', 'image'}:
      return '', 403
    path = '.user/preset_' + pType
    name = request.values['name'] if 'name' in request.values else None
    data = request.values['data'] if 'data' in request.values else None
    if data:
      return savePreset(path)(data), 200
    else:
      if name:
        res = cache[name][1] if name in cache else loadPreset(path)(name + '.json', True)
        if res:
          return res, 200
        else:
          return '', 404
      else:
        if os.path.exists(path):
          res = [*filter(None, map(loadPreset(path), os.listdir(path)))]
          return json.dumps(res , ensure_ascii=False, separators=(',', ':')), 200
        else:
          return '[]', 200
  except Exception:
    return '', 403


import time
import copy
import gobject

from phony.base.log import ClassLogger
from RPi import GPIO
from types import MethodType

class Inputs(ClassLogger):
  _layout = {}
  _inputs_by_channel = {}

  _rising_callback_by_channel_name = {}
  _falling_callback_by_channel_name = {}
  _pulse_callback_by_channel_name = {}

  def __init__(self, layout):
    ClassLogger.__init__(self)

    # IO event callbacks occur in another thread, dbus/gdk need
    # to be made aware of this.
    gobject.threads_init()

    GPIO.setmode(GPIO.BCM)

    self._layout = layout
    for name, config in layout.iteritems():
      for point in ['pin', 'pull_up_down']:
        Inputs._raise_if_not_in(point, config)

      config = copy.deepcopy(config)
      config['name'] = name

      self._inputs_by_channel[config['pin']] = config
      self._configure_input(name, config)

  def on_rising_edge(self, channel_name, callback):
    self._rising_callback_by_channel_name[channel_name] = callback

  def on_falling_edge(self, channel_name, callback):
    self._falling_callback_by_channel_name[channel_name] = callback

  def on_pulse(self, channel_name, callback):
    self._pulse_callback_by_channel_name[channel_name] = callback

  #@ClassLogger.TraceAs.call()
  def _channel_changed(self, channel):
    name = self._inputs_by_channel[channel]['name']

    do_rise = name in self._rising_callback_by_channel_name
    do_fall = name in self._falling_callback_by_channel_name

    if do_rise or do_fall:
      time.sleep(0.01)

      if GPIO.input(channel):
        high = 1
      else:
        high = 0

      if high and do_rise:
        self._rising_callback_by_channel_name[name]()

      if not high and do_fall:
        self._falling_callback_by_channel_name[name]()

    if name in self._pulse_callback_by_channel_name:
      self._pulse_callback_by_channel_name[name]()

  def _configure_input(self, name, configuration):
    pin = configuration['pin']

    self.log().debug('Pin %d -> %s' % (pin, name))

    if configuration['pull_up_down'] == 'up':
      pull_up_or_down = GPIO.PUD_UP
    else:
      pull_up_or_down = GPIO.PUD_DOWN

    if 'debounce' in configuration:
      debounce = configuration['debounce']
    else:
      debounce = 0

    GPIO.setup(pin, GPIO.IN, pull_up_down = pull_up_or_down)
    GPIO.add_event_detect(pin, GPIO.BOTH, callback = self._channel_changed, bouncetime = debounce)

  @staticmethod
  def _raise_if_not_in(point, config):
    if point not in config:
      raise Exception('Missing required configuration point %s' % point)

  def __enter__(self):
    return self

  def __exit__(self, exc_type, exc_value, traceback):
    for channel in self._inputs_by_channel:
      GPIO.remove_event_detect(channel)

class Outputs(ClassLogger):
  _layout = None

  def __init__(self, layout):
    ClassLogger.__init__(self)

    # IO event callbacks occur in another thread, dbus/gdk need
    # to be made aware of this.
    gobject.threads_init()

    GPIO.setwarnings(False)
    GPIO.setmode(GPIO.BCM)

    self._layout = layout
    for name, config in layout.iteritems():
      for point in ['pin', 'default']:
        Outputs._raise_if_not_in(point, config)

      self._conigure_output(name, config)

  def _conigure_output(self, name, configuration):
    pin = configuration['pin']

    self.log().debug('Pin %d -> %s' % (pin, name))

    GPIO.setup(pin, GPIO.OUT)

    if 'invert_logic' in configuration and configuration['invert_logic']:
      set_pin = lambda self,value: GPIO.output(pin, not value)
    else:
      set_pin = lambda self,value: GPIO.output(pin, value)

    set_pin(None, configuration['default'])

    setattr(self, name, MethodType(set_pin, self, type(self)))

  @staticmethod
  def _raise_if_not_in(point, config):
    if point not in config:
      raise Exception('Missing required configuration point %s' % point)

  def __enter__(self):
    return self

  def __exit__(self, exc_type, exc_value, traceback):
    pass


def select(msg:str,n_options:int)->int:
    print(msg)
    while(True):
        ch = input('Select 1 to: '+str(n_options)+'> ')
        if not ch.isnumeric():
            print('Error input format ')
            continue
        chint = int(ch)
        if chint >=1 and chint <= n_options:
            return chint
        print("Selection not in range!")
        continue

def print_dict(mydic:dict,offset:int):
    for key,values in mydic.items():
        for i in range(offset):
            print(' ', end='')
        print(key,' : ', end='')
        if isinstance(values,dict):
            print()
            print_dict(values,offset+8)
        else:
            print(values)

def dict_2_str(mydic:dict,offset:int)->str:
    st:str = ""
    for key,values in mydic.items():
        for i in range(offset):
            st +=' '

        st += key+' : '
        if isinstance(values,dict):
            st += "\n"
            st += dict_2_str(values,offset+8)
        else:
            st += str(values)
            st += "\n"
    return st


import models
from typing import Optional
from sqlalchemy.orm import Session
from db import engine, SessionLocal
from fastapi.responses import HTMLResponse
from fastapi.staticfiles import StaticFiles
from fastapi.templating import Jinja2Templates
from fastapi import FastAPI, Request, Header, Depends

models.Base.metadata.create_all(bind=engine)

app = FastAPI()
app.mount("/static", StaticFiles(directory="assets"), name="static")
templates = Jinja2Templates(directory="templates")

# Dependency
def get_db():
    db = SessionLocal()
    try:
        yield db
    finally:
        db.close()

@app.on_event('startup')
def startup_populate_db():
    db = SessionLocal()
    num_films = db.query(models.Film).count()
    if num_films == 0:
        films = models.HARD_CODED_FILMS
        for film in films:
            db.add(models.Film(**film))
        db.commit()
        print('Films successfully created !!!!!!!!!!')
    db.close()

@app.get('/', response_class=HTMLResponse)
async def films_list_view(
    request: Request,
    hx_request: Optional[str] = Header(None),
    db: Session = Depends(get_db),
    page: int = 1
):

    N = 5 # Films per page
    OFFSET = (page - 1) * N

    films = db.query(models.Film).offset(OFFSET).limit(N)
    num_films = db.query(models.Film).count()

    context = {
        'num_films': num_films,
        'request': request,
        'films': films,
        'page': page,
    }

    if hx_request:
        return templates.TemplateResponse('partials/table.html', context)

    return templates.TemplateResponse('films_list.html', context)


# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from django.db import models, migrations

class Migration(migrations.Migration):

    dependencies = [
        ('discussions', '0001_initial'),
    ]

    operations = [
        migrations.AlterModelOptions(
            name='discussion',
            options={'get_latest_by': 'updated', 'ordering': ['-updated']},
        ),
        migrations.AddField(
            model_name='discussion',
            name='closed',
            field=models.BooleanField(default=False),
            preserve_default=True,
        ),
        migrations.AddField(
            model_name='discussion',
            name='sticky',
            field=models.BooleanField(default=False),
            preserve_default=True,
        ),
        migrations.AddField(
            model_name='discussion',
            name='updated',
            field=models.DateTimeField(null=True),
            preserve_default=True,
        ),
        migrations.AlterField(
            model_name='discussion',
            name='title',
            field=models.CharField(max_length=255),
            preserve_default=True,
        ),
    ]


from django.shortcuts import redirect, render, get_object_or_404
from django.urls import reverse

from .models import Product, Review
from .forms import ReviewForm, NoReviewForm

def product_list_view(request):
    template = 'app/product_list.html'
    products = Product.objects.all()

    context = {
        'product_list': products,
    }

    return render(request, template, context)

def product_view(request, pk):
    print('****************** FIRST METHOD ',request.method, ' *********************')
    template = 'app/product_detail.html'
    product = get_object_or_404(Product, id=pk)
    session = request.session.session_key
    print('Session id:', session)
    form = ReviewForm(request.POST)
    #print('Form type:', type(form), 'Form content:', form)
    is_reviewed = False

    def print_and_review(request, pk):
        print('----------------')
        print('Req session:', request.session)
        print('Req sess reviewed_products:', request.session['reviewed_products'])
        print('No review from this session on product', pk)
        review = Review()
        review.text = form.cleaned_data['text']
        review.product = product
        review.save()
        saved_list = request.session['reviewed_products']
        saved_list.append(pk)
        request.session['reviewed_products'] = saved_list

    if request.method == 'GET':
        print('WE IN GET!!')
        if not ('reviewed_products' in request.session):
            print('*** WE in First IF ***')
            form = ReviewForm(request.POST)
            reviews = Review.objects.all()
            is_reviewed = False
            context = {
            'form': form,
            'product': product,
            'reviews': reviews,
            'is_review_exist': is_reviewed,
            }
        else:
            if not (pk in request.session['reviewed_products']):
                print('*** WE in Second IF ***')
                form = ReviewForm(request.POST)
                reviews = Review.objects.all()
                is_reviewed = False
                context = {
                'form': form,
                'product': product,
                'reviews': reviews,
                'is_review_exist': is_reviewed,
                }
            else:
                print('You in GET method, and you reviewed this product')
                is_reviewed = True
                reviews = Review.objects.all()
                form = ReviewForm(request.POST)
                context = {
                'form': form,
                'product': product,
                'reviews': reviews,
                'is_review_exist': is_reviewed,
                }

    if request.method == 'POST':
        if form.is_valid():
            if not ('reviewed_products' in request.session):
                request.session['reviewed_products'] = []
                print_and_review(request, pk)

            else:
                if not (pk in request.session['reviewed_products']):
                    print_and_review(request, pk)
                else:
                    print('!!!!You reviewed this product!!!!')
                    is_reviewed = True
        reviews = Review.objects.all()
        for k in reviews:
            print('Reviews we have:', k.text)

        if is_reviewed:
            form = NoReviewForm(request.POST)
        else:
            form = ReviewForm(request.POST)

        context = {
            'form': form,
            'product': product,
            'reviews': reviews,
            'is_review_exist': is_reviewed,
        }

    return render(request, template, context)


from typing import Optional

from aioredis import Redis

from excars import config
from excars.models.profiles import Profile

def _get_key_for(user_id: str) -> str:
    return f"users:{user_id}:profile"

async def save(redis_cli: Redis, profile: Profile):
    await redis_cli.set(_get_key_for(profile.user_id), profile.json())

async def get(redis_cli: Redis, user_id: str) -> Optional[Profile]:
    data = await redis_cli.get(_get_key_for(user_id))
    if not data:
        return None
    return Profile.parse_raw(data)

async def delete(redis_cli: Redis, user_id: str) -> None:
    await redis_cli.delete(_get_key_for(user_id))

async def persist(redis_cli: Redis, user_id: str) -> None:
    await redis_cli.persist(_get_key_for(user_id))

async def expire(redis_cli: Redis, user_id: str) -> None:
    await redis_cli.expire(_get_key_for(user_id), timeout=config.PROFILE_TTL)


import itertools
import math
from collections import defaultdict
from copy import deepcopy
from functools import reduce

INPUT = open("./input_files/input_14", "r").read().strip("\n")

def get_reactions():
    reactions = [r for r in INPUT.split('\n')]
    results = dict()
    for reaction in reactions:
        ingredients, result = reaction.split(' => ')
        amount, output = result.split(' ')
        results[output] = (int(amount), [(int(i.split(' ')[0]), i.split(' ')[1]) for i in ingredients.split(', ')])

    return results

REACTIONS = get_reactions()

def make(ammount, output, spares):
    if output == 'ORE':
        return ammount

    if output in spares:  # We might have to over produce some stuff. Go PLANET!
        spares_to_use = min(spares[output], ammount)
        ammount -= spares_to_use
        spares[output] -= spares_to_use

    if ammount == 0:  # no ore used, all from stock
        return 0

    reaction = REACTIONS[output]
    full_reactions = ammount // reaction[0]
    short = ammount % reaction[0]
    if short > 0:  # Put away for ReCycling
        full_reactions += 1
        if output not in spares.keys():
            spares[output] = 0
        spares[output] += reaction[0] - short

    ore = [make(a * full_reactions, i, spares) for a, i in reaction[1]]

    return sum(ore)

def run_1():
    spares = dict()
    return make(1, 'FUEL', spares)

def run_2():
    goal = 1000000000000
    # target = goal // 337075
    # target = 5193698
    # target = 5194098
    target = 5194168

    ore = 0
    while ore < goal:
        spares = dict()
        ore = make(target, 'FUEL', spares)
        print(target, ore, ore > goal)
        target += 1
    return target - 2

print(run_1())
print(run_2())


n = int(input())
xy = [list(map(int, input().split())) for _ in range(n)]
l = len(xy)
ans = 0
for i in range(l):
    xi, yi = xy[i][0], xy[i][1]
    for j in range(i+1, l):
        xj, yj = xy[j][0], xy[j][1]

        a = abs((yi-yj)/(xi-xj))
        if a <= 1:
            ans += 1

print(ans)


import socket
import time

from collections import defaultdict
from typing import Optional, Union

class ClientError(Exception):
    pass

class Client:
    def __init__(self, server_ip: str, port: int, timeout: Optional[int] = None):
        self._socket = socket.socket()
        self._socket.connect((server_ip, port))
        self._socket.settimeout(timeout)

    def put(self, metric_name: str, value: Union[int, float], timestamp: Optional[int]):
        if timestamp is None:
            timestamp = int(time.time())
        self._socket.send(f"put {metric_name} {value} {int(timestamp)}\n".encode())
        response = self._read_all()
        if response[:2] != "ok":
            raise ClientError()

    def get(self, metric_name: str):
        self._socket.send(f"get {metric_name}".encode())
        response = self._read_all()
        if response[:2] != "ok":
            raise ClientError()

        result = defaultdict(list)

        for i, line in enumerate(response.split("\n")):
            if not i or line == "":
                continue
            try:
                metric, value, timestamp = line.split()
                result[metric].append((int(timestamp), float(value)))
            except ValueError:
                raise ClientError()

        for key in result.keys():
            result[key] = sorted(result[key], key=lambda x: -x[-1])

        return result

    def _read_all(self):
        raw_response = bytearray()
        chunk = self._socket.recv(1024)
        raw_response.extend(chunk)
        while chunk.decode()[-2:] != "\n\n":
            chunk = self._socket.recv(1024)
            raw_response.extend(chunk)
        return raw_response.decode()


from tkinter import *
root=Tk()
root.geometry("430x500")
root.resizable(0,0)
# namee StringVar(20)
# contact IntVar
# email StringVar(20)
# gen StringVar(20)
# city StringVar(20)
# state StringVar(20)

def showdata():
    # file=open("Registration.txt","a")
    # file.write(f"name: {name.get()}\ncontect: {contact.get()}\nemail: {email.get()}\nGender : {Gen.get()}\nCity : {selcton1.get()}\nState : {selcton2.get()}\n\n")
    print(f"name: {namee.get()}\ncontect: {contact.get()}\nemail: {email.get()}\nGender : {gen.get()}\nCity : {city.get()}\nState : {state.get()}\n\n")

namee=StringVar()
contact=IntVar()
contact.set(" ")
email=StringVar()
Male=IntVar()
Female=IntVar()
gen=StringVar()
gen.set("Male")

city=StringVar()
city.set( " " )
state=StringVar()
state.set( " " )

Button1=StringVar()

l0 = Label(text="Please Enter details below", font='Verdana 10 bold', bg="orange", fg="white", padx=60,pady=12)
l0.pack(fill=X)

def connect_databas():

    import mysql.connector

    mydb = mysql.connector.connect(
        host = "localhost",
        user = "root",
        password = "",
        database="banking",
        port='3306'
    )
    print(namee.get(),contact.get(),email.get(),gen.get(),city.get(),state.get())
    cursor = mydb.cursor()
    query=f"insert into user(namee,contact,email,gen,city,state) values(%s,%s,%s,%s,%s,%s)"
    # args=
    cursor.execute(query,(namee.get(),contact.get(),email.get()),gen.get(),city.get(),state.get())
    mydb.commit()
# l0.pack(anchor="n", side="top", fill=X, padx=5)

root.title("Registration From")

LName=Label(root,text="Name*",font='Verdana 10 bold',pady=10,padx=20)
LName.place(x=80,y=100)
EName=Entry(bd=2,relief="raised",font='Verdana 10 bold',textvariable=namee)
EName.place(x=200,y=100,width=150,height=30)

LContact=Label(root,text="Contact*",font='Verdana 10 bold')
LContact.place(x=80,y=150)
EContact=Entry(bd=2,relief="raised",font='Verdana 10 bold',textvariable=contact)
EContact.place(x=200,y=150,width=150,height=30)

Label_Email=Label(root,text="Email*",font='Verdana 10 bold')
Label_Email.place(x=100,y=200)
Entry_Email=Entry(bd=2,relief="raised",font='Verdana 10 bold',textvariable=email)
Entry_Email.place(x=200,y=200,width=150,height=30)

LGender=Label(root,text="Gender*",font='Verdana 10 bold')
LGender.place(x=80,y=250)
RadioMale=Radiobutton(root,text="Male",value="Male",font='Verdana 10 bold',variable=gen)
RadioMale.place(x=180,y=250,width=100,height=30)
RadioFemale=Radiobutton(root,text="Female",value="Female",font='Verdana 10 bold',variable=gen)
RadioFemale.place(x=270,y=250,width=100,height=30)

LabelCity=Label(root,text="City*",font='Verdana 10 bold')
LabelCity.place(x=110,y=300)
LabelCity=Entry(bd=2,relief="raised",font='Verdana 10 bold',textvariable=city)
LabelCity.place(x=200,y=300,width=150,height=30)
options1 = [
    "Surat",
    "New Delhi",
    "Bengaluru",
    "Mumbai",
    "London",
    "Paris",
    "Rio",
    "Tokyo",
    "Bangkok",
    "Helsinki",
    "Nairobi",
    "istanbul"
]
CityDropdown= OptionMenu( root,city , *options1)
CityDropdown.place(x=330,y=300,width=25,height=30)

LabelState=Label(root,text="State*",font='Verdana 10 bold')
LabelState.place(x=100,y=350)
LabelState=Entry(bd=2,relief="raised",font='Verdana 10 bold',textvariable=state)
LabelState.place(x=200,y=350,width=150,height=30)
options2 = [
    "Gujarat",
    "Delhi",
    "Karnataka",
    "Maharashtra",
    "UK",
    "France",
    "Brazil",
    "Japan",
    "Maryand",
    "Hong Kong",
    "Kenya",
    "Turkey"
]
StateDropdown = OptionMenu( root ,state, *options2)
StateDropdown.place(x=330,y=350,width=25,height=30)

RagisterButton=Button(text="Register",font='Verdana 10 bold',bg="orange",fg="black",bd=5,relief="raised",command=connect_databas)
RagisterButton.place(x=150,y=400,width=130,height=40)

root.mainloop()


#!/usr/bin/env python
# -*- coding: utf-8 -*-
import random
import sys
from comp_moves import *
sys.setrecursionlimit(100000000)

class Game_C:
    def __init__(self, data, ax):
        self.ax = ax
        self.data = data
        self.turn = 1
        self.a = 1
        self.pickedpiece = None

    def onclick(self, event):
        if self.turn == 1:
            if self.a == 1:
                self.pickedpiece = cell_cords(event.xdata, event.ydata)
                if (self.pickedpiece not in self.data.position or self.data.position[self.pickedpiece][0] != 'W')\
                        or not has_legal_move(cell_cords(event.xdata, event.ydata), self.data.position):
                    pass
                else:
                    self.a = 0
            else:
                if lm(self.pickedpiece, cell_cords(event.xdata, event.ydata), self.data.position) and \
                        not king_will_in_danger(self.pickedpiece, cell_cords(event.xdata, event.ydata),
                                                self.data.position):
                    self.a = 1
                    self.turn = 0
                    self.do_human_move(event)
                    plt.show()
        else:
            self.turn = 1
            self.do_computer_move()
            plt.show()

    def do_human_move(self, event):
        image = plt.imread(self.data.position[self.pickedpiece] + '.png')
        if cell_cords(event.xdata, event.ydata) in self.data.position:
            self.data.pos_img[cell_cords(event.xdata, event.ydata)].remove()
        self.data.position[cell_cords(event.xdata, event.ydata)] = self.data.position[self.pickedpiece]
        del self.data.position[self.pickedpiece]
        imgplot = plt.imshow(image, extent=cords_cords(event.xdata, event.ydata), zorder=2)
        self.data.pos_img[cell_cords(event.xdata, event.ydata)] = imgplot
        self.data.pos_img[self.pickedpiece].remove()
        self.create_new_queen([self.pickedpiece, cell_cords(event.xdata, event.ydata)])
        plt.show()

    def do_computer_move(self):
        lis = every_legal_move('B', self.data.position)
        lis1 = optimize_lis(lis, self.data.position)
        if len(lis1) == 0:
            plt.title('whites won', color=mes_col)
        else:
            a = random.choice(lis1)
            image = plt.imread(self.data.position[a[0]] + '.png')
            if a[1] in self.data.position:
                self.data.pos_img[a[1]].remove()
            self.data.position[a[1]] = self.data.position[a[0]]
            del self.data.position[a[0]]
            imgplot = plt.imshow(image, extent=cords_cell(a[1]), zorder=2)
            self.data.pos_img[a[1]] = imgplot
            self.data.pos_img[a[0]].remove()
            self.create_new_queen(a)
            plt.show()

    def create_new_queen(self, move):
        if move[1][1] == '8' and \
                self.data.position[move[1]] == 'WP':
            image = plt.imread('WQ.png')
            self.data.pos_img[move[1]].remove()
            self.data.position[move[1]] = 'WQ'
            imgplot = plt.imshow(image, extent=cords_cell(move[1]), zorder=2)
            self.data.pos_img[move[1]] = imgplot
        if move[1][1] == '1' and \
                self.data.position[move[1]] == 'BP':
            image = plt.imread('BQ.png')
            self.data.pos_img[move[1]].remove()
            self.data.position[move[1]] = 'BQ'
            imgplot = plt.imshow(image, extent=cords_cell(move[1]), zorder=2)
            self.data.pos_img[move[1]] = imgplot

def letsplay():
    plt.delaxes()
    ax = create_axis()
    data = Data()
    game = Game_C(data, ax)
    draw_desk(ax)
    annotate(ax)
    data.daxatva()
    fig.canvas.mpl_connect('button_press_event', game.onclick)
    plt.show()

letsplay()
plt.show()


from os import getlogin
from tkinter import EventType
from tkinter.constants import OFF
import PySimpleGUI as sg
import pyperclip
from PySimpleGUI.PySimpleGUI import OFFICIAL_PYSIMPLEGUI_BUTTON_COLOR, WIN_CLOSED, ColorChooserButton, ObjToStringSingleObj, Window, main

# App theme
sg.theme('Dark Brown')

# Main variables
Rows = 0
Column = 0
color_storage = 'clor'
code_list = []
new_line = '\n'
final_code = 'Your code will be displayed here..'
demo_code_list = []
reset = False

# To generate button name and keys
def fun(row,col):
    if row == 0:
        return col
    else:
        return (Column*row)+col

# LED number gennerator
def led_number(arguss):
    fresh = (new_line.join(arguss))
    return fresh

# Demo code generator
def generate_demo_code():

    code = (f'''#include <FastLED.h>
#define NUM_LEDS 25
#define DATA_PIN 3
#define CLOCK_PIN 13

CRGB leds[NUM_LEDS];

void setup() {{

    FastLED.addLeds<NEOPIXEL, DATA_PIN>(leds, NUM_LEDS);
}}

void loop() {{

{led_number(demo_code_list)}

}}''')
    return code

# Code generator
def generate_code():

    code = (f'''#include <FastLED.h>
#define NUM_LEDS 25
#define DATA_PIN 3
#define CLOCK_PIN 13

CRGB leds[NUM_LEDS];

void setup() {{

    FastLED.addLeds<NEOPIXEL, DATA_PIN>(leds, NUM_LEDS);
}}

void loop() {{

{led_number(code_list)}

}}''')
    return code

# Start screen layout
pop_layout = [[[sg.Text('Number of Rows')], [sg.Input(key='-rownum-')]],
                [[sg.Text('Number of Colums')], [sg.Input(key='-colnum-')]],
                [[sg.Text('LED Type')], [sg.Input(key='-ledtype-')]],
                [[sg.Text('one')], [sg.Input()]],
                [[sg.Text('one')], [sg.Input()]],
                [[sg.Text('one')], [sg.Input()]],
                [[sg.Button('OK')]]  ]
pop_window = sg.Window('Color picker', pop_layout)

# Popup color chooser window layout
layout_popup = [[sg.Input('#xxxxxx', key='_COLOR_', size=(10,1)), sg.ColorChooserButton('Choose Color', target='_COLOR_')], [sg.Button('OK'), sg.Button('cancel')]]
window_popup = sg.Window('Color picker', layout_popup)

# Popup for variable collection
def popup_dialoue():
    global Rows,Column
    while True:
        event, values = pop_window.read()
        if event == WIN_CLOSED:
            break
        if event == 'OK':
            rozz = int(values['-rownum-'])
            colz = int(values['-colnum-'])
            Rows = rozz
            Column = colz
            led = values['-ledtype-']
            print (Rows, Column, led)
            for led in range (Rows*Column):
                code_list.append((f'leds[{led}] = CRGB::red;'))
            for led in range (Rows*Column):
                demo_code_list.append((f'leds[{led}] = CRGB::black;'))
            pop_window.close()
            main_window(rozz, colz)

# Main window
def main_window(Rows, Column):
    global code_list, final_code, reset
    # Main window layout
    matrix_layout = [[[sg.Button(f'{fun(row,col)}', key=f'{fun(row,col)}', button_color='black', size=(1,1), pad=0) for col in range (Column)] for row in range (Rows)],
    [sg.Checkbox('Sequential'), sg.Text('Delay:'), sg.Input(size = (10,1))],
    [sg.Button('Generate Code'), sg.Button('Reset')]]
    code_layout = [[sg.MLine(f'{final_code}', key='-CODE-', size =(50,20))],
                    [sg.Button('Copy code', key='-copy_btn-')], [sg.Button('Update', key='-update_btn-')]]
    # layout = [[matrix_layout],[code_layout]]
    matrix_window = sg.Window('Matrix', matrix_layout)
    while True:
        event, values = matrix_window.read()
        # matrix_window.refresh()
        print (event,values)
        if event == WIN_CLOSED:
            break
        else:
            for i in range (Rows*Column):
                if event == f'{i}':
                    color_value = sg.popup_get_text('enter color')
                    code_list[i] = f'leds[{i}] = CRGB::{color_value};'
                    print (code_list[i])
                    matrix_window.Element(f'{i}').Update(button_color=color_value)

                elif event == 'Reset':
                    matrix_window.Element(f'{i}').Update(button_color='Black')
                    reset = True
                    #final_code = generate_demo_code()
                    # final_code = demo_code
                    # for i in range (Rows*Column):
                    #code_list.append((f'leds[{i}] = CRGB::Black;'))

                elif event == 'Generate Code':
                    if reset == True:
                        reset = False
                        final_code = generate_demo_code()
                    else:final_code = generate_code()
                    code_wind()
                    break
                    # code_window['-CODE-'].update(final_code)

# Code window
def code_wind():
    global final_code
    # Code window layout
    code_layout = [[sg.MLine(f'{final_code}', key='-CODE-', size =(50,20))],
                    [sg.Button('Copy code')]]
    code_window = sg.Window('Code', code_layout)
    # code_window['-CODE-'].update(final_code)
    while True:
        event, values = code_window.read(timeout=400)
        if event == WIN_CLOSED:
            break
        else:
            if event == 'Copy code':
                pyperclip.copy(final_code)
            else: code_window.refresh()
    code_window.close()

popup_dialoue()


#!/usr/bin/env python3
# Yes, I am aware that I just switched from 2 spaces to 4 spaces. I installed linux on my desktop and this
# is the default formatting from vim, and also I remembered that it's the preferred tab-width for python.
# I am truly and deeply sorry if this has offended you. If you would like to seek financial compensation
# for this tradgedy, please email me at the address on my github profile, and I'll send you like...
# 5 cents, followed by seeking financial compensation for you seeking financial compensation from me...

import re
import sys

# get some regexes compiled:
node_re = re.compile(r'(\w+) \((\d+)\)')
relationship_re = re.compile(r'(\w+) \((\d+)\) -> (.+)')

if len(sys.argv) > 1:
    infilename = sys.argv[1]
else:
    infilename = 'input.txt'

parent_nodes = set()
child_nodes = set()

with open(infilename, 'r') as infile:
    lines = [line.strip() for line in infile]

for line in lines:
    if '->' not in line:
        match = node_re.match(line)
        child_nodes.add(match.group(1))

    elif '->' in line:
        match = relationship_re.match(line.strip())
        parent_nodes.add(match.group(1))

        children = [n.strip() for n in match.group(3).split(',')]
        for child in children:
            child_nodes.add(child)

print(parent_nodes - child_nodes)


import argparse
from functools import partial

from sklearn.model_selection import train_test_split

from data.dataset import load_dataset
from optimization.bayesian import (
    BayesianOptimizer,
    xgb_dinner_objective,
    xgb_lunch_objective,
)

def define_argparser():
    parse = argparse.ArgumentParser("Optimize")
    parse.add_argument("--trials", type=int, default=150)
    parse.add_argument("--params", type=str, default="params.pkl")
    parse.add_argument("--token", type=str, default=None)
    parse.add_argument("--liar", default=True, action="store_false")
    parse.add_argument("--verbose", type=int, default=False)
    parse.add_argument("--time", type=str, default="lunch")
    parse.add_argument("--path", type=str, default="../../input/predict-meals/")
    parse.add_argument("--name", default="Optimization", type=str)
    args = parse.parse_args()
    return args

def _main(args: argparse.Namespace):
    train, test = load_dataset(args.path)

    if args.time == "lunch":
        X_lunch = train[["월", "일", "요일", "식사가능자수", "본사출장자수", "본사시간외근무명령서승인건수", "중식참여율"]]
        y_lunch = train["중식계"]
        x_train, x_valid, y_train, y_valid = train_test_split(
            X_lunch, y_lunch, test_size=0.15, random_state=42
        )
        objective = partial(
            xgb_lunch_objective,
            x_train=x_train,
            y_train=y_train,
            x_valid=x_valid,
            y_valid=y_valid,
            verbose=args.verbose,
        )

        bayesian_optim = BayesianOptimizer(objective)

        study = bayesian_optim.bulid_study(
            trials=args.trials, name=args.name, liar=args.liar
        )
        bayesian_optim.xgb_lunch_save_params(study, args.params)

    elif args.time == "dinner":
        X_dinner = train[
            ["월", "일", "요일(석식)", "식사가능자수", "본사출장자수", "본사시간외근무명령서승인건수", "석식참여율"]
        ]
        y_dinner = train["석식계"]
        x_train, x_valid, y_train, y_valid = train_test_split(
            X_dinner, y_dinner, test_size=0.15, random_state=42
        )
        objective = partial(
            xgb_dinner_objective,
            x_train=x_train,
            y_train=y_train,
            x_valid=x_valid,
            y_valid=y_valid,
            verbose=args.verbose,
        )

        bayesian_optim = BayesianOptimizer(objective)

        study = bayesian_optim.bulid_study(
            trials=args.trials, token=args.token, name=args.name, liar=args.liar
        )

        bayesian_optim.xgb_dinner_save_params(study, args.params)

    else:
        raise ValueError

if __name__ == "__main__":
    args = define_argparser()
    _main(args)


import os
import config
import wcwidth
from tabulate import tabulate
from bplus import bplustree, leaf
from catalog import catalog_manager, tables as cat_tables, indices as cat_indices

# store the record file, with pre-created index
ind_tables = {}

class index_manager():
    global ind_tables

    def __init__(self):
        pass
        # if not os.path.exists(config.index_path):
        #     os.makedirs(config.index_path)

    def create_table(self, _table):
        ind_tables[_table] = bplustree(_table + "rec")

    def drop_table(self, _table):
        # clear all the records
        self.delete_rec(_table)
        # delete rec file
        os.remove(config.index_path + _table + "rec.json")
        ind_tables.pop(_table)

    def create_index(self, _index, _table):
        # value of index would be the primary key of the table
        ind_tables[_index] = bplustree("{}_{}".format(_index, _table))

        recs = self.get_all_rec(_table)

        col = cat_indices[_index]["column"]

        for rec in recs:
            ind_tables[_index].insert(rec[col], rec[int(cat_tables[_table].primary)])

    def drop_index(self, _index, _table):
        # delete index file
        os.remove(config.index_path + "{}_{}".format(_index, _table)+ ".json")
        ind_tables.pop(_index)

    def insert_rec(self, _table, _values):
        self.__load__(_table)
        self.__load_i__(_table)
        for i, col in enumerate(cat_tables[_table].attributes):
            if col.d_type == 'i':
                _values[i] = int(_values[i])
            elif col.d_type == 'c':
                _values[i] = _values[i].strip().replace("'", '')
            else:
                _values[i] = float(_values[i])
            # check for unique
            if col.is_unique:
                self.check_unique(_table, i, _values[i])

        record_tree = ind_tables[_table]
        prim_key = cat_tables[_table].primary

        # insert into record file
        record_tree.insert(_values[prim_key], _values)

        # insert into index file
        for _index in cat_indices.items():
            if _index[1]["table"] == _table:
                ind_tables[_index[0]].insert(_values[_index[1]["column"]], _values[prim_key])

        print('Successfully insert into table {}\n'.format(_table), end='')

    def delete_rec(self, _table, conditions=[]):
        self.__load__(_table)
        self.__load_i__(_table)

        if len(conditions) == 0:
            ind_tables[_table] = bplustree(_table + "rec")

            print("Successfully delete all entrys from table '{}'".format(_table))

        # WHERE
        else:
            cons, primary = self.convert_conditions(_table, conditions)

            leaves = self.find_leaf_condition(_table, cons[primary]) if primary else self.find_leaf_condition(_table, cons[0])

            results = [ val  for _leaf in leaves for val in _leaf.pt if self.check_conditions(val, cons) ]

            for rec in results:
                ind_tables[_table].delete(rec[cat_tables[_table].primary])

                for _index in cat_indices.items():
                    if _index[1]["table"] == _table:
                        ind_tables[_index[0]].delete(rec[_index[1]["column"]])

            print("Successfully delete {} entrys from table '{}'".format(len(results), _table))

    def select_rec(self, _table, conditions, atts):
        self.__load__(_table)

        results = []

        # WHERE
        # there is WHERE clause
        if conditions != '':
            cons, primary = self.convert_conditions(_table, conditions)

            leaves = self.find_leaf_condition(_table, cons[primary]) if primary else self.find_leaf_condition(_table, cons[0])

            results = [ val  for _leaf in leaves for val in _leaf.pt if self.check_conditions(val, cons) ]
        # there is no condition
        else:
            results = self.get_all_rec(_table)

        # PROJECT
        # print(cat_tables)
        att_info = [att.name for att in cat_tables[_table].attributes]
        att_names = att_info

        if atts != '*':
            att_names = [i.strip() for i in atts.split(',')]
            att_index = [att_info.index(i) for i in att_names]

            # project the wanted attributes of records
            results = [ [ att for i, att in enumerate(rec) if i in att_index ] for rec in results]

        print(tabulate(results, headers=att_names, tablefmt='fancy_grid'))
        print("\n {} records selected".format(len(results)))

    def chech_user(self, user, pswd):
        self.__load__("sys")
        cons = [(0 , '=', user), (1, '=', pswd)]
        leaves = self.find_leaf_condition("sys", cons[0])

        results = [ val  for _leaf in leaves for val in _leaf.pt if self.check_conditions(val, cons) ]

        return True if len(results) != 0 else False

    def __load_i__(self, t_name):
        # load index
        for _index in cat_indices.items():
            if _index[1]["table"] == t_name:
                ind_tree = bplustree("{}_{}".format(_index[0], t_name))
                bplustree.__load__("{}_{}".format(_index[0], t_name), ind_tree)
                ind_tables[_index[0]] = ind_tree

    def __load__(self, t_name):
        if t_name not in ind_tables.keys():
            # load table rec
            print("Loading Table", t_name)
            tree = bplustree(t_name + "rec")
            bplustree.__load__(t_name + "rec", tree)
            ind_tables[t_name] = tree

    def __store__(self):
        for _table in ind_tables.values():
            _table.__store__()

    def convert_conditions(self, _table, conditions):
        # parameters: "a = 8 and b = c and a <> c"
        # return: [('a', '=', '8'), ('b', '=', 'c'), ('a', '<>', 'c')], primary
        # primary == false, if there is no primary in the conditions,
        #                   else primary = index of the conditions
        lists = [x for x in conditions.strip().split(' ') if  x!= "and"]
        cons = []
        primary = False
        for i in range(int(len(lists)/3)):
            col_name = lists[3 * i]
            col_index = cat_tables[_table].get_index(col_name)

            d_type = cat_tables[_table].attributes[col_index].d_type
            val = lists[3 * i + 2]

            if d_type == 'i':
                val = int(val)
            elif d_type == 'f':
                val = float(val)
            else:
                val.replace("'", '')

            if col_index == cat_tables[_table].primary:
                primary = i

            cons.append((col_index, lists[3 * i + 1], val))

        return cons, primary

    def find_leaf_condition(self, _table, con):
        column, condition, value = con[0], con[1], con[2]
        primary_key = cat_tables[_table].primary
        first_leaf =  ind_tables[_table].root

        while type(first_leaf) is not leaf:
            first_leaf = first_leaf.pt[0]

        nodes = []
        if primary_key == column and condition != '<>':
            # kernel: the leaf that satisfy the value
            kernel = ind_tables[_table].find_leaf(value)

            if condition == '=':
                for val in kernel.pt:
                    if val[column] == value:
                        nodes.append(kernel)
                        break
            elif condition == '<=':
                cur_node = first_leaf
                while cur_node != kernel:
                    nodes.append(cur_node)
                    cur_node = cur_node.nt

                for val in kernel.pt:
                    if val[column] <= value:
                        nodes.append(kernel)
                        break
            elif condition == '<':
                cur_node = first_leaf
                while cur_node != kernel:
                    nodes.append(cur_node)
                    cur_node = cur_node.nt

                for val in kernel.pt:
                    if val[column] < value:
                        nodes.append(kernel)
                        break
            elif condition == '>':
                for val in kernel.pt:
                    if val[column] > value:
                        nodes.append(kernel)
                        break
                while kernel.nt != "none":
                    kernel = kernel.nt
                    nodes.append(kernel)

            elif condition == '>=':
                for val in kernel.pt:
                    if val[column] >= value:
                        nodes.append(kernel)
                        break
                while kernel.nt != "none":
                    kernel = kernel.nt
                    nodes.append(kernel)
            else:
                raise SyntaxError(config.index_where_fail)

        else:
            while first_leaf != "none":
                # linear scan
                for val in first_leaf.pt:
                    if self.check_conditions(val, [con]):
                        nodes.append(first_leaf)
                        break

                first_leaf = first_leaf.nt
        return nodes

    def check_conditions(self, _values, conditions):
        # check each records in the given leaves with conditions
        # return the list of satisfied records
        for con in conditions:
            _value = _values[con[0]]
            if con[1] == '<':
                if not (_value < con[2]):
                    return False
            elif con[1] == '<=':
                if not (_value <= con[2]):
                    return False
            elif con[1] == '>':
                if not (_value > con[2]):
                    return False
            elif con[1] == '>=':
                if not (_value >= con[2]):
                    return False
            elif con[1] == '<>':
                if not (_value != con[2]):
                    return False
            elif con[1] == '=':
                if not (_value == con[2]):
                    return False
            else:
                raise SyntaxError(config.index_where_fail)
        return True

    def check_unique(self, _table, column, value):
        att = cat_tables[_table].attributes

        n = self.find_leaf_condition(_table, [column, '=', value])
        if len(n):
            raise ValueError("Index Module : column '{}' does not satisfy unique constrains.".format(att[column].name))

    def get_all_rec(self, _table):
        self.__load__(_table)

        first_leaf = ind_tables[_table].root
        results = []
        while type(first_leaf) is not leaf:
            first_leaf = first_leaf.pt[0]
        while first_leaf != "none":
            for rec in first_leaf.pt:
                results.append(rec)

            first_leaf = first_leaf.nt

        return results

    def __finalize__(self):
        self.__store__()

if __name__ == "__main__":

    i = index_manager()

    i.create_table("test")
    print(ind_tables)