import os
import secrets

import flask

from ._is_reload_process import is_reload_process
from ._oauth2 import Oauth2

class LocalhostToken:
    """Uses a method similar to jupyter notebook. This method is only used during
    interactive usage on localhost, and the workflow is as follows:

    - During the flask app building, a one-time-token (ott) and a cookie_token
      is generated.
    - When the app is ready, the user needs to "login" using this
      one-time-token in the url (http://localhost:{port}?ott={token})
    - If ott is valid - a cookie with a separate token is set, and the
      one-time-token is discarded. The cookie is then used for subsequent
      requests.

    If the user fails both providing a valid one-time-token and a valid cookie
    token, all localhost requests gets a 401.

    If the app is in non-portable mode, the one-time-token and
    cookie token  are reused on app reload (in order to ensure live reload
    works without requiring new login).

    The port is used as a postfix on the cookie name in order to make sure that
    two different localhost applications running simultaneously do not interfere.
    """

    def __init__(self, app: flask.app.Flask, port: int, oauth2: Oauth2 = None):
        self._app = app
        self._port = port
        self._oauth2 = oauth2

        if not is_reload_process():
            # One time token (per run) user has to provide
            # when visiting the localhost app the first time.
            self._ott = os.environ["WEBVIZ_OTT"] = LocalhostToken.generate_token()

            # This is the cookie token set in the users browser after
            # successfully providing the one time token
            self._cookie_token = os.environ[
                "WEBVIZ_COOKIE_TOKEN"
            ] = LocalhostToken.generate_token()

        else:
            self._ott = os.environ["WEBVIZ_OTT"]
            self._cookie_token = os.environ["WEBVIZ_COOKIE_TOKEN"]

        self._ott_validated = False
        self.set_request_decorators()

    @staticmethod
    def generate_token() -> str:
        return secrets.token_urlsafe(nbytes=64)

    @property
    def one_time_token(self) -> str:
        return self._ott

    def set_request_decorators(self) -> None:
        # pylint: disable=inconsistent-return-statements
        @self._app.before_request
        def _check_for_ott_or_cookie():  # type: ignore[no-untyped-def]

            if not self._ott_validated and self._ott == flask.request.args.get("ott"):
                self._ott_validated = True
                flask.g.set_cookie_token = True
                return flask.redirect(flask.request.base_url)

            if self._cookie_token == flask.request.cookies.get(
                f"cookie_token_{self._port}"
            ):
                self._ott_validated = True

                if self._oauth2:
                    return self._oauth2.check_access_token()

            else:
                flask.abort(401)

        @self._app.after_request
        def _set_cookie_token_in_response(
            response: flask.wrappers.Response,
        ) -> flask.wrappers.Response:
            if flask.g.get("set_cookie_token", False):
                response.set_cookie(
                    key=f"cookie_token_{self._port}", value=self._cookie_token
                )
            return response


import pygame
from settings import Settings
from ship import Ship
import game_functions as gf
from pygame.sprite import Group

def run_game():
    # Initialise game and create a screen object
    pygame.init()
    ai_settings = Settings()

    screen = pygame.display.set_mode((ai_settings.screen_width,ai_settings.screen_height))
    pygame.display.set_caption("Alien Invasion")

    ship = Ship(ai_settings, screen)

    # make a group to store bullets in
    bullets = pygame.sprite.Group()

    # Start loop for game
    while True:

        gf.check_events(ai_settings, screen, ship, bullets)
        ship.update()
        bullets.update()
        gf.update_bullets(bullets)
        gf.udpate_screen(ai_settings, screen, ship, bullets)

run_game()


import psycopg2

try:
    conn = psycopg2.connect(
        database='exampleDB',
        user='user',
        host='localhost',
        port=5432,
        password=''
    )
    # Obtenemos un cursor
    cursor1 = conn.cursor()

    #Definimos los nuevos datos que vamos a ingresar
    peliculas = [
        ("El Padrino", 1972),
        ("Batman: El caballero de la noche", 2008),
        ("Pulp Fiction", 1994)
    ]

    #Definimos el cuerpo de la consulta
    query = "INSERT INTO Peliculas VALUES ('{nombre}', {estreno});"
    for nombre, estreno in peliculas:
        cursor1.execute(query.format(nombre=nombre, estreno=estreno))

    # Guardamos los cambios
    conn.commit()
    # Cerramos el cursor
    cursor1.close()

    #Obtenemos un cursor con el que ejecutamos las consultas
    cursor2 = conn.cursor()
    cursor2.execute("SELECT * FROM Peliculas")
    row = cursor2.fetchone()
    while row:
        print(row)
        row = cursor2.fetchone()

    cursor2.close()
    # MUY IMPORTANTE
    conn.close()

except Exception as e:
    print('Hubo un problema :c')
    print(e)


import logging
import ntpath
import os
import pickle
import shutil
import time

import pywren_ibm_cloud.sort.config
from pywren_ibm_cloud.sort.asynchronous.sort import sort_async
from pywren_ibm_cloud.sort.config import INTERMEDIATE_PATH_PREFIX, OUTPUT_PATH_PREFIX, \
    DEFAULT_GRANULE_SIZE_SHUFFLE, PARTITION_FILE_PATH_PREFIX, CHUNK_RANGE_FILE_NAME, \
    PARSER_FATA_FILE_NAME, SAMPLE_PATH_PREFIX
from pywren_ibm_cloud.sort.parse import parse
from pywren_ibm_cloud.sort.phase1 import partitions_into_segments_csv
from pywren_ibm_cloud.sort.predict.search_optimal import search_optimal
from pywren_ibm_cloud.sort.tests.phase1_alternatives.phase1_imzml import map_chunks_into_segments_imzml_v3
from pywren_ibm_cloud.sort.phase2 import reduce_partition_segments
from pywren_ibm_cloud.sort.sample import sample_dataset_imzml, sample_dataset_csv

# Using enum class create enumerations
from pywren_ibm_cloud.sort.utils import get_dataset_size

SORT_DATA_FORMATS = {"imzml", "csv"}
DEFAULT_NUM_WORKERS = 5

logger = logging.getLogger(__name__)

# TODO: delete sleep time argument, only for straggler sensitivity testing.
def create_sort_csv(pw, input_data_path, format_of_data, num_segm, primary_key_column,
                    num_workers_p1=None, granularity=None, delimiter=None, dtypes=None,
                    speculative_map=False, speculative_reduce=False, asynchronous=False,
                    output_path=None, output_bucket=None, segment_ranges=None):
    print("Sort dataset in {} segments".format(num_segm))
    print("Key column: {}".format(primary_key_column))
    print("Asynchronous: {}".format(asynchronous))
    print("Speculative execution: map {} reduce {}".format(speculative_map, speculative_reduce))

    # Manage path format
    if input_data_path.startswith("cos"):
        bucket = input_data_path.split("/")
        bucket = bucket[3]
        path = '/'.join(input_data_path.split("/")[4:])
    else:
        path = input_data_path
    if segment_ranges is not None:
        if isinstance(segment_ranges, str):
            segment_ranges = pickle.load(open(segment_ranges, 'rb'))
            try:
                iter(segment_ranges)
            except Exception:
                raise ValueError("segment_ranges object must be iterable")
            segment_ranges = list(segment_ranges)
        if not isinstance(segment_ranges, list):
            raise ValueError("segment_ranges param must be a list")
    file_name = ntpath.basename(path)
    csv_file_path = path

    my_executor_id = pw.executor_id.replace("/", "_")
    intermediate_path = "{}_{}_{}".format(INTERMEDIATE_PATH_PREFIX, file_name, my_executor_id)
    if output_path is None:
        output_path = "{}_{}_{}".format(OUTPUT_PATH_PREFIX, file_name, my_executor_id)
    if output_bucket is None:
        output_bucket = bucket
    if num_workers_p1 is None:
        num_workers_p1 = num_segm
    if granularity is None:
        granularity = DEFAULT_GRANULE_SIZE_SHUFFLE
    partition_file_path = "{}_{}_{}".format(PARTITION_FILE_PATH_PREFIX, file_name, my_executor_id)
    chunk_range_file_path = "{}/{}.pickle".format(intermediate_path, CHUNK_RANGE_FILE_NAME)
    parser_file_path = "{}/{}.pickle".format(intermediate_path, PARSER_FATA_FILE_NAME)
    sample_info_path = "{}_{}_{}".format(SAMPLE_PATH_PREFIX, file_name, my_executor_id)

    if num_segm is None:
        dataset_size = get_dataset_size(pw, bucket, csv_file_path)
        print("Dataset size {}".format(dataset_size))
        num_segm = search_optimal(pw.config, dataset_size, granularity)
        num_workers_p1 = num_segm
        print("Inferenced {} mappers and {} reducers".format(num_workers_p1, num_segm))

    print("Parsing")
    parse(pw,
          input_bucket=bucket,
          output_bucket=bucket,
          input_path=csv_file_path,
          intermediate_path=intermediate_path,
          output_path=output_path,
          num_workers_phase1=num_workers_p1,
          num_workers_phase2=num_segm,
          delimiter=delimiter,
          granularity=granularity,
          partition_file_path=partition_file_path,
          parser_file_path=parser_file_path,
          sample_info_path=sample_info_path,
          partition_bucket=bucket,
          chunk_range_file_path=chunk_range_file_path,
          chunk_range_bucket=bucket,
          sort_column_numbers=[primary_key_column],
          runtime_memory=pw.config['pywren']['runtime_memory'],
          sample=True,
          dtypes=dtypes,
          sampling_mode="random",
          canary=False,
          segment_ranges=segment_ranges)

    if segment_ranges is None:
        print("Sampling")
        sample_dataset_csv(pw,
                           parser_file_path,
                           output_bucket,
                           num_workers_p1,
                           sample_type="random",
                           canary=False)

    print("Mapping chunks into segments")

    # Create straggler info
    # random.seed()
    # straggler_ids_p1 = random.sample(list(range(num_workers_p1)), max(int(num_workers_p1*DEFAULT_SPECULATIVECAP_TOTAL_TASKS), 1))
    # for id in straggler_ids_p1:
    #       ibm_cos.put_object(Bucket=bucket, Key="straggler_{}".format(id), Body=pickle.dumps(id))
    # print(straggler_ids_p1)
    # straggler_ids_p2 = random.sample(list(range(num_segm)),
    #                                   max(int(num_segm * DEFAULT_SPECULATIVECAP_TOTAL_TASKS), 1))
    # for id in straggler_ids_p2:
    #      ibm_cos.put_object(Bucket=bucket, Key="straggler_p2_{}".format(id), Body=pickle.dumps(id))
    # print(straggler_ids_p2)

    if not asynchronous:
        partitions_into_segments_csv(pw,
                                     num_workers_p1,
                                     parser_file_path,
                                     output_bucket,
                                     speculative=speculative_map)

        print("Reducing segments")
        reduce_partition_segments(pw,
                                  num_segm,
                                  parser_file_path,
                                  output_bucket,
                                  speculative=speculative_reduce)

    else:
        sort_async(pw,
                   num_workers_p1,
                   num_segm,
                   parser_file_path,
                   output_bucket,
                   speculative_map=speculative_map,
                   speculative_reduce=speculative_reduce)

    print("Sort finished, output segments at: ")
    print("bucket {}".format(output_bucket))
    print("path {}".format(output_path))

def create_sort_imzml(pw, input_data_path, format_of_data, ibm_cos, segm_n, num_workers=None, granularity=None):
    if granularity is not None:
        pywren_ibm_cloud.sort.config.DEFAULT_GRANULE_SIZE_SHUFFLE = granularity
        # ut.DEFAULT_GRANULE_SIZE_REDUCE = granularity

    print("Sort dataset in {} segments".format(segm_n))
    start_time = time.time()

    if num_workers != None:
        effective_num_workers = num_workers
    else:
        effective_num_workers = DEFAULT_NUM_WORKERS

    # Directory for temporary files
    shutil.rmtree('tmp', ignore_errors=True)
    os.mkdir("tmp")

    print("Generating parser")
    # Manage path format
    if input_data_path.startswith("cos"):
        bucket = input_data_path.split("/")

        bucket = bucket[3]
        path = '/'.join(input_data_path.split("/")[4:])
    else:
        path = input_data_path

    print("Bucket " + bucket + " and path " + path)

    prefix = "ordered_segments"
    objs = ibm_cos.list_objects_v2(Bucket=bucket, Prefix=prefix)
    while 'Contents' in objs:
        keys = [obj['Key'] for obj in objs['Contents']]
        formatted_keys = {'Objects': [{'Key': key} for key in keys]}
        ibm_cos.delete_objects(Bucket=bucket, Delete=formatted_keys)

        objs = ibm_cos.list_objects_v2(Bucket=bucket, Prefix=prefix)

    # Create local metadata object
    # imzml_metadata = ibm_cos.get_object(Bucket=bucket, Key=''.join([path, ".imzml"]))['Body'].read()
    # metadata_file_path = "tmp/" + input_data_path.split("/")[-1] + ".imzml"
    ibd_file_path = ''.join([path, ".ibd"])
    metadata_file_path = ''.join([path, ".imzml"])

    num_workers, parser_data, start_sampling_time = sample_dataset_imzml(pw, bucket,
                                                                         metadata_file_path, ibd_file_path,
                                                                         effective_num_workers,
                                                                         "random", segm_n, ibm_cos)
    print("Sampling finished")
    print("Final number of workers {}".format(num_workers))
    #
    start_time_effective = time.time()
    print("Mapping chunks into segments")

    map_chunks_into_segments_imzml_v3(pw, num_workers, bucket, ibd_file_path,
                                      bucket, "tmp/partition_file.pickle", parser_data)

    print("Reducing segments")
    # reduce_chunk_segments_imzml(pw, num_workers, bucket, bucket,
    #                             segm_n)

    end_time_effective = time.time()

    # # Sample dataset
    print("Removing temporal files")

    shutil.rmtree('tmp', ignore_errors=True)
    prefix = "tmp"
    args = {'info': {'prefix': prefix, 'bucket': bucket}}
    futures = pw.call_async(ut.clear_cos_prefix, args)
    pw.get_result(futures)

    end_time = time.time()
    print("Sort ended")
    print("--- %s seconds ---" % (end_time - start_time))
    print("--- %s seconds without loading ---" % (end_time - start_sampling_time))
    print("--- %s seconds without loading and sampling ---" % (end_time - start_time_effective))
    print("--- %s seconds without final clearing ---" % (end_time_effective - start_time))

    f = open("equations_results.txt", 'a')
    f.write("{}\n".format([(end_time - start_time), (end_time - start_sampling_time), (end_time - start_time_effective),
                           (end_time_effective - start_time)]))
    f.close()


#!/usr/bin/env python
"""
File: exec_cmds.py
Description: Execute commands asynchronously.
CreateDate: 2022/1/16
Author: xuwenlin
E-mail: wenlinxu.njfu@outlook.com
"""
from io import TextIOWrapper
import click
from pybioinformatic import TaskManager, Displayer
displayer = Displayer(__file__.split('/')[-1], version='0.1.0')

def main(command_file: TextIOWrapper, processing_num: int):
    task_manager = TaskManager([line.strip() for line in command_file], processing_num)
    task_manager.parallel_run_cmd()

@click.command(context_settings=dict(help_option_names=['-h', '--help']))
@click.option('-f', '--command_file', 'command_file',
              metavar='<file>', type=click.File('r'), required=True,
              help='Input file including command (one command per line).')
@click.option('-n', '--processing_num', 'processing_num',
              metavar='<int>', type=int, default=1, show_default=True,
              help='Number of processing.')
@click.option('-V', '--version', 'version', help='Show author and version information.',
              is_flag=True, is_eager=True, expose_value=False, callback=displayer.version_info)
def run(command_file, processing_num):
    """Execute commands asynchronously."""
    main(command_file, processing_num)

if __name__ == '__main__':
    run()


import numpy as np
import multiprocessing as mp
from numba import njit, jit
from time import sleep, time
import os, sys

FILE_DIR = os.path.dirname(os.path.realpath(__file__))
PYTHON_DIR = f"{FILE_DIR}/../"
sys.path.insert(0, PYTHON_DIR)

from helper_functions.hdf5_handler import HDF5Handler
from helper_functions.plot_signal import plot_signal

@njit(cache=True, fastmath=True)
def process_signal(
    signal: np.ndarray,
    threshold: float,
    cutoff: int,
    packet: np.ndarray,
    carryover: int,
    packet_slack: float,
    last_signal: np.ndarray,
) -> tuple:
    """Decides if the signal is part of a packet

    Arguments:
        signal (np.ndarray): The numpy array that carries the IQ packets of the
            signal data.

        threshold (float): The minimum value that a signal must exceed to be
            considered part of a packet.

        cutoff (int): The number of IQ values that are allowed to be under the
            threshold and still be considered part of a packet.

        packet (np.ndarray): Holds the pieces of collected signals that  contain
            the packet information.

        carryover (int): If a packet is not finished being created then this
        will contain the value of the number of index's that were below the
        threshold when the signal ended (if any).

        packet_slack (int): The amount of indexes that will be added to the discoverd
            packet to ensure the whole packet is captured.

    Returns:
        tuple (list[np.ndarray], bool, int, bool):
        - list[np.ndarray]: A list containing all captured signals
        - bool: Indicates if the last packet in the list was completely captured.
        - int: Indicates how many indexes where below the threshold on the continuing packet
        - bool: Indicates if the first two packets in the list need to be concatenated.
    """
    # Skips if signal is None
    if signal == None:
        return (None, True, 0)
    # Skips if the array is empty
    if not signal.all():
        return (None, True, 0)
    last_signal = last_signal.ravel()
    if last_signal.any():
        last_signal = np.trim_zeros(last_signal)
    # Ensures array is 1D
    signal = signal.ravel()
    signal: np.ndarray = np.trim_zeros(signal)
    abs_signal: np.ndarray = np.absolute(signal)
    # Check if the max value is above the threshold
    max_value_in_signal = np.max(abs_signal)
    if max_value_in_signal < threshold:
        return (None, True, 0)
    # Each value maps to a index in abs_signal where the value is above the
    # threshold
    threshold_list: np.ndarray = np.where(abs_signal > threshold)[0]
    # Each value represents the difference between index i and i+1 in
    # threshold_list.
    threshold_diff: np.ndarray = np.diff(threshold_list)
    # Each value represents the
    cutoff_list: np.ndarray = np.where(threshold_diff > cutoff)[0]

    all_packets: list = list()
    new_carryover: int = signal.size - threshold_list[-1]
    end_of_packet_reached: bool = False
    # Checks if the current last packet does not carry over into the next signal
    if new_carryover > cutoff:
        end_of_packet_reached = True
        new_carryover = 0

    # If there is no packet and there is no cutoff found
    if packet == None:
        if cutoff_list.size == 0:
            # print("A")
            if last_signal.any():
                signal = np.concatenate((last_signal, signal))
            if threshold_list[-1] > packet_slack:
                return (
                    [signal[threshold_list[0] : threshold_list[-1] + packet_slack]],
                    end_of_packet_reached,
                    new_carryover,
                )
            else:
                return (
                    [signal[threshold_list[0] : threshold_list[-1]]],
                    end_of_packet_reached,
                    new_carryover,
                )
        for i in range(cutoff_list.size + 1):
            cutoff_list_value: int = cutoff_list[i]
            # Find the first packet
            if i == 0:
                # print("B") #! WORKING
                all_packets.append(
                    signal[
                        threshold_list[0]
                        - packet_slack : threshold_list[cutoff_list_value]
                    ]
                )
            # Find the last packet
            elif i == cutoff_list.size:
                # print("C") #! WORKING
                all_packets.append(
                    signal[
                        threshold_list[cutoff_list[-1]]
                        - packet_slack : threshold_list[-1]
                        + 1
                    ]
                )
            # Find all other packets
            else:
                # print("D") #! WORKING
                last_cutoff_list_value: int = cutoff_list[i - 1]
                all_packets.append(
                    signal[
                        threshold_list[last_cutoff_list_value + 1]
                        - packet_slack : threshold_list[cutoff_list_value]
                    ]
                )
        return (all_packets, end_of_packet_reached, new_carryover)
    else:
        if cutoff_list.size == 0 and end_of_packet_reached:
            if last_signal.any():
                signal = np.concatenate((last_signal, signal))
            # print("E")
            if threshold_list[-1] > packet_slack:
                return (
                    [signal[threshold_list[0] : threshold_list[-1] + packet_slack]],
                    end_of_packet_reached,
                    new_carryover,
                )
            else:
                if last_signal.any():
                    signal = np.concatenate((last_signal, signal))
                return (
                    [signal[threshold_list[0] : threshold_list[-1] + packet_slack]],
                    end_of_packet_reached,
                    new_carryover,
                )
        elif cutoff_list.size == 0 and not end_of_packet_reached:
            # print("F") #! WORKING
            joined_signal: np.ndarray = np.concatenate((packet, signal))
            return ([joined_signal], end_of_packet_reached, new_carryover)
        # Check if the carryover packet ended or if it continues into this signal
        packet_finished: bool = False
        if (threshold_list[0] + carryover) > cutoff:
            # print("G")
            all_packets.append(packet)
            packet_finished = True
        # Find all packets
        for i in range(cutoff_list.size + 1):
            if not cutoff_list.size > 0:
                break
            cutoff_list_value: int = cutoff_list[i]
            # Find the first packet
            if i == 0 and not packet_finished:
                # print("H")
                all_packets.append(
                    np.concatenate(
                        (packet, signal[: threshold_list[cutoff_list_value]])
                    )
                )
            elif i == 0 and packet_finished:
                # print("I")
                all_packets.append(
                    signal[threshold_list[0] : threshold_list[cutoff_list_value]]
                )
            # Find the last packet
            elif i == cutoff_list.size:
                # print("J")
                all_packets.append(
                    signal[
                        threshold_list[cutoff_list[-1]]
                        - packet_slack : threshold_list[-1]
                        + 1
                    ]
                )
            # Find all other packets
            else:
                # print("K")
                last_cutoff_list_value: int = cutoff_list[i - 1]
                all_packets.append(
                    signal[
                        threshold_list[last_cutoff_list_value + 1]
                        - packet_slack : threshold_list[cutoff_list_value]
                    ]
                )
        return (all_packets, end_of_packet_reached, new_carryover)

class PacketDetect:
    def __init__(
        self,
        stream_q: mp.Queue,
        threshold: float,
        cutoff: int,
        packet_q: mp.Queue,
        packet_slack: int,
    ):
        """A class that handles detecting when a signal is part of a packet.

        Arguments:
            stream_q (mp.Queue): A queue holding iq samples and the order in
                which they were added.

            threshold (float): The value that signifies when a signal should
                start to considered a packet.

            cutoff (int): The number of iq values that need to be below the
                threshold for the signal to be considered ended.

            packet_q (mp.Queue): A queue holding iq samples and a bool
                identifying if they are part of a packet.

            packet_slack (int): The amount of indexes that will be added to the
                discovered packet to ensure the whole packet is captured.
        """
        self.stream_q: mp.Queue = stream_q
        self.packet_q: mp.Queue = packet_q
        self.threshold: float = threshold
        self.cutoff: int = cutoff
        self.packet_slack: int = packet_slack
        self.last_signal = np.zeros(10, dtype=np.complex64)
        self.packet: np.ndarray = None
        self.carryover: int = None
        self.run = True

    def __prime_packet_detect(self) -> None:
        print("Preparing packet_detect")
        hdf5 = HDF5Handler()
        primer_signals = list()
        primer_signals.append(hdf5.get_signal("priming_signals", "signal0"))
        primer_signals.append(hdf5.get_signal("priming_signals", "signal1"))
        primer_signals.append(hdf5.get_signal("priming_signals", "signal2"))
        primer_signals.append(hdf5.get_signal("priming_signals", "signal3"))
        # Runs the jit function with dummy data to compile it before running
        # real data through it
        for signal in primer_signals:
            signal_chunks = np.array_split(signal, 40)
            for chunk in signal_chunks:
                self.stream_q.put(chunk)
        self.stream_q.put("DONE")
        self.__find_packets(True)
        # Clean out packet_q of dummy data
        while True:
            data = self.packet_q.get()
            if type(data) == str:
                if data == "DONE":
                    break
        print("packet_detect preped")

    def __find_packets(self, priming: bool = False) -> None:
        """Decides when a signal is part of a packet."""
        count = 0
        while self.run:
            count += 1
            # Display heartbeat
            if count > 5000:
                print("packet_detect still alive")
                count = 0
            # Gets the siganl data
            signal: np.ndarray = self.stream_q.get()
            start_time = time()
            # Breaks the loop
            if type(signal) == str:
                self.packet_q.put("DONE")
                break
            # Porcesses the signal
            all_packets, end_of_packet_reached, self.carryover = process_signal(
                signal,
                self.threshold,
                self.cutoff,
                self.packet,
                self.carryover,
                self.packet_slack,
                self.last_signal,
            )
            self.last_signal = signal
            if not all_packets:
                continue
            if len(all_packets) > 0 and end_of_packet_reached:
                self.packet = None
                self.carryover = 0
                self.packet_q.put(all_packets)
            elif len(all_packets) > 0 and not end_of_packet_reached:
                self.packet = all_packets.pop()
                self.packet_q.put(all_packets)
            # print(f'TIME: {time() - start_time}')
        print("EXITED PACKET_DETECT")

    def start_packet_detect(self) -> None:
        # self.__prime_packet_detect()
        self.__find_packets()

if __name__ == "__main__":
    # q_1 = mp.Queue()
    # q_2 = mp.Queue()
    # packet_d = PacketDetect(q_1, 1.6, 500, q_2, 100.0, 1.5)
    # packet_d.prime_packet_detect()
    pass


#!/usr/bin/env python3

from collections import defaultdict

import json
import yaml

def humanize_pos(pos):
    return {
        "A-": "adjective",
        "C-": "conjunction",
        "D-": "adverb",
        "N-": "noun",
        "P-": "preposition",
        "RA": "article",
        "RD": "demonstrative",
        "RI": "indefinite/interrogative pronoun",
        "RP": "personal pronoun",
        "RR": "relative pronoun",
        "V-": "verb",
        "X-": "particle",
    }[pos]

CASES = {
    "N": "nominative",
    "G": "genitive",
    "D": "dative",
    "A": "accusative",
    "V": "vocative",
}

NUMBERS = {
    "S": "singular",
    "P": "plural",
}

GENDERS = {
    "M": "masculine",
    "F": "feminine",
    "N": "neuter",
    "-": "",
}

DEGREES = {
    "-": "",
}

ASPECTS_TENSES = {
    "A": "aorist",
    "P": "present",
    "F": "future",
    "I": "imperfect",
    "X": "perfect",
}

ASPECTS = {
    "P": "continuous",
    "A": "aorist",
    "X": "perfect"
}

VOICES = {
    "A": "active",
    "M": "1st medio-passive",
    "P": "2nd medio-passive",
}

MOODS = {
    "I": "indicative",
    "N": "infinitive",
    "S": "subjunctive",
    "P": "participle",
}

PERSONS = {
    "1": "1st person",
    "2": "2nd person",
    "3": "3rd person",
}

def humanize_parse(pos, parse):
    person, aspect_tense, voice, mood, case, number, gender, degree = parse
    if pos in ["C-", "D-", "P-", "X-"]:
        return ""
    elif pos == "A-":
        return " ".join([CASES[case], NUMBERS[number], GENDERS[gender], DEGREES[degree]])
    elif pos in ["N-", "RA", "RD", "RI", "RP", "RR"]:
        return " ".join([CASES[case], NUMBERS[number], GENDERS[gender]])
    elif pos == "V-":
        if aspect_tense not in "AF" and voice == "P":
            voice = "M"
        if mood in "DSO":
            return " ".join([
                ASPECTS[aspect_tense],
                VOICES[voice],
                MOODS[mood],
                PERSONS[person],
                NUMBERS[number]
            ])
        if mood == "I":
            return " ".join([
                ASPECTS_TENSES[aspect_tense],
                VOICES[voice],
                MOODS[mood],
                PERSONS[person],
                NUMBERS[number]
            ])
        elif mood == "P":
            return " ".join([
                ASPECTS[aspect_tense],
                VOICES[voice],
                MOODS[mood],
                CASES[case],
                NUMBERS[number],
                GENDERS[gender]
            ])
        elif mood == "N":
            return " ".join([
                ASPECTS[aspect_tense],
                VOICES[voice],
                MOODS[mood]
            ])

GLOSS_OVERRIDES = {
    "Μωϋσῆς": "Moses",
}

def get_gloss(lemma):
    if lemma in GLOSS_OVERRIDES:
        return GLOSS_OVERRIDES[lemma]

    if "gloss" not in lexical_entries[lemma]:
        print("no gloss for {}".format(lemma))
        quit()
    return lexical_entries[lemma]["gloss"]

# assumes it's in a directory nextdoor
with open("../morphological-lexicon/lexemes.yaml") as f:
    lexical_entries = yaml.load(f)

words = []
forms = {}
lexemes = {}
children = defaultdict(list)

with open("raw_data/john_3_a.txt") as f:
    for line in f:
        word_id, bcv, para_id, sent_id, pos, parse, crit, text, word, norm, lemma, rel, head = line.strip().split()

        if (lemma, pos) not in lexemes:
            lexeme_id = len(lexemes)
            lexemes[(lemma, pos)] = lexeme_id
        else:
            lexeme_id = lexemes[(lemma, pos)]

        if (norm, pos, parse, lexeme_id) not in forms.keys():
            form_id = len(forms)
            forms[(norm, pos, parse, lexeme_id)] = form_id
        else:
            form_id = forms[(norm, pos, parse, lexeme_id)]

        if head == "None":
            head = None
        else:
            children[head].append(word_id)

        words.append({
            "word_id": word_id,
            "text": text,
            "form_id": form_id,
            "rel": rel,
            "head": head,
        })

for word in words:
    word["children"] = children[word["word_id"]]

with open("base.json", "w") as f:
    json.dump(words, f, indent=2, sort_keys=True, ensure_ascii=False)

ordered_forms = []
for t, form_id in sorted(forms.items(), key=lambda pair: pair[1]):
    form, pos, parse, lexeme_id = t
    ordered_forms.append({
        "form": form,
        "parse": humanize_parse(pos, parse),
        "lexeme_id": lexeme_id,
    })

with open("forms.json", "w") as f:
    json.dump(ordered_forms, f, indent=2, sort_keys=True, ensure_ascii=False)

ordered_lexemes = []
for t, lexeme_id in sorted(lexemes.items(), key=lambda pair: pair[1]):
    lemma, pos = t
    ordered_lexemes.append({
        "lemma": lemma,
        "pos": humanize_pos(pos),
        "gloss": get_gloss(lemma),
    })

with open("lexemes.json", "w") as f:
    json.dump(ordered_lexemes, f, indent=2, sort_keys=True, ensure_ascii=False)


#!/usr/bin/env python
# -*- coding: utf-8 -*-
import sys, os
import pytz
import json, time
import  config, helpers
from etoro import Etoro
from analyzer import AnalyzeStocks
from apscheduler.schedulers.blocking import BlockingScheduler
from crawler_logging import logger
from datetime import datetime, timezone, timedelta

def get_etoro_instance():

	# Open Web Driver
	etoro_instance = Etoro()

	#Login To Site
	login_status = etoro_instance.login()

	if login_status is True:

		if config.AccountType == "VIRTUAL":
			logger.info(f"Switching to VIRTUAL Account ...")
			time.sleep(5)
			etoro_instance.switch_account(to_demo=True)
			time.sleep(3)

		if config.AccountType != etoro_instance.current_account_type:
			raise Exception(
				f"Switch Account Failed. should be <{config.AccountType}>"
				f" instead of <{etoro_instance.current_account_type}> !")

		return etoro_instance

	elif login_status is False and (
		etoro_instance.has_server_error or etoro_instance.site_not_reachable()
	):
		retries = 2
		while(login_status is False and retries < etoro_instance.MAX_RETRIES):
			logger.warning(
				f'Error Login :: {config.login_fail_msg}, Auto Retrying:'
				f'{retries}/{etoro_instance.MAX_RETRIES}'
			)
			# del etoro_instance
			# etoro_instance = Etoro()
			etoro_instance.login()
			login_status = etoro_instance.get_loggedin_username()
			retries+=1

		if login_status is False:
			raise Exception("Max retries done to login but failed")

	else:
		raise Exception("Login Failed. Check Username or Password")

def buy_trade(etoro_instance):
	try:
		detail = ""

		# etoro_instance.login()
		#checking  current balance
		clientCredit = helpers.clientCredit(login_data=etoro_instance.get_login_info)

		open_markets_only = config.analyze_open_markets_only
		logger.info(
			f"Analyzing Today Stocks For {'opened' if open_markets_only else 'all'} markets ..."
		)

		analyzer = AnalyzeStocks()

		top_markets = analyzer.today_price_analysis(
			stocks_sort_by=config.stocks_sort_by,
			time_slots_count=24,
			open_markets_only=open_markets_only,
			time_slots_pick=2)

		# top_markets = analyzer.trade_insights(
		# 	etoro_instance.get_insights(),
		#  	open_markets_only=open_markets_only, sort_by="growth")

		for t1, top_market in enumerate(top_markets):
			logger.info(f"\nGoing to open Buying Trade for :\n{top_market}\n")
			buy_trade, buy_trade_res  = etoro_instance.trade(
				ins=top_market.get("InstrumentId"), IsBuy=True)
			if buy_trade is False:
				detail = (
					f"Couldnot open buying position for: '{top_market.get('SymbolFull')}'"
					f" reason :\n{buy_trade_res}\n")
				logger.warning(detail)
			else:
				detail = (
					f"Opened buying position for: '{top_market.get('SymbolFull')}'"
					f" response :\n{buy_trade_res}\n")
				logger.info(detail)
				break

		logger.info(f"\nGoing to update User Date ...")
		user_data = etoro_instance.get_login_info
		logger.info(f"\nGot User Data :\n{user_data}\n")

		logger.info(f"\nGoing to update User Trade History ...")
		user_trade_history = etoro_instance.get_trade_history
		logger.info(f"\nGot User Trade History :\n{user_trade_history}\n")

		msg = '<buy_trade> finished ...'
		print('+'*len(msg))
		print(msg)
		print('+'*len(msg))

	except Exception as e:
		exc_type, exc_obj, exc_tb = sys.exc_info()
		fname = os.path.split(exc_tb.tb_frame.f_code.co_filename)[1]
		err_detail = e, fname, exc_tb.tb_lineno
		detail = f"Following Error occured in buy_trade ::\n{err_detail}\n"
		logger.error(detail)

	#write trade logs
	helpers.write_csv("Buying", detail)

def sell_trade(etoro_instance):
	try:
		detail = ""
		# etoro_instance.login()

		logger.info(f"Going to get last Ordered Trades (For Opening Selling Position ) ...")

		lastOrderedTrades = helpers.lastOrderedTrade(isBuy=True)

		if not lastOrderedTrades:
			logger.info(f"No Last Ordered Trades found to open a selling position.")

		for t1, lastOrderedTrade in enumerate(lastOrderedTrades):

			instrumentID = lastOrderedTrade['InstrumentID']
			instrumentData = helpers.find_instrument_by_id(instrumentID)
			lastOrderedTrade.update({k:v for k,v in instrumentData.items()
				if k in ("InstrumentDisplayName", "SymbolFull",)})
			instrumentSymbol = instrumentData["SymbolFull"]
			instrumentDisplayName = instrumentData["InstrumentDisplayName"]
			instrumentTitle = f"{instrumentSymbol} - {instrumentDisplayName}"
			positionID = lastOrderedTrade['PositionID']

			logger.info(f"\n[{t1+1}/{len(lastOrderedTrades)}] :\n{lastOrderedTrade}\n")

			logger.info(f"Going to get User Trade History ...")
			tradeHistory = etoro_instance.get_trade_history

			closedOrder = helpers.isOrderClosed(
				positionID, data_list=tradeHistory,
				path=config.closed_trade_history_file)

			if not closedOrder:
				logger.info(
					f"<[{instrumentTitle}]: postionID->"
					f"{positionID} instrumentID->{instrumentID}>"
					" is not closed yet. skipping this...")
				continue

			# here opens a selling postion for this trade

			logger.info(f"Going to open Selling Trade for: {instrumentTitle}\n")
			sell_trade, sell_trade_res  = etoro_instance.trade(
				ins=instrumentID, IsBuy=False)

			if sell_trade is False:
				detail = (
					f"Couldnot open selling position for: '{instrumentTitle}'"
					f" reason :\n{sell_trade_res}\n")
				logger.warning(detail)
			else:
				detail = (
					f"Opened selling position for: '{instrumentTitle}'"
					f" response :\n{sell_trade_res}\n")
				logger.info(detail)

			logger.info(f"\nGoing to update User Date ...")
			user_data = etoro_instance.get_login_info
			logger.info(f"\nGot User Data :\n{user_data}\n")

			logger.info(f"\nGoing to update User Trade History ...")
			user_trade_history = etoro_instance.get_trade_history
			logger.info(f"\nGot User Trade History :\n{user_trade_history}\n")

		msg = "<sell_trade> finished ..."
		print('+'*len(msg))
		print(msg)
		print('+'*len(msg))

	except Exception as e:
		exc_type, exc_obj, exc_tb = sys.exc_info()
		fname = os.path.split(exc_tb.tb_frame.f_code.co_filename)[1]
		err_detail = e, fname, exc_tb.tb_lineno
		detail = f"Following Error occured in sell_trade ::\n{err_detail}\n"
		logger.error(detail)

	#write trade logs
	helpers.write_csv("Selling", detail)

if __name__ == '__main__':
	exchange_to_follow = helpers.get_exchange_info(config.Default_Exchange)
	day_of_week_opens = exchange_to_follow['Market Opens'].split()[0].lower().replace("day","")
	day_of_week_closes = exchange_to_follow['Market Closes'].split()[0].lower().replace("day","")
	exchange_closing = datetime.strptime(exchange_to_follow['Market Closes'].split()[1], "%H:%M")
	hour_minute = exchange_closing - timedelta(minutes=config.Exchange_Schedular_Minutes)
	day_of_week = f"{day_of_week_opens}-{day_of_week_closes}"

	logger.info(f"\nScheduler started at: {datetime.now().astimezone(pytz.timezone('UTC'))}\n")
	logger.info(
		f"Trader For <{exchange_to_follow['Exchange']}> scheduled to run at:"
		f"\n[Day Weeks: {day_of_week}]\t[Exchange closing hour: "
		f"{exchange_closing.hour}:{exchange_closing.minute:02d} UTC]\t[Job starts at: "
		f"{hour_minute.hour}:{hour_minute.minute:02d} UTC]\n")

	#graps etoro instance with logged in driver and swticed to virtual/real account
	etoro_instance = get_etoro_instance()

	#scheduler = BlockingScheduler({'apscheduler.timezone': 'Europe/London'})
	scheduler = BlockingScheduler({'apscheduler.timezone': 'UTC'})

	# schedular to buy_trade
	scheduler.add_job(
		buy_trade, 'cron', args=[etoro_instance], day_of_week=day_of_week,
		minute=hour_minute.minute, hour=hour_minute.hour
	)

	# schedular to sell_trade
	scheduler.add_job(sell_trade,'interval',args=[etoro_instance],minutes=35)

	# scheduler.add_job(buy_trade, 'cron', args=[etoro_instance],
	# 	minute=9, hour=00)

	#scheduler to display scheduled jobs
	scheduler.add_job(lambda : scheduler.print_jobs(),'interval',minutes=10)
	scheduler.start()


from functools import partial
import logging
import os
import glob

from sqlalchemy.orm.exc import NoResultFound
from sqlalchemy_continuum.utils import version_class
from urllib import quote
from core import db
from core import Node, File
import core.config as config
from core import request_handler as _request_handler
from core.archive import get_archive_for_node
from contenttypes import Container
from contenttypes import Content
from contenttypes.data import Data
from schema.schema import existMetaField
from web.frontend.filehelpers import sendZipFile, splitpath, build_transferzip, node_id_from_req_path, split_image_path,\
    preference_sorted_image_mimetypes, version_id_from_req, get_node_or_version
from utils import userinput
import utils.utils
from utils.utils import getMimeType, clean_path, get_filesize
import tempfile
from utils.compat import iterkeys
from core import httpstatus

logg = logging.getLogger(__name__)
q = db.query

def _send_thumbnail(thumb_type, req):
    try:
        nid = node_id_from_req_path(req)
    except ValueError:
        return 400

    version_id = version_id_from_req(req)

    node_or_version = get_node_or_version(nid, version_id, Data)

    if not node_or_version.has_read_access():
        return 404

    FileVersion = version_class(File)
    if version_id:
        version = node_or_version
        files = version.files.filter_by(filetype=thumb_type, transaction_id=version.transaction_id).all()
        if not files:
            # files may be None if in this version only metadata changed
            # then try previous transaction_ids
            files = version.files.filter(FileVersion.filetype==thumb_type, FileVersion.transaction_id<=version.transaction_id). \
                order_by(FileVersion.transaction_id.desc())
        for f in files:
            if f.exists:
                return _request_handler.sendFile(req, f.abspath, f.mimetype)

        ntype, schema = version.type, version.schema
    else:
        # no version id given
        # XXX: better to use scalar(), but we must ensure that we have no dupes first
        node = node_or_version
        for f in node.files.filter_by(filetype=thumb_type):
            if f.exists:
                return _request_handler.sendFile(req, f.abspath, f.mimetype)

        try:
            ntype, schema = node.type, node.schema
        except NoResultFound:
            return 404

    for p in _request_handler.getFileStorePaths("/img/"):
        for test in ["default_thumb_%s_%s.*" % (ntype, schema),
                     "default_thumb_%s.*" % schema,
                     "default_thumb_%s.*" % ntype]:
            fps = glob.glob(os.path.join(p, test))
            if fps:
                thumb_mimetype, thumb_type = utils.utils.getMimeType(fps[0])
                return _request_handler.sendFile(req, fps[0], thumb_mimetype, force=1)

    return _request_handler.sendFile(req, config.basedir + "/web/img/questionmark.png", "image/png", force=1)

send_thumbnail = partial(_send_thumbnail, u"thumb")
send_thumbnail2 = partial(_send_thumbnail, u"presentation")

def _send_file_with_type(filetype, mimetype, req, checkonly=False):
    try:
        nid = node_id_from_req_path(req)
    except ValueError:
        return 400

    version_id = version_id_from_req(req)
    node = get_node_or_version(nid, version_id, Content)

    if node is None or not node.has_data_access():
        return 404

    fileobj = None
    file_query = node.files.filter_by(filetype=filetype)
    # if version_id == u"published":
    if version_id:
        file_query = file_query.filter_by(transaction_id=node.transaction_id)
        fileobj = file_query.scalar()
        # fileobj may be None if in this version only metadata changed
        # then try previous transaction_ids
        if not fileobj:
            FileVersion = version_class(File)
            # this a long lasting query
            file_query = node.files.filter_by(filetype=filetype)
            fileobj = file_query.filter(FileVersion.transaction_id <= node.transaction_id).\
                order_by(FileVersion.transaction_id.desc()).first()
    if mimetype:
        file_query = file_query.filter_by(mimetype=mimetype)

    if not fileobj:
        fileobj = file_query.scalar()
    if fileobj is not None:
        if checkonly:
            return 200
        return _request_handler.sendFile(req, fileobj.abspath, fileobj.mimetype)

    return 404

send_doc = partial(_send_file_with_type, u"document", None)

def send_image(req):
    try:
        nid, file_ext = split_image_path(req.path)
    except ValueError:
        return 400

    version_id = version_id_from_req(req)

    node = get_node_or_version(nid, version_id, Content)

    # XXX: should be has_data_access instead, see #1135
    if node is None or not node.has_read_access():
        return 404

    image_files_by_mimetype = {f.mimetype: f for f in node.files.filter_by(filetype=u"image")}

    if not image_files_by_mimetype:
        # no image files? forget it...
        return 404

    def _send(fileobj):
        return _request_handler.sendFile(req, fileobj.abspath, fileobj.mimetype)

    client_mimetype = None

    if file_ext:
        # client wants a specific mimetype
        client_mimetype = node.MIMETYPE_FOR_EXTENSION.get(file_ext)
        if not client_mimetype:
            return httpstatus.HTTP_NOT_ACCEPTABLE

        image_file = image_files_by_mimetype.get(client_mimetype)
        if image_file:
            return _send(image_file)
        else:
            return httpstatus.HTTP_NOT_ACCEPTABLE

    # figure out what we want to send, in that order:
    server_preferred_mimetypes = preference_sorted_image_mimetypes(node, iterkeys(image_files_by_mimetype))

    accept_mimetypes = _request_handler.accept_mimetypes(req)

    if accept_mimetypes:
        client_mimetype = accept_mimetypes.best_match(server_preferred_mimetypes)
        if client_mimetype:
            # file for mimetype must exist here
            image_file = image_files_by_mimetype[client_mimetype]
            return _send(image_file)
        else:
            return httpstatus.HTTP_NOT_ACCEPTABLE
    else:
        # client doesn't have any preferences, send our choice
        return _send(image_files_by_mimetype[server_preferred_mimetypes[0]])

    return 404

def send_original_file(req):
    try:
        nid = node_id_from_req_path(req)
    except ValueError:
        return 400

    version_id = version_id_from_req(req)

    node = get_node_or_version(nid, version_id, Data)

    if node is None or not node.has_data_access():
        return 404

    original_filetype = node.get_original_filetype()
    original_file = node.files.filter_by(filetype=original_filetype).scalar()
    if original_file is not None:
        return _request_handler.sendFile(req, original_file.abspath, original_file.mimetype)

    return 404

def send_file(req):
    parts = splitpath(req.path)
    if len(parts) != 2:
        return 400

    nidstr, filename = parts
    if nidstr.endswith("_transfer.zip"):
        nidstr = nidstr[:-13]

    nid = userinput.string_to_int(nidstr)
    if nid is None:
        return 400

    version_id = version_id_from_req(req)

    node = get_node_or_version(nid, version_id)

    if (node is None
            or isinstance(node, Container) and not node.has_read_access()
            or isinstance(node, Content) and not node.has_data_access()):
        return 404

    def _send_attachment(filepath, mimetype):
        file_ext = os.path.splitext(filepath)[1]
        if existMetaField(node.schema, u'nodename'):
            display_file_name = u'{}{}'.format(os.path.splitext(os.path.basename(node.name))[0], file_ext)
        else:
            display_file_name = filename
        try:
            display_file_name.encode('ascii')
        except UnicodeEncodeError:
            req.reply_headers["Content-Disposition"] = u'attachment; filename="{0}"; filename*=UTF-8\'\'{0}'.\
                format(quote(display_file_name.encode('utf8')))
        else:
            req.reply_headers["Content-Disposition"] = u'attachment; filename="{}"'.format(display_file_name)
        return _request_handler.sendFile(req, filepath, mimetype)

    if filename is None:
        # build zip-file and return it
        with tempfile.NamedTemporaryFile() as tmpfile:
            files_written = build_transferzip(tmpfile, node)
            if files_written == 0:
                return 404
            # don't enable nginx x_accel_redirect for temporary files
            return _request_handler.sendFile(req, tmpfile.name, "application/zip", nginx_x_accel_redirect_enabled=False)

    # try full filename
    for f in node.files:
        if f.base_name == filename:
            return _send_attachment(f.abspath, f.mimetype)

    archive = get_archive_for_node(node)
    if archive:
        filepath = archive.get_local_filepath(node)
        mimetype, _ = getMimeType(filepath)
        return _send_attachment(filepath, mimetype)

    else:
        # try only extension
        file_ext = os.path.splitext(filename)[1]
        for f in node.files:
            if os.path.splitext(f.base_name)[1] == file_ext and f.filetype in [u'document', u'original', u'mp3']:
                logg.warn("serving file %s for node %s only by matched extension", f.path, node.id)
                return _send_attachment(f.abspath, f.mimetype)

    return 404

def send_attachment(req):
    try:
        nid = node_id_from_req_path(req)
        version_id = version_id_from_req(req)
    except ValueError:
        return 400

    node = get_node_or_version(nid, version_id, Data)

    if (node is None
            or isinstance(node, Container) and not node.has_read_access()
            or isinstance(node, Content) and not node.has_data_access()):
        return 404

    attachment_file = node.files.filter_by(filetype=u"attachment").first()
    if attachment_file is not None:
        # filename is attachment.zip
        sendZipFile(req, file.abspath)

def send_attfile(req):
    """send single attachment file to user"""
    parts = req.path[9:].split('/')

    if len(parts) < 2:
        return 400

    nid = userinput.string_to_int(parts[0])
    if nid is None:
        return 400

    version_id = version_id_from_req(req)

    node = get_node_or_version(nid, version_id, Data)

    # XXX: why do we want to send attachments from containers?
    if (node is None
            or isinstance(node, Container) and not node.has_read_access()
            or isinstance(node, Content) and not node.has_data_access()):
        return 404

    paths = ["/".join(parts[1:]), "/".join(parts[1:-1])]
    fileobjs = [fo for fo in node.files if fo.path in paths]

    if not fileobjs:
        return 404

    fileobj = fileobjs[0]

    if fileobj.mimetype == u'inode/directory':
        # files in attachment directory cannot be found in node.files
        # so send file directly as it was made in mysql
        filename = clean_path("/".join(parts[1:]))
        path = os.path.join(config.get("paths.datadir"), filename)
        mime, type = getMimeType(filename)
        if (get_filesize(filename) > 16 * 1048576):
            req.reply_headers["Content-Disposition"] = 'attachment; filename="{}"'.format(filename)

        return _request_handler.sendFile(req, path, mime)

    if (fileobj.size > 16 * 1048576):
        req.reply_headers["Content-Disposition"] = u'attachment; filename="{}"'.format(fileobj.base_name).encode('utf8')

    return _request_handler.sendFile(req, fileobj.abspath, fileobj.mimetype)

def fetch_archived(req):
    try:
        nid = node_id_from_req_path(req)
    except ValueError:
        return 400

    node = q(Content).get(nid)

    archive = get_archive_for_node(node)
    if archive:
        try:
            archive.fetch_file_from_archive(node)
        except:
            logg.exception("exception in fetch_file_from_archive for archive %s", archive.archive_type)
            msg = "fetch archive for node failed"
            req.setStatus(500)
            req.write(msg)
        else:
            req.write('done')
    else:
        msg = "archive for node not found"
        req.setStatus(404)
        req.write(msg)
        logg.warn(msg)

    db.session.commit()

def send_from_webroot(req):
    import core.webconfig

    if core.webconfig.theme is not None:
        webroot_dirs = [core.webconfig.theme.path, "web/root"]
    else:
        webroot_dirs = ["web/root"]

    for webroot_dir in webroot_dirs:
        filepath = os.path.join(config.basedir, webroot_dir, req.path.strip("/"))
        if os.path.isfile(filepath):
            return _request_handler.sendFile(req, filepath, getMimeType(filepath)[0])

    return 404

### redirects for legacy handlers

def redirect_images(req):
    req.reply_headers["Location"] = "/image" + req.uri[7:]
    return 301


from collections import OrderedDict
from copy import copy
from struct import pack_into
from threading import Lock

from lstore.disk_helper import *
from lstore.page import Page

class Cache:
    def __init__(self, size: int, appendix: str):
        """
        :param size:
        Attributes:
            cache: OrderedDict[page_key: Tuple[bool dirty, Page]]
                page_key = base|tail-(page_index)-(column_index)
        """
        self.size = size
        self.cache = OrderedDict()
        self.last_rid = {}
        self.appendix = appendix  # In the form of 'ECS165/Grades'
        self.disk_helper = DiskHelper(appendix)

        last_base_rid, last_tail_rid = self.disk_helper.get_last_rids()
        self.last_rid['base'] = last_base_rid
        self.last_rid['tail'] = last_tail_rid

        # Use Page Latch to ensure atomic R/W operations
        # Two latches are only used in static methods __get_page and __set_page
        # One extra latch locks up the last rid
        self.set_latch = Lock()
        self.get_latch = Lock()
        self.rid_latch = Lock()

    # Public APIs

    def get_new_rid(self, range_type: str) -> bytes:
        self.rid_latch.acquire()

        page_index, byte_offset = unpack('II', self.last_rid[range_type])
        entry_offset = byte_offset // WORDSIZE

        entry_offset += 1
        if entry_offset == PAGESIZE // WORDSIZE:
            page_index += 1
            # Skips num_record in tail pages, num_record and TPS in base pages
            if range_type == 'base':
                entry_offset = 2
            elif range_type == 'tail':
                entry_offset = 1
            else:
                raise ValueError("Range Type Error")
        new_rid = pack('II', page_index, entry_offset * WORDSIZE)
        self.last_rid[range_type] = new_rid

        self.rid_latch.release()
        return new_rid

    def __del__(self):
        for key, (is_dirty, page) in self.cache.items():
            range_type, page_index, column = self.__parse_key(key)
            # No need to flush the clean pages
            if not is_dirty:
                continue
            self.disk_helper.write_page(range_type, page_index, column, page)

    def get_page(self, range_type: str, page_index: int, column: int) -> Page:
        """Interface to get a Page"""
        return self.__get_page(self.__generate_key(range_type, page_index,
                                                   column))

    def get_entry(self, range_type: str, rid: bytes, query_column: int) \
            -> bytes:
        """
        Returns the single data entry in the table.
        Args:
            range_type: 'base' | 'tail', the page range to read
            rid: the target RID of the record to read
            query_column: the index of the column to select
        Returns:
            each byte of the data in the entry
        """
        page_index, page_offset = unpack('II', rid)
        target_page = self.get_page(range_type, page_index, query_column)
        return target_page.read_field(page_offset)

    def set_page(self, range_type: str, page_index: int, column: int,
                 new_page: Page):
        """ Interface to set a Page """
        self.__set_page(self.__generate_key(range_type, page_index, column),
                        new_page)

    def set_entry(self, range_type: str, rid: bytes, query_column: int,
                  data: bytes = None, is_append: bool = False) -> None:
        """
        Return: Set entry return page to keep reference in table layer
        Sets one data entry with specified data, increments the counter of
        the page if is_append is set to True
        Args:
            range_type: 'base' | 'tail', the page range to write
            rid: the target RID of the record to write
            query_column: the index of the column to select
            data: the new data to be written, if None, then only incrementing
            counter of the page without calling Page.write_field
        """
        page_index, page_offset = unpack('II', rid)
        target_page = copy(self.get_page(range_type, page_index, query_column))
        key = self.__generate_key(range_type, page_index, query_column)

        if is_append:
            target_page.num_records += 1
            pack_into('Q', target_page.data, 0, target_page.num_records)

        if data is None:
            return

        target_page.write_field(page_offset, data)
        self.__set_page(key, target_page)
        return

    def last_page_index(self, range_type: str) -> int:
        if range_type == 'base':
            last_base_rid = self.last_rid['base']
        elif range_type == 'tail':
            last_base_rid = self.last_rid['tail']
        else:
            raise ValueError('unrecognized range_type, '
                             'expecting \'base\' or \'tail\', but got {}'
                             .format(range_type))

        last_page_index, _ = unpack('II', last_base_rid)
        return last_page_index

    # Private APIs

    def __set_page(self, key: str, val: Page):
        self.set_latch.acquire()

        if key in self.cache:
            del self.cache[key]

        self.cache[key] = (True, val)
        if len(self.cache) > self.size:
            key, (is_dirty, page) = self.cache.popitem(last=False)
            # print("Evicting: Dirty?", is_dirty)
            if not is_dirty:
                self.set_latch.release()
                return  # not writing clean pages to disks

            range_type, page_index, column = self.__parse_key(key)
            self.disk_helper.write_page(range_type, page_index, column, page)

        self.set_latch.release()

    def __get_page(self, key: str) -> Page:
        self.get_latch.acquire()

        range_type, page_index, column = self.__parse_key(key)
        if key not in self.cache:
            target_page = self.disk_helper.read_page(
                range_type, page_index, column)
            self.__set_page(key, target_page)
            self.cache[key] = (False, target_page)
            ret_page = target_page
        else:
            self.cache.move_to_end(key)
            ret_page = self.cache[key][1]

        self.get_latch.release()

        return ret_page

    @staticmethod
    def __parse_key(key: str) -> Tuple[str, int, int]:
        parsed_key = key.split('-')
        return parsed_key[0], int(parsed_key[1]), int(parsed_key[2])

    @staticmethod
    def __generate_key(range_type: str, page_index: int, column: int) -> str:
        return '-'.join((range_type, str(page_index), str(column)))


#!/usr/bin/python3
# -*- coding: UTF-8 -*-
import re
import os
import sys
import json
import argparse
from collections import Counter

class ParserLog:

    def __init__(self, filename):
        self.filename = filename
        self.regexp_url = r'00]\s".{0,}\sHTTP\/1.'
        self.search_mask_method = {"\"GET ": 0, "\"POST ": 0, "\"PUT ": 0,
                                   "\"DELETE ": 0, "\"HEAD ": 0, "\"OPTIONS ": 0,
                                   "\"CONNECT ": 0
                                   }
        self.regexp_4xx_error = r"\s4[0-9]{2}\s"
        self.regexp_5xx_error = r'"\s5[0-9]{2}\s'
        self.total_request = None
        self.dict_4xx_error = {}
        self.dict_5xx_error = {}
        self.dict_number_request = {}
        self.dict_method_number = {}
        self.log_file = self.reader()
        self.get_report_values()

    def reader(self):
        with open(self.filename) as file:
            log_file = file.read()
        return log_file

    @staticmethod
    def dict_counter(dictionary: dict, key: str) -> dict:
        if key in dictionary.keys():
            dictionary[key] += 1
        else:
            dictionary[key] = 1
        return dictionary

    @staticmethod
    def ordered_values(dictinary: dict, amount: int) -> list:
        return Counter(dictinary).most_common(amount)

    def get_report_values(self):
        string_list = self.log_file.split("\n")

        for line in string_list:
            found_matches = re.findall(self.regexp_url, line)

            if found_matches:
                list_split = found_matches[0].split(" ")
                url = list_split[2]
                method = list_split[1].split('"')[1]
                if len(method) < 8:
                    self.dict_method_number = self.dict_counter(
                        self.dict_method_number, method
                    )
                self.dict_number_request = self.dict_counter(
                    self.dict_number_request, url
                )
            self.total_request = sum(self.dict_method_number.values())
            split_line = line.split(" ")

            error_4xx = re.findall(self.regexp_4xx_error, line)
            if len(error_4xx):
                length_request = len(split_line[6])
                status_code = error_4xx[0].split(" ")[1]
                request = split_line[6]
                self.dict_4xx_error[split_line[0]] = [
                    length_request, status_code, request
                ]

            error_5xx = re.findall(self.regexp_5xx_error, line)
            if len(error_5xx):
                ip_address = split_line[0]
                self.dict_5xx_error = self.dict_counter(
                    self.dict_5xx_error, ip_address
                )

    def report_total_number_request(self):
        return f"---> Общее количество запросов: {self.total_request}\n"

    def report_total_count_method(self):
        result = f"---> Общее количество запросов по типу:\n"
        for elem in self.dict_method_number.keys():
            result += f"Метод {elem} - {self.dict_method_number[elem]}\n"
        return result

    def report_top_request(self):
        result = f"---> Топ 10 самых частых запросов:\n"
        for elem in self.ordered_values(self.dict_number_request, 10):
            result += f"{elem[0]} - {elem[1]} \n"
        return result

    def report_top_size_request_4xx(self):
        result = f"---> Топ 5 самых больших по размеру запросов, которые завершились клиентской (4ХХ) ошибкой:\n"
        for elem in self.ordered_values(self.dict_4xx_error, 5):
            result += f"IP:{elem[0]} - Длина:{elem[1][0]} - Статус код:{elem[1][1]}\n"
            result += f"Запрос: {elem[1][2]}\n ----------------------------\n"
        return result

    def report_top_ip_request_5xx(self):
        result = f"---> Топ 5 пользователей по количеству запросов, которые завершились серверной (5ХХ) ошибкой:\n"
        for elem in self.ordered_values(self.dict_5xx_error, 5):
            result += f"{elem[0]} - {elem[1]}\n"
        return result

    def get_report(self):
        result = f"Отчёт по лог файлу {self.filename}\n"
        result += self.report_total_number_request()
        result += self.report_total_count_method()
        result += self.report_top_request()
        result += self.report_top_size_request_4xx()
        result += self.report_top_ip_request_5xx()
        return result

    def get_report_json(self):
        result = [{'total_request': self.total_request}, self.dict_method_number,
                  dict(self.ordered_values(self.dict_number_request, 10)),
                  dict(self.ordered_values(self.dict_4xx_error, 5)),
                  dict(self.ordered_values(self.dict_5xx_error, 5))]

        return json.dumps(result)

    def export_report_txt(self, filename):
        with open(filename, 'w') as file:
            file.write(self.get_report())

    def export_report_json(self, filename):
        with open(filename, 'w') as file:
            file.write(self.get_report_json())

def console_parser():
    parser = argparse.ArgumentParser()
    parser.add_argument('-l', '--log', default='access.log')
    parser.add_argument('-o', '--output', default=None)
    parser.add_argument('-j', '--json', default=None)
    return parser

if __name__ == '__main__':
    parser = console_parser()
    namespace = parser.parse_args(sys.argv[1:])

    if os.path.isfile(namespace.log):
        parser_log = ParserLog(namespace.log)
        if not (namespace.output or namespace.json):
            print("The file to save the result does not exist")
            exit(1)
        if namespace.output:
            parser_log.export_report_txt(namespace.output)
            print(f'Results successfully saved to {namespace.output}')
        if namespace.json:
            parser_log.export_report_json(namespace.json)
            print(f'Results successfully saved  {namespace.json}')
    else:
        print("Log file does not exist")
        exit(1)


import datetime
from config import API_TOKEN, ADMIN_ID
from aiogram import Bot, Dispatcher, types
from aiogram.dispatcher import FSMContext
from aiogram.contrib.fsm_storage.memory import MemoryStorage
from aiogram.dispatcher.filters.state import StatesGroup, State

bot = Bot(token=API_TOKEN, parse_mode=types.ParseMode.HTML)
dp = Dispatcher(bot, storage=MemoryStorage())

class Form(StatesGroup):
    name = State()
    birth_date = State()
    adress = State()
    phone_number = State()

def valid_date(date_text: str):
    try:
        datetime.datetime.strptime(date_text, '%d.%m.%Y')
        return True
    except ValueError:
        return False

@dp.message_handler(commands='start', state='*')
async def cmd_start(message: types.Message, state: FSMContext = None) -> None:
    await state.finish()
    await message.answer(f"Assalomu alaykum {message.from_user.get_mention(as_html=True)}")
    await message.answer(f"To'liq ism-familyangizni kiriting")
    await Form.name.set()

@dp.message_handler(commands=['help', 'about'])
async def cmd_help(message: types.Message) -> None:
    await message.answer("Help")

@dp.message_handler(state=Form.name)
async def form_name(message: types.Message, state: FSMContext = None) -> None:
    await state.update_data(
        {"full_name": message.text}
    )

    await message.answer(
        "Tug'ilgan kun oy yilingizni dd.mm.yyyy formatda kiriting.\n"
        "Masalan 31.12.1999"
    )

    await Form.next()

@dp.message_handler(state=Form.birth_date)
async def form_name(message: types.Message, state: FSMContext = None) -> None:
    if valid_date(message.text):
        # To'g'ri formatda kiritildi
        await state.update_data(
            {"birth_date": message.text}
        )

        await message.answer(
            "Yashash manzilingizni kiriting.\n"
            "Viloyat, mahalla, ko'cha, xonadon"
        )

        await Form.next()

    else:
        await message.answer(
            "Noto'g'ri format!\n"
            "Iltimos qayta tekshirib dd.mm.yyyy formatda kiriting.\n"
            "Masalan 31.12.1999"
        )

@dp.message_handler(state=Form.adress)
async def enter_adress(message: types.Message, state: FSMContext):

    await state.update_data(
        {"adress": message.text}
    )

    await message.answer(
        text="Pastdagi <b>«📞Telefon raqamni yuborish»</b> tugmasini bosib telefon raqamingizni jo'nating",
        reply_markup=types.ReplyKeyboardMarkup(
            keyboard=[
                [types.KeyboardButton(text="📞Telefon raqamni yuborish", request_contact=True)]
            ],
            resize_keyboard=True,
            one_time_keyboard=True,
        )
    )

    await Form.next()

@dp.message_handler(content_types=types.ContentTypes.CONTACT, state=Form.phone_number)
async def enter_phone_number(message: types.Message, state: FSMContext):
    if message.contact.user_id == message.from_user.id:
        # o'zini kontakti
        phone_number = message.contact.phone_number
        await state.update_data(
            {"phone_number": phone_number}
        )

        datas = await state.get_data()
        name = datas['full_name']
        birth_date = datas['birth_date']
        adress = datas['adress']
        phone_number = datas['phone_number']
        if phone_number[0] != '+':
            phone_number = '+' + phone_number
        txt = [
            f"👤Foydalanuvchi: {message.from_user.get_mention(as_html=True)}",
            f"👥Ismi: {name}",
            f"📆Tug'ilgan kuni: {birth_date}",
            f"📍Manzili: {adress}",
            f"📞Tel: {phone_number}"
        ]
        m = await message.answer(
            "\n".join(txt)
        )

        await bot.send_message(
            chat_id=ADMIN_ID,
            text="\n".join(txt),
            reply_markup=types.InlineKeyboardMarkup(inline_keyboard=[
                [types.InlineKeyboardButton(text="✅Tasdiqlash", callback_data=f"ok_{message.from_user.id}")],
                [types.InlineKeyboardButton(text="❌Rad etish", callback_data=f"no_{message.from_user.id}")],
            ])
        )

        await m.reply("Sizning ma'lumotlaringiz adminga yuborildi. Tasdiqlanishini kuting.")

        await state.finish()
    else:
        await message.answer(
            text="Iltimos faqat o'zingizning telefon raqamingizni yuboring.",
            reply_markup=types.ReplyKeyboardMarkup(
                keyboard=[
                    [types.KeyboardButton(text="📞Telefon raqamni yuborish", request_contact=True)]
                ],
                resize_keyboard=True,
                one_time_keyboard=True,
            )
        )

@dp.message_handler(content_types=types.ContentTypes.ANY, state=Form.phone_number)
async def enter_phone_number_error(message: types.Message, state: FSMContext):
    await message.answer(
        text="Iltimos faqat o'zingizning telefon raqamingizni yuboring.",
        reply_markup=types.ReplyKeyboardMarkup(
            keyboard=[
                [types.KeyboardButton(text="📞Telefon raqamni yuborish", request_contact=True)]
            ],
            resize_keyboard=True,
            one_time_keyboard=True,
        )
    )

@dp.callback_query_handler(text_startswith="ok_", user_id=ADMIN_ID)
async def admin_commit(call: types.CallbackQuery):
    await call.answer("✅Tasdiqlandi")
    await call.message.edit_text(
        text=call.message.text + "\n\n✅Tasdiqlandi",
    )
    user = call.data.replace("ok_", '')
    await bot.send_message(
        chat_id=user,
        text="Sizning ma'lumotlaringiz admin tomonidan tasdiqlandi. Endi botdan foydalanishingiz mumkin."
    )

@dp.callback_query_handler(text_startswith="no_", user_id=ADMIN_ID)
async def admin_cancel(call: types.CallbackQuery):
    await call.answer("❌Rad etildi")
    await call.message.edit_text(
        text=call.message.text + "\n\n❌Rad etildi",
    )
    user = call.data.replace("no_", '')
    await bot.send_message(
        chat_id=user,
        text="Sizning ma'lumotlaringiz admin tomonidan rad etildi😕"
    )


from asyncio import gather, get_event_loop, set_event_loop, new_event_loop
from itertools import chain
from logging import getLogger
from os import getenv
from random import randint
from time import sleep

import httpx
from flask import Flask, jsonify, make_response

app = Flask(__name__)

logger = getLogger(__name__)

SOURCES_PORT = getenv("SOURCES_PORT")

async def get_source(source_id):
    async with httpx.AsyncClient() as client:
        try:
            resp = await client.get(
                f"http://127.0.0.1:{SOURCES_PORT}/source/{source_id}", timeout=2
            )
            data = resp.json()
        except httpx.ReadTimeout:
            data = []
        except Exception as e:
            logger.error(e)
            data = []
    return data

@app.route("/")
def root():
    try:
        loop = get_event_loop()
    except RuntimeError:
        loop = new_event_loop()
        set_event_loop(loop)
    result = loop.run_until_complete(gather(*[get_source(i) for i in range(1, 4)]))

    return jsonify(
        sorted(list(chain.from_iterable(result)), key=lambda item: item["id"])
    )

@app.route("/source/<source_id>")
def source(source_id):
    with open(f"sources/source{source_id}.json", "rt") as source_file:
        data = source_file.read()
    sleep(randint(0, 3))
    response = make_response(data)
    response.headers["Content-Type"] = "application/json"
    return response


from collections import deque
n = int(input())
deque = deque()
for i in range(1, n+1):
    deque.append(i)

for i in range(n):
    if len(deque) == 1:
        break
    deque.popleft()
    deque.append(deque[0])
    deque.popleft()

print(deque[0])


import pm4py

def execute_script():
    log = pm4py.read_xes("../tests/input_data/receipt.xes")
    fea_df = pm4py.extract_features_dataframe(log, include_case_id=True)
    # sets the case ID as index for the dataframe, so a row for a specific case
    # can be retrieved
    fea_df.set_index("case:concept:name", inplace=True)
    # identifies the features for the case with identifier "case-10017"
    features_per_case = fea_df.loc["case-10017"].to_dict()
    print(features_per_case)

if __name__ == "__main__":
    execute_script()


import json
from flask import Blueprint, jsonify, request
from hashlib import md5

from quiz.models import db, Test, Assessment, Question, Answer, Response

api = Blueprint('api', __name__)

@api.route('/test/<int:test_id>/', methods=('GET',))
def get_test(test_id):
    test = Test.query.get(test_id)
    return jsonify(test.to_dict())

@api.route('/assessment/<string:user_hash>/', methods=('POST',))
def continue_assessment(user_hash):
    return Assessment.query.get(user_hash=user_hash)

@api.route('/assessment/', methods=('POST',))
def create_assessment():
    data = request.get_json()
    user_hash = md5()
    user_hash.update(json.dumps(data).encode())
    assessment = Assessment(
        fname=data['fname'],
        lname=data['lname'],
        email=data['email'],
        test_id=data['test_id'],
        user_hash=user_hash.hexdigest())
    db.session.add(assessment)
    db.session.commit()
    return jsonify(assessment.to_dict()), 201

@api.route('/test/', methods=('POST',))
def create_test():
    data = request.get_json()
    questions = []

    for q in data['questions']:
        answers = []
        for answer in q['answers']:
            answer = Answer(
                answer=answer['answer'],
                is_correct=answer.get('is_correct'))
            answers.append(answer)

        q = Question(
            question=q['question'],
            answers=answers)
        questions.append(q)

    duration = data['duration']

    test = Test(name=data['name'], questions=questions, duration=duration)
    db.session.add(test)
    db.session.commit()
    return jsonify(test.to_dict()), 201

@api.route('/response/', methods=('POST',))
def create_response():
    data = request.get_json()
    assessment = Assessment.query.get(data['assessment'])
    question = Question.query.get(data['question'])
    answer = Answer.query.get(data['answer'])
    test_response = Response(
        assessment=assessment,
        question=question,
        answer=answer)
    db.session.add(test_response)
    db.session.commit()
    return jsonify(test_response.to_dict()), 201


"""GRASP-based algorithm class definitions."""

from __future__ import (
    annotations,
)

import logging
from random import (
    Random,
)
from typing import (
    TYPE_CHECKING,
)

from ...models import (
    Planning,
)
from ..abc import (
    Algorithm,
)
from .iterative import (
    IterativeAlgorithm,
)
from .sequential import (
    SequentialAlgorithm,
)

if TYPE_CHECKING:
    from typing import (
        Dict,
        Any,
        Tuple,
        Type,
    )

logger = logging.getLogger(__name__)

class GraspAlgorithm(Algorithm):
    """GRASP algorithm implementation.

    This implementation is based on the Greedy Randomized Adaptive Search Procedure meta-heuristic. For more information
    about how it works, you can visit the following link:
    https://en.wikipedia.org/wiki/Greedy_randomized_adaptive_search_procedure
    """

    def __init__(
        self,
        no_improvement_threshold: int = 1,
        first_solution_kwargs: Dict[str, Any] = None,
        local_search_kwargs: Dict[str, Any] = None,
        seed: int = 56,
        *args,
        **kwargs
    ):
        """Construct a new instance.

        :param no_improvement_threshold: Manages the number of allowed iterations without any improvement.
        :param first_solution_kwargs: Named arguments for the first solution algorithm.
        :param local_search_kwargs: Named arguments for the local search algorithm.
        :param seed: A seed to manage randomness.
        :param args: Additional positional arguments.
        :param kwargs: Additional named arguments.
        """
        super().__init__(*args, **kwargs)

        if first_solution_kwargs is None:
            first_solution_kwargs = dict()
        if local_search_kwargs is None:
            local_search_kwargs = dict()

        self.no_improvement_threshold = no_improvement_threshold
        self.first_solution_kwargs = first_solution_kwargs
        self.local_search_kwargs = local_search_kwargs
        self.random = Random(seed)
        self.args = args
        self.kwargs = kwargs

    def _build_first_solution_algorithm(self, **kwargs) -> Tuple[Type[Algorithm], Dict]:
        kwargs.update(self.first_solution_kwargs.copy())
        if "fleet" not in kwargs:
            kwargs["fleet"] = self.fleet
        if "job" not in kwargs:
            kwargs["job"] = self.job
        return IterativeAlgorithm, kwargs

    def _build_local_search_algorithm(self, **kwargs) -> Tuple[Type[Algorithm], Dict]:
        kwargs.update(self.local_search_kwargs.copy())
        if "fleet" not in kwargs:
            kwargs["fleet"] = self.fleet
        if "job" not in kwargs:
            kwargs["job"] = self.job
        kwargs["algorithm_cls"] = SequentialAlgorithm
        kwargs["restart_mode"] = False
        kwargs["episodes"] = 3
        return IterativeAlgorithm, kwargs

    def _optimize(self) -> Planning:
        algorithm = IterativeAlgorithm(
            algorithm_cls=SequentialAlgorithm,
            algorithms_cls=[self._build_first_solution_algorithm(), self._build_local_search_algorithm()],
            *self.args,
            **self.kwargs
        )
        result = algorithm.optimize()
        return result.planning


#! /usr/bin/env python3
#-*- coding: UTF-8 -*-

### Legal
#
# Author:  Thomas DEBESSE <dev@illwieckz.net>
# License: ISC
#

import sys
from colorama import Fore, Style, init

# keep an eye on the default Python's print function
_print = print

verbosity = None

def laconic(message):
	if sys.stdout.isatty():
		message = Fore.GREEN + message + Style.RESET_ALL
	_print(message)

def print(message):
	if verbosity != "laconic":
		if sys.stdout.isatty():
			message = Fore.GREEN + message + Style.RESET_ALL
		_print(message)

def verbose(message):
	if verbosity == verbose:
		if sys.stdout.isatty():
			message = Style.DIM + message + Style.RESET_ALL

		_print(message)

def warning(message):
	message = "Warning: " + message

	if sys.stdout.isatty():
		message = Fore.YELLOW + message + Style.RESET_ALL

	_print(message)

def help(message, exit=False):
	message = "Help: " + message

	if sys.stdout.isatty():
		message = Fore.MAGENTA + message + Style.RESET_ALL

	_print(message)

	if exit:
		raise SystemExit()

def notice(message):
	message = "Notice: " + message

	if sys.stdout.isatty():
		message = Fore.CYAN + message + Style.RESET_ALL

	_print(message)

def error(message, silent=False, exit=True):
	_message = message
	message = "Error: " + message

	if sys.stdout.isatty():
		message = Fore.RED + message + Style.RESET_ALL
	_print(message)

	if exit:
		if silent:
			raise SystemExit()
		else:
			raise ValueError(_message)