"""Contains pathfinding and maze generation algorithms"""

# Handles how much C++ the the program should use
from src.pathfinding.cpp_or_py import use_square_h
if use_square_h:
    from src.pathfinding.cpp.modules import Square
else:
    from src.pathfinding.py.square import Square
from lib.timer import sleep

from threading import Lock
from dataclasses import dataclass, field
from queue import PriorityQueue
from time import perf_counter_ns
import random

@dataclass(slots=True)
class AlgoState:
    """Stores the state of the algorithms, whether they are finished or not"""
    # Possible phases
    PHASE_ALGO: int = field(init=False)
    PHASE_MAZE: int = field(init=False)

    # Possible algorithms
    ALGO_DIJKSTRA: int = field(init=False)
    ALGO_A_STAR: int = field(init=False)
    ALGO_BI_DIJKSTRA: int = field(init=False)
    ALGO_BEST_PATH: int = field(init=False)
    ALGO_RECURSIVE_MAZE: int = field(init=False)

    # The current phase and current/last algorithm.
    _phase: int = field(init=False)
    _algo: int = field(init=False)
    _finished: bool = False  # Cobination with ALGO preserves past

    # Special variables
    _unique_int: int = 0  # Starts +1 when called by self._next_int()
    NONE: int = _unique_int  # Value is 0 which returns false when casted to bool
    lock: Lock  = Lock()

    # Run options
    _start: Square = None
    _mid: Square = None
    _end: Square = None
    _ignore_square: Square = None

    # Control the speed of algorithms
    _DEFAULT_BEST_PATH_DELAY_MS: int = 3
    _best_path_delay_ms: int = field(init=False)
    _DEFAULT_RECURSIVE_MAZE_DELAY_US: int = 250
    _recursive_maze_delay_us: int = field(init=False)

    # Timer for algorithms
    timer_total: float = 0
    timer_avg: float = None
    timer_max: float = float("-inf")
    timer_min: float = float("inf")
    timer_count: int = 0
    _timer_start_time: float = None

    def __post_init__(self):
        """Initialize variables with their unique values."""
        self.PHASE_ALGO = self._generate_unique_int()
        self.PHASE_MAZE = self._generate_unique_int()
        self.ALGO_DIJKSTRA = self._generate_unique_int()
        self.ALGO_A_STAR = self._generate_unique_int()
        self.ALGO_BI_DIJKSTRA = self._generate_unique_int()
        self.ALGO_BEST_PATH = self._generate_unique_int()
        self.ALGO_RECURSIVE_MAZE = self._generate_unique_int()
        self.reset()

    def start_loop(self) -> None:
        """Starts the algo loop. Place on a daemon thread."""
        self._algo_loop()

    def run_options(self, start, mid, end, ignore_square) -> None:
        """Set the options that will be performed on run"""
        with self.lock:
            self._start = start
            self._mid = mid
            self._end = end
            self._ignore_square = ignore_square

    def run(self, phase, algo) -> None:
        """Start an algorithm using PHASE and ALGO, NULL where applicable."""
        self._set_phase(phase)
        self._set_algo(algo)
        self._set_finished(False)

    def check_phase(self) -> int:
        """Checks the phase"""
        with self.lock:
            return self._phase

    def check_algo(self) -> int:
        """Checks the algo"""
        with self.lock:
            return self._algo

    def check_finished(self) -> bool:
        """Checks if algo is finished"""
        with self.lock:
            return self._finished

    def reset(self) -> None:
        """Resets options to their default values"""
        with self.lock:
            self._phase = self.NONE
            self._algo = self.NONE
            self._start = None
            self._mid = None
            self._end = None
            self._ignore_square = None
            self._finished = False
            self._best_path_delay_ms = self._DEFAULT_BEST_PATH_DELAY_MS
            self._recursive_maze_delay_us = self._DEFAULT_RECURSIVE_MAZE_DELAY_US

    def set_best_path_delay(self, ms: int) -> None:
        """Change the delay for the next best path"""
        with self.lock:
            self._best_path_delay_ms = ms

    def set_recursive_maze_delay(self, us: int) -> None:
        """Change the delay for the next recursive maze"""
        with self.lock:
            self._recursive_maze_delay_us = us

    def _set_phase(self, phase: int) -> None:
        """Change the phase. Use PHASE constants."""
        with self.lock:
            self._phase = phase

    def _set_algo(self, algo: int) -> None:
        """Change the algo. Use ALGO constants."""
        with self.lock:
            self._algo = algo

    def _set_finished(self, x: bool) -> None:
        """Set finshed to true or false"""
        with self.lock:
            self._finished = x

    def _algo_loop(self) -> None:
        """This loop is placed on a daemon thread and watches for updates."""
        while True:
            # Check if algo
            if self.check_phase() == self.PHASE_ALGO and not self.check_finished():
                previous_algo = self.check_algo()
                if not self._mid:
                    if self.check_algo() == self.ALGO_DIJKSTRA:
                        dijkstra(self, self._start, self._end, self._ignore_square, draw_best_path=True)
                    elif self.check_algo() == self.ALGO_A_STAR:
                        a_star(self, self._start, self._end, self._ignore_square, draw_best_path=True)
                    elif self.check_algo() == self.ALGO_BI_DIJKSTRA:
                        bi_dijkstra(self, self._start, self._end, self._ignore_square, draw_best_path=True)
                else:
                    start_mid_end(self, self._start, self._mid, self._end)
                self.set_best_path_delay(self._DEFAULT_BEST_PATH_DELAY_MS)  # Set to 0 with no vis
                self._set_algo(previous_algo)  # Preserves more info
                self._set_finished(True)
                self._set_phase(self.NONE)

            # Check if maze
            elif self.check_phase() == self.PHASE_MAZE and not self.check_finished():
                if self.check_algo() == self.ALGO_RECURSIVE_MAZE:
                    recursive_maze(self)
                    self.set_recursive_maze_delay(self._DEFAULT_RECURSIVE_MAZE_DELAY_US)
                self._set_finished(True)
                self._set_phase(self.NONE)

    def _timer_start(self) -> None:
        """Start timer for algo. Not for general use."""
        self._timer_start_time = perf_counter_ns()

    def _timer_end(self, count=True) -> None:
        """End timer for algo. Not for general use."""
        end = perf_counter_ns()
        total = (end - self._timer_start_time) / 10**9  # Time in seconds
        self.timer_total += total
        if count:
            self.timer_count += 1
        if self.timer_count:
            self.timer_avg = self.timer_total / self.timer_count
        if total:  # Make it obvious for 0 max values
            self.timer_max = max(self.timer_max, total)
        if total:  # 0 min values are trivial
            self.timer_min = min(self.timer_min, total)

    def _timer_reset(self) -> None:
        """Resets timer. Not for general use."""
        self.timer_total: float = 0
        self.timer_avg: float = None
        self.timer_max: float = float("-inf")
        self.timer_min: float = float("inf")
        self.timer_count: int = 0
        self._timer_start_time: float = None

    def _generate_unique_int(self) -> int:
        """Assign unique int on every call"""
        self._unique_int += 1
        return self._unique_int

    def thread_lock(self) -> None:
        """For use in custom context manager for consistency with C++"""
        self.lock.acquire()

    def thread_unlock(self) -> None:
        """For use in custom context manager for consistency with C++"""
        self.lock.release()

def dijkstra(algo: AlgoState, start: Square, end: Square, ignore_square: Square, draw_best_path: bool) -> dict:
    """Code for the dijkstra algorithm"""
    # Clear previous and start timer here to include setup of algo into timer
    algo._timer_reset()
    algo._timer_start()

    # Used to determine the order of squares to check. Order of args helper decide the priority.
    open_set = PriorityQueue()
    queue_pos = 0
    open_set.put((0, queue_pos, start))

    # Determine what is the best square to check
    g_score = {Square.get_square(row, col): float("inf") for row in range(Square.get_num_rows()) for col in range(Square.get_num_cols())}
    g_score[start] = 0

    # Keeps track of next square for every square in graph. A linked list basically.
    came_from = {}

    # End timer here to start it again in loop
    algo._timer_end(count=False)

    # Continues until every square has been checked or best path found
    while not open_set.empty():

        # Time increments for each square being checked
        algo._timer_start()

        # Gets the square currently being checked
        curr_square: Square = open_set.get()[2]

        # Terminates if found the best path
        if curr_square == end:
            if draw_best_path:
                _best_path(algo, came_from, end)
            return came_from

        # Decides the order of neighbours to check
        nei: Square
        for nei in curr_square.get_neighbours():
            # Ignore walls
            if nei.is_wall():
                continue

            # Only check square if not already checked.
            temp_g_score = g_score[curr_square] + 1
            if temp_g_score < g_score[nei]:
                came_from[nei] = curr_square
                g_score[nei] = temp_g_score
                queue_pos += 1
                open_set.put((g_score[nei], queue_pos, nei))

                # Set nei to open under certain conditions
                if not nei.is_closed() and nei != end and nei != ignore_square:
                    with algo.lock:
                        nei.set_open()

        # Sets square to closed after finished checking
        if curr_square != start and curr_square != ignore_square:
            with algo.lock:
                curr_square.set_closed()

        # End timer to increment count
        algo._timer_end()

    return came_from

def a_star(algo: AlgoState, start: Square, end: Square, ignore_square: Square, draw_best_path: bool) -> dict:
    """Code for the A* algorithm"""
    # Clear previous and start timer here to include setup of algo into timer
    algo._timer_reset()
    algo._timer_start()

    # Used to determine the order of squares to check. Order of args helper decide the priority.
    open_set = PriorityQueue()
    queue_pos = 0
    open_set.put((0, queue_pos, start))

    # Determine what is the best square to check
    g_score = {Square.get_square(row, col): float("inf") for row in range(Square.get_num_rows()) for col in range(Square.get_num_cols())}
    g_score[start] = 0
    f_score = {Square.get_square(row, col): float("inf") for row in range(Square.get_num_rows()) for col in range(Square.get_num_cols())}
    f_score[start] = _heuristic(start.get_pos(), end.get_pos())

    # Keeps track of next square for every square in graph. A linked list basically.
    came_from = {}

    # End timer here to start it again in loop
    algo._timer_end(count=False)

    # Continues until every square has been checked or best path found
    while not open_set.empty():

        # Time increments for each square being checked
        algo._timer_start()

        # Gets the square currently being checked
        curr_square: Square = open_set.get()[2]

        # Terminates if found the best path
        if curr_square == end:
            if draw_best_path:
                _best_path(algo, came_from, end)
            return came_from

        # Decides the order of neighbours to check
        nei: Square
        for nei in curr_square.get_neighbours():
            # Ignore walls
            if nei.is_wall():
                continue

            # Only check square if not already checked.
            temp_g_score = g_score[curr_square] + 1
            if temp_g_score < g_score[nei]:
                came_from[nei] = curr_square
                g_score[nei] = temp_g_score
                f_score[nei] = temp_g_score + _heuristic(nei.get_pos(), end.get_pos())
                queue_pos += 1
                open_set.put((f_score[nei], queue_pos, nei))

                # Set nei to open under certain conditions
                if not nei.is_closed() and nei != end and nei != ignore_square:
                    with algo.lock:
                        nei.set_open()

        # Sets square to closed after finished checking
        if curr_square != start and curr_square != ignore_square:
            with algo.lock:
                curr_square.set_closed()

        # End timer to increment count
        algo._timer_end()

    return came_from

def _heuristic(pos1: tuple, pos2: tuple) -> int:
    """Used by A* to prioritize traveling towards next square"""
    x1, y1 = pos1
    x2, y2 = pos2
    return abs(x1 - x2) + abs(y1 - y2)

def bi_dijkstra(algo: AlgoState, start: Square, end: Square, ignore_square: Square, draw_best_path: bool) -> dict | Square:
    """Code for Bi-directional Dijkstra algorithm. Custom algorithm made by me."""
    # Clear previous and start timer here to include setup of algo into timer
    algo._timer_reset()
    algo._timer_start()

    # Used to determine the order of squares to check. Order of args helper decide the priority.
    open_set = PriorityQueue()
    queue_pos = 0
    FIRST_SWARM = "FIRST_SWARM"
    open_set.put((0, queue_pos, start, FIRST_SWARM))
    queue_pos += 1
    SECOND_SWARM = "SECOND_SWARM"
    open_set.put((0, queue_pos, end, SECOND_SWARM))

    # Determine what is the best square to check
    g_score = {Square.get_square(row, col): float("inf") for row in range(Square.get_num_rows()) for col in range(Square.get_num_cols())}
    g_score[start] = 0
    g_score[end] = 0

    # Keeps track of next square for every square in graph. A linked list basically.
    came_from = {}

    # Track the last squares for each swarm
    first_swarm = set()
    second_swarm = set()
    first_swarm_meet_square: Square = None
    second_swarm_meet_square: Square = None

    # End timer here to start it again in loop
    algo._timer_end(count=False)

    # Continues until every square has been checked or best path found
    while not open_set.empty():

        # Terminates if the swarms meet each other
        if first_swarm_meet_square or second_swarm_meet_square:
            # Allow access the meet squares using the known start and end squares
            if draw_best_path:
                _best_path_bi_dijkstra(algo, came_from, first_swarm_meet_square, second_swarm_meet_square)
            return came_from, first_swarm_meet_square, second_swarm_meet_square

        # Time increments for each square being checked
        algo._timer_start()

        # Gets the square currently being checked.
        temp = open_set.get()
        curr_square: Square = temp[2]
        swarm = temp[3]

        # Decides the order of neighbours to check for both swarms.
        for nei in curr_square.get_neighbours():
            # Ignore walls
            if nei.is_wall():
                continue

            # Only check square if not already checked.
            temp_g_score = g_score[curr_square] + 1
            if temp_g_score < g_score[nei]:
                came_from[nei] = curr_square
                g_score[nei] = temp_g_score
                queue_pos += 1
                open_set.put((g_score[nei], queue_pos, nei, swarm))

                # Set nei to open under certain conditions
                if not nei.is_closed() and nei != ignore_square:
                    if swarm == FIRST_SWARM and nei != end:
                        first_swarm.add(nei)
                        with algo.lock:
                            nei.set_open()
                    elif swarm == SECOND_SWARM and nei != start:
                        second_swarm.add(nei)
                        with algo.lock:
                            nei.set_open()
            # Conditions for when path is found
            elif swarm == FIRST_SWARM and nei in second_swarm:
                first_swarm_meet_square = curr_square
                second_swarm_meet_square = nei
                break
            elif swarm == SECOND_SWARM and nei in first_swarm:
                first_swarm_meet_square = nei
                second_swarm_meet_square = curr_square
                break

        # Sets square to closed after finished checking
        if curr_square != start and curr_square != end and curr_square != ignore_square:
            with algo.lock:
                    curr_square.set_closed()

        # End timer to increment count
        algo._timer_end()

    return came_from, first_swarm_meet_square, second_swarm_meet_square

def _best_path_bi_dijkstra(algo: AlgoState, came_from: dict,
    first_swarm_meet_square: Square,second_swarm_meet_square: Square) -> None:
    """Used by bi_dijkstra to draw best path for both swarms"""
    _best_path(algo, came_from, first_swarm_meet_square)
    # Best path skips these two naturally so need to set them here.
    with algo.lock:
        first_swarm_meet_square.set_path()
        second_swarm_meet_square.set_path()
    _best_path(algo, came_from, second_swarm_meet_square, reverse=True)

def _best_path(algo: AlgoState, came_from: dict, curr_square: Square, reverse: bool = False) -> None:
    """Main algo for reconstructing path"""
    # Update info
    algo._set_algo(algo.ALGO_BEST_PATH)

    # Puts square path into list so it's easier to traverse in either direction and choose start and end points
    path: list = []
    while curr_square in came_from:
        curr_square = came_from[curr_square]
        path.append(curr_square)

    # Need to traverse in reverse depending on what part of algo
    square: Square
    if reverse:
        for square in path[:-1]:
            sleep(algo._best_path_delay_ms, unit="ms")
            with algo.lock:
                square.set_path()
    else:
        for square in path[len(path) - 2 :: -1]:
            sleep(algo._best_path_delay_ms, unit="ms")
            with algo.lock:
                square.set_path()

def start_mid_end(algo: AlgoState, start: Square, mid: Square, end: Square) -> None:
    """Used if algos need to reach mid square first"""
    # Selects the correct algo to use
    if algo.check_algo() == algo.ALGO_DIJKSTRA:
        start_to_mid = dijkstra(algo, start, mid, end, draw_best_path=False)
        mid_to_end = dijkstra(algo, mid, end, start, draw_best_path=False)

        # Fixes squares disappearing when dragging
        with algo.lock:
            start.set_start()
            mid.set_mid()
            end.set_end()

        _best_path(algo, start_to_mid, mid)
        _best_path(algo, mid_to_end, end)
    elif algo.check_algo() == algo.ALGO_A_STAR:
        start_to_mid = a_star(algo, start, mid, end, draw_best_path=False)
        mid_to_end = a_star(algo, mid, end, start, draw_best_path=False)

        # Fixes squares disappearing when dragging
        with algo.lock:
            start.set_start()
            mid.set_mid()
            end.set_end()

        _best_path(algo, start_to_mid, mid)
        _best_path(algo, mid_to_end, end)
    elif algo.check_algo() == algo.ALGO_BI_DIJKSTRA:
        temp = bi_dijkstra(algo, start, mid, end, draw_best_path=False)
        start_to_mid = temp[0]
        first_swarm_meet_square = temp[1]
        second_swarm_meet_square = temp[2]
        temp = bi_dijkstra(algo, mid, end, start, draw_best_path=False)
        mid_to_end = temp[0]
        third_swarm_meet_square = temp[1]
        fourth_swarm_meet_square = temp[2]

        # Fixes squares disappearing when dragging
        with algo.lock:
            start.set_start()
            mid.set_mid()
            end.set_end()

        _best_path_bi_dijkstra(algo, start_to_mid, first_swarm_meet_square, second_swarm_meet_square)
        _best_path_bi_dijkstra(algo, mid_to_end, third_swarm_meet_square, fourth_swarm_meet_square)

def recursive_maze(algo: AlgoState, chamber: tuple = None,
    division_limit: int = 3, num_gaps: int = 3) -> None:
    """Creates maze using recursive division."""
    # Only perform these on first call
    if not chamber:
        algo._timer_reset()

    # Start timer here to include setup in timer
    algo._timer_start()

    # Creates chambers to divide into
    if chamber is None:
        chamber_width: int = Square.get_num_rows()
        chamber_height: int = Square.get_num_cols()
        chamber_left: int = 0
        chamber_top: int = 0
    else:
        chamber_width: int = chamber[2]
        chamber_height: int = chamber[3]
        chamber_left: int = chamber[0]
        chamber_top: int = chamber[1]

    # Helps with location of chambers
    x_divide = int(chamber_width / 2)
    y_divide = int(chamber_height / 2)

    # End timer here to resume in loop
    algo._timer_end(count=False)

    # Draws vertical maze line within chamber
    if chamber_width >= division_limit:
        for y in range(chamber_height):
            algo._timer_start()
            square: Square = Square.get_square(chamber_left + x_divide, chamber_top + y)
            with algo.lock:
                square.set_wall()
            sleep(algo._recursive_maze_delay_us, unit="us")
            algo._timer_end()

    # Draws horizontal maze line within chamber
    if chamber_height >= division_limit:
        for x in range(chamber_width):
            algo._timer_start()
            square: Square = Square.get_square(chamber_left + x, chamber_top + y_divide)
            with algo.lock:
                square.set_wall()
            sleep(algo._recursive_maze_delay_us, unit="us")
            algo._timer_end()

    # Start timer again
    algo._timer_start()

    # Terminates if below division limit
    if chamber_width < division_limit and chamber_height < division_limit:
        return

    # Defining limits on where to draw walls
    top_left: tuple = (chamber_left, chamber_top, x_divide, y_divide)
    top_right: tuple = (
        chamber_left + x_divide + 1,
        chamber_top,
        chamber_width - x_divide - 1,
        y_divide,
    )
    bottom_left: tuple = (
        chamber_left,
        chamber_top + y_divide + 1,
        x_divide,
        chamber_height - y_divide - 1,
    )
    bottom_right: tuple = (
        chamber_left + x_divide + 1,
        chamber_top + y_divide + 1,
        chamber_width - x_divide - 1,
        chamber_height - y_divide - 1,
    )

    # Combines all chambers into one object
    chambers: tuple = (top_left, top_right, bottom_left, bottom_right)

    # Defines location of the walls
    left: tuple = (chamber_left, chamber_top + y_divide, x_divide, 1)
    right: tuple = (
        chamber_left + x_divide + 1,
        chamber_top + y_divide,
        chamber_width - x_divide - 1,
        1,
    )
    top: tuple = (chamber_left + x_divide, chamber_top, 1, y_divide)
    bottom: tuple = (
        chamber_left + x_divide,
        chamber_top + y_divide + 1,
        1,
        chamber_height - y_divide - 1,
    )

    # Combines walls into one object
    walls: tuple = (left, right, top, bottom)

    # Prevents drawing wall over gaps
    gaps_to_offset: list = [x for x in range(num_gaps - 1, Square.get_num_rows(), num_gaps)]

    # End timer here to resume in loop
    algo._timer_end(count=False)

    # Draws the gaps into the walls
    for wall in _get_random_sample(walls, num_gaps):

        # Continue timer here
        algo._timer_start()

        if wall[3] == 1:
            x = _get_randrange(wall[0], wall[0] + wall[2])
            y = wall[1]
            if x in gaps_to_offset and y in gaps_to_offset:
                if wall[2] == x_divide:
                    x -= 1
                else:
                    x += 1
            if x >= Square.get_num_rows():
                x = Square.get_num_rows() - 1
        else:
            x = wall[0]
            y = _get_randrange(wall[1], wall[1] + wall[3])
            if y in gaps_to_offset and x in gaps_to_offset:
                if wall[3] == y_divide:
                    y -= 1
                else:
                    y += 1
            if y >= Square.get_num_rows():
                y = Square.get_num_rows() - 1
        square: Square = Square.get_square(x, y)
        with algo.lock:
            square.reset()

        algo._timer_end()

    # Recursively divides chambers
    for chamber in chambers:
        recursive_maze(algo, chamber)

def _get_random_sample(population: tuple, k: int) -> list:
    """Returns a k length list of unique elements from population"""
    return random.sample(population, k)

def _get_randrange(start: int, stop: int) -> int:
    """Return a random int within a range"""
    return random.randrange(start, stop)


#!/usr/bin/env python
"""
Springboard compiler

:author: Athanasios Anastasiou
:date: Mar 2022

"""
import os
import pyparsing
import click
import urllib

class SpringboardError(Exception):
    pass

class SymbolRedefined(SpringboardError):
    pass

class SymbolUndefined(SpringboardError):
    pass

class CircularDependency(SpringboardError):
    pass

class CircularDefinition(SpringboardError):
    pass

class SpringboardProgram:
    def __init__(self):
        self._parser = self.get_parser()
        self._symbol_defs = {"+": "+", "-": "-",
                             ">": ">", "<": "<",
                             "[": "[", "]": "]",
                             ",": ",", ".": "."}
        self._code_info = None

    @property
    def imports(self):
        return self._code_info[0]["imports"]

    @property
    def symbol_defs(self):
        return self._symbol_defs

    @property
    def code(self):
        return self._code_info[0]["code"]

    def from_string(self, a_program, previous_imports=[]):
        """
        Initialises a Springboard program given a string.

        :param a_program: A string that conforms to Springboard's grammar
        :type a_program: str
        :param previous_imports: A list of all imports in the main namespace to avoid circular references.
        :type previous_imports: list

        :returns: A Springboard program initialised with all its three sections.
        :rtype: SpringboardProgram

        :raises CircularDependency: If a file being imported imports a file that refers to the file being imported.
        :raises SymbolRedefined: Self explanatory.
        """
        self._code_info = self._parser.parseString(a_program)
        # If there are imports, prepopulate the symbol definition table
        cwd = os.getcwd()
        p_imports=previous_imports + []
        for an_import in self.imports:
            # Break on circular references
            if an_import not in p_imports:
                p_imports.append(an_import)
            else:
                raise CircularDependency(f"Circular dependency involving {an_import} and {','.join(previous_imports)}.")
            # Change the current working directoy to enable relative imports
            import_path, import_file = os.path.split(an_import)
            if len(import_path) > 0:
                os.chdir(import_path)
            u = SpringboardProgram().from_file(import_file, p_imports)
            os.chdir(cwd)
            self._symbol_defs.update(u.symbol_defs)

        # Append the locally defined symbols
        for a_symbol_def in self._code_info[0]["symbol_defs"]:
            if a_symbol_def["symbol"] not in self._symbol_defs:
                self._symbol_defs[a_symbol_def["symbol"]] = a_symbol_def["code"]
            else:
                raise SymbolRedefined(f"Attempt to redefine symbol {a_symbol_def['symbol']}, from {self._symbol_defs[a_symbol_def['symbol']]} to {a_symbol_def['code']}.")
        return self

    def from_file(self, a_file, previous_imports=[]):
        """
        Initialises a Springboard program given a file name.

        :param a_file: The filename of a text file that contains Springboard code.
        :type a_file: str
        :param previous_imports: See `Springboard.from_string`
        :type previous_imports: list

        :returns: A SpringboardProgram object with all its three sections populated.
        :rtype: SpringboardProgram
        """
        p_imports = previous_imports + []
        with open(a_file, "rt") as fd:
            data = fd.read()
        return self.from_string(data, p_imports)

    def compile(self, a_program=None, symbols_compiled=[]):
        """
        Compiles a Springboard program to brainfuck.

        :param a_program: A string containing Springboard code.
        :type a_program: str
        :param symbols_compiled: The set of symbols whose definition requires compilation of a given symbol.
        :type symbols_compiled: list[str]

        :returns: A string that contains purely brainfuck code (i.e. composed entirely of the brainfuck grammar's symbols).
        :rtype: str

        :raises CircularDefinition: If a symbol being defined requires the compilation of a symbol being defined.
        :raises SymbolUndefined: If a symbol being defined refers to a symbol that is not defined anywhere.
        """
        source_code = a_program
        if a_program is None:
            source_code = list(self.code)
        compiled_code = ""
        # While there are symbols, keep substituting them
        for a_symbol in source_code:
            if a_symbol in symbols_compiled:
                raise CircularDefinition(f"Circular definition involving {a_symbol} and {','.join(symbols_compiled)}.")
            if a_symbol not in self._symbol_defs:
                raise SymbolUndefined(f"Symbol {a_symbol} is undefined.")
            symbol_code = self._symbol_defs[a_symbol]
            if type(symbol_code) is not str:
                self.symbol_defs[a_symbol] = "".join(self.compile(symbol_code, symbols_compiled + [a_symbol]))
            compiled_code = compiled_code + self.symbol_defs[a_symbol]
        return compiled_code

    @staticmethod
    def get_parser():
        """
        Parses Springboard's grammar.

        springboard_program := imports_section defs_section code_section
        imports_section := import_statement*
        import_statement := import \".*?\"
        defs_section := def_statement*
        def_statement := : symbol_identifier code_section ;
        symbol_identifier := [a-zA-Z0-9_]+
        code_section := (basic_code_block | loop_code_block)*
        basic_code_block := "<"|">"|"+"|"-"|"."|","
        loop_code_block := basic_code_block | ("[" (basic_code_block | loop_code_block)* "]")
        """
        symbol_id = pyparsing.Regex("[a-zA-Z0-9_]+")
        code_section = pyparsing.ZeroOrMore(pyparsing.Regex("[+\-\.,<>\[\]]") ^ symbol_id)
        def_statement = pyparsing.Group(pyparsing.Suppress(":") + symbol_id("symbol") + code_section("code") + pyparsing.Suppress(";"))
        defs_section = pyparsing.ZeroOrMore(def_statement)
        import_statement = pyparsing.Suppress("import") + pyparsing.QuotedString("\"")
        imports_section = pyparsing.ZeroOrMore(import_statement)
        sb_program = pyparsing.Group(imports_section("imports") + defs_section("symbol_defs") + code_section("code"))
        sb_program.ignore(pyparsing.Literal("#") + pyparsing.rest_of_line())
        return sb_program

@click.command()
@click.argument("input_file", type=click.File(mode="r"))
@click.argument("output_file", type=click.File(mode="w"))
@click.option("-b", "--base-url",
              type=click.STRING,
              default="https://aanastasiou.github.io/brainfuck-visualizer/?bf=",
              help="Sets the base URL towards a try-it-online service.")
@click.option("--url/--no-url",
              default=False,
              help="If set, returns the program encoded in URL form, ready to "
                   "be included in a link")
def sbc(input_file, output_file, base_url, url):
    """
    Springboard compiler.

    The springboard compiler accepts two arguments:\n
    - input_file\n
    - output_file\n

    Both can be stdin/stdout, by using "-".

    Two options are provided to control posting to a try-it-online URL:\n
    - --base-url\n
    - --url

    Examples:\n
       - echo "+>+[-<+>]"|./sbc.py - -\n
       - echo "+>+[-<+>]"|./sbc.py - - --url

    The default base URL is: https://aanastasiou.github.io/brainfuck-visualizer/?bf=
    """
    try:
        # Generate unoptimised code (contains successive <> or +-)
        code = ''.join(SpringboardProgram().from_string(input_file.read()).compile())
        # TODO: HIGH, Sort the parse actions in the following rules
        r1 = pyparsing.Regex("[<>][<>]+").set_parse_action(lambda s, l, t: (">" if str(t).count(">") >= str(t).count("<") else "<") * abs(str(t).count(">") - str(t).count("<")))
        r2 = pyparsing.Regex("[\+\-][\+\-]+").set_parse_action(lambda s, l, t: ("+" if str(t).count("+") >= str(t).count("-") else "-") * abs(str(t).count("+") - str(t).count("-")))
        # Optimise the code by simplifying continuous segments of <> or +- characters
        optimised_code = r2.transform_string(r1.transform_string(code))
        if url:
            optimised_code = f"{base_url}{urllib.parse.quote(optimised_code)}"
        output_file.write(f"{optimised_code}\n")
    except SpringboardError as e:
        click.echo(f"{e}")

if __name__ == "__main__":
    sbc()


import openai

openai.api_base = 'http://localhost:1234/v1'

openai.api_key = ''

# 'Llama2 Chat' prompt format:
prefix = "[INST]"
suffix = "[/INST]"

def get_completion(prompt, temperature=0.0):
    formatted_prompt = f"{prefix}{prompt}{suffix}"

    response = openai.ChatCompletion.create(
        model="local model",
        temperature=temperature,
        messages=[{"role": "user", "content": formatted_prompt}]
    )

    return response.choices[0].message["content"]


from dotenv import load_dotenv
load_dotenv(override=True)

import os
appOAuthServer=os.getenv('OAUTH_SERVER')
appOAuthCredential=os.getenv('OAUTH_CRED')
appOAuthRedirectUrl=os.getenv('OAUTH_REDIRECT_URL')

import hvac
vault=hvac.Client(
    url=os.getenv('VAULT_ADDR'),
    token=os.getenv('VAULT_TOKEN')
    )

import uuid
from flask import Flask,redirect,request,session
app = Flask(__name__)
app.secret_key=str(uuid.uuid4())

from flask_session import Session
app.config["SESSION_PERMANENT"] = False
app.config["SESSION_TYPE"] = "filesystem"
Session(app)

import requests

@app.route('/')
def index():
    creds=vault.read(f'oauthapp/creds/{appOAuthCredential}')
    if creds is None:
        state=str(uuid.uuid4())
        session['state']=state
        response=vault.write(f'oauthapp/auth-code-url', server=appOAuthServer,
            redirect_url=appOAuthRedirectUrl,
            scopes='spark:people_read',
            state=state)
        url=response['data']['url']
        href=f"location.href='{url}'"
        return f'
Unauthorized! <button onclick="{href}">Authorize</button>
'
    access_token=creds['data']['access_token']
    response=requests.get('https://webexapis.com/v1/people/me', headers={'Authorization': f'Bearer {access_token}'})
    displayName=response.json()['displayName']
    return f'
Authorized!  User display name: {displayName}
'

@app.route('/auth')
def auth():
    code=request.args.get('code')
    state=request.args.get('state')
    if not state == session.get('state'):
        return 'Mismatched state'
    response=vault.write(f'oauthapp/creds/{appOAuthCredential}',
        server=appOAuthServer,
        redirect_url=appOAuthRedirectUrl,
        code=code)
    return redirect('/')


from django.conf.urls import url, include
from rest_framework import routers
from .views import (UserViewSet, GroupViewSet, GenderList, GenderDetail, CountryList, CountryDetail, LanguageList,
                    LanguageDetail, CredentialList, CredentialDetail, PersonList, PersonDetail, CategoryList,
                    CategoryDetail, ArticleList, ArticleDetail, UserProfileList, UserProfileDetail, MyUserProfile)

router = routers.DefaultRouter()
router.register(r'users', UserViewSet)
router.register(r'groups', GroupViewSet)

# Wire up our API using automatic URL routing.
# Additionally, we include login URLs for the browsable API.
urlpatterns = [
    url(r'^', include(router.urls)),
    url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework')),
    url(r'^genders/$', GenderList.as_view()),
    url(r'^genders/(?P<pk>[0-9]+)/$', GenderDetail.as_view()),
    url(r'^countries/$', CountryList.as_view()),
    url(r'^countries/(?P<pk>[0-9]+)/$', CountryDetail.as_view()),
    url(r'^languages/$', LanguageList.as_view()),
    url(r'^languages/(?P<pk>[0-9]+)/$', LanguageDetail.as_view()),
    url(r'^credentials/$', CredentialList.as_view()),
    url(r'^credentials/(?P<pk>[0-9]+)/$', CredentialDetail.as_view()),
    url(r'^persons/$', PersonList.as_view()),
    url(r'^persons/(?P<pk>[0-9]+)/$', PersonDetail.as_view()),
    url(r'^categories/$', CategoryList.as_view()),
    url(r'^categories/(?P<pk>[0-9]+)/$', CategoryDetail.as_view()),
    url(r'^articles/$', ArticleList.as_view()),
    url(r'^articles/(?P<pk>[0-9]+)/$', ArticleDetail.as_view()),
    url(r'^userprofiles/$', UserProfileList.as_view()),
    url(r'^userprofiles/(?P<pk>[0-9]+)/$', UserProfileDetail.as_view()),
    url(r'^myuserprofile/$', MyUserProfile.as_view()),
    #url(r'^articlecomments/$', ArticleCommentList.as_view()),
    #url(r'^articlecomments/(?P<pk>[0-9]+)/$', ArticleCommentDetail.as_view()),
    #url(r'^threads/$', ThreadList.as_view()),
    #url(r'^threads/(?P<pk>[0-9]+)/$', ThreadDetail.as_view()),
    #url(r'^threadcomments/$', ThreadCommentList.as_view()),
    #url(r'^threadcomments/(?P<pk>[0-9]+)/$', ThreadCommentDetail.as_view()),
]


from django.urls import path
from . import views
from django.conf import settings
from django.conf.urls.static import static

urlpatterns=[
    path('' , views.dashboard , name='dashboard'),
    path('teachers', views.teachers, name ='teachers'),
    path('students', views.students, name='students'),
    path('staff', views.staff, name='staff' ),
    path('add_student', views.add_student, name='add_student'),
    path('add_staff', views.add_staff, name='add_staff'),
    path('add_teacher', views.add_teacher, name='add_teacher'),
    path('search/', views.search_results, name='search_results'),
    path("neighbourhood/<str:pk>/", views.single_neighbourhood, name='single_neighbourhood'),

]


from argparse import ArgumentParser
from json import dump, dumps, load, loads
from logging import INFO, basicConfig, getLogger
from subprocess import run

from emoji import emojize
from telegram import InlineKeyboardButton, InlineKeyboardMarkup, Update
from telegram.ext import (CallbackContext, CallbackQueryHandler,
                          CommandHandler, PicklePersistence, Updater)

from structures.parking import Parking as Parking
from structures.stats import Stats as Stats

def start(update: Update, context: CallbackContext) -> None:
    """Send first messages to user."""
    if (config['whitelist'] and str(update.effective_user.id) in users
       or not config['whitelist']):
        manage_user(update, context)
        parking = context.bot_data['parking']
        markup = make_keyboard(context, str(update.effective_user.id))
        welcome = (r'Вас приветствует *Парковочный бот Logrocon*\!' +
                   '\nВыберете место кнопками ниже')
        update.effective_message.reply_text(welcome, parse_mode='MarkdownV2')
        update.effective_message.reply_text(
            parking.state_text, reply_markup=markup)
        log_event(update, 'Отправил start')

def stop(update: Update, context: CallbackContext) -> None:
    """Say goodbye, delete user data."""
    if (config['whitelist'] and str(update.effective_user.id) in users
       or not config['whitelist']):
        try:
            log_event(update, 'Отправил stop')
            update.effective_message.reply_text(
                'Вы перестали получать уведомления. Вы можете в любой момент' +
                ' вернутся к их получению командой /start.')
            manage_user(update, context, False)
        except KeyError:
            log_event(update, 'Отправил stop повторно')

def parking_handler(update: Update, context: CallbackContext) -> None:
    """Handler for place selection buttons."""
    if (config['whitelist'] and str(update.effective_user.id) in users
       or not config['whitelist']):
        manage_user(update, context)
        number = update.callback_query.data
        try:
            parking = context.bot_data['parking']
            stats = context.bot_data['stats']
            for place in parking.places:
                if place.number == number:
                    stats.count(place)
                    place.toggle_state(str(update.effective_user.id))
                    state = place.state
            if state == 'reserved':
                action_text = 'зарезервировал'
            elif state == 'occupied':
                action_text = 'занял'
            elif state == 'free':
                action_text = 'освободил'
            update.callback_query.answer(f'Вы {action_text}и место {number}')
            action = (f'*{users[str(update.effective_user.id)]}* ' +
                      f'{action_text} место *{number}*')
            update_state(update, context, action)
            log_event(update, action)
        except ValueError:
            update.callback_query.answer(f'Место {number} не свободно!')
            log_event(update, f'Нажал на несвободное место {number}')

def cancel_handler(update: Update, context: CallbackContext) -> None:
    """Handler for cancel reserve button."""
    if (config['whitelist'] and str(update.effective_user.id) in users
       or not config['whitelist']):
        manage_user(update, context)
        number = update.callback_query.data.split('.')[1]
        parking = context.bot_data['parking']
        try:
            for place in parking.places:
                if place.number == number:
                    place.cancel_reserve(str(update.effective_user.id))
            update.callback_query.answer(f'Вы отменили резерв места {number}')
            action = (f'*{users[str(update.effective_user.id)]}* ' +
                      f'отменил резерв места *{number}*')
            update_state(update, context, action)
            log_event(update, action)
        except ValueError:
            update.callback_query.answer(
                'Используйте клавиатуру из последнего сообщения!')
            log_event(update, 'Пытался отменить резерв на старой клавиатуре')

def clear_handler(update: Update, context: CallbackContext) -> None:
    """Handler for clear parking button."""
    if (config['whitelist'] and str(update.effective_user.id) in users
       or not config['whitelist']):
        manage_user(update, context)
        try:
            parking = context.bot_data['parking']
            places = parking.clear()
            if places:
                stats = context.bot_data['stats']
                for place in places:
                    stats.count(place)
            update.callback_query.answer('Вы выбрали очистку парковки')
            action = (f'*{users[str(update.effective_user.id)]}* ' +
                      'очистил парковочное пространство')
            update_state(update, context, action)
            log_event(update, action)
        except ValueError:
            update.callback_query.answer(
                'Используйте клавиатуру из последнего сообщения!')
            log_event(update, 'Пытался очистить парковку на старой клавиатуре')

def statistics_handler(update: Update, context: CallbackContext) -> None:
    """Handler for statistic button."""
    if (config['whitelist'] and str(update.effective_user.id) in users
       or not config['whitelist']):
        manage_user(update, context)
        update.callback_query.answer('Вы запросили статистику')
        stats = context.bot_data['stats']
        update_state(update, context, stats.message_text, True)
        log_event(update, 'Запросил статистику')

def update_state(update: Update, context: CallbackContext, info: str,
                 personal=False) -> None:
    """Sends personal or bulk messages to users.

    Args:
        update: for identifying users and getting bot for bulk send.
        context: for getting bot and user data.
        info: info string for info message.
        personal (optional): should this message be personal only.
        Defaults to False.
    """
    parking = context.bot_data['parking']
    if personal:
        markup = make_keyboard(context, str(update.effective_user.id))
        update.effective_message.reply_text(info, parse_mode='MarkdownV2')
        update.effective_message.reply_text(parking.state_text,
                                            reply_markup=markup)
    else:
        for user in users:
            markup = make_keyboard(context, user)
            update.effective_message.bot.send_message(
                text=info, chat_id=user, parse_mode='MarkdownV2')
            update.effective_message.bot.send_message(
                text=parking.state_text, chat_id=user, reply_markup=markup)
            log_event(update, f'Отправили уведомление {users[user]}')

def make_keyboard(context: CallbackContext,
                  user_id: str) -> InlineKeyboardMarkup:
    """Making of personalized keyboards."""
    keyboard = []
    parking = context.bot_data['parking']
    for place in parking.state:
        place_sign, state, number, occupant = place
        if occupant is not None:
            person = users[str(occupant)]
        else:
            person = 'место свободно'
        caption = ' '.join([place_sign, number, person])
        place_button = InlineKeyboardButton(caption, callback_data=number)
        cancel_button = InlineKeyboardButton(' '.join(
            [emojize(':right_arrow_curving_left:'), 'Отменить резерв']),
            callback_data=''.join(['cancel.', number]))
        clear_button = InlineKeyboardButton(' '.join(
            [emojize(':FREE_button:'), 'Очистить парковку']),
            callback_data='clear')
        statistics_button = InlineKeyboardButton(' '.join(
            [emojize(':bar_chart:'), 'Статистика']),
            callback_data='statistics')
        if state == 'reserved' and occupant == user_id:
            keyrow = []
            keyrow.append(place_button)
            keyrow.append(cancel_button)
            keyboard.append(keyrow)
        else:
            keyboard.append([place_button])
    if not parking.is_free:
        keyrow = []
        keyrow.append(clear_button)
        keyrow.append(statistics_button)
        keyboard.append(keyrow)
    else:
        keyboard.append([statistics_button])
    return InlineKeyboardMarkup(keyboard)

def manage_user(update: Update, context: CallbackContext, check=True) -> None:
    """Managing users.

    Args:
        check (optional): if not check - than it's user remove.
        Defaults to True.
    """
    user_id = str(update.effective_user.id)
    if check:
        if update.effective_user.full_name is None:
            username = update.effective_user.username
        else:
            username = update.effective_user.full_name
        # Replace for telegram markdown v2
        for ch in ['_', '*', '[', ']', '(', ')', '~', '`', '>',
                   '#', '+', '-', '=', '|', '{', '}', '.', '!']:
            username = username.replace(ch, '')
        if user_id not in users or users[user_id] != username:
            users[user_id] = username
            save_json(config['users_file'], users)
            stats = context.bot_data['stats']
            stats.update_users(users)
            log_event(update, 'Добавили пользователя')
    elif not check:
        users.pop(user_id)
        save_json(config['users_file'], users)
        log_event(update, 'Удалили пользователя')

def log_event(update: Update, action: str) -> None:
    try:
        username = f'{users[str(update.effective_user.id)]}'
    except KeyError:
        username = update.effective_user.username
    action = action.replace('*', '')
    logger.log(INFO, f'{username} - {action}')

def load_json(filename: str) -> dict:
    try:
        with open(filename) as file:
            data = load(file)
        return data
    except FileNotFoundError:
        exit(f'File "{filename}" does not exist')

def save_json(filename: str, data: dict) -> None:
    with open(filename, 'w') as file:
        dump(data, file, indent=4, sort_keys=True)

def get_config() -> dict:
    parser = ArgumentParser(
        prog='Logrocon Parking Bot v.3')
    parser.add_argument('-c', '--config',  default='config.json', metavar='C',
                        help='config file name')
    args = vars(parser.parse_args())
    config = load_json(args['config'])
    return config

def toggle_whitelist(update: Update, context: CallbackContext) -> None:
    """Toggling bot's whitelist on and off by bot owner."""
    if update.effective_user.id == config['owner_id']:
        config['whitelist'] = not config['whitelist']
        update.effective_message.reply_text('Whitelist mode: ' +
                                            f'{config["whitelist"]}')
        log_event(update, 'Переключил режим whitelist на ' +
                  f'{config["whitelist"]}')
    else:
        log_event(update, 'Отправил whitelist, хотя не должен о ней знать')

def get_logs(update: Update, context: CallbackContext) -> None:
    """Getting logs by messages from bot by bot owner."""
    if update.effective_user.id == config['owner_id']:
        if not context.args:
            length = config['logging']['log_length']
            log_event(update, f'Отправил logs без аргументов, берем {length}')
        else:
            length = context.args[0]
            log_event(update, f'Отправил logs с аргументом {length}')
        result = run(['tail', '-n', length, config['logging']['log_file']],
                     capture_output=True, universal_newlines=True)
        log = result.stdout
        if len(log) > 4096:
            for x in range(0, len(log), 4096):
                update.effective_message.reply_text(log[x:x+4096])
        else:
            update.effective_message.reply_text(log)
    else:
        log_event(update, 'Отправил logs, хотя не должен о ней знать')

def get_stats(update: Update, context: CallbackContext) -> None:
    """Getting statistics by message from bot by bot owner."""
    if update.effective_user.id == config['owner_id']:
        update.effective_message.reply_text(
            dumps(context.bot_data['stats'].as_dict, indent=4))
        log_event(update, 'Экспортировал статистику в json')
    else:
        log_event(update, 'Отправил get_stats, хотя не должен о ней знать')

def set_stats(update: Update, context: CallbackContext) -> None:
    """Setting statistics by message from bot owner to bot."""
    if update.effective_user.id == config['owner_id']:
        if not context.args:
            update.effective_message.reply_text('Отсутствуют аргументы')
            log_event(update, f'Отправил set_stats без аргументов')
        else:
            stats = ''
            for item in context.args:
                stats = stats + ' ' + item
            context.bot_data['stats'].as_dict = loads(stats)
            update.effective_message.reply_text('Статистика импортирована')
            log_event(update, 'Импортировал статистику из json')
    else:
        log_event(update, 'Отправил set_stats, хотя не должен о ней знать')

config = get_config()
"""dict: all config options."""

users = load_json(config['users_file'])
"""dict: bot users."""

# Set logging
log_format = '%(asctime)s %(levelname)s %(name)s %(message)s'
basicConfig(filename=config['logging']['log_file'],
            format=log_format, level=INFO)
logger = getLogger(__name__)

handlers = [CommandHandler('start', start),
            CommandHandler('stop', stop),
            CallbackQueryHandler(cancel_handler, pattern='cancel.*'),
            CallbackQueryHandler(clear_handler, pattern='clear'),
            CallbackQueryHandler(statistics_handler, pattern='statistics'),
            CallbackQueryHandler(parking_handler),
            CommandHandler('whitelist', toggle_whitelist),
            CommandHandler('logs', get_logs, pass_args=True),
            CommandHandler('get_stats', get_stats),
            CommandHandler('set_stats', set_stats, pass_args=True)]

def main():
    updater = Updater(token=config['token'], persistence=PicklePersistence(
        filename=config['data_file'], store_chat_data=False,
        store_user_data=False, on_flush=False))
    dispatcher = updater.dispatcher
    dispatcher.bot_data['stats'] = dispatcher.bot_data.get('stats',
                                                           Stats(users))
    dispatcher.bot_data['parking'] = dispatcher.bot_data.get(
        'parking', Parking(config['places']))
    # Create new parking if places in config changed
    if ([x[2] for x in dispatcher.bot_data['parking'].state]
       != config['places']):
        dispatcher.bot_data['parking'] = Parking(config['places'])
    for handler in handlers:
        dispatcher.add_handler(handler)
    updater.start_polling(drop_pending_updates=True)
    updater.idle()

if __name__ == '__main__':
    main()


#!/usr/bin/env python3
import rospy
import datetime
import sys, os
from rosgraph_msgs.msg import Log

rospy.init_node('NECST_logger')

###config
save_to = '/home/amigos/log'
try:
    file_name = sys.argv[1]
except:
    file_name = ''
###

def save_file_conf():
    today = datetime.date.today()
    year = today.year
    month = today.month
    day = today.day
    _save_to = os.path.join(save_to, str(year), str(month), str(day))
    _file_name = file_name.split('.')[0]+'.txt'
    if os.path.exists(_save_to):pass
    else:
        os.makedirs(_save_to, exist_ok = True)
        print('Log is save to {}'.format(_save_to))
    return _save_to, _file_name

def save(req):
    ret = save_file_conf()
    savefile = os.path.join(ret[0], ret[1])
    if not req.file == file_name:return
    if '#' in list(req.msg):
        args = req.msg.split('#')[1]
        f_name = req.msg.split('#')[0]
        log = '[{}] : ({}) : {}{}'.format(datetime.datetime.fromtimestamp(req.header.stamp.to_time()), req.file,f_name, args)
        print(log)
    else:
        log = '[{}] : ({}) : {}'.format(datetime.datetime.fromtimestamp(req.header.stamp.to_time()), req.file,req.msg)
        print(log)

    f = open(savefile,'a')
    f.write(log+'\n')
    f.close()

if __name__ == '__main__':
    if file_name == '':
        file_name = input('Pleae input script name [ex : ROS_controller.py]')
    sub = rospy.Subscriber('rosout_agg', Log, save, queue_size=100)
    print('*** Logger Start {} ***'.format(file_name))
    rospy.spin()


# %%
from pathlib import Path
import csv

import matplotlib.pyplot as plt
from datetime import datetime

path = Path("weather_data/en_climate_daily_ON_6158355_2023_P1D.csv")
lines = path.read_text().splitlines()

reader = csv.reader(lines)
header_row = next(reader)

# Extract the percipitation.
dates, percips = [], []
for row in reader:
    current_date = datetime.strptime(row[4], "%Y-%m-%d")
    percip = float(row[11])
    if percip != 0:
        dates.append(current_date)
        percips.append(percip)

# Plot the Total Precipitation (mm).
# The sum of the total rainfall and the water equivalent of the total snowfall in millimetres (mm), observed at the location during a specified time interval.
plt.style.use("seaborn-v0_8")
fig, ax = plt.subplots(figsize=(10,6))
ax.scatter(dates, percips, color='green')

# Format plot.
ax.set_title("Daily Total Perciptations (mm), From January 1, 2023 to August 16, 2023", fontsize=16)
ax.set_xlabel("Dates (YYYY-MM-DD)")
fig.autofmt_xdate()
plt.ylabel('Total Precipitation (mm)')
plt.tight_layout()

plt.show()


import logging
from django.conf import settings

class ShowDatabaseQueries(logging.Filter):
    def filter(self, record):
        return settings.DATABASE_DEBUG

LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'filters': {
        'require_debug_false': {
            '()': 'django.utils.log.RequireDebugFalse',
        },
        'require_debug_true': {
            '()': 'django.utils.log.RequireDebugTrue',
        },
        'require_database_debug_true': {
            '()': ShowDatabaseQueries,
        }
    },
    'formatters': {
        'django.server': {
            '()': 'django.utils.log.ServerFormatter',
            'format': '[{server_time}] {message}',
            'style': '{',
        }
    },
    'handlers': {
        'docker': {
            'level': 'DEBUG',
            'class': 'logging.StreamHandler',
        },
        'console': {
            'level': 'INFO',
            'filters': ['require_debug_true'],
            'class': 'logging.StreamHandler',
        },
        'database': {
            'level': 'DEBUG',
            'filters': ['require_database_debug_true'],
            'class': 'logging.StreamHandler',
        },
        'django.server': {
            'level': 'INFO',
            'class': 'logging.StreamHandler',
            'formatter': 'django.server',
        },
        'mail_admins': {
            'level': 'ERROR',
            'filters': ['require_debug_false'],
            'class': 'django.utils.log.AdminEmailHandler'
        }
    },
    'loggers': {
        '': {
            'handlers': ['console',],
            'level': 'DEBUG',
        },
        'django': {
            'handlers': ['console', 'mail_admins'],
            'level': 'INFO',
        },
        'django.server': {
            'handlers': ['django.server'],
            'level': 'INFO',
            'propagate': False,
        },
        'django.db.backends': {
            'level': 'DEBUG',
            'handlers': ['database'],
            'propagate': False,
        }
    },
}


import json
from functions import get_access_token, get_animal_types, get_animals_by_type, \
                     get_animals_dataset, print_babies_adults, print_animal_types, \
                     digit_check, string_check, string_check_1, add_animal, info_about_pet

with open('data.json') as infile:
    dataset = json.load(infile)

    print("Welcome to the Pet Project!")
while True:

    print( "Enter your option:\n",
          "Enter 1 if you want to see all possible types of animals\n",
          "Enter 2 if you want to delete adopted animal\n",
          "Enter 3 if you want to add new animal to dataset\n",
          "Enter 4 if you want to update data from the website\n",
          "Enter 5 if you want to exit the programm\n")

    option1 = digit_check(5, 1)

    if option1 == 1:
        while True:
            print_animal_types(dataset)

            print("   Enter 1 if you want to adopt animal of some type\n",
                  "  Enter 2 if you want to exit to the main menu")

            option2 = digit_check(2, 1)

            if option2 == 1:

                type_animal = string_check(dataset, "Enter, animal of what type you would like to adopt: ")

                print_babies_adults(dataset, type_animal)

                name_adopt = string_check(dataset[type_animal], "Enter name of animal which characteristics you would like to see: ")

                info_about_pet(dataset, type_animal, name_adopt)

                answer = string_check_1("Yes", "No", "Do you confirm that you want to adopt this pet? Enter Yes or No: ")

                if answer == "Yes":
                    del dataset[type_animal][name_adopt]

            if option2 == 2:
                break

    if option1 == 2:

        while True:

            print("   Enter 1 if you want to delete pet from the dataset\n",
                  "  Enter 2 if you want to exit to the main menu\n")

            option3 = digit_check(2, 1)

            if option3 == 1:

                print_animal_types(dataset)

                type_delete = string_check(dataset, "Enter, animal of what type you would like to delete from the dataset: ")

                print_babies_adults(dataset, type_delete)

                name_delete = string_check(dataset[type_delete], "Enter name of animal which you want to delete: ")

                del dataset[type_delete][name_delete]

            if option3 == 2:
                break

    if option1 == 3:

        while True:

            print("   Enter 1 if you want to add pet to the dataset\n",
                  "  Enter 2 if you want to exit to the main menu\n")

            option4 = digit_check(2, 1)

            if option4 == 1:

                print_animal_types(dataset)
                type_add = string_check(dataset, "Enter, animal of what type you would like to add to the dataset: ")
                name_add = add_animal(dataset, type_add)

                info_about_pet(dataset, type_add, name_add)
                print("\n")

            else:
                break

    if option1 == 4:
        token   = get_access_token()
        types   = get_animal_types(token)
        dataset = get_animals_dataset(types, token)
        print("Data was successfully updated! \n")

    if option1 == 5:
        break

with open('data.json', 'w') as outfile:
    json.dump(dataset, outfile)


import logging
import re

class ColorUtil:

    @staticmethod
    def ShadeColor(hexColor, percent):
        try:
            hexNum = int(hexColor[1:], 16)
            t = 0 if percent < 0 else 255
            p = percent * -1 if percent < 0 else percent

            R = hexNum >> 16
            G = hexNum >> 8 & 0x00FF
            B = hexNum & 0x0000FF

            # print(hexColor, percent)
            # print(R, G, B)

            Rhex = hex(round((t - R) * p) + R)[2:].zfill(2)
            Ghex = hex(round((t - G) * p) + G)[2:].zfill(2)
            BHex = hex(round((t - B) * p) + B)[2:].zfill(2)

            # print(Rhex, Ghex, BHex)

            hexString = '#' + Rhex + Ghex + BHex

            # print(hexString)
            # print()

            return hexString
        except Exception as e:
            logging.error(logging.exception("Error creating shade of color"))

    # https://stackoverflow.com/questions/20275524/how-to-check-if-a-string-is-an-rgb-hex-string
    @staticmethod
    def IsValidHexColor(hexColor):
        hexstring = re.compile(r'#[a-fA-F0-9]{3}(?:[a-fA-F0-9]{3})?$')
        return bool(hexstring.match(hexColor))


import pygame

class Bullet(pygame.sprite.Sprite):
    def __init__(self, gun):
        pygame.sprite.Sprite.__init__(self)
        self.image=pygame.Surface((10,10))
        self.rect=self.image.get_rect()
        self.image.fill((255,0,0))
        self.rect.centerx=gun.rect.centerx
        self.rect.centery=gun.rect.centery

    def update(self):
        self.rect.y-=10
        self.score=0


import numpy as np

from typing import List

#本质:元素的左上角元素都相同
class Solution:
    def isToeplitzMatrix(self, matrix: List[List[int]]) -> bool:
        if not matrix or not matrix[0]:
            return True
        m, n = len(matrix), len(matrix[0])

        for i in range(m):
            for j in range(n):
                if 0 <= i - 1 < m and j + 1 < n:

                    if matrix[i-1][j] != matrix[i][j+1]:
                       return False

        return True

if __name__ == '__main__':
    matrix = [[1, 2, 3, 4], [5, 1, 2, 3], [9, 5, 1, 2]]
    matrix = [[1,2],[2,2]]
    matrix = [[41, 45], [81, 41], [73, 81], [47, 73], [0, 47], [79, 76]]
    print(Solution().isToeplitzMatrix(matrix))


"""pip/setuptools packaging

Based off https://github.com/pypa/sampleproject/blob/master/setup.py
"""

# Always prefer setuptools over distutils
from setuptools import setup, find_packages
# To use a consistent encoding
from codecs import open
from os import path, remove
import shutil

from malboxes._version import __version__

here = path.abspath(path.dirname(__file__))

_tempfiles = []
def _prepare():
    """Preparing files for package"""
    # Here are files I want packaged but also in top-level directory as it is mostly
    # unrelated to actual build
    # pip will install data_files in an odd location so I copy them in package at
    # build time
    root_data_files = ['LICENSE', 'README.adoc', 'TODO.adoc']

    for f in root_data_files:
        _tempfiles.append(shutil.copy(path.join(here, f),
                                      path.join(here, 'malboxes')))

    # docs
    shutil.copytree(path.join(here, 'docs'), path.join(here, 'malboxes/docs'),
                    ignore=shutil.ignore_patterns('presentation'))

def _teardown():
    """Removing temporary files"""

    for f in _tempfiles:
        remove(path.join(here, f))

    shutil.rmtree(path.join(here, 'malboxes/docs'))

# Get the long description from the README file
# TODO process README to make it pure plaintext
with open(path.join(here, 'README.adoc'), encoding='utf-8') as f:
    long_description = f.read()

_prepare()

setup(
    name='malboxes',
    version=__version__,

    description='Build Malware VMs (boxes) or whole environments based on '
                'templates. Useful for analysts, sandboxes or honeypots. '
                'Leverages devops workflow with Vagrant and Packer.',
    long_description=long_description,

    url='https://github.com/gosecure/malboxes',

    author='Malboxes Team',
    author_email='obilodeau@gosecure.ca',

    license='GPLv3+',

    # See https://pypi.python.org/pypi?%3Aaction=list_classifiers
    classifiers=[
        # How mature is this project? Common values are
        #   3 - Alpha
        #   4 - Beta
        #   5 - Production/Stable
        'Development Status :: 4 - Beta',

        # Indicate who your project is intended for
        'Intended Audience :: Information Technology',
        'Topic :: Security',

        # Pick your license as you wish (should match "license" above)
        'License :: OSI Approved :: GNU General Public License v3 or later '
        '(GPLv3+)',

        # Specify the Python versions you support here. In particular, ensure
        # that you indicate whether you support Python 2, Python 3 or both.
        #'Programming Language :: Python :: 2',
        #'Programming Language :: Python :: 2.6',
        #'Programming Language :: Python :: 2.7',
        'Programming Language :: Python :: 3',
        'Programming Language :: Python :: 3.3',
        'Programming Language :: Python :: 3.4',
        'Programming Language :: Python :: 3.5',
    ],

    # What does your project relate to?
    keywords='virtual-machine malware reverse-engineering vagrant packer',

    # Once we have more code we'll migrate to a package and use find_packages()
    packages=find_packages(exclude=['contrib', 'docs', 'tests']),

    # List run-time dependencies here.  These will be installed by pip when
    # your project is installed. For an analysis of "install_requires" vs pip's
    # requirements files see:
    # https://packaging.python.org/en/latest/requirements.html
    install_requires=['appdirs', 'Jinja2', 'jsmin', 'boto3'],

    # List additional groups of dependencies here (e.g. development
    # dependencies). You can install these using the following syntax,
    # for example:
    # $ pip install -e .[dev,test]
    #extras_require={
    #    'dev': ['check-manifest'],
    #    'test': ['coverage'],
    #},

    include_package_data = True,
    zip_safe = False,

    # install malboxes executable
    entry_points={
        'console_scripts': [
            'malboxes=malboxes:main',
        ],
    },
)

_teardown()


from rest_framework import serializers
from .models import PetModel, FA
from datetime import date,datetime,timedelta
from django.utils import timezone

class PetSerial(serializers.ModelSerializer):
	class Meta:
		model=PetModel
		fields=(
			"Category",
			"Name",
			"Sex",
			"BirthDt",
			"City",
			"Departement",
			"Statut",
			"OK_CHAT",
			"OK_CHIEN",
			"OK_ENFANT",
			"FA"
			)

	def create(self, validated_data):
		return PetModel.objects.create(**validated_data)

	def update(self, instance, validated_data):
		instance.Category=validated_data.get("Category", instance.Category)
		instance.Name=validated_data.get("Name", instance.Name)
		instance.Sex=validated_data.get("Sex", instance.Sex)
		instance.BirthDt=validated_data.get("BirthDt", instance.BirthDt)
		instance.City=validated_data.get("City", instance.City)
		instance.Departement=validated_data.get("Departement", instance.Departement)
		instance.Statut=validated_data.get("Statut", instance.Statut)
		instance.OK_CHAT=validated_data.get("OK_CHAT", instance.OK_CHAT)
		instance.OK_CHIEN=validated_data.get("OK_CHIEN", instance.OK_CHIEN)
		instance.OK_ENFANT=validated_data.get("OK_ENFANT", instance.OK_ENFANT)
		instance.save()
		return instance


import json
from collections import Counter

from template import *

relation_ground_truth_count = json.load(open("../../data/relation_count.json"))
for relation in relation_list[:1]:
    result_data = []
    with open(f"./data/alias/query_result/{relation}.json", "r") as f:
        for line in f:
            json_obj = json.loads(line)
            result_data.append(json_obj)
    vote_data = {}
    with open(f"./data/alias/query_result_vote/{relation}.json", "w") as out:
        for query in result_data:
            if query['input']['query_id'] in vote_data:
                vote_data[query['input']['query_id']]["answer"].append(query['output'])
            else:
                vote_data[query['input']['query_id']] = {"sentence": query['input']['query']['prompt'], "head": query['input']['head'], "label": query['input'][
                    'label'], "answer": [query['output']]}
        tp, fp, tn, fn = 0, 0, 0, 0
        for query_id, query_data in vote_data.items():
            answer_list = query_data['answer']
            result = [a for a in answer_list]
            vote_answer = max(result, key=answer_list.count)
            copy_vote_data = query_data.copy()
            copy_vote_data['tail'] = vote_answer
            copy_vote_data['vote_answer'] = vote_answer
            copy_vote_data['head'] = query_data['head']
            if vote_answer == "yes" and copy_vote_data['label'] == "tp":
                tp += 1
                copy_vote_data['result'] = "true_p"
            if vote_answer == "yes" and copy_vote_data['label'] == "fp":
                fp += 1
                copy_vote_data['result'] = "false_p"
            if vote_answer == "no" or vote_answer == "unknown" and copy_vote_data['label'] == "tp":
                fn += 1
                copy_vote_data['result'] = "false_n"
            if vote_answer == "no" or vote_answer == "unknown" and copy_vote_data['label'] == "fp":
                tn += 1
                copy_vote_data['result'] = "true_n"
            out.write(json.dumps(copy_vote_data) + "\n")
        print(f"{relation} tp:{tp} fp:{fp} tn:{tn} fn:{fn}, recall:{tp / relation_ground_truth_count[relation]}")


"""
This module contains functions for creating transformer models that operate on grid-like inputs.

Functions:

- grid_transformer: returns a callable transformer model constructor that can operate on grid-like inputs.
"""
from typing import Optional, Tuple, Callable, Union

import core_tools.ops as K
import tensorflow as tf
from tensorflow.keras.layers import Dense

from core_tools.core import rgb, get_extractor, log_shape, Extractor
from grid_transformer.constants import TILE

from grid_transformer.utils import get_map_fn

# from tensorflow.python.keras.layers import LayerNormalization, Lambda, Conv2D, Layer,Embedding

def Tokenizer(
        batch_no: Optional[int] = None,
        col: int = 3,
        row: int = 3,
        channel: Optional[str] = None,
        extractor_input: Union[int, Tuple[int, int, int]] = 224,
        extractor: Union[str, Callable] = "ef",
        output_size: int = 10,
        pooling: Optional[Union[str, int, Callable]] = "flat2d",
        map_fn: Union[str, Callable] = "batch",
        return_extractor_input: bool = False,
        show_shape: Union[bool, Callable] = False,
        **kwargs
) -> Callable:
    """
        Applies a grid transformation to an image.

        Parameters
        ----------
        extractor_input : Union[int, Tuple[int, int, int]]
            Shape of the image extractor.
        batch_no : Optional[int]
            Number of batches to be used.
        col : int
            Number of columns in the grid.
        row : int
            Number of rows in the grid.
        no : int
            Number of attention heads.
        extractor : Union[str, Callable]
            Extractor to be used for extracting features from the image.
        output_size : int
            Size of the output of the transformer model.
        pos_emd : str
            Type of positional encoding to be used.
        last : Union[str, Callable]
            Last layer of the transformer model.
        pooling : Optional[Union[str, int, Callable]]
            Pooling function to be used.
        model : Optional[tf.keras.Model]
            Transformer model to be used.
        map_fn : Union[str, Callable]
            Function to map the extracted features to the transformer model.
        channel : Optional[str]
            How channels are handled.
        last_index : Optional[int]
            Index of the last layer.
        return_extractor_input : bool
            If True, returns the input of the extractor.
        return_attention_scores : bool
            If True, returns the attention scores.
        **kwargs :
            Additional keyword arguments to be passed to the transformer model.

        Returns
        -------
        Callable
            Grid Transformer constructor.
        """
    extractor_input = (extractor_input, extractor_input, 3) if isinstance(extractor_input,
                                                                          int) else extractor_input

    batch_no = batch_no
    extractor = extractor
    output_size = output_size
    pooling = pooling
    channel = channel
    map_fn = get_map_fn(map_fn)

    # def input_show(*args, **kwargs):
    #     if hasattr(args[0][0], "numpy"):
    #         ims(args[0][0].transpose((2, 1, 0)))

    # @log_shape(show_shape, "Tokenizer", in_fn=input_show)
    @log_shape(show_shape, "Tokenizer")
    def apply(x: tf.Tensor) -> Union[tf.Tensor, Tuple[tf.Tensor, tf.Tensor]]:
        nonlocal batch_no
        nonlocal extractor
        nonlocal pooling
        nonlocal channel

        shape = tf.shape(x)
        if channel == TILE:
            x = tf.transpose(x[..., None], [0, 3, 1, 2, 4])
            x = rgb((1, 1, 1, 1, 3))(x)

        else:
            x = tf.reshape(x, tf.concat([shape[:-1], [int(x.shape[-1] / 3), 3]], axis=0))
            x = tf.transpose(x, [0, 3, 1, 2, 4])

        if batch_no is None:
            batch_no = int(x.shape[1] / (row * col))

        if row > 1 or col > 1:
            x = K.create_image_grid2(x, row=row, col=col)
            x = x[:, :, :extractor_input[0], :extractor_input[1]]

        if batch_no > 1:
            extractor = map_fn(get_extractor(data=extractor_input, batch=False, model=extractor))
        else:
            x = x[:, 0]

        if callable(extractor) and pooling is None:
            y = log_shape(show_shape, "Extractor")(extractor)(x)
            if y.shape[-1] != output_size:
                y = log_shape(show_shape, "IT: Extractor pooling")(Dense(output_size))(y)

        elif extractor:
            y = Extractor(
                data=tuple(x.shape),
                model=extractor,
                projection=output_size,
                pooling=pooling,
                show_shape=show_shape,
            )(x)
        else:
            y = x

        if return_extractor_input:
            return y, x

        return y

    return apply


from allauth.account.forms import SignupForm
from django import forms as d_forms
from django.contrib.auth import forms, get_user_model
from django.contrib.auth.forms import UserChangeForm, UserCreationForm
from django.contrib.auth.models import Group
from django.core.exceptions import ObjectDoesNotExist, ValidationError
from django.utils.translation import gettext_lazy as _

User = get_user_model()

class CustomUserCreationForm(UserCreationForm):
    email = d_forms.EmailField(required=True, help_text="Required")

    error_message = UserCreationForm.error_messages.update(
        {"duplicate_username": _("This username has already been taken.")}
    )

    class Meta(UserCreationForm.Meta):
        model = User

    def clean_email(self):
        """
        Verify email is available.
        """
        email = self.cleaned_data.get("email")
        qs = User.objects.filter(email=email)
        if qs.exists():
            raise forms.ValidationError(
                "Email is either invalid or already taken"
            )
        return email

    def clean_username(self):
        username = self.cleaned_data["username"]
        try:
            User.objects.get(username=username)
        except User.DoesNotExist:
            return username
        raise ValidationError(self.error_messages["duplicate_username"])

class CustomUserChangeForm(UserChangeForm):
    class Meta(UserChangeForm.Meta):
        model = User

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.fields["email"].required = True
        self.fields["name"].required = True

#  Django allauth authentication
class AcademySignUpForm(SignupForm):
    # specify a choice field that matches choice fields on our model

    type = d_forms.ChoiceField(
        choices=[("STUDENT", "Student"), ("INSTRUCTOR", "Instructor")]
    )

    def custom_signup(self, request, user):
        # set the user type from the form response

        user.type = self.cleaned_data["type"]
        user_group = Group.objects.get(name="Instructor")
        if user.type == User.Types.INSTRUCTOR:
            user_group.user_set.add(user)
        user.save()


import datetime
from pandas_datareader import data as pdr
import queue
import threading
from pprint import pprint
def pullHistoricalData(holdings, benchmarks, start_date, end_date):

    def assign_data_to_ticker(holdings, benchmarks, data):

        for ticker in list(holdings.keys()):
            holdings[ticker]['historicalData'] = data[ticker]['historicalData']
            holdings[ticker]['ninetyDayData'] = data[ticker]['ninetyDayData']
        for ticker in list(benchmarks.keys()):
            benchmarks[ticker]['historicalData'] = data[ticker]['historicalData']
            benchmarks[ticker]['ninetyDayData'] = data[ticker]['ninetyDayData']
        return holdings, benchmarks

    def worker(num):
        def ensure_90_days(ticker, ninety_day_start, start_date, end_date):

            #print("About to make call with ninety start: " + str(ninety_day_start))
            try:
                yahoo_data = pdr.get_data_yahoo(ticker, ninety_day_start, end_date)
                #print("Received yahoo_data for " + str(ticker))
            except:
                print("ensure_90_days has failed for: " + str(ticker))
            difference = 90 - len(list(yahoo_data['Close'][:start_date]))
            #print("The current difference is: " + str(difference))
            if difference > 0:
                ninety_day_start = ninety_day_start - datetime.timedelta(days=difference)
                #print("About to call function with new ninety start date of: " + str(ninety_day_start))
                yahoo_data = ensure_90_days(ticker, ninety_day_start, start_date, end_date)
            return yahoo_data

        while True:
            #print("Queue length: " + str(q.qsize()))
            item = q.get()
            if item is None:
                break
            ticker, ninety_day_start, start_date, end_date = item
            start = datetime.datetime.strptime(start_date, '%Y-%m-%d')
            ninety_day_start = start - datetime.timedelta(days=129)
            if True:
                if ticker not in done:
                    #print("ticker: " + ticker)
                    #print("done: " + str(done))
                    try:
                        yahoo_data = ensure_90_days(ticker, ninety_day_start, start_date, end_date)
                    except:
                        print("FAILURE POINT A")
                    try:
                        data[ticker] = {}
                        data[ticker]['ninetyDayData'] = list(yahoo_data['Close'][:start_date])
                        data[ticker]['historicalData'] = list(yahoo_data['Close'][start_date:])
                        #print("Completed " + str(item))
                        done.add(ticker)
                        #print("appending " + ticker + "to done")
                    except:
                        print("FAILURE POINT B")

                else:
                    print("Already completed: " + str(ticker) + ". Rejecting.")

            #print(yahoo_data['Close'][:start_date])

            q.task_done()

    requests = []
    start = datetime.datetime.strptime(start_date, '%Y-%m-%d')
    ninety_day_start = start - datetime.timedelta(days=129)
    for ticker in holdings.keys():
        requests.append((ticker, ninety_day_start, start_date, end_date))
    for ticker in benchmarks.keys():
        if ticker not in holdings.keys():
            requests.append((ticker, ninety_day_start, start_date, end_date))
    #print("requests: ")
    #pprint(requests)
    q = queue.Queue()
    done = set()
    data = {}
    threads = []

    thread_count = len(requests)
    #print("Creating " + str(thread_count) + " threads...")
    for i in range(thread_count):
        t = threading.Thread(target=worker, args=(i,))
        t.start()
        threads.append(t)
        #print("i: " + str(i))

    for item in requests:
        #print("item: " + str(item))
        q.put(item)

    q.join()
    #print("q has joined.")
    for i in range(len(threads)):
        q.put(None)
    for t in threads:
        t.join

    return assign_data_to_ticker(holdings, benchmarks, data)

def printDates():

    filename = 'files/AMN.csv'
    file = open(filename, 'r')
    dates = []
    for line in file:
        lineArray = line.split(',')
        dates.append(lineArray[0])

    print(dates)

def getDates():
    filename = 'files/AMN.csv'
    file = open(filename, 'r')
    dates = []
    for line in file:
        lineArray = line.split(',')
        dates.append(lineArray[0])
    return dates

def pullImpliedVols(connection, startDate, endDate):
    dummyArray = [1, 2, 3]


# -*- coding: utf-8 -*-
"""
Created on Sun Jul 23 15:48:44 2023

@author: shikh
"""

import streamlit as st
import main_gp as gp
st.set_option('deprecation.showPyplotGlobalUse', False)
#gp.GaussianEngine(1,0.014,230,1,"C")
#gp.plot()
st.title("Air dispersion simulation")

st.text("Using Gaussian plume model")

def main():
    st.title("Stack properties:")

    slider_label1 = "Stack height (meter)?"
    stack_height = st.slider(slider_label1, 0, 10, 1)

    st.text_label1=("Emission rate (gram/second) ?")
    emission_rate = st.text_input(st.text_label1,0.001)

    st.title("Wind properties:")

    slider_label2 = "Wind direction ?"
    wind_direction = st.slider(slider_label2, 0, 360, 60)

    st.text_label3=("wind speed (meter/second) ?")
    wind_speed = st.text_input(st.text_label3,1)

    options = ['A','B','C','D','E','F']

    stability_class = st.selectbox("Select a stability class", options)

    #gp.GaussianEngine(stack_height,emission_rate,wind_direction,wind_speed,"C")
    st.title("---------------Model result---------------")

    result=gp.GaussianEngine(stack_height,float(emission_rate),wind_direction,float(wind_speed),stability_class)

    gp.plot(result,wind_direction)

if __name__=="__main__":
    main()


import argparse
import random
import sys
from game import *

class OpeningBook():
  """
  Very, very simple opening book to give the bot some direction.
  """
  def __init__(self, game):
    self.game = game

  def findMove(self):
    """
        .   .   .
         / \
      . |wG1| .
         \ /
        .   .   .

    1. wG1
    """
    if self.game.turnNumber == 1:
      return Move(self.game.currentPlayer.pieces['G1'], Point.NONE, Point(0,0,0))

    """
       .   .   .   .
        / \ / \
     . |bG1|w__| .
        \ / \ /
       .   .   .   .

    1. w__, 2. bG1 -w__
    """
    if self.game.turnNumber == 2:
      return Move(self.game.currentPlayer.pieces['G1'], Point.NONE, Point(-1,-1,0))

    """
      .   .   .   .
               / \
        .   . |wQ | .
         / \ / \ /
      . |b__|wG1| .
         \ / \ /
        .   .   .   .

    1. wG1, 2. b__ -wG1, 3. wQ wG1/
    """
    if self.game.turnNumber == 3:
      return Move(self.game.currentPlayer.pieces['Q'], Point.NONE, Point(1,0,0))

class MoveSearch():
  WIN_SCORE = 2**15 - 1

  def __init__(self, game):
    self.game = game
    self.horizonDepth = 1
    self.bestMove = None
    self.heuristic = Heuristic(game)

  def findMove(self):
    self.minimax(self.horizonDepth, float('-infinity'), float('infinity'))
    return self.bestMove

  def minimax(self, depth, alpha, beta):
    """
      Basic Alpha-Beta min-maxing
    """
    val = self.checkWinScore()
    if not val == None:
      return val
    if depth <= 0:
      val = self.evaluate()
      return val

    validMoves = self.game.getValidMoves()
    for move in validMoves:
      self.game.makeMove(move)

      val = -self.minimax(depth - 1, -beta, -alpha)

      self.game.unmakeMove(move)

      if val >= beta: # our opponent won't let us get to this move, it's too good
        return beta

      if val > alpha: # yea! a better move that we can get to
        alpha = val
        if depth == self.horizonDepth:
          self.bestMove = move

    return alpha

  def checkWinScore(self):
    winner = self.game.getWinner()
    if winner == Game.WINNER_NONE:
      return None

    signFlip = 1
    if self.game.currentPlayer.color == Player.BLACK:
      signFlip = -1

    if winner == Game.WINNER_DRAW:
      return signFlip * MoveSearch.CONTEMPT_FACTOR

    return signFlip * (MoveSearch.WIN_SCORE + depth) * winner

  def evaluate(self):
    signFlip = 1
    if self.game.currentPlayer.color == Player.BLACK:
      signFlip = -1

    return signFlip * self.heuristic.evaluate()

class Heuristic():
  """
    Positive => WHITE is winning!
  """
  def __init__(self, game):
    self.game = game

  def evaluate(self):
    return random.randrange(-10, 10)

class Randy():
  """ A bot that will play random moves in Hive """
  def __init__(self, args):
    self.args = self._parseArgs(args)
    self.game = Game('' , '', self.args['times'], self.args['moves'], self.args['expansions'])
    self.player = self.game.currentPlayer
    self.bestMove = None

  def _parseArgs(self, args):
    parser = argparse.ArgumentParser(prog="randy", argument_default='')
    parser.add_argument(args[0], default='')
    parser.add_argument('--times', default='30000,0,0') # game time, white used, black used (ms)
    parser.add_argument('--moves', default='') # 1. wS1, 2. bG1 -wS1, 3. wQ wS1/, ...
    parser.add_argument('--expansions', default='') # LMD
    args = parser.parse_args(args)
    return vars(args)

  def run(self):
    #self.game.printBoard()

    self.bestMove = OpeningBook(self.game).findMove()
    if not self.bestMove:
      self.bestMove = MoveSearch(self.game).findMove()

    self.printMove()

  def printMove(self):
    if not self.bestMove:
      sys.stdout.write('pass')
    else:
      sys.stdout.write(self.game.getMoveNotation(self.bestMove))

if __name__ == "__main__":
  Randy(sys.argv).run()


from pathlib import Path

import mmcv
from mmcls.apis import inference_model
from mmdet.apis import inference_detector
from mmseg.apis import inference_segmentor

from mmrazor.apis import init_mmcls_model, init_mmdet_model, init_mmseg_model

def _sync_bn2bn(config: mmcv.Config) -> None:

    def dfs(cfg_dict) -> None:
        if isinstance(cfg_dict, dict):
            for k, v in cfg_dict.items():
                if k == 'norm_cfg':
                    if v['type'] == 'SyncBN':
                        v['type'] = 'BN'
                dfs(v)

    dfs(config._cfg_dict)

def test_init_mmcls_model() -> None:
    from mmcls.datasets import ImageNet

    config_file = 'configs/nas/spos/spos_subnet_shufflenetv2_8xb128_in1k.py'
    config = mmcv.Config.fromfile(config_file)
    config.model = None
    # Replace SyncBN with BN to inference on CPU
    _sync_bn2bn(config)

    mutable_file = 'configs/nas/spos/SPOS_SHUFFLENETV2_330M_IN1k_PAPER.yaml'
    model = init_mmcls_model(
        config,
        device='cpu',
        cfg_options={'algorithm.mutable_cfg': mutable_file})
    model.CLASSES = ImageNet.CLASSES
    assert not hasattr(model, 'architecture')
    assert hasattr(model, 'backbone')
    assert hasattr(model, 'neck')
    assert hasattr(model, 'head')

    img = mmcv.imread(Path(__file__).parent.parent / 'data/color.jpg', 'color')
    result = inference_model(model, img)
    assert isinstance(result, dict)
    assert result.get('pred_label') is not None
    assert result.get('pred_score') is not None
    assert result.get('pred_class') is not None

def test_init_mmdet_model() -> None:
    config_file = \
        'configs/nas/detnas/detnas_subnet_frcnn_shufflenetv2_fpn_1x_coco.py'
    config = mmcv.Config.fromfile(config_file)
    config.model = None
    # Replace SyncBN with BN to inference on CPU
    _sync_bn2bn(config)

    mutable_file = \
        'configs/nas/detnas/DETNAS_FRCNN_SHUFFLENETV2_340M_COCO_MMRAZOR.yaml'
    model = init_mmdet_model(
        config,
        device='cpu',
        cfg_options={'algorithm.mutable_cfg': mutable_file})
    assert not hasattr(model, 'architecture')

    img = mmcv.imread(Path(__file__).parent.parent / 'data/color.jpg', 'color')
    result = inference_detector(model, img)
    assert isinstance(result, list)

def test_init_mmseg_model() -> None:
    config_file = 'configs/distill/cwd/' \
        'cwd_cls_head_pspnet_r101_d8_pspnet_r18_d8_512x1024_cityscapes_80k.py'
    config = mmcv.Config.fromfile(config_file)
    config.model = None
    # Replace SyncBN with BN to inference on CPU
    _sync_bn2bn(config)

    # Enable test time augmentation
    config.data.test.pipeline[1].flip = True

    model = init_mmseg_model(config, device='cpu')
    assert not hasattr(model, 'architecture')
    assert hasattr(model, 'backbone')
    assert hasattr(model, 'decode_head')
    assert hasattr(model, 'auxiliary_head')

    img = mmcv.imread(Path(__file__).parent.parent / 'data/color.jpg', 'color')
    result = inference_segmentor(model, img)
    assert result[0].shape == (300, 400)


import pytest
from brownie import chain, RewardsManager, reverts
from math import floor
from utils.config import network_name
from os.path import exists
import json

rewards_period = 3600 * 24 * 7
rewards_amount = 5_000 * 10**18

def test_acceptance(
    ldo_token,
    stranger,
    rewards_contract,
    helpers,
    accounts,
    ldo_holder,
):
    deployment_file_path = f"deployed-{network_name().replace('fork', 'main')}.json"

    if not exists(deployment_file_path):
        pytest.skip(f"no RewardsManager deployed on {network_name()}")

    chain.sleep(3600 * 24 * 7)
    chain.mine()

    f = open(deployment_file_path, "r")
    deployment_data = json.load(f)
    rewards_manager = RewardsManager.at(
        deployment_data["curveRewardsManager"]["baseAddress"]
    )
    f.close()

    balance_before = ldo_token.balanceOf(rewards_contract)

    reward_data = rewards_contract.reward_data(ldo_token)
    if reward_data[0] != rewards_manager:
        current_distributor = accounts.at(reward_data[0], {"force": True})
        rewards_contract.set_reward_distributor(
            ldo_token, rewards_manager, {"from": current_distributor}
        )
    reward_data = rewards_contract.reward_data(ldo_token)

    assert reward_data[0] == rewards_manager
    assert reward_data[1] == rewards_manager.period_finish()

    for month in range(2):
        with reverts("manager: low balance"):
            rewards_manager.start_next_rewards_period({"from": stranger})

        ldo_token.transfer(rewards_manager, 4 * rewards_amount, {"from": ldo_holder})
        balance_before = ldo_token.balanceOf(rewards_contract)

        reward_data = rewards_contract.reward_data(ldo_token)
        assert reward_data[1] == rewards_manager.period_finish()

        assert rewards_manager.is_curve_rewards_period_finished() == True

        tx = rewards_manager.start_next_rewards_period({"from": stranger})

        assert rewards_manager.is_curve_rewards_period_finished() == False

        reward_data = rewards_contract.reward_data(ldo_token)
        assert reward_data[1] + rewards_period * 3 == rewards_manager.period_finish()

        helpers.assert_single_event_named(
            "NewRewardsPeriodStarted", tx, {"amount": rewards_amount}
        )

        helpers.assert_single_event_named(
            "WeeklyRewardsAmountUpdated", tx, {"newWeeklyRewardsAmount": rewards_amount}
        )

        chain.sleep(rewards_period - 10)
        chain.mine()

        assert rewards_manager.is_curve_rewards_period_finished() == False

        with reverts("manager: rewards period not finished"):
            rewards_manager.start_next_rewards_period({"from": stranger})

        assert ldo_token.balanceOf(rewards_contract) == balance_before + rewards_amount

        chain.sleep(10)
        chain.mine()

        for week in range(3):

            reward_data = rewards_contract.reward_data(ldo_token)
            assert (
                reward_data[1] + rewards_period * (3 - week)
                == rewards_manager.period_finish()
            )

            balance_before = ldo_token.balanceOf(rewards_contract)

            assert rewards_manager.is_curve_rewards_period_finished() == True

            tx = rewards_manager.start_next_rewards_period({"from": stranger})

            assert rewards_manager.is_curve_rewards_period_finished() == False

            reward_data = rewards_contract.reward_data(ldo_token)
            assert (
                reward_data[1] + rewards_period * (3 - week - 1)
                == rewards_manager.period_finish()
            )

            helpers.assert_single_event_named(
                "NewRewardsPeriodStarted", tx, {"amount": rewards_amount}
            )

            chain.sleep(rewards_period - 10)
            chain.mine()

            assert rewards_manager.is_curve_rewards_period_finished() == False

            with reverts("manager: rewards period not finished"):
                rewards_manager.start_next_rewards_period({"from": stranger})

            assert (
                ldo_token.balanceOf(rewards_contract) == balance_before + rewards_amount
            )

            chain.sleep(10)
            chain.mine()