import re
import logging
import sys
import os

import yaml
from rdflib import ConjunctiveGraph, Literal, URIRef, BNode, Namespace

from dipper.graph.Graph import Graph as DipperGraph
from dipper.utils.CurieUtil import CurieUtil
from dipper import curie_map as curie_map_class
from dipper.models.BiolinkVocabulary import BioLinkVocabulary as blv

LOG = logging.getLogger(__name__)

class RDFGraph(DipperGraph, ConjunctiveGraph):
    """
    Extends RDFLibs ConjunctiveGraph
    The goal of this class is wrap the creation
    of triples and manage creation of URIRef,
    Bnodes, and literals from an input curie
    """

    curie_map = curie_map_class.get()
    curie_util = CurieUtil(curie_map)

    # make global translation table available outside the ingest
    with open(
        os.path.join(
            os.path.dirname(__file__),
            '../../translationtable/GLOBAL_TERMS.yaml')) as fhandle:
        globaltt = yaml.safe_load(fhandle)
        globaltcid = {v: k for k, v in globaltt.items()}

    def __init__(self, are_bnodes_skized=True, identifier=None):
        # print("in RDFGraph  with id: ", identifier)
        super().__init__('IOMemory', identifier)
        self.are_bnodes_skized = are_bnodes_skized
        self.prefixes = set()

        # Can be removed when this is resolved
        # https://github.com/RDFLib/rdflib/issues/632
		# 2020 oct. possibly fixed
        # for pfx in ('OBO',):  # , 'ORPHA'):
        #    self.bind(pfx, Namespace(self.curie_map[pfx]))

    def _make_category_triple(
            self, subject, category, predicate=blv.terms['category']
    ):
        """
        add a triple to capture subject or object category (in CURIE form) that was
        passed to addTriple()
        """
        try:
            self.add((
                self._getnode(subject),
                self._getnode(predicate),
                self._getnode(category)))
        except:
            LOG.warning(
                "Problem adding triple in _makeCategoryTriple for " + \
                "subj: %s pred: %s obj(category): %s",
                subject, predicate, category)

    def _is_literal(self, thing):
        """
        make inference on type (literal or CURIE)

        return: logical
        """
        if self.curie_regexp.match(thing) is not None or\
           thing.split(':')[0].lower() in ('http', 'https', 'ftp'):
            object_is_literal = False
        else:
            object_is_literal = True

        return object_is_literal

    def addTriple(
            self,
            subject_id,
            predicate_id,
            obj,
            object_is_literal=None,
            literal_type=None,
            subject_category=None,
            object_category=None
    ):

        if object_is_literal is None:
            object_is_literal = self._is_literal(obj)

        # add triples for subject category info
        if subject_category is not None:
            self._make_category_triple(subject_id, subject_category)

        # add triples for obj category info, if obj is not a literal
        if not object_is_literal:
            if object_category is not None:
                self._make_category_triple(obj, object_category)
        else: # emit warning if object category is given for a literal
            if object_category is not None:
                LOG.warning("I was given a category %s for obj: %s, " +
                            "which seems to be a literal!",
                            object_category, obj)

        if object_is_literal is True:
            if isinstance(obj, str):
                re.sub(r'[\t\n\r\f\v]+', ' ', obj)  # reduce any ws to a space
            if literal_type is not None and obj is not None and obj not in ("", " "):
                literal_type_iri = self._getnode(literal_type)

                self.add(
                    (self._getnode(subject_id), self._getnode(predicate_id),
                     Literal(obj, datatype=literal_type_iri)))
            elif obj is not None:
                # could attempt to infer a type here but there is no use case
                self.add((
                    self._getnode(subject_id), self._getnode(predicate_id),
                    Literal(obj)))
            else:
                LOG.warning(
                    "None as literal object for subj: %s and pred: %s",
                    subject_id, predicate_id)
                # get a sense of where the None is comming from
                # magic number here is "steps up the call stack"
                # TODO there may be easier/ideomatic ways to do this now
                for call in range(2, 0, -1):
                    LOG.warning(
                        '\t%sfrom: %s', '\t' * call, sys._getframe(call).f_code.co_name)

        elif obj is not None and obj != '':  # object is a resource
            self.add((
                self._getnode(subject_id),
                self._getnode(predicate_id),
                self._getnode(obj)))
        else:
            LOG.warning(
                "None/empty object IRI for subj: %s and pred: %s",
                subject_id, predicate_id)

    def skolemizeBlankNode(self, curie):
        stripped_id = re.sub(r'^_:|^_', '', curie, 1)
        return URIRef(self.curie_map['BNODE'] + stripped_id)

    def _getnode(self, curie):
        """
        This is a wrapper for creating a URIRef or Bnode object
        with a given a curie or iri as a string.

        If an id starts with an underscore, it assigns it to a BNode, otherwise
        it creates it with a standard URIRef.
        Alternatively, self.skolemize_blank_node is True,
        it will skolemize the blank node

        :param curie: str identifier formatted as curie or iri
        :return: node: RDFLib URIRef or BNode object
        """
        node = None
        if curie[0] == '_':
            if self.are_bnodes_skized:
                node = self.skolemizeBlankNode(curie)
            else:  # delete the leading underscore to make it cleaner
                node = BNode(re.sub(r'^_:|^_', '', curie, 1))

        # Check if curie string is actually an IRI
        elif curie[:4] == 'http' or curie[:3] == 'ftp' or curie[:4] == 'jdbc':
            node = URIRef(curie)
        else:
            iri = RDFGraph.curie_util.get_uri(curie)
            if iri is not None:
                node = URIRef(iri)
                # Bind prefix map to graph
                prefix = curie.split(':')[0]
                self.prefixes.add(prefix)
            else:
                LOG.error("couldn't make URI for %s", curie)
                # get a sense of where the CURIE-ish? thing is comming from
                # magic number here is "steps up the call stack"
                for call in range(3, 0, -1):
                    LOG.warning(
                        '\t%sfrom: %s', '\t' * call, sys._getframe(call).f_code.co_name)
        return node

    def bind_all_namespaces(self):
        """
            Results in the RDF @prefix directives for every ingest
            being added to this ingest.
        """
        for prefix in self.curie_map.keys():
            iri = self.curie_map[prefix]
            self.bind(prefix, Namespace(iri))

    # serialize() conflicts between rdflib & Graph.serialize abstractmethod
    # GraphUtils expects the former.  (too bad there is no multiple dispatch)
    # rdflib version
    def serialize(
            self, destination=None, format='turtle', base=None, encoding=None
    ):
        for prefix in self.prefixes:
            mapped_iri = self.curie_map[prefix]
            self.bind(prefix, Namespace(mapped_iri))
        return ConjunctiveGraph.serialize(self, destination, format)


from pathlib import Path
from shutil import move
from threading import Thread
import logging

folders = []
extensions = []

def grabs_folder(path: Path):
    for el in path.iterdir():
        if el.is_dir():
            folders.append(el)
            grabs_folder(el)

def sort_file(path: Path):
    for el in path.iterdir():
        if el.is_file():
            ext = el.suffix
            new_path = base_folder / ext
            try:
                new_path.mkdir(exist_ok=True, parents=True)
                move(el, new_path / el.name)
            except OSError as e:
                logging.error(e)

def del_empty_folders(path: Path):
    for el in path.iterdir():
        if el.is_dir():
            try:
                el.rmdir()
            except OSError:
                pass

if __name__ == '__main__':
    logging.basicConfig(level=logging.DEBUG, format="%(threadName)s %(message)s")
    base_folder = Path(input('Type path to folder:'))

    folders.append(base_folder)
    grabs_folder(base_folder)
    threads = []
    for folder in folders:
        th = Thread(target=sort_file, args=(folder,))
        th.start()
        threads.append(th)

    [th.join() for th in threads]
    del_empty_folders(base_folder)
    print('The process has been finished successfully')


import importlib
import sys
from unittest import mock

class MockConfig:
	def __init__(self):
		self.bot = mock.MagicMock()
		self.state = mock.Mock()

def set_up_class(cls, *module_names):
	mock_config = MockConfig()
	sys.modules['config'] = mock_config
	try:
		for module_name in module_names:
			module = importlib.import_module(module_name)
			setattr(cls, module_name, module)
	except Exception:
		del sys.modules['config']
		raise

def tear_down_class(cls):
	del sys.modules['config']


import numpy as np
import numpy.random
import matplotlib.pyplot as plt
import scipy.optimize

def jj_cpr_ballistic(gamma, tau):
    return np.sin(gamma) / np.sqrt(1 - tau * np.sin(gamma/2)**2)

def jj_free_energy_ballistic(gamma, tau):
    return 4 / tau * (1 - np.sqrt(1 - tau * np.sin(gamma/2)**2))

# d/dγ I(γ)
def jj_diff_ballistic(gamma, tau):
    nom_vals = 1 - tau * np.sin(gamma / 2)**2
    return 1/4 * tau * np.sin(gamma)**2 / (nom_vals)**(3/2) + \
        np.cos(gamma) / np.sqrt(nom_vals)

def _normalize_phase(phi):
    phi = np.fmod(phi, 2 * np.pi)
    phi = np.where(phi < 0, phi + 2 * np.pi, phi)
    # normalize to (-pi, pi)
    phi = np.where(phi > np.pi, phi - 2*np.pi, phi)
    return phi

class network:
    def __init__(self, Nx, Ny, diff_x=None, diff_y=None, *, cpr_x, cpr_y, free_energy_x, free_energy_y):
        self.Nx = Nx
        self.Ny = Ny
        self.cpr_x = cpr_x
        self.cpr_y = cpr_y
        self.free_energy_x = free_energy_x
        self.free_energy_y = free_energy_y
        self.diff_x = diff_x
        self.diff_y = diff_y

        self.island_x_coords, self.island_y_coords = np.meshgrid(np.arange(Nx), np.arange(Ny), indexing="ij")
        self.phi_matrix = np.zeros((Nx, Ny), dtype=np.float32)
        self.set_frustration(0)

    def reset_network(self):
        self.phi_matrix *= 0
        self.set_frustration(0)

    def set_random_state(self):
        self.phi_matrix = np.float32(2 * np.pi * numpy.random.rand(self.Nx, self.Ny))

    def set_frustration(self, f):
        Nx = self.Nx
        Ny = self.Ny
        A_x = np.linspace(0, -(Ny-1) * f, Ny) + (Ny - 1)/2 * f
        A_x = np.tile(A_x, (Nx - 1, 1))
        A_y = np.linspace(0, (Nx-1) * f, Nx) - (Nx-1)/2 * f
        A_y = np.tile(A_y, (Ny - 1, 1)).T

        self.A_x = np.float32(-np.pi * A_x)
        self.A_y = np.float32(-np.pi * A_y)

    def add_phase_gradient(self, d_phi):
        for i in range(self.Nx):
            for j in range(self.Ny):
                self.phi_matrix[i,j] += d_phi * (i + 1)

    def add_vortex(self, x0, y0, vorticity=1):
        self.phi_matrix += vorticity * np.arctan2(self.island_y_coords - y0,
                                                  self.island_x_coords - x0)

    def get_gamma_matrices(self):
        Nx = self.Nx
        Ny = self.Ny
        gamma_x = np.zeros((Nx - 1, Ny))
        gamma_y = np.zeros((Nx, Ny - 1))

        gamma_x += self.A_x
        gamma_y += self.A_y

        phi_matrix = self.phi_matrix
        gamma_x +=  phi_matrix[1:,:] - phi_matrix[:-1,:]
        gamma_y += phi_matrix[:,1:] - phi_matrix[:,:-1]
        return (gamma_x, gamma_y)

    def get_current_matrices(self):
        gamma_x, gamma_y = self.get_gamma_matrices()
        return self.cpr_x(gamma_x), self.cpr_y(gamma_y)

    def get_current(self):
        I_x, I_y = self.get_current_matrices()
        return np.sum(I_x[0,:])

    def free_energy(self):
        gamma_x, gamma_y = self.get_gamma_matrices()
        return np.sum(self.free_energy_x(gamma_x)) + \
            np.sum(self.free_energy_y(gamma_y))

    def winding_number(self):
        # integrate grad φ around the array
        phi_matrix = self.phi_matrix
        rv = 0
        # bottom edge
        rv += np.sum(_normalize_phase(phi_matrix[1:,0] - phi_matrix[:-1,0]))
        # right edge
        rv += np.sum(_normalize_phase(phi_matrix[-1,1:] - phi_matrix[-1,:-1]))
        # top edge
        rv += -np.sum(_normalize_phase(phi_matrix[1:,-1] - phi_matrix[:-1,-1]))
        # left edge
        rv += -np.sum(_normalize_phase(phi_matrix[0,1:] - phi_matrix[0,:-1]))
        return rv

    def plot_phases(self):
        plt.clf()
        m = self.phi_matrix.copy()
        m = np.flip(m, axis=1)
        m = np.swapaxes(m, 0, 1)
        plt.imshow(m/np.pi, aspect='equal', cmap='gray')
        plt.colorbar(format="%.1f", label='φ')

    def plot_currents(self):
        Nx = self.Nx
        Ny = self.Ny
        x_currents, y_currents = self.get_current_matrices()

        x_current_xcoords, x_current_ycoords = np.meshgrid(np.arange(Nx-1), np.arange(Ny), indexing="ij")
        x_current_xcoords = x_current_xcoords.astype('float64')
        x_current_ycoords = x_current_ycoords.astype('float64')
        x_current_xcoords += 0.5
        y_current_xcoords, y_current_ycoords = np.meshgrid(np.arange(Nx), np.arange(Ny-1), indexing="ij")
        y_current_xcoords = y_current_xcoords.astype('float64')
        y_current_ycoords = y_current_ycoords.astype('float64')
        y_current_ycoords += 0.5
        plt.clf()
        plt.quiver(x_current_xcoords, x_current_ycoords,
           x_currents, np.zeros(x_currents.shape),
           pivot='mid', units='width', scale=5*Nx, width=1/(30*Nx))
        plt.quiver(y_current_xcoords, y_current_ycoords,
           np.zeros(y_currents.shape), y_currents,
           pivot='mid', units='width', scale=5*Nx, width=1/(30*Nx))
        plt.scatter(self.island_x_coords, self.island_y_coords, marker='s', c='b', s=5)

    # do not use newton solver? simple gradient descent seems to converge
    # with similar speed when using an optimized ε parameter
    def optimization_step_newton(self):
        # phi -> phi - cpr(phi) / cpr'(phi)

        Nx = self.Nx
        Ny = self.Ny
        phi_matrix = self.phi_matrix

        A_x = self.A_x
        A_y = self.A_y
        cpr_x = self.cpr_x
        cpr_y = self.cpr_y
        diff_x = self.diff_x
        diff_y = self.diff_y

        for i in range(Nx):
            for j in range(Ny):
                I_prime = 0
                I = 0
                phi_i_j = phi_matrix[i,j]
                # y-component
                if j > 0:
                    gamma = phi_i_j - phi_matrix[i,j-1] + A_y[i, j-1]
                    I += cpr_y(gamma)
                    I_prime += diff_y(gamma)
                if j < Ny - 1:
                    gamma = -phi_i_j + phi_matrix[i,j+1] + A_y[i,j]
                    I += -cpr_y(gamma)
                    I_prime += diff_y(gamma)
                # x-component
                if i == 0:
                    gamma = phi_i_j - self.phi_l + A_x[0, j]
                    I += cpr_x(gamma)
                    I_prime += diff_x(gamma)

                    gamma = -phi_i_j + phi_matrix[i+1, j] + A_x[1,j]
                    I += -cpr_x(gamma)
                    I_prime += diff_x(gamma)

                elif i == Nx - 1:
                    gamma = -phi_i_j + self.phi_r + A_x[i+1, j]
                    I += -cpr_x(gamma)
                    I_prime += diff_x(gamma)

                    gamma = phi_i_j - phi_matrix[i-1, j] + A_x[i,j]
                    I += cpr_x(gamma)
                    I_prime += diff_x(gamma)
                else:
                    gamma = -phi_i_j + phi_matrix[i+1,j]+ A_x[i+1, j]
                    I += -cpr_x(gamma)
                    I_prime += diff_x(gamma)

                    gamma = phi_i_j - phi_matrix[i-1, j]+ A_x[i,j]
                    I += cpr_x(gamma)
                    I_prime += diff_x(gamma)

                new_phi = phi_i_j - I / I_prime
                phi_matrix[i, j] = new_phi

        return np.abs(I)

    def optimization_step(self, optimize_leads=False, temp=0, fix_contacts=False, epsilon=0.4):
        # minimize free energy f(phi) using gradient descent
        # update all phi's in-place
        # phi -> phi - ε f'(phi)

        Nx = self.Nx
        Ny = self.Ny
        phi_matrix = self.phi_matrix

        A_x = self.A_x
        A_y = self.A_y
        cpr_x = self.cpr_x
        cpr_y = self.cpr_y

        I_norm = 0

        for i in range(Nx):
            if fix_contacts and (i == 0  or i == Nx - 1):
                continue
            for j in range(Ny):
                f_prime = 0
                phi_i_j = phi_matrix[i,j]

                # x-component
                if i > 0:
                    f_prime += cpr_x(phi_i_j - phi_matrix[i-1, j]+ A_x[i-1,j])
                if i < Nx - 1:
                    f_prime += -cpr_x(-phi_i_j + phi_matrix[i+1,j]+ A_x[i, j])

                # y-component
                if j > 0:
                    f_prime += cpr_y(phi_i_j - phi_matrix[i,j-1] + A_y[i, j-1])
                if j < Ny - 1:
                    f_prime += -cpr_y(-phi_i_j + phi_matrix[i,j+1] + A_y[i,j])

                new_phi = phi_i_j - epsilon * f_prime
                if temp > 0:
                    new_phi += temp * numpy.random.randn()
                phi_matrix[i, j] = new_phi
                I_norm += np.abs(f_prime)
        return I_norm / (Nx * Ny)

    def find_ground_state(self, T_start=0.35, N_max=5000, *args, **kwargs):
        # annealing schedule
        for i in range(N_max):
            temp = T_start * (N_max - i) / N_max
            delta = self.optimization_step(temp=temp)
            print("temp = %g\ndelta = %g" % (temp, delta))
        # converge
        return self.optimize(temp = 0, *args, **kwargs)

    def optimize(self, maxiter=10000, delta_tol=1e-2, *args, **kwargs):
        for i in range(maxiter):
            delta = self.optimization_step(*args, **kwargs)
            if i % 100 == 0:
                print("i = %d, delta = %.3g" % (i, delta))
            if delta < delta_tol:
                print("i(final) = %d, delta(final) = %.3g" % (i, delta))
                break
        return delta


import tweepy
import tweeting
import argparse
from time import sleep

parser = argparse.ArgumentParser(description="Tweet news stories periodically according to global priorities.")
parser.add_argument('-dbg_mode', default=False, type=bool, nargs=1, help="Run in debug mode (default = False)")
parser.add_argument('-tw_cred', default='twitter_API_keys.txt', type=str, nargs=1,
                    help="Contains Twitter API credentials. Must be in directory above repo.")
parser.add_argument('-news_cred', default='newsapi_key.txt', type=str, nargs=1,
                    help="Contains NewsAPI key. Must be in directory above repo.")
parser.add_argument('-url_path', default='url_content_lookup.csv', type=str, nargs=1,
                    help="Directory of the url lookup table")
parser.add_argument('-qaly_path', type=str, nargs=1, default='global_prios/global_prios.csv',
                    help="Path to the QALY table (default =global_prios/global_prios.csv)")
parser.add_argument('-db_filename', default='news.db', type=str, nargs=1,
                    help="Name of news database. Default = news.db")

parser.add_argument('-periodicity_s', default=3600, type=float, nargs=1,
                    help="Tweet periodicity (s). Default=3600.")
parser.add_argument('-max_time', default=7*24*3600, type=float, nargs=1,
                    help="Duration to tweet (s). Default=604800 (1 week).")
parser.add_argument('-tweet_time_window', default=2*7*24.0, type=float, nargs=1,
                    help="Time window to search into the past for news (hours). Default=336 (2 weeks).")
parser.add_argument('-news_refresh_period', default=24.0/3, type=float, nargs=1,
                    help="Periodicity to update news database (hours). Default = 8.")

args = parser.parse_args()
dbg_mode = args.dbg_mode
twitter_credentials_filename = args.tw_cred
news_api_filename = args.news_cred
url_path = args.url_path
qaly_path = args.qaly_path
db_filename = args.db_filename
periodicity_s = args.periodicity_s
max_time = args.max_time
tweet_time_window = args.tweet_time_window
news_refresh_period = args.news_refresh_period

credentials_dir = '../'

# Parse twitter credentials from the text file, see https://developer.twitter.com/en/apps
fp = open(credentials_dir+twitter_credentials_filename, 'r')
credentials = fp.read().splitlines()
fp.close()

consumer_token = credentials[0].split('=')[1]
consumer_secret = credentials[1].split('=')[1]
access_token = credentials[2].split('=')[1]
access_token_secret = credentials[3].split('=')[1]

# Get news API key
fp = open(credentials_dir+news_api_filename, 'r')
api_key = fp.read().split()[0]

# Set twitter credentials
auth = tweepy.OAuthHandler(consumer_token, consumer_secret)
auth.set_access_token(access_token, access_token_secret)
tweepyapi = tweepy.API(auth)

while True:
    tweeting.tweet_news(tweepyapi, api_key, qaly_path, url_path,
                        db_filename, tweet_time_window, news_refresh_period,
                        dbg_mode=dbg_mode)
    sleep(periodicity_s)


# reading file name
fn = input('Enter file name: ')
# making sure user enters valid file name
try:
    fh = open(fn)
except:
    print('Invalid Name')
    quit()
# creating dictionary & list
counts = dict()
lst = list()
# reading through the file
for ln in fh:
# finding the required line
    if ln.startswith('From '):
        ln = ln.rstrip()
        ln = ln.split()
# extracting the hours
        ln.pop(0)
        ln.pop(0)
        ln.pop(0)
        ln.pop(0)
        ln.pop(0)
        ln.pop(1)
        hrs = ln[0]
# extracting only the hour data
        hrs = hrs.split(':')
        hrs.pop(1)
        hrs.pop(1)
# counting the number of hours
        for hrc in hrs:
            counts[hrc] = counts.get(hrc, 0) + 1
# sorting the count by hours and printing the data
for k, v in sorted(counts.items()):
    print(k, v)


# ---------------------------------------------------------------------------- #
#                                                                              #
# 	Module:       main.py                                                      #
# 	Author:       oscarmccullough                                              #
# 	Created:      Thu Sep 15 2022                                              #
# 	Description:  V5 project                                                   #
#                                                                              #
# ---------------------------------------------------------------------------- #

# Library imports
from vex import *

# Brain should be defined by default
brain=Brain()

# define threewireport, makes defining threewireports easier
ThreeWirePort = brain.three_wire_port

#toggle variable example
pneumaticsToggle = False
# define all motors and devices here

# motors example
# name = Motor(PORT, GearSetting, reversed)
frontLeft = Motor(Ports.PORT1, GearSetting.RATIO_18_1, True)
backLeft = Motor(Ports.PORT2, GearSetting.RATIO_18_1, True)
frontRight = Motor(Ports.PORT10, GearSetting.RATIO_18_1, False)
backRight = Motor(Ports.PORT20, GearSetting.RATIO_18_1, False)

# use motor_groups to group together motors on the same side
leftDrive = MotorGroup(frontLeft, backLeft)
rightDrive = MotorGroup(frontRight, backRight)

# controller example - controller = Controller(ControllerType.PRIMARY | PARTNER )
controller = Controller(ControllerType.PRIMARY)

# inertial sensor example - imu = Inertial(PORT)
imu = Inertial(Ports.PORT15)

# pneumatics example pneu1 = Pneumatics(ThreeWirePort)
pneu1 = Pneumatics(ThreeWirePort.a)

# RotationSensor Example rot1 = Rotation(PORT)
rot1 = Rotation(Ports.PORT12)

# function callbacks - useful for button.pressed
def toggle_pneumatics():
    global pneumaticsToggle
    pneumaticsToggle = not pneumaticsToggle

# define callbacks for when a button is pressed
controller.buttonL1.pressed(toggle_pneumatics)

brain.screen.print("Hello V5\n")

# When using an inertial sensor, you need to calibrate it
def imu_calibrate():
    global imu
    #start calibrating
    imu.calibrate()
    while imu.is_calibrating():
        wait(50, MSEC)

# pre-autonomous function - this runs before a match starts and is where sensors are initialized, rezeroed, etc.
def pre_autonomous():
    brain.screen.clear_screen()
    brain.screen.print("Entering Pre-Auton\n")
    # Call our IMU Sensor Calibration
    imu_calibrate()

# autonomous function - this runs your autonomous code, the 15 seconds at the start of the match
def autonomous():
    brain.screen.clear_screen()
    brain.screen.print("Autonomous...\n")

# usercontrol - this runs your driver code, or the last 1:45 of the match
def user_control():
    brain.screen.clear_screen()

    # add a while loop to ensure everything stays running
    while True:

        # Tank Drive, independent control of left and right side
        # Axis 3 - Y-Axis on Left Joystick, Axis 2 - Y-Axis on Right Joystick

        leftDrive.spin(FORWARD, controller.axis3.position(), VelocityUnits.PERCENT)
        rightDrive.spin(FORWARD, controller.axis2.position(), VelocityUnits.PERCENT)

        # Arcade Drive - Y-Axis controls vertical movement, X-Axis controls horizontal
        # Axis 4 - X-Axis on Left Joystick, Axis 1 - X-Axis on Right Joystick
        # define variables for vertical and horizontal movement
        # uncomment these lines if you want to use arcade drive
        # vertical = controller.axis3.position()
        # horizontal = controller.axis1.position()
        # leftDrive.spin(FORWARD, vertical - horizontal, VelocityUnits.PERCENT)
        # rightDrive.spin(FORWARD, vertical + horizontal, VelocityUnits.PERCENT)

        # running pneumatics with toggle and callback
        if pneumaticsToggle:
            pneu1.open
        else:
            pneu1.close
        wait(10, MSEC)

# Define competition control instance
comp = Competition(user_control, autonomous)
pre_autonomous()


"""
Handle photobooth configuration.
"""

import os
import sys
import logging
import yaml

class Configuration:
    """
    Create configuration object.
    """

    def __init__(self, file):
        self.logger = logging.getLogger(__name__)
        self.file = file
        self._get_config()

    def _get_config(self):
        """
        Try to extract configuration from YAML file
        """
        try:
            # Open configuration file and load YAML
            with open(self.file, 'r', encoding="utf-8") as f_cfg:
                self.logger.debug("Load %s configuration file.", self.file)
                config = yaml.load(f_cfg)

            # Set configuration attribute
            self.resolution = config['resolution']
            self.pictures_directory = os.path.expanduser(config['pictures_directory'])

            # Set meta for each language
            for lang in config['languages'].keys():
                logging.debug("Set lang [%s]", config['languages'])
                setattr(self, lang, config['languages'][lang])

        except KeyError as key_e:
            self.logger.error("Parameters missing in configuration file: %s.", key_e, exc_info=True)
            sys.exit(2)
        except (OSError, yaml.YAMLError):
            self.logger.error("Failed to parse configuration file", exc_info=True)
            sys.exit(2)


# @PascalPuchtler

# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at

#     http://www.apache.org/licenses/LICENSE-2.0

# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ==============================================================================

# This class is inspired by https://github.com/EdjeElectronics/TensorFlow-Lite-Object-Detection-on-Android-and-Raspberry-Pi/blob/master/TFLite_detection_webcam.py
class ObjectDetection:

    def __init__(self, objectDetectionNetwork, labelPath):
        self.objectDetectionNetwork = objectDetectionNetwork
        self.labels = self.getLabels(labelPath)

    def analyseImage(self, image):
        boxes, classes, scores = self.objectDetectionNetwork.analyseImage(image)
        imH=image.shape[0]
        imW=image.shape[1]
        pylons = self.filterAndLabelBoxes(boxes, classes, scores, imH, imW )
        return pylons

    def filterAndLabelBoxes(self, boxes, classes, scores, imH, imW, minConfThreshold = 0.5):
        # Loop over all detections and draw detection box if confidence is above minimum threshold
        objects = []
        for i in range(len(scores)):
            if ((scores[i] > minConfThreshold) and (scores[i] <= 1.0)):
                label = str(int(classes[i]))
                if int(classes[i]) < len(self.labels):
                    label = self.labels[int(classes[i])]
                objects.append({
                'ymin': int(max(1,(boxes[i][0] * imH))),
                'xmin': int(max(1,(boxes[i][1] * imW))),
                'ymax': int(min(imH,(boxes[i][2] * imH))),
                'xmax': int(min(imW,(boxes[i][3] * imW))),
                'label': label,
                'score': scores[i]
                })
        return objects

    def getLabels(self, labelPath):
        with open(labelPath, 'r') as f:
            labels = [line.strip() for line in f.readlines()]

            # Have to do a weird fix for label map if using the COCO "starter model" from
            # https://www.tensorflow.org/lite/models/object_detection/overview
            # First label is '???', which has to be removed.
            if labels[0] == '???':
                del(labels[0])
        return labels


# https://leetcode.com/problems/word-search-ii/
"""
Time complexity:- O(N * M * W), where N and M are the dimensions of the board and W is the total number of characters in the words.
Space Complexity:- O(W)
"""

"""
Intuition:

The findWords method uses a Trie data structure to efficiently search for words on the board.
It iterates through the board cells and starts the search from each cell if it is a prefix in the Trie.
The find_str function performs a depth-first search (DFS) on the board to find words in the Trie.
The unique words found are stored in the res set.
"""
from collections import defaultdict
from functools import reduce
from typing import List

class Solution:
    def findWords(self, board: List[List[str]], words: List[str]) -> List[str]:
        # Create a Trie data structure
        Trie = lambda: defaultdict(Trie)
        trie = Trie()
        END = True

        # Build the trie using the given words
        for word in words:
            reduce(dict.__getitem__, word, trie)[END] = word

        # Set to store unique results
        res = set()

        def find_str(i, j, t):
            # Helper function to explore the board and find words
            if END in t:
                res.add(t[END])

            letter = board[i][j]
            board[i][j] = ""  # Mark the cell as visited

            # Check adjacent cells and continue the search
            if i > 0 and board[i - 1][j] in t:
                find_str(i - 1, j, t[board[i - 1][j]])
            if j > 0 and board[i][j - 1] in t:
                find_str(i, j - 1, t[board[i][j - 1]])
            if i < len(board) - 1 and board[i + 1][j] in t:
                find_str(i + 1, j, t[board[i + 1][j]])
            if j < len(board[0]) - 1 and board[i][j + 1] in t:
                find_str(i, j + 1, t[board[i][j + 1]])

            board[i][j] = letter  # Restore the original cell value

            return

        # Iterate through the board
        for i, row in enumerate(board):
            for j, char in enumerate(row):
                # If the current cell is a prefix in the trie, start the search
                if board[i][j] in trie:
                    find_str(i, j, trie[board[i][j]])

        return list(res)


import os

# Specified path
s = input('Please input some path:')
path = "C:/Users/77718/Documents/Work/Pyhton/KBTU/"+ s

# Get list of directories present in the specified path
dirs = [d for d in os.listdir(path) if os.path.isdir(os.path.join(path, d))]

# Get list of files present in the specified path
files = [f for f in os.listdir(path) if os.path.isfile(os.path.join(path, f))]

# Print the list of directories and files
print("List of Directories:")
for d in dirs:
    print(d)

print("\nList of Files:")
for f in files:
    print(f)


#-----------------------------------------------------------------------------------------#
import torch
import matplotlib.pyplot as plt
import deepwave
from deepwave import scalar
import numpy as np
import warnings
#-----------------------------------------------------------------------------------------#
warnings.filterwarnings("ignore", category=UserWarning)
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
print(device)
#-----------------------------------------------------------------------------------------#

ny = 500
nx = 500

# vp = 1500 * torch.ones(ny, nx)
ny = 2301; nx = 751; dx = 4.0
v = torch.from_file('data/modeling/velocity.bin', size=ny*nx).reshape(ny, nx).to(device)

ny = 100
nx = 300

# vp = 1500 * torch.ones(ny, nx)
# vs = 1000 * torch.ones(ny, nx)
# rho = 2200 * torch.ones(ny, nx)

# 1) Create 2 layers
layer_boundary = ny // 2  # Create a layer boundary in the middle of the y-axis

# 2 & 3) Define vp for top and bottom layers
vp = torch.ones(ny, nx)  # Creating vp tensor
vp[:layer_boundary, :] = 1500  # Top layer
vp[layer_boundary:, :] = 4000  # Bottom layer
#-----------------------------------------------------------------------------------------#

# NOTE in case for QC input velocity
# v = v.cpu().numpy()
# plt.imshow(np.rot90(v, 3), cmap='gray', vmin=2000, vmax=5000)
# plt.show()

#-----------------------------------------------------------------------------------------#

n_shots = 115
n_sources_per_shot = 1
d_source = 20  # 20 * 4m = 80m
first_source = 10  # 10 * 4m = 40m
source_depth = 2  # 2 * 4m = 8m

freq = 25
nt = 750
dt = 0.004
peak_time = 1.5 / freq

# source_locations
source_locations = torch.zeros(n_shots, n_sources_per_shot, 2, dtype=torch.long, device=device)
source_locations[..., 1] = source_depth
# source_locations[:, 0, 0] = (torch.arange(n_shots) * d_source +
                            #  first_source)

# source_amplitudes
source_amplitudes = (deepwave.wavelets.ricker(freq, nt, dt, peak_time)
                    .repeat(n_shots, n_sources_per_shot, 1)
                    .to(device))

out = scalar(v, dx, dt, source_amplitudes=source_amplitudes,
             source_locations=source_locations,
             accuracy=8,
             pml_freq=freq)

# receiver_amplitudes = out[-1]
# vmin, vmax = torch.quantile(receiver_amplitudes[0],
#                             torch.tensor([0.05, 0.95]).to(device))
# _, ax = plt.subplots(1, 2, figsize=(10.5, 7), sharey=True)
# ax[0].imshow(receiver_amplitudes[57].cpu().T, aspect='auto',
#              cmap='gray', vmin=vmin, vmax=vmax)
# ax[1].imshow(receiver_amplitudes[:, 192].cpu().T, aspect='auto',
#              cmap='gray', vmin=vmin, vmax=vmax)
# ax[0].set_xlabel("Channel")
# ax[0].set_ylabel("Time Sample")
# ax[1].set_xlabel("Shot")
# plt.tight_layout()
# plt.show()

# receiver_amplitudes.cpu().numpy().tofile('test.bin')


import os
mypath = r'\Documents\Certificates' #change to correct folder path

files = []
for r, d, f in os.walk(mypath):
    for file in f:
        if '.pdf' in file: # you can change this to e.g .txt, to get any text file
            files.append(file.replace('_', ' ').replace('.pdf', '').title())

for f in range(len(files)):
    print(f+1, files[f], sep='. ')


from flask import Flask, request, jsonify
from flask_mail import Mail, Message
import json
import sqlalchemy
from sqlalchemy import or_,desc
from tables import db,GDPs, Impact, ImpactPredicted

app = Flask(__name__)
app.config['MAIL_SERVER'] = 'smtp.googlemail.com'
app.config['MAIL_PORT'] = 587
app.config['MAIL_USE_TLS'] = True
app.config['MAIL_USERNAME'] = '***@gmail.com'  # enter your email he$
app.config['MAIL_DEFAULT_SENDER'] = '***@gmail.com' # enter your ema$
app.config['MAIL_PASSWORD'] = '****' # enter your password here

mail = Mail(app)

app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql+mysqlconnector://doadmin:k6hjzqqbj408kaa7@covinsights-database-do-user-7582405-0.a.db.ondigitalocean.com:25060/CovInsights'
db.init_app(app)

@app.route("/",  methods=['GET', 'POST'])
def test():
    return 'true'

@app.route("/getGDPs",  methods=['GET', 'POST'])
def getGDPs():
    result = GDPs.query.all()
    response = []
    for row in result:
        l = []
        l.append(row.Country)
        l.append(row.GDP)
        l.append(row.Code)
        response.append(l)

    response = {
        "data" : response
    }

    return response

@app.route("/getImpact",  methods=['GET', 'POST'])
def getImpact():
    response = { 'status' : True }
    try:
        content = json.loads(request.data)
        country= content['country']

        result = Impact.query.filter_by(Economy=country).all()

        values = []
        for row in result:
            if row.Sector == '_All' :
                response['gdp'] = row.GDP
                response['Emp'] = row.Employment
            else:
                values.append(row.GDP)

        response['values'] = values

        currentGDP = GDPs.query.get(country)
        response['currentGDP'] = currentGDP.GDP
        print(response)

    except Exception as e:
        print('Exception:', e.__class__)
        return {
            'status': False,
            'content': 'Unknown error. Please contact the developer.'
        }

    return response

@app.route("/getImpactPredicted",  methods=['GET', 'POST'])
def getImpactPredicted():
    response = { 'status' : True }
    try:
        content = json.loads(request.data)
        country= content['country']

        result = ImpactPredicted.query.filter_by(Economy=country).all()

        values = []
        for row in result:
            if row.Sector == '_All' :
                response['gdp'] = row.GDP
                response['Emp'] = row.Employment
            else:
                values.append(row.GDP)

        response['values'] = values

        currentGDP = GDPs.query.get(country)
        response['currentGDP'] = currentGDP.GDP
        print(response)

    except Exception as e:
        print('Exception:', e.__class__)
        return {
            'status': False,
            'content': 'Unknown error. Please contact the developer.'
        }

    return response

@app.route("/subscribe", methods=['GET', 'POST'])
def subscribe():
    content = json.loads(request.data)
    mailID = content['mailid']

    response = {}

    try:
        msg = Message("Your report is here | CovInsights", recipients=[mailID])
        msg.body = "Thank you for using our service!"
        with app.open_resource("../CovInsights Report.pdf") as fp:
            msg.attach("CovInsights Report.pdf", "application/pdf", fp.read())
        mail.send(msg)
    except Exception as e:
        response['status'] = False
        response['error'] = str(e)
        return response

    response['status'] = True

    return response

if __name__ == "__main__":
    app.run(host="0.0.0.0", debug=True)

B Sudharsan - CovInsights App/Backend Files/app.py


import cv2
from picamera import PiCamera
from picamera.array import PiRGBArray
import time, socket, logging, configparser, argparse, sys
from utils import Utils

parser = argparse.ArgumentParser()
parser.add_argument('--d', nargs=1, default=None)
args = parser.parse_args()

APP_DIR = args.d[0] if args.d != None else "./"
CONFIGURATIONS = APP_DIR + 'configuration.ini'

logging.basicConfig(
    level=logging.DEBUG,
    format="%(asctime)s [%(levelname)s] %(message)s",
    handlers=[
        logging.FileHandler(APP_DIR + 'logs/video-streamer | ' + str(time.asctime()) + '.log'),
        logging.StreamHandler()
    ]
)

config = configparser.ConfigParser()

if len(config.read(CONFIGURATIONS)) == 0:
    logging.error("Could Not Read Configurations File: " + CONFIGURATIONS)
    sys.exit()

DRONE_ID = config['drone']['id']
HOST_IP = config['cloud-app']['ip']
VIDEO_PORT = int( config['cloud-app']['video-port'])

GRAYSCALE = config['video']['grayscale'].lower() == 'true'
FRAMES_PER_SECOND = int( config['video']['fps'])
JPEG_QUALITY = int( config['video']['quality'])
WIDTH = int( config['video']['width'])
HEIGHT = int( config['video']['height'])

logging.info('FPS: %s  Quality: %s  Width %s Height %s  Grayscale: %s',
             str(FRAMES_PER_SECOND), str(JPEG_QUALITY), str(WIDTH), str(HEIGHT), GRAYSCALE)
logging.info('Drone ID: %s  Video Recipient: %s:%s', str(DRONE_ID), str(HOST_IP), str(VIDEO_PORT))

camera = None
video_socket = None

while(True):
    try:
        camera = PiCamera()
        camera.resolution = (WIDTH, HEIGHT)
        camera.framerate = FRAMES_PER_SECOND

        rawCapture = PiRGBArray(camera, size=(WIDTH, HEIGHT))
        time.sleep(0.1)

        logging.info("Camera module initiated")

        video_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        video_socket.connect((HOST_IP, VIDEO_PORT))

        logging.info("Socket Opened, Video Streaming started")

        for frame in camera.capture_continuous(rawCapture, format="bgr", use_video_port=True):
            image_data = frame.array

            image_data = cv2.rotate(image_data, cv2.ROTATE_180)

            if GRAYSCALE:
                image_data = cv2.cvtColor(image_data, cv2.COLOR_BGR2GRAY)

            code, jpg_buffer = cv2.imencode(".jpg", image_data, [int(cv2.IMWRITE_JPEG_QUALITY), JPEG_QUALITY])

            datagramMsgBytes = Utils.create_datagram_message(DRONE_ID, jpg_buffer)

            video_socket.sendall(datagramMsgBytes)

            rawCapture.truncate(0)

    except Exception as e:
        logging.error("Video Stream Ended: "+str(e))

        if camera != None:
            camera.close()
        if video_socket != None:
            video_socket.close()

        time.sleep(2)


L,R = map(int,input().split())
sum = 0
if L%2 == 0:
    start = L+1
else:
    start = L

for i in range(start,R+1,2):
    sum = sum + i

print(sum)


#!/usr/bin/env python
import argparse
import re
import json
from os.path import isfile

def a(lines):
    return len(lines)

def t(requests):
    stats = {}
    for dict_ in requests:
        method = dict_['method']

        if method not in stats.keys():
            stats[method] = 0

        stats[method] += 1

    ret = []
    for key in stats:
        dict_ = {}
        dict_['method'] = key
        dict_['count'] = stats[key]
        ret.append(dict_)

    return ret

def f(requests):
    requests.sort(key=lambda x: x['url'])
    ans = []
    flag = True
    tmp = {}
    for elm in requests:
        if flag:
            tmp['url'] = elm['url']
            tmp['count'] = 0
            flag = False
        if elm['url'] != tmp['url']:
            ans.append(tmp)
            tmp = {}
            tmp['url'] = elm['url']
            tmp['count'] = 1
        else:
            tmp['count'] += 1

    ans.append(tmp)
    ans.sort(key=lambda x: x['count'], reverse=True)
    ans = ans[:10]

    ret = []
    for request in ans:
        dict_ = {}
        dict_['url'] = request['url']
        dict_['count'] = request['count']
        ret.append(dict_)

    return ret

def c(requests):
    requests = list(filter(lambda x: x['code'] in range(400, 500), requests))
    requests.sort(key=lambda x: x['len'], reverse=True)
    ans = requests[:5]

    ret = []
    for request in ans:
        dict_ = {}
        dict_['url'] = request['url']
        dict_['code'] = request['code']
        dict_['len'] = request['len']
        dict_['ip'] = request['ip']
        ret.append(dict_)

    return ret

def s(requests):
    requests = list(filter(lambda x: x['code'] in range(500, 600), requests))
    requests.sort(key=lambda x: x['ip'])
    ans = []
    flag = True
    tmp = {}
    for elm in requests:
        if flag:
            tmp['ip'] = elm['ip']
            tmp['count'] = 0
            flag = False
        if elm['ip'] != tmp['ip']:
            ans.append(tmp)
            tmp = {}
            tmp['ip'] = elm['ip']
            tmp['count'] = 1
        else:
            tmp['count'] += 1

    ans.append(tmp)
    ans.sort(key=lambda x: x['count'], reverse=True)
    ans = ans[:5]

    ret = []
    for request in ans:
        dict_ = {}
        dict_['ip'] = request['ip']
        dict_['count'] = request['count']
        ret.append(dict_)

    return ret

def to_requests(lines):
    requests = []
    for line in lines:
        dict_ = {}
        splited = re.split('[ "]', line)
        dict_['ip'] = splited[0]
        dict_['method'] = splited[6]
        dict_['url'] = splited[7]
        dict_['code'] = int(splited[10])
        if splited[11] == '-':
            dict_['len'] = 0
        else:
            dict_['len'] = int(splited[11])
        requests.append(dict_)

    return requests

def main():
    outfile = 'analyzed'

    parser = argparse.ArgumentParser(usage='analyze.py  [--json]  a | t | f | c | s  <FILE>',
                                     epilog=f'Имя выходного файла - "{outfile}".')
    parser.add_argument('task', action='store', help='см. в README.md', choices=['a', 't', 'f', 'c', 's'])
    parser.add_argument('file', action='store', metavar='FILE', help='входной файл')
    parser.add_argument('--json', action='store_true', help='записать вывод в формате JSON')

    args = parser.parse_args()

    if isfile(outfile):
        print(f"File '{outfile}' exists, overwrite? (yes/NO): ", end='')
        in_ = input()
        if not (in_ == 'y' or in_ == 'yes'):
            raise FileExistsError()

    with open(args.file) as fl:
        lines = fl.read().split('\n')

    if lines[-1] == '':
        del lines[-1]

    task = args.task
    if task == 'a':
        res = a(lines)
    else:
        requests = to_requests(lines)
        if task == 't':
            res = t(requests)
        elif task == 'f':
            res = f(requests)
        elif task == 'c':
            res = c(requests)
        elif task == 's':
            res = s(requests)
        else:
            raise Exception()

    with open(outfile, 'w') as fl:
        if args.json:
            fl.write(json.dumps(res))
        else:
            if isinstance(res, list):
                for line in res:
                    for key in line:
                        fl.write(str(line[key]) + ' ')
                    fl.write('\n')
            elif isinstance(res, int):
                fl.write(str(res))
            else:
                raise Exception()

if __name__ == '__main__':
    main()


def is_leap(year):
    leap = False
    if year % 400 == 0 or (year % 4 == 0 and year % 100 != 0):
        # if the year is divisible by 400 or divisible by 4 but not by 100, it's a leap year
        leap = True

    return leap

year = int(input("Enter a year: "))
print(is_leap(year))


from __future__ import (absolute_import, division, print_function,
                        unicode_literals)
import math

import datetime  # For datetime objects
import os.path  # To manage paths
import sys  # To find out the script name (in argv[0])

# Import the backtrader platform
import backtrader as bt
import backtrader.indicators as btind
import backtrader.feeds as btfeeds

class GoldenCross(bt.Strategy):
    params = (('fast', 50), ('slow', 200),
              ('order_percentage', 0.95), ('ticker', 'SPY'))

    def __init__(self):
        self.fast_moving_average = bt.indicators.SMA(
            self.data.close, period=self.params.fast, plotname='50 Day Moving Average'
        )
        self.slow_moving_average = bt.indicators.SMA(
            self.data.close, period=self.params.slow, plotname='200 Day Moving Average'
        )

        self.crossover = bt.indicators.CrossOver(
            self.fast_moving_average, self.slow_moving_average)

    def next(self):
        # If position size is 0, we own 0 shares
        if self.position.size == 0:
            # Crossover is 1, so Golden Cross happened
            if self.crossover > 0:
                amount_to_invest = (
                    self.params.order_percentage * self.broker.cash)
                self.size = math.floor(amount_to_invest / self.data.close)

                print("Buy {} share of {} at {}".format(
                    self.size, self.params.ticker, self.data.close[0]))

                self.buy(size=self.size)
        if self.position.size > 0:
            if self.crossover < 0:
                print("Sell {} shares of {} at {}".format(
                    self.size, self.params.ticker, self.data.close[0]))
                self.close()

if __name__ == '__main__':
    # Create a cerebro entity
    cerebro = bt.Cerebro()

    # Add a strategy
    cerebro.addstrategy(GoldenCross)

    # Datas are in a subfolder of the samples. Need to find where the script is
    # because it could have been called from anywhere
    modpath = os.path.dirname(os.path.abspath(sys.argv[0]))
    datapath = os.path.join(
        modpath, '/Users/alfredopzr/Desktop/Coinbase-Python/Coinbase-Python/datas/SPY.csv')

    # Create a Data Feed
    data = bt.feeds.YahooFinanceCSVData(
        dataname=datapath,
        # Do not pass values before this date
        fromdate=datetime.datetime(2000, 1, 3),
        # Do not pass values before this date
        todate=datetime.datetime(2021, 9, 13),
        # Do not pass values after this date
        reverse=False)

    # Add the Data Feed to Cerebro
    cerebro.adddata(data)

    # Set our desired cash start
    cerebro.broker.setcash(10000.0)

    # Add a FixedSize sizer according to the stake
    # cerebro.addsizer(bt.sizers.AllInSizer, percents=95)

    # Set the commission
    cerebro.broker.setcommission(commission=0.00)

    # Print out the starting conditions
    print('Starting Portfolio Value: %.2f' % cerebro.broker.getvalue())

    # Run over everything
    cerebro.run()

    # Print out the final result
    print('Final Portfolio Value: %.2f' % cerebro.broker.getvalue())

    # Plot the result
    cerebro.plot()


'''
    Posts routes
        /posts (args: position, amount)
        /post (args: id)
'''

from flask_api import status
from flask import request
from flask import Blueprint
from service.upload_image import UploadImage
from databases.models.post import Post, PostStatus
from databases.models.photo import Photo
from decorators.token import token_required
from exceptions.posts import PostArgsError, APIexception
from exceptions.token import DecodeToken
from exceptions.validate import InvalidImage
from config.db import db
from config.config import BASE_COUNT_POSTS, BASE_POSITION_POSTS, SECRET_KEY, ACTIVE_POST_STATUS
from validations.routes.new_post import PostValid
from tokens.token_hendler import TokenManager

posts = Blueprint('posts', __name__, template_folder='templates')

@posts.route('/posts', endpoint='get_posts', methods=['GET'])
@token_required
def get_posts():
    '''Posts slize
        ?position=0&amount=0
    '''

    position = request.args.get('position', default=BASE_POSITION_POSTS, type=int)
    amount = request.args.get('amount', default=BASE_COUNT_POSTS, type=int)

    if position < 0 or amount < 0:
        return PostArgsError.message, status.HTTP_400_BAD_REQUEST

    slice_posts = Post.query.order_by(
        Post.id.desc()).offset(position).limit(amount).all()
    amount = Post.query.count()

    return {'posts': slice_posts, 'size': amount}, status.HTTP_200_OK

@posts.route('/new-post', endpoint='set_post', methods=['POST'])
@token_required
def set_post():
    '''Post
        add new post

        title: str
        text: str
        status: str
        likes: int
        view: int
        shared: int
        user: User
        photos: Photo
    '''

    try:
        post_form = PostValid(**request.form)
        validate_date = post_form.validate()
    except APIexception as error:
        return error.message, status.HTTP_400_BAD_REQUEST

    try:
        user_id = TokenManager.get_id_user(SECRET_KEY ,request.headers['Access-Token'])
    except DecodeToken as error:
        return error.message, status.HTTP_400_BAD_REQUEST

    img_photo = None
    if request.method == 'POST' and 'file' in request.files:
        try:
            img_photo = UploadImage(request.files['file']).save_image()
        except InvalidImage as error:
            return error.message, status.HTTP_400_BAD_REQUEST

    post_status = PostStatus.query.filter_by(name=ACTIVE_POST_STATUS).first()
    if post_status is None:
        status_post = PostStatus()
        status_post.name = ACTIVE_POST_STATUS
        db.session.add(status_post)  # pylint: disable=no-member
        db.session.commit()  # pylint: disable=no-member

    try:
        new_post = Post()
        new_post.title = validate_date['title']
        new_post.text = validate_date['text']
        new_post.status_id = PostStatus.query.filter_by(name=ACTIVE_POST_STATUS).first().id
        new_post.user_id = user_id
        db.session.add(new_post)  # pylint: disable=no-member
        db.session.commit()  # pylint: disable=no-member
        if img_photo is not None:
            photo = Photo()
            photo.photo = img_photo
            photo.user_id = user_id
            photo.post_id = new_post.id
            db.session.add(photo)  # pylint: disable=no-member
            db.session.commit()  # pylint: disable=no-member

    except APIexception as error:
        return error.message, status.HTTP_400_BAD_REQUEST

    return {'post' : new_post}, status.HTTP_200_OK


import os

move = input("Please enter move: ")
name = input("Please enter csv name: ")
path = f'dataset/{move}/'
files = os.listdir(path)

counter = 1
for file in files:
    _, ext = os.path.splitext(file)
    os.rename(os.path.join(path, file), os.path.join(path, name + str(counter) + ext))
    counter += 1


import random

# <--->
from .board import Spawn, Player, Launch
from .helpers import find_shortcut_routes
from .logger import logger

# <--->

def defend_shipyards(agent: Player):
    board = agent.board

    need_help_shipyards = []
    for sy in agent.shipyards:
        if sy.action:
            continue

        incoming_hostile_fleets = sy.incoming_hostile_fleets
        incoming_allied_fleets = sy.incoming_allied_fleets

        if not incoming_hostile_fleets:
            continue

        incoming_hostile_power = sum(x.ship_count for x in incoming_hostile_fleets)
        incoming_hostile_time = min(x.eta for x in incoming_hostile_fleets)
        incoming_allied_power = sum(
            x.ship_count
            for x in incoming_allied_fleets
            if x.eta < incoming_hostile_time
        )

        ships_needed = incoming_hostile_power - incoming_allied_power
        if sy.ship_count > ships_needed:
            sy.set_guard_ship_count(min(sy.ship_count, int(ships_needed * 1.1)))
            continue

        # spawn as much as possible
        num_ships_to_spawn = min(
            int(agent.available_kore() // board.spawn_cost), sy.max_ships_to_spawn
        )
        if num_ships_to_spawn:
            logger.debug(f"Spawn ships to protect shipyard {sy.point}")
            sy.action = Spawn(num_ships_to_spawn)

        need_help_shipyards.append(sy)

    for sy in need_help_shipyards:
        incoming_hostile_fleets = sy.incoming_hostile_fleets
        incoming_hostile_time = min(x.eta for x in incoming_hostile_fleets)

        for other_sy in agent.shipyards:
            if other_sy == sy or other_sy.action or not other_sy.available_ship_count:
                continue

            distance = other_sy.distance_from(sy)
            if distance == incoming_hostile_time - 1:
                routes = find_shortcut_routes(
                    board, other_sy.point, sy.point, agent, other_sy.ship_count
                )
                if routes:
                    logger.info(f"Send reinforcements {other_sy.point}->{sy.point}")
                    other_sy.action = Launch(
                        other_sy.available_ship_count, random.choice(routes)
                    )
            elif distance < incoming_hostile_time - 1:
                other_sy.set_guard_ship_count(other_sy.ship_count)


"""
One table verb initializations
"""
import itertools

from .operators import DataOperator
from .expressions import Expression

__all__ = ['define', 'create', 'sample_n', 'sample_frac', 'select',
           'rename', 'distinct', 'unique', 'arrange', 'group_by',
           'ungroup', 'group_indices', 'summarize',
           'query', 'do', 'head', 'tail', 'pull', 'slice_rows',
           # Aliases
           'summarise', 'mutate', 'transmute',
           ]

class define(DataOperator):
    """
    Add column to DataFrame

    Parameters
    ----------
    data : dataframe, optional
        Useful when not using the ``>>`` operator.
    args : strs, tuples, optional
        Expressions or ``(name, expression)`` pairs. This should
        be used when the *name* is not a valid python variable
        name. The expression should be of type :class:`str` or
        an *interable* with the same number of elements as the
        dataframe.
    kwargs : dict, optional
        ``{name: expression}`` pairs.

    Examples
    --------
    >>> import pandas as pd
    >>> df = pd.DataFrame({'x': [1, 2, 3]})
    >>> df >> define(x_sq='x**2')
       x  x_sq
    0  1     1
    1  2     4
    2  3     9
    >>> df >> define(('x*2', 'x*2'), ('x*3', 'x*3'), x_cubed='x**3')
       x  x*2  x*3  x_cubed
    0  1    2    3        1
    1  2    4    6        8
    2  3    6    9       27
    >>> df >> define('x*4')
       x  x*4
    0  1    4
    1  2    8
    2  3   12

    Notes
    -----
    If :obj:`plydata.options.modify_input_data` is ``True``,
    :class:`define` will modify the original dataframe.
    """

    def __init__(self, *args, **kwargs):
        self.set_env_from_verb_init()
        cols = []
        exprs = []
        for arg in args:
            if isinstance(arg, str):
                col = expr = arg
            else:
                col, expr = arg
            cols.append(col)
            exprs.append(expr)

        _cols = itertools.chain(cols, kwargs.keys())
        _exprs = itertools.chain(exprs, kwargs.values())
        self.expressions = [Expression(stmt, col)
                            for stmt, col in zip(_exprs, _cols)]

class create(define):
    """
    Create DataFrame with columns

    Similar to :class:`define`, but it drops the existing columns.

    Parameters
    ----------
    data : dataframe, optional
        Useful when not using the ``>>`` operator.
    args : strs, tuples, optional
        Expressions or ``(name, expression)`` pairs. This should
        be used when the *name* is not a valid python variable
        name. The expression should be of type :class:`str` or
        an *interable* with the same number of elements as the
        dataframe.
    kwargs : dict, optional
        ``{name: expression}`` pairs.

    kwargs : dict, optional
        ``{name: expression}`` pairs.

    Examples
    --------
    >>> import pandas as pd
    >>> df = pd.DataFrame({'x': [1, 2, 3]})
    >>> df >> create(x_sq='x**2')
       x_sq
    0     1
    1     4
    2     9
    >>> df >> create(('x*2', 'x*2'), ('x*3', 'x*3'), x_cubed='x**3')
       x*2  x*3  x_cubed
    0    2    3        1
    1    4    6        8
    2    6    9       27
    >>> df >> create('x*4')
       x*4
    0    4
    1    8
    2   12
    """

class sample_n(DataOperator):
    """
    Sample n rows from dataframe

    Parameters
    ----------
    data : dataframe, optional
        Useful when not using the ``>>`` operator.
    n : int, optional
        Number of items from axis to return.
    replace : boolean, optional
        Sample with or without replacement. Default = False.
    weights : str or ndarray-like, optional
        Default 'None' results in equal probability weighting.
        If passed a Series, will align with target object on index. Index
        values in weights not found in sampled object will be ignored and
        index values in sampled object not in weights will be assigned
        weights of zero.
        If called on a DataFrame, will accept the name of a column
        when axis = 0.
        Unless weights are a Series, weights must be same length as axis
        being sampled.
        If weights do not sum to 1, they will be normalized to sum to 1.
        Missing values in the weights column will be treated as zero.
        inf and -inf values not allowed.
    random_state : int or numpy.random.RandomState, optional
        Seed for the random number generator (if int), or numpy RandomState
        object.
    axis : int or string, optional
        Axis to sample. Accepts axis number or name. Default is stat axis
        for given data type (0 for Series and DataFrames, 1 for Panels).

    Examples
    --------
    >>> import pandas as pd
    >>> import numpy as np
    >>> rs = np.random.RandomState(1234567890)
    >>> df = pd.DataFrame({'x': range(20)})
    >>> df >> sample_n(5, random_state=rs)
         x
    5    5
    19  19
    14  14
    8    8
    17  17
    """
    def __init__(self, n=1, replace=False, weights=None,
                 random_state=None, axis=None):
        self.kwargs = dict(n=n, replace=replace, weights=weights,
                           random_state=random_state, axis=axis)

class sample_frac(DataOperator):
    """
    Sample a fraction of rows from dataframe

    Parameters
    ----------
    data : dataframe, optional
        Useful when not using the ``>>`` operator.
    frac : float, optional
        Fraction of axis items to return. Cannot be used with `n`.
    replace : boolean, optional
        Sample with or without replacement. Default = False.
    weights : str or ndarray-like, optional
        Default 'None' results in equal probability weighting.
        If passed a Series, will align with target object on index. Index
        values in weights not found in sampled object will be ignored and
        index values in sampled object not in weights will be assigned
        weights of zero.
        If called on a DataFrame, will accept the name of a column
        when axis = 0.
        Unless weights are a Series, weights must be same length as axis
        being sampled.
        If weights do not sum to 1, they will be normalized to sum to 1.
        Missing values in the weights column will be treated as zero.
        inf and -inf values not allowed.
    random_state : int or numpy.random.RandomState, optional
        Seed for the random number generator (if int), or numpy RandomState
        object.
    axis : int or string, optional
        Axis to sample. Accepts axis number or name. Default is stat axis
        for given data type (0 for Series and DataFrames, 1 for Panels).

    Examples
    --------
    >>> import pandas as pd
    >>> import numpy as np
    >>> rs = np.random.RandomState(1234567890)
    >>> df = pd.DataFrame({'x': range(20)})
    >>> df >> sample_frac(0.25, random_state=rs)
         x
    5    5
    19  19
    14  14
    8    8
    17  17
    """

    def __init__(self, frac=None, replace=False, weights=None,
                 random_state=None, axis=None):
        self.kwargs = dict(
            frac=frac, replace=replace, weights=weights,
            random_state=random_state, axis=axis)

class select(DataOperator):
    """
    Select columns by name

    Parameters
    ----------
    data : dataframe, optional
        Useful when not using the ``>>`` operator.
    names : tuple, optional
        Names of columns in dataframe. Normally, they are strings
        can include slice e.g :py:`slice('col2', 'col5')`.
        You can also exclude columns by prepending a ``-`` e.g
        py:`select('-col1')`, will include all columns minus than
        *col1*.
    startswith : str or tuple, optional
        All column names that start with this string will be included.
    endswith : str or tuple, optional
        All column names that end with this string will be included.
    contains : str or tuple, optional
        All column names that contain with this string will be included.
    matches : str or regex or tuple, optional
        All column names that match the string or a compiled regex pattern
        will be included. A tuple can be used to match multiple regexs.
    drop : bool, optional
        If ``True``, the selection is inverted. The unspecified/unmatched
        columns are returned instead. Default is ``False``.

    Examples
    --------
    >>> import pandas as pd
    >>> x = [1, 2, 3]
    >>> df = pd.DataFrame({'bell': x, 'whistle': x, 'nail': x, 'tail': x})
    >>> df >> select('bell', 'nail')
       bell  nail
    0     1     1
    1     2     2
    2     3     3
    >>> df >> select('bell', 'nail', drop=True)
       whistle  tail
    0        1     1
    1        2     2
    2        3     3
    >>> df >> select('whistle',  endswith='ail')
       whistle nail  tail
    0        1    1     1
    1        2    2     2
    2        3    3     3
    >>> df >> select('bell',  matches=r'\\w+tle$')
       bell  whistle
    0     1        1
    1     2        2
    2     3        3

    You can select column slices too. Like :meth:`~pandas.DataFrame.loc`,
    the stop column is included.

    >>> df = pd.DataFrame({'a': x, 'b': x, 'c': x, 'd': x,
    ...                    'e': x, 'f': x, 'g': x, 'h': x})
    >>> df
       a  b  c  d  e  f  g  h
    0  1  1  1  1  1  1  1  1
    1  2  2  2  2  2  2  2  2
    2  3  3  3  3  3  3  3  3
    >>> df >> select('a', slice('c', 'e'), 'g')
       a  c  d  e  g
    0  1  1  1  1  1
    1  2  2  2  2  2
    2  3  3  3  3  3

    You can exclude columns by prepending ``-``

    >>> df >> select('-a', '-c', '-e')
       b  d  f  g  h
    0  1  1  1  1  1
    1  2  2  2  2  2
    2  3  3  3  3  3

    Remove and place column at the end

    >>> df >> select('-a', '-c', '-e', 'a')
       b  d  f  g  h  a
    0  1  1  1  1  1  1
    1  2  2  2  2  2  2
    2  3  3  3  3  3  3

    Notes
    -----
    To exclude columns by prepending a minus, the first column
    passed to :class:`select` must be prepended with minus.
    :py:`select('-a', 'c')` will exclude column ``a``, while
    :py:`select('c', '-a')` will not exclude column ``a``.
    """
    def __init__(self, *names, startswith=None, endswith=None,
                 contains=None, matches=None, drop=False):
        def as_tuple(obj):
            if obj is None:
                return tuple()
            elif isinstance(obj, tuple):
                return obj
            elif isinstance(obj, list):
                return tuple(obj)
            else:
                return (obj,)

        self.names = names
        self.startswith = as_tuple(startswith)
        self.endswith = as_tuple(endswith)
        self.contains = as_tuple(contains)
        self.matches = as_tuple(matches)
        self.drop = drop

    @staticmethod
    def from_columns(*columns):
        """
        Create a select verb from the columns specification

        Parameters
        ----------
        *columns : list-like | select | str | slice
            Column names to be gathered and whose contents will
            make values.

        Return
        ------
        out : select
            Select verb representation of the columns.
        """
        from .helper_verbs import select_all, select_at, select_if
        n = len(columns)
        if n == 0:
            return select_all()
        elif n == 1:
            obj = columns[0]
            if isinstance(obj, (select, select_all, select_at, select_if)):
                return obj
            elif isinstance(obj, slice):
                return select(obj)
            elif isinstance(obj, (list, tuple)):
                return select(*obj)
            elif isinstance(obj, str):
                return select(obj)
            else:
                raise TypeError(
                    "Unrecognised type {}".format(type(obj))
                )
        else:
            return select(*columns)

class rename(DataOperator):
    """
    Rename columns

    Parameters
    ----------
    data : dataframe, optional
        Useful when not using the ``>>`` operator.
    args : tuple, optional
        A single positional argument that holds
        ``{'new_name': 'old_name'}`` pairs. This is useful if the
        *old_name* is not a valid python variable name.
    kwargs : dict, optional
        ``{new_name: 'old_name'}`` pairs. If all the columns to be
        renamed are valid python variable names, then they
        can be specified as keyword arguments.

    Examples
    --------
    >>> import pandas as pd
    >>> import numpy as np
    >>> x = np.array([1, 2, 3])
    >>> df = pd.DataFrame({'bell': x, 'whistle': x,
    ...                    'nail': x, 'tail': x})
    >>> df >> rename(gong='bell', pin='nail')
       gong  whistle  pin  tail
    0     1        1    1     1
    1     2        2    2     2
    2     3        3    3     3
    >>> df >> rename({'flap': 'tail'}, pin='nail')
       bell  whistle  pin  flap
    0     1        1    1     1
    1     2        2    2     2
    2     3        3    3     3

    Notes
    -----
    If :obj:`plydata.options.modify_input_data` is ``True``,
    :class:`rename` will modify the original dataframe.
    """
    lookup = None

    def __init__(self, *args, **kwargs):
        lookup = args[0] if len(args) else {}
        self.lookup = {v: k for k, v in lookup.items()}
        self.lookup.update({v: k for k, v in kwargs.items()})

class distinct(DataOperator):
    """
    Select distinct/unique rows

    Parameters
    ----------
    data : dataframe, optional
        Useful when not using the ``>>`` operator.
    columns : list-like, optional
        Column names to use when determining uniqueness.
    keep : {'first', 'last', False}, optional
        - ``first`` : Keep the first occurence.
        - ``last`` : Keep the last occurence.
        - False : Do not keep any of the duplicates.

        Default is False.
    kwargs : dict, optional
        ``{name: expression}`` computed columns. If specified,
        these are taken together with the columns when determining
        unique rows.

    Examples
    --------
    >>> import pandas as pd
    >>> df = pd.DataFrame({'x': [1, 1, 2, 3, 4, 4, 5],
    ...                    'y': [1, 2, 3, 4, 5, 5, 6]})
    >>> df >> distinct()
       x  y
    0  1  1
    1  1  2
    2  2  3
    3  3  4
    4  4  5
    6  5  6
    >>> df >> distinct(['x'])
       x  y
    0  1  1
    2  2  3
    3  3  4
    4  4  5
    6  5  6
    >>> df >> distinct(['x'], 'last')
       x  y
    1  1  2
    2  2  3
    3  3  4
    5  4  5
    6  5  6
    >>> df >> distinct(z='x%2')
       x  y  z
    0  1  1  1
    2  2  3  0
    >>> df >> distinct(['x'], z='x%2')
       x  y  z
    0  1  1  1
    2  2  3  0
    3  3  4  1
    4  4  5  0
    6  5  6  1
    >>> df >> define(z='x%2') >> distinct(['x', 'z'])
       x  y  z
    0  1  1  1
    2  2  3  0
    3  3  4  1
    4  4  5  0
    6  5  6  1
    """
    columns = None
    keep = 'first'

    def __init__(self, *args, **kwargs):
        self.set_env_from_verb_init()
        if len(args) == 1:
            if isinstance(args[0], (str, bool)):
                self.keep = args[0]
            else:
                self.columns = args[0]
        elif len(args) == 2:
            self.columns, self.keep = args
        elif len(args) > 2:
            raise Exception("Too many positional arguments.")

        # define
        if kwargs:
            if self.columns is None:
                self.columns = []
            elif not isinstance(self.columns, list):
                self.columns = list(self.columns)

            _cols = list(kwargs.keys())
            _exprs = list(kwargs.values())
            self.columns.extend(_cols)
        else:
            _cols = []
            _exprs = []

        self.expressions = [Expression(stmt, col)
                            for stmt, col in zip(_exprs, _cols)]

class arrange(DataOperator):
    """
    Sort rows by column variables

    Parameters
    ----------
    data : dataframe, optional
        Useful when not using the ``>>`` operator.
    args : tuple
        Columns/expressions to sort by.
    reset_index : bool, optional (default: True)
        If ``True``, the index is reset to a sequential range index.
        If ``False``, the original index is maintained.

    Examples
    --------
    >>> import pandas as pd
    >>> import numpy as np
    >>> df = pd.DataFrame({'x': [1, 5, 2, 2, 4, 0],
    ...                    'y': [1, 2, 3, 4, 5, 6]})
    >>> df >> arrange('x')
       x  y
    0  0  6
    1  1  1
    2  2  3
    3  2  4
    4  4  5
    5  5  2
    >>> df >> arrange('x', '-y')
       x  y
    0  0  6
    1  1  1
    2  2  4
    3  2  3
    4  4  5
    5  5  2
    >>> df >> arrange('np.sin(y)')
       x  y
    0  4  5
    1  2  4
    2  0  6
    3  2  3
    4  1  1
    5  5  2
    """
    expressions = None

    def __init__(self, *args, reset_index=True):
        self.set_env_from_verb_init()
        self.reset_index = reset_index
        name_gen = ('col_{}'.format(x) for x in range(100))
        self.expressions = [
            Expression(stmt, col)
            for stmt, col in zip(args, name_gen)
        ]

class group_by(define):
    """
    Group dataframe by one or more columns/variables

    Parameters
    ----------
    data : dataframe, optional
        Useful when not using the ``>>`` operator.
    args : strs, tuples, optional
        Expressions or ``(name, expression)`` pairs. This should
        be used when the *name* is not a valid python variable
        name. The expression should be of type :class:`str` or
        an *interable* with the same number of elements as the
        dataframe.
    add_ : bool, optional
        If True, add to existing groups. Default is to create
        new groups.
    kwargs : dict, optional
        ``{name: expression}`` pairs.

    Examples
    --------
    >>> import pandas as pd
    >>> df = pd.DataFrame({'x': [1, 5, 2, 2, 4, 0, 4],
    ...                    'y': [1, 2, 3, 4, 5, 6, 5]})
    >>> df >> group_by('x')
    groups: ['x']
       x  y
    0  1  1
    1  5  2
    2  2  3
    3  2  4
    4  4  5
    5  0  6
    6  4  5

    Like :meth:`define`, :meth:`group_by` creates any
    missing columns.

    >>> df >> group_by('y-1', xplus1='x+1')
    groups: ['y-1', 'xplus1']
       x  y  y-1  xplus1
    0  1  1    0       2
    1  5  2    1       6
    2  2  3    2       3
    3  2  4    3       3
    4  4  5    4       5
    5  0  6    5       1
    6  4  5    4       5

    Columns that are grouped on remain in the dataframe after any
    verb operations that do not use the group information. For
    example:

    >>> df >> group_by('y-1', xplus1='x+1') >> select('y')
    groups: ['y-1', 'xplus1']
       y-1  xplus1  y
    0    0       2  1
    1    1       6  2
    2    2       3  3
    3    3       3  4
    4    4       5  5
    5    5       1  6
    6    4       5  5

    Notes
    -----
    If :obj:`plydata.options.modify_input_data` is ``True``,
    :class:`group_by` will modify the original dataframe.
    """
    groups = None

    def __init__(self, *args, add_=False, **kwargs):
        self.set_env_from_verb_init()
        super().__init__(*args, **kwargs)
        self.add_ = add_
        self.groups = [expr.column for expr in self.expressions]

class ungroup(DataOperator):
    """
    Remove the grouping variables for dataframe

    Parameters
    ----------
    data : dataframe, optional
        Useful when not using the ``>>`` operator.

    Examples
    --------
    >>> import pandas as pd
    >>> df = pd.DataFrame({'x': [1, 2, 3],
    ...                    'y': [1, 2, 3]})
    >>> df >> group_by('x')
    groups: ['x']
       x  y
    0  1  1
    1  2  2
    2  3  3
    >>> df >> group_by('x') >> ungroup()
       x  y
    0  1  1
    1  2  2
    2  3  3
    """

class group_indices(group_by):
    """
    Generate a unique id for each group

    Parameters
    ----------
    data : dataframe, optional
        Useful when not using the ``>>`` operator.
    args : strs, tuples, optional
        Expressions or ``(name, expression)`` pairs. This should
        be used when the *name* is not a valid python variable
        name. The expression should be of type :class:`str` or
        an *interable* with the same number of elements as the
        dataframe. As this verb returns an array, the tuples have
        no added benefit over strings.
    kwargs : dict, optional
        ``{name: expression}`` pairs. As this verb returns an
        array, keyword arguments have no added benefit over
        :class:`str` positional arguments.

    Returns
    -------
    out : numpy.array
        Ids for each group

    Examples
    --------
    >>> import pandas as pd
    >>> df = pd.DataFrame({'x': [1, 5, 2, 2, 4, 0, 4],
    ...                    'y': [1, 2, 3, 4, 5, 6, 5]})
    >>> df >> group_by('x')
    groups: ['x']
       x  y
    0  1  1
    1  5  2
    2  2  3
    3  2  4
    4  4  5
    5  0  6
    6  4  5
    >>> df >> group_by('x') >> group_indices()
    array([1, 4, 2, 2, 3, 0, 3])

    You can pass the group column(s) as parameters to
    :class:`group_indices`

    >>> df >> group_indices('x*2')
    array([1, 4, 2, 2, 3, 0, 3])
    """

class summarize(define):
    """
    Summarise multiple values to a single value

    Parameters
    ----------
    data : dataframe, optional
        Useful when not using the ``>>`` operator.
    args : strs, tuples, optional
        Expressions or ``(name, expression)`` pairs. This should
        be used when the *name* is not a valid python variable
        name. The expression should be of type :class:`str` or
        an *interable* with the same number of elements as the
        dataframe.
    kwargs : dict, optional
        ``{name: expression}`` pairs.

    Examples
    --------
    >>> import pandas as pd
    >>> import numpy as np
    >>> df = pd.DataFrame({'x': [1, 5, 2, 2, 4, 0, 4],
    ...                    'y': [1, 2, 3, 4, 5, 6, 5],
    ...                    'z': [1, 3, 3, 4, 5, 5, 5]})

    Can take only positional, only keyword arguments or both.

    >>> df >> summarize('np.sum(x)', max='np.max(x)')
       np.sum(x)  max
    0         18    5

    When summarizing after a :class:`group_by` operation
    the group columns are retained.

    >>> df >> group_by('y', 'z') >> summarize(mean_x='np.mean(x)')
       y  z  mean_x
    0  1  1     1.0
    1  2  3     5.0
    2  3  3     2.0
    3  4  4     2.0
    4  5  5     4.0
    5  6  5     0.0

    .. rubric:: Aggregate Functions

    When summarizing the following functions can be used, they take
    an array and return a *single* number.

    - ``min(x)`` - Alias of :func:`numpy.amin` (a.k.a ``numpy.min``).
    - ``max(x)`` - Alias of :func:`numpy.amax` (a.k.a ``numpy.max``).
    - ``sum(x)`` - Alias of :func:`numpy.sum`.
    - ``cumsum(x)`` - Alias of :func:`numpy.cumsum`.
    - ``mean(x)`` - Alias of :func:`numpy.mean`.
    - ``median(x)`` - Alias of :func:`numpy.median`.
    - ``std(x)`` - Alias of :func:`numpy.std`.
    - ``first(x)`` - First element of ``x``.
    - ``last(x)`` - Last element of ``x``.
    - ``nth(x, n)`` - *nth* value of ``x`` or ``numpy.nan``.
    - ``n_distinct(x)`` - Number of distint elements in ``x``.
    - ``n_unique(x)`` - Alias of ``n_distinct``.
    - ``n()`` - Number of elements in current group.

    The aliases of the Numpy functions save you from typing 3 or 5 key
    strokes and you get better column names. i.e ``min(x)`` instead of
    ``np.min(x)`` or ``numpy.min(x)`` if you have Numpy imported.

    >>> df = pd.DataFrame({'x': [0, 1, 2, 3, 4, 5],
    ...                    'y': [0, 0, 1, 1, 2, 3]})
    >>> df >> summarize('min(x)', 'max(x)', 'mean(x)', 'sum(x)',
    ...                 'first(x)', 'last(x)', 'nth(x, 3)')
       min(x)  max(x)  mean(x)  sum(x)  first(x)  last(x)  nth(x, 3)
    0       0       5      2.5      15         0        5          3

    Summarizing groups with aggregate functions

    >>> df >> group_by('y') >> summarize('mean(x)')
       y  mean(x)
    0  0      0.5
    1  1      2.5
    2  2      4.0
    3  3      5.0

    >>> df >> group_by('y') >> summarize(y_count='n()')
       y  y_count
    0  0        2
    1  1        2
    2  2        1
    3  3        1

    You can use ``n()`` even when there are no groups.

    >>> df >> summarize('n()')
       n()
    0    6
    """

class query(DataOperator):
    """
    Return rows with matching conditions

    Parameters
    ----------
    data : dataframe, optional
        Useful when not using the ``>>`` operator.
    expr : str
        The query string to evaluate.  You can refer to variables
        in the environment by prefixing them with an '@' character
        like ``@a + b``. Allowed functions are `sin`, `cos`, `exp`,
        `log`, `expm1`, `log1p`, `sqrt`, `sinh`, `cosh`, `tanh`,
        `arcsin`, `arccos`, `arctan`, `arccosh`, `arcsinh`,
        `arctanh`, `abs` and `arctan2`.
    reset_index : bool, optional (default: True)
        If ``True``, the index is reset to a sequential range index.
        If ``False``, the original index is maintained.
    kwargs : dict
        See the documentation for :func:`pandas.eval` for complete
        details on the keyword arguments accepted by
        :meth:`pandas.DataFrame.query`.

    Examples
    --------
    >>> import pandas as pd
    >>> df = pd.DataFrame({'x': [0, 1, 2, 3, 4, 5],
    ...                    'y': [0, 0, 1, 1, 2, 3],
    ...                    'z': list('aabbcd')})
    >>> df >> query('x % 2 == 0')
       x  y  z
    0  0  0  a
    1  2  1  b
    2  4  2  c

    >>> df >> query('x % 2 == 0 & y > 0')
       x  y  z
    0  2  1  b
    1  4  2  c

    By default, Bitwise operators ``&`` and ``|`` have the same
    precedence as the booleans ``and`` and ``or``.

    >>> df >> query('x % 2 == 0 and y > 0')
       x  y  z
    0  2  1  b
    1  4  2  c

    ``query`` works within groups

    >>> df >> query('x == x.min()')
       x  y  z
    0  0  0  a

    >>> df >> group_by('y') >> query('x == x.min()')
    groups: ['y']
       x  y  z
    0  0  0  a
    1  2  1  b
    2  4  2  c
    3  5  3  d

    When working with strings, the values should be quoted.

    >>> df >> query('z == "a"')
       x  y  z
    0  0  0  a
    1  1  0  a

    You can refer to variables in the environment by prefixing them
    with an `@` character.

    >>> w = list('rrbbst')
    >>> df >> query('z == @w')
       x  y  z
    0  2  1  b
    1  3  1  b

    For more information see :meth:`pandas.DataFrame.query`. To query
    rows and columns with ``NaN`` values, use :class:`dropna`

    Notes
    -----
    :class:`~plydata.one_table_verbs.query` is the equivalent of
    dplyr's `filter` verb but with slightly different python syntax
    the expressions.
    """
    expression = None

    def __init__(self, expr, reset_index=True, **kwargs):
        self.set_env_from_verb_init()
        self.reset_index = reset_index
        self.expression = expr
        self.kwargs = kwargs

class do(DataOperator):
    """
    Do arbitrary operations on a dataframe

    Considering the *split-apply-combine* data manipulation
    strategy, :class:`do` gives a window into which to place
    the complex *apply* actions, and also control over the form of
    results when they are combined. This allows

    Parameters
    ----------
    data : dataframe, optional
        Useful when not using the ``>>`` operator.
    func : function, optional
        A single function to apply to each group. *The
        function should accept a dataframe and return a
        dataframe*.
    kwargs : dict, optional
        ``{name: function}`` pairs. *The function should
        accept a dataframe and return an array*. The function
        computes a column called ``name``.

    Examples
    --------
    >>> import pandas as pd
    >>> import numpy as np
    >>> df = pd.DataFrame({'x': [1, 2, 2, 3],
    ...                    'y': [2, 3, 4, 3],
    ...                    'z': list('aabb')})

    Define a function that uses numpy to do a least squares fit.
    It takes input from a dataframe and output is a dataframe.
    ``gdf`` is a dataframe that contains only rows from the current
    group.

    >>> def least_squares(gdf):
    ...     X = np.vstack([gdf.x, np.ones(len(gdf))]).T
    ...     (m, c), _, _, _ = np.linalg.lstsq(X, gdf.y, None)
    ...     return pd.DataFrame({'intercept': c, 'slope': [m]})

    Define functions that take x and y values and compute the
    intercept and slope.

    >>> def slope(x, y):
    ...     return np.diff(y)[0] / np.diff(x)[0]
    ...
    >>> def intercept(x, y):
    ...     return y.values[0] - slope(x, y) * x.values[0]

    Demonstrating do

    >>> df >> group_by('z') >> do(least_squares)
    groups: ['z']
       z  intercept  slope
    0  a        1.0    1.0
    1  b        6.0   -1.0

    We can get the same result, by passing separate functions
    that calculate the columns independently.

    >>> df >> group_by('z') >> do(
    ...     intercept=lambda gdf: intercept(gdf.x, gdf.y),
    ...     slope=lambda gdf: slope(gdf.x, gdf.y))
    groups: ['z']
       z  intercept  slope
    0  a        1.0    1.0
    1  b        6.0   -1.0

    The functions need not return numerical values. Pandas columns can
    hold any type of object. You could store result objects from more
    complicated models. Each model would be linked to a group. Notice
    that the group columns (``z`` in the above cases) are included in
    the result.

    Notes
    -----
    You cannot have both a position argument and keyword
    arguments.
    """
    single_function = False

    def __init__(self, func=None, **kwargs):
        if func is not None:
            if kwargs:
                raise ValueError(
                    "Unexpected positional and keyword arguments.")
            if not callable(func):
                raise TypeError(
                    "func should be a callable object")

        if func:
            self.single_function = True
            self.expressions = [Expression(func, None)]
        else:
            stmts_cols = zip(kwargs.values(), kwargs.keys())
            self.expressions = [
                Expression(stmt, col) for stmt, col in stmts_cols
            ]

class head(DataOperator):
    """
    Select the top n rows

    Parameters
    ----------
    data : dataframe, optional
        Useful when not using the ``>>`` operator.
    n : int, optional
        Number of rows to return. If the ``data`` is grouped,
        then number of rows per group. Default is 5.

    Examples
    --------
    >>> import pandas as pd
    >>> df = pd.DataFrame({
    ...     'x': [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
    ...     'y': list('aaaabbcddd') })
    >>> df >> head(2)
       x  y
    0  1  a
    1  2  a

    Grouped dataframe

    >>> df >> group_by('y') >> head(2)
    groups: ['y']
       x  y
    0  1  a
    1  2  a
    2  5  b
    3  6  b
    4  7  c
    5  8  d
    6  9  d
    """
    def __init__(self, n=5):
        self.n = n

class tail(DataOperator):
    """
    Select the bottom n rows

    Parameters
    ----------
    data : dataframe, optional
        Useful when not using the ``>>`` operator.
    n : int, optional
        Number of rows to return. If the ``data`` is grouped,
        then number of rows per group. Default is 5.

    Examples
    --------
    >>> import pandas as pd
    >>> df = pd.DataFrame({
    ...     'x': [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
    ...     'y': list('aaaabbcddd') })
    >>> df >> tail(2)
        x  y
    8   9  d
    9  10  d

    Grouped dataframe

    >>> df >> group_by('y') >> tail(2)
    groups: ['y']
        x  y
    0   3  a
    1   4  a
    2   5  b
    3   6  b
    4   7  c
    5   9  d
    6  10  d
    """
    def __init__(self, n=5):
        self.n = n

class pull(DataOperator):
    """
    Pull a single column from the dataframe

    Parameters
    ----------
    data : dataframe, optional
        Useful when not using the ``>>`` operator.
    column : name
        Column name or index id.
    use_index : bool
        Whether to pull column by name or by its integer
        index. Default is False.

    Examples
    --------
    >>> import pandas as pd
    >>> df = pd.DataFrame({
    ...     'x': [1, 2, 3],
    ...     'y': [4, 5, 6],
    ...     'z': [7, 8, 9]
    ... })
    >>> df
       x  y  z
    0  1  4  7
    1  2  5  8
    2  3  6  9
    >>> df >> pull('y')
    array([4, 5, 6])
    >>> df >> pull(0, True)
    array([1, 2, 3])
    >>> df >> pull(-1, True)
    array([7, 8, 9])

    Notes
    -----
    Always returns a numpy array.

    If :obj:`plydata.options.modify_input_data` is ``True``,
    :class:`pull` will not make a copy the original column.
    """
    def __init__(self, column, use_index=False):
        self.column = column
        self.use_index = use_index

class slice_rows(DataOperator):
    """
    Select rows

    A wrapper around :class:`slice` to use when piping.

    Parameters
    ----------
    data : dataframe, optional
        Useful when not using the ``>>`` operator.
    *args : tuple
        (start, stop, step) as expected by the builtin :class:`slice`
        type.

    Examples
    --------
    >>> import pandas as pd
    >>> df = pd.DataFrame({'x': range(10), 'y': range(100, 110)})
    >>> df >> slice_rows(5)
       x    y
    0  0  100
    1  1  101
    2  2  102
    3  3  103
    4  4  104

    >>> df >> slice_rows(3, 7)
       x    y
    3  3  103
    4  4  104
    5  5  105
    6  6  106

    >>> df >> slice_rows(None, None, 3)
       x    y
    0  0  100
    3  3  103
    6  6  106
    9  9  109

    The above examples are equivalent to::

        df[slice(5)]
        df[slice(3, 7)]
        df[slice(None, None, 3)]

    respectively.

    Notes
    -----
    If :obj:`plydata.options.modify_input_data` is ``True``,
    :class:`slice_rows` will not make a copy the original dataframe.
    """
    def __init__(self, *args):
        self.slice = slice(*args)

# Aliases
mutate = define
transmute = create
unique = distinct
summarise = summarize


# 1014

X = int(input())
Y = float(input())

# regra de três pra saber quantos km foram andados por litro
km_per_l = X * 1 / Y

print('%.3f' % km_per_l, 'km/l')