import numpy as np

from utils import pad_to_shape
from filters import gaussian_kernel, median_filter

def phase_correlation(f, g, blur=False):
    F_f = np.fft.fft2(f)
    F_g = np.fft.fft2(g)
    R = F_f * np.conj(F_g)
    R /= np.abs(R)
    if blur:
        gauss = np.fft.fft2(pad_to_shape(gaussian_kernel(5), R.shape))
        return np.fft.ifft2(R * gauss).real
    else:
        r = np.fft.ifft2(R).real
        return np.fft.ifftshift(r)

def warp_log_polar(img):
    if len(img.shape) != 2:
        raise ValueError("Image must be grayscale")

    y_center, x_center = img.shape[0] / 2, img.shape[1] / 2
    radius = np.sqrt(y_center ** 2 + x_center ** 2)

    result = np.zeros((360, int(radius)))
    theta, r = np.meshgrid(*[np.arange(d) for d in result.shape])

    rho = radius ** (r / radius)
    theta_rad = theta * np.pi / 180

    y_indices = np.int32(rho * np.sin(theta_rad) + y_center).clip(0, img.shape[0] - 1)
    x_indices = np.int32(rho * np.cos(theta_rad) + x_center).clip(0, img.shape[1] - 1)
    result[theta, r] = img[y_indices, x_indices]

    return result

def apply_transform(img, translation=(0,0), rotation=0, scale=1, crop_center=False):
    s, theta, (ty, tx) = scale, rotation * np.pi / 180, translation
    M = np.array([[s * np.cos(theta), -s * np.sin(theta), tx],
                  [s * np.sin(theta),  s * np.cos(theta), ty],
                  [                0,                  0,  1]])
    M_inv = np.linalg.pinv(M)

    result = np.zeros(3 * np.array(img.shape))
    old_coords = np.vstack(np.where(np.ones_like(img)) + (np.ones((img.size), dtype='int32'),))

    new_coords = np.int32(M_inv @ old_coords + np.array(img.shape + (0,)).reshape(-1, 1))
    result[new_coords[0], new_coords[1]] = img[old_coords[0], old_coords[1]]

    if crop_center:
        ymin, ymax = img.shape[0], 2 * img.shape[0]
        xmin, xmax = img.shape[1], 2 * img.shape[1]
    else:
        ymin, ymax = np.min(new_coords[0]), np.max(new_coords[0]) + 1
        xmin, xmax = np.min(new_coords[1]), np.max(new_coords[1]) + 1

    return median_filter(result[ymin:ymax,xmin:xmax])


import argparse
import cv2
import logging
import matplotlib.pyplot as plt
import numpy as np
import os
import plotly.graph_objects as go
import yaml

from utils.transformation_utils import (
    get_intrinsic_matrix_from_vanishing_points,
    get_plane_equation,
    get_vanishing_points,
    get_vector_normal_to_plane,
)

from utils.utils import (
    get_file_name,
    get_image_annotations,
    get_point_annotations,
    read_image,
)

def main(args):
    with open(args.config_path, 'r') as stream:
        config = yaml.safe_load(stream)

    # Read config
    img_file = config['IMG']
    colors = config['COLORS']
    n_planes = config['N_PLANES']
    depths = config['DEPTHS']

    out_path = os.path.join(
        args.out_path, 'annotations_' + get_file_name(img_file, ext='.npy')
    )
    img = read_image(img_file)

    # Get all required annotations

    if args.load_annotations:
        parallel_line_annotations, parallel_lines_img_annotated, \
        plane_annotations, known_points = np.load(
            out_path,
            allow_pickle=True
        )
    else:
        # 3 pairs of parallel lines.
        parallel_line_annotations, \
        parallel_lines_img_annotated = get_image_annotations(
            img,
            colors[:3],
            n_pairs=3,
            title='Annotate 3 pairs of parallel lines that are orthogonal to ' +
                'each other.'
        )

        parallel_line_annotations = parallel_line_annotations.reshape(3, 2, 2, 2)

        # Annotate planes 5 points at a time - 4 corners of plane and 1 "known"
        # point with assumed depth.
        plane_annotations = []
        known_points = []

        for _ in range(n_planes):
            annotations, _ = get_point_annotations(
                img,
                colors[:5],
                n_points=5
            )

            annotations = np.hstack((annotations, np.ones((5, 1))))

            assert annotations.shape == (5, 3)

            plane_annotations.append(annotations[: -1])
            known_points.append(annotations[-1])

        plane_annotations = np.array(plane_annotations)
        known_points = np.array(known_points)

        np.save(
            out_path,
            (
                parallel_line_annotations,
                parallel_lines_img_annotated,
                plane_annotations,
                known_points
            )
        )

    plane_annotations = np.load('data/q3/q3.npy', allow_pickle=True)
    plane_annotations = np.concatenate((plane_annotations, np.ones((5, 4, 1))), axis=-1)

    known_points, _ = get_point_annotations(
        img,
        colors[:5],
        n_points=5
    )
    known_points = np.concatenate((known_points, np.ones((5, 1))), axis=-1)

    # Get K
    assert parallel_line_annotations.shape == (3, 2, 2, 2)

    vanishing_points = get_vanishing_points(parallel_line_annotations)
    K = get_intrinsic_matrix_from_vanishing_points(vanishing_points)
    K_inv = np.linalg.inv(K)

    logging.info(f'Intrinsics matrix for {img_file}: \n{K}\n')

    plane_normals = []

    for annotations in plane_annotations:
        plane_normals.append(get_vector_normal_to_plane(annotations, K))

    # Figure out which pixexl lies in what plane.
    planes_annotated_img = np.copy(img)
    plane_per_pixel_img = np.zeros_like(img, dtype=np.uint8)
    plane_per_pixel = np.ones_like(img[..., 0]) * -1

    for i, (annotations, color) in enumerate(zip(plane_annotations, colors)):
        cv2.fillPoly(
            plane_per_pixel_img,
            np.array([annotations[..., :2]], dtype=np.int32),
            color=color
        )
        cv2.fillPoly(
            plane_per_pixel,
            np.array([annotations[..., :2]], dtype=np.int32),
            color=i
        )
        cv2.polylines(
            planes_annotated_img,
            np.array([annotations[..., :2]], dtype=np.int32),
            isClosed=True,
            color=color,
            thickness=5,
        )

    plt.imshow(plane_per_pixel_img)
    plt.savefig(
        os.path.join(args.out_path, 'planes_' + get_file_name(img_file)),
        bbox_inches='tight'
    )
    plt.show()
    plt.close()

    plt.imshow(planes_annotated_img)
    plt.savefig(
        os.path.join(args.out_path, 'planes_annotated_' + get_file_name(img_file)),
        bbox_inches='tight'
    )
    plt.close()

    pixels_x, pixels_y = np.meshgrid(
        np.arange(img.shape[1]),
        np.arange(img.shape[0])
    )
    pixels = np.stack((pixels_x, pixels_y, np.ones_like(pixels_x)), axis=-1)

    real_points_3d = np.ones_like(img) * -1

    for i, (annotations, known_point, depth) in enumerate(
        zip(plane_annotations, known_points, depths)
    ):
        if i == 5:
            break

        plane = get_plane_equation(annotations, K, known_point, depth)
        valid_pixels = pixels[plane_per_pixel == i].reshape(-1, 3, 1)

        points_3d = (K_inv @ valid_pixels).reshape(-1, 3)

        lambdas = - plane[-1] / (
            plane[0] * points_3d[..., 0] + plane[1] * points_3d[..., 1] + \
            plane[2] * points_3d[..., 2]
        )
        lambdas = lambdas.reshape(-1, 1)

        real_points_3d[plane_per_pixel == i] = lambdas * points_3d

    filtered_real_points_3d = real_points_3d[
        np.all(real_points_3d != -1, axis=-1)
    ].reshape(-1, 3)

    img_colors = img[np.all(real_points_3d != -1, axis=-1)].reshape(-1, 3) / 255.

    # fig = plt.figure(figsize=(12, 12))
    # ax = fig.add_subplot(projection='3d')

    # ax.scatter(
    #     filtered_real_points_3d[:, 0],
    #     filtered_real_points_3d[:, 1],
    #     filtered_real_points_3d[:, 2],
    #     c=img_colors)
    # plt.show()

    marker_data = go.Scatter3d(
        x=filtered_real_points_3d[:,0],
        y=filtered_real_points_3d[:,1],
        z=filtered_real_points_3d[:,2],
        marker=dict(
            size=2,
            color=img_colors,
            opacity=0.8
        ),
        mode='markers'
    )
    fig=go.Figure(data=marker_data)
    fig.show()

if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument(
        '--config-path',
        help="Defines the config file path.",
        type=str,
        default='configs/q3.yaml'
    )
    parser.add_argument(
        '--out-path',
        help="Defines the output file path.",
        type=str,
        default='output/q3'
    )
    parser.add_argument(
        '-l',
        '--load-annotations',
        help="Defines whether annotations should be loaded from file.",
        action='store_true'
    )
    args = parser.parse_args()

    os.makedirs(args.out_path, exist_ok=True)
    logging.basicConfig(
        filename=os.path.join(args.out_path, 'log.txt'),
        filemode='a',
        format='%(asctime)s,%(msecs)d %(name)s %(levelname)s %(message)s',
        datefmt='%H:%M:%S',
        level=logging.INFO
    )

    main(args)


"""Util functions for integration"""
import logging

from .const import MetadataFilter, PropertyToEntityDescription, DOMAIN, NAME

_LOGGER: logging.Logger = logging.getLogger(__package__)

def get_properties_by_filter(metadata: dict, filtering: MetadataFilter) -> dict:
    """Filter properties based on attributes for presentation"""
    result = {}
    for name, value in metadata.items():
        if (name in PropertyToEntityDescription.__members__) is False:
            continue
        if value.readable is not filtering.readable:
            continue
        if value.writeable is not filtering.writeable:
            continue
        if value.type in filtering.types:
            to_add = False

            if filtering.any_fields is None and filtering.no_fields is None:
                to_add = True
            else:
                if filtering.any_fields is not None:
                    for field in filtering.any_fields:
                        if value.__dict__.get(field, None) is not None:
                            to_add = True
                            break

                if filtering.no_fields is not None:
                    count_no_fields = len(filtering.no_fields)
                    for field in filtering.no_fields:
                        if value.__dict__.get(field, None) is not None:
                            count_no_fields = -1
                            break
                        else:
                            count_no_fields = count_no_fields - 1
                    if count_no_fields == 0:
                        to_add = True
            if to_add is True:
                result[name] = value
    return result

def get_product_properties_by_filter(lists: [], filtering: MetadataFilter):
    """Get product properties entitites list by filter"""
    product_properties = []
    for products in lists:
        for product in products:
            metadatas = get_properties_by_filter(product.metadata, filtering)
            for value in metadatas.values():
                product_properties.append(value)
    return product_properties

def get_device_info(product):
    """generate device info dict"""
    return {
        "identifiers": {(DOMAIN, product.serial_no)},
        "name": product.name,
        "model": product.model,
        "sw_version": product.software_version,
        "manufacturer": NAME,
    }


#!/usr/bin/env python
# -*- encoding: utf-8 -*-
import os
from setuptools import setup, find_packages

README = open(os.path.join(os.path.dirname(__file__), 'README.rst')).read()

def version():
    from gocd_cli.commands import echo
    return echo.__version__

setup(
    name='gocd-cli.commands.echo',
    author='Björn Andersson',
    author_email='ba@sanitarium.se',
    license='MIT License',
    description='An example echo command',
    long_description=README,
    version=version(),
    packages=find_packages(exclude=('tests',)),
    install_requires=[
        'gocd-cli>=0.7,<1.0',
    ],
)


import os

from django.core.management.base import BaseCommand
from django.conf import settings

try:
    import crontab
except (ImportError, ModuleNotFoundError):
    crontab = None

def find_job(tab, comment):
    for job in tab:
        if job.comment == comment:
            return job
    return None

class Command(BaseCommand):
    """
    Installs a cron tasks.
    """

    help = "Installs a cron tasks."

    def add_arguments(self, parser):
        parser.add_argument('--action', default="")

    def handle(self, *args, **options):
        """Installs Cron

        :param args: None
        :param options: None
        :return: None
        """
        if not os.path.isfile('/usr/bin/crontab'):
            print("WARNING: /usr/bin/crontab not found, skipping crontab config.")
            return

        if not crontab:
            print("WARNING: crontab module is not installed, skipping crontab config.")
            return

        action = options.get('action')
        tab = crontab.CronTab(user=True)
        virtualenv = os.environ.get('VIRTUAL_ENV', None)

        cwd = settings.PROJECT_DIR.replace('/', '_')

        jobs = [
            {
                'name': '{}_janeway_cron_job'.format(cwd),
                'time': 30,
                'task': 'execute_cron_tasks',
                'type': 'mins',
            },
            {
                'name': '{}_janeway_ithenticate_job'.format(cwd),
                'time': 30,
                'task': 'store_ithenticate_scores',
                'type': 'mins',
            },
            {
                'name': '{}_janeway_sitemaps_job'.format(cwd),
                'time': 4,
                'task': 'generate_sitemaps',
                'type': 'hourly',
            },
            {
                'name': '{}_janeway_reader_notifications'.format(cwd),
                'time': 23,
                'task': 'send_publication_notifications',
                'type': 'daily',
            },
        ]

        if settings.ENABLE_ENHANCED_MAILGUN_FEATURES:
            jobs.append(
                {
                    'name': '{}_janeway_mailgun_job'.format(cwd),
                    'time': 59,
                    'task': 'check_mailgun_stat',
                    'type': 'mins',
                }
            )

        for job in jobs:
            current_job = find_job(tab, job['name'])

            if not current_job:
                django_command = "{0}/manage.py {1}".format(settings.BASE_DIR, job['task'])
                if virtualenv:
                    command = '%s/bin/python3 %s' % (virtualenv, django_command)
                else:
                    command = '%s' % (django_command)

                cron_job = tab.new(command, comment=job['name'])

                if job.get('type') == 'daily':
                    cron_job.setall('0 {} * * *'.format(job['time']))
                elif job.get('type') == 'hourly':
                    cron_job.setall('0 */{} * * *'.format(job['time']))
                else:
                    cron_job.minute.every(job['time'])

            else:
                print("{name} cron job already exists.".format(name=job['name']))

        if action == 'test':
            print(tab.render())
        elif action == 'quiet':
            pass
        else:
            tab.write()


import numpy as np

class MatrixInterpolation:
    """
    This is a simple class for linear matrix interpolation.
    The intention is to create an interpolation method for AIC matrices, which is similar to but faster than
    interp1d from scipy.
    A test cases using unsteady AIC matrices of the Allegra configuration resulted in numerically equal results
    and a 5-10x faster computation time compared to scipy. Extrapolation is supported.

    Inputs
       x: 1-D array of n_samples
    data: 3-D array of matrices to interpolate, Notation [n_samples, n_rows, n_columns]

    Output
          2-D array of interpolated matrix values
    """

    def __init__(self, x, data):
        self.x = np.array(x)
        self.n_samples = len(self.x)
        self.data = np.array(data)
        self.gradients = np.zeros_like(self.data)

        self.calc_gradients()

    def __call__(self, i):
        return self.interpolate(i)

    def calc_gradients(self):
        # calculate the gradients between all samples
        for m in range(self.n_samples-1):
            self.gradients[m,:,:] = (self.data[m+1,:,:] - self.data[m,:,:]) / (self.x[m+1] - self.x[m])
        # repeat the last set of gradients to make sure there are right-sided gradients available in case of extrapolation
        self.gradients[-1,:,:] = self.gradients[-2,:,:]

    def interpolate(self, i):
        # find the nearest neighbor
        pos = np.abs(self.x - i).argmin()
        # calculate the delta
        delta = i - self.x[pos]
        # when the delta is negative, then take the left sided gradients, except when we are at the lower bound
        if delta < 0.0 and pos > 0:
            pos_gradients = pos - 1
        else:
            pos_gradients = pos
        # perform linear interpolation and return result
        return self.data[pos,:,:] + self.gradients[pos_gradients,:,:]*delta


from helper_functions import exercise

import argparse
import matplotlib.pyplot as plt
import pandas as pd
import random

from os import path
from sklearn.cluster import KMeans
from sklearn.decomposition import PCA
from sklearn.preprocessing import StandardScaler

@exercise
def zad1():
    data_path = 'dane/Sales_Transactions_Dataset_Weekly.csv'
    if not path.isfile(data_path):
        print(
            f'Brak pliku {data_path}, należy go pobrać z http://archive.ics.uci.edu/ml/machine-learning-databases/00396/Sales_Transactions_Dataset_Weekly.csv')
        return
    df = pd.read_csv(data_path, index_col='Product_Code')
    print(f'Wczytano {data_path}')
    # Dane zawierają kolumny użyteczne w tym zadaniu W0-W51, oraz niepotrzebne na poczet tego zadania - MIN, MAX oraz znormalizowane
    df = df.iloc[:, :52]
    print('Pozostawiono tylko kolumny W0-W51')
    # Pozostałe kolumny należy przeskalować, aby mozna było użyć algorytmu PCA
    scaler = StandardScaler()
    scaled_features = pd.DataFrame(scaler.fit_transform(df))
    scaled_features.columns = df.columns
    print('Przeskalona wartości przy pomocy StandardScaler')

    # Użycie algorytmu PCA, aby zmniejszyć wymiarowość danych
    pca = PCA(n_components=2)
    processed_data = pca.fit_transform(scaled_features)
    processed_df = pd.DataFrame(data=processed_data, columns=[f'COMP{i}' for i in range(processed_data.shape[1])])
    print('Zmniejszono wymiarowość do 2 przy użyciu PCA')
    return processed_df

@exercise
def zad2(clusters, data):
    kmeans = KMeans(n_clusters=clusters, init='k-means++', random_state=0)
    processed_df_kmeans = kmeans.fit_predict(data)

    markers = [(i, j, 0) for i in range(2, 10) for j in range(1, 3)]

    # Dodanie do wykresu poszczególnych klastrów
    for i in range(clusters):
        plt.scatter(
            data[processed_df_kmeans == i]['COMP0'],
            data[processed_df_kmeans == i]['COMP1'],
            s=20,
            c=[(random.random(), random.random(), random.random())],
            marker=markers[i],
            label=f'Skupienie {i}'
        )
    # Dodanie do wykresu centroidów
    plt.scatter(
        kmeans.cluster_centers_[:, 0],
        kmeans.cluster_centers_[:, 1],
        s=30,
        c='red',
        marker='*',
        label='Centroidy'
    )
    plt.title('K-MEANS++')
    plt.legend()
    plt.show()

@exercise
def zad4(data):
    wcss = []
    for i in range(2, 16):
        kmeans = KMeans(n_clusters=i, init='k-means++', max_iter=300, n_init=10, random_state=0)
        kmeans.fit(data)
        wcss.append(kmeans.inertia_)
    plt.plot(range(2, 16), wcss)
    plt.title('Elbow Method')
    plt.xlabel('Number of clusters')
    plt.ylabel('WCSS')
    plt.show()

def prepare_parser():
    parser = argparse.ArgumentParser(
        description='sum the integers at the command line')
    parser.add_argument(
        '--clusters', type=int, default=5,
        help='Number of clusters for k-means, default: 5')
    return parser

if __name__ == '__main__':
    parser = prepare_parser()
    args = parser.parse_args()
    data = zad1()
    zad2(args.clusters, data)
    zad4(data)


##############################################################
# KeOLA data directory monitoring tool - W.M. Keck Observatory
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# Author: Ian Cunnyngham
# Mentor: Dr. Luca Rizzi
#
#   This service watches the collection of active logs, tracking
# their addition and removal from active status, monitoring all
# their associated data directories for FITS data, and ingesting
# the header metadata of these files as they are added.
# Additionally, helper modules have been written to obtain
# additional information from the Keck's information relavant
# to each log including weather data and twilight information.
# Weather data is polled at weatherPollInterval min intervals,
# and can also be requested directly from the log interface.
# Twilight info is polled on initial ObsLog tracking, only
# adding it to the log if it is not present already.
#
#   All of this functionality runs through one cycle and then
# sleeps for sleepTime seconds
#
#   The intention of this script is that it be fully "stateless".
# That is to say, the script can crash and be restarted with no
# loss of continuity.  Nothing is stored internally that is not
# simply a convenient local copy of what is in the database.
#
################################################################

import os, time, sys
import shutil

from datetime import datetime, timedelta, date
try:
    from astropy.io import fits as pyfits
except ImportError:
    import pyfits
from astropy.io.fits.card import Undefined, UNDEFINED

import functools
import pymongo, bson
import warnings
import fnmatch
import logging

# Custom mododules for pulling in data from outside sources
#import urllib2
try:
    from urllib.request import urlopen
    #from urllib import URLError
    from urllib import error
except ImportError:
    from urllib2 import urlopen,URLError
import getWeather
import getSchedules

### Configuration ###

# How long (in seconds) should the script sleep in between monitoring cycles
sleepTime = 15

# How long (in minutes) between weather updates
weatherPollInterval = 60

# logging facility
logging.basicConfig(filename='/home/keola/obsMonitor/KeOLA/dataMon.logdir/dataMon-'+time.strftime("%d%b%Y")+'.log', level=logging.DEBUG)

### Observation Log monitoring Class ###

class ObsLog:
    def __init__(self, workingDB, logID):
        """ Initializes and begins tracking of a log that has been marked as active """

        self.db = workingDB
        self.id = logID

        # Query the database for this log's info and store it
        self.log = self.db.logs.find_one({"_id": logID})

        # Store the instrument name for conevenience
        self.instrument = self.log["instrument"].upper()

        # Query the database for this log's instrument information and store info
        self.instr = self.db.instruments.find_one({"name": self.instrument})

        # Determine the fits file name pattern to be used to find new files
        self.fnamePattern = "*.fits"
        if "fnamePattern" in self.instr:
            self.fnamePattern = self.instr["fnamePattern"]
        logging.info( "The file pattern is "+self.fnamePattern)

        # Determine if the "ignore_end_card" flag should be used in reading
        # this instruments FITS data
        if "missing_end_card" in self.instr and self.instr["missing_end_card"]:
            self.missing_end_card = True
        else:
            self.missing_end_card = False

        if "instrAttr" in self.instr:
            self.instrAttr = self.instr["instrAttr"]
        else:
            self.instrAttr = [0, "INSTRUME"]

        if "alternateName" in self.instr:
            self.alternateName = self.instr["alternateName"]
        else:
            self.alternateName = "None"

        # Catch if twilight information is missing, and if so, add it
        if "twilight" not in self.log:
            logging.info( "Appending twilight information to log " + str(self.id))

            # Catch potential errors trying to fetch scehdule data from the web
            try:
                # Get the schedules for this log's date, select Keck I's schedule
                delta=timedelta(days=1)
                twilight = getSchedules.getTwilight(self.log["utcDate"].date()-delta)
            except:
                logging.warning( "Error getting twilight info from schedule, appending empty entry")
                twilight = {}

            # Append and save it to the log
            self.log["twilight"] = twilight
            self.db.logs.save( self.log )

        # If twilight is properly attached to this log, update the sunset and sunrise times
        if ("twilight" in self.log) and ("sunset" and "sunrise" in self.log["twilight"]):
            global startPoll, endPoll
            sunrise = datetime.strptime(self.log["twilight"]["sunrise"], "%H:%M:%S")
            sunset = datetime.strptime(self.log["twilight"]["sunset"], "%H:%M:%S")
            startPoll = (sunset - timedelta( minutes=60 )).time()
            endPoll = (sunrise + timedelta( minutes=60 )).time()

        # Try to find the date of the last weather entry
        filter = {"logID":self.id, "type":"weather"}
        lastWeather = self.db.entries.find(filter).sort([("utcDate",-1)]).limit(1)

        if lastWeather.retrieved > 0:
            # If it exists, store the date.
            self.weatherUpdated = lastWeather[0]["utcDate"]
        else:
            # Else, make sure the weather will be updated on next polling
            # by setting a phantom last update time
            self.weatherUpdated = (datetime.utcnow() - timedelta( minutes=weatherPollInterval+1 ))

    def alertEntry(self, alert):
        aEntry = {"type": "alert",
            "title": alert,
            "logID": self.id,
            "utcDate": now }
        self.db.entries.insert_one( aEntry )

    def weatherEntry(self, weather):
        now = datetime.utcnow()

        try:
            w = weather[ self.instr["telescope"] ].current()
        except IOError:
            logging.warning( "Error opening weather log, appending empty entry")
            w = {}

        wEntry = {"type": "weather",
            "weather": w,
            "logID": self.id,
            "utcDate": now }
        self.db.entries.save( wEntry )

        self.weatherUpdated = now

    def excludeEntry(self, f, dir, reason=""):
        exEntry = {"type": "exclude",
            "filename": f,
            "directory": dir,
            "reason": reason,
            "logID": self.id,
            "utcDate": datetime.utcnow()}
        self.db.entries.save( exEntry )

    def startDir(self, dir):
        """ Start tracking a directory now that FITS files have been found in it """
        # append the directory to the activeDirs list
        self.log["activeDirs"].append( dir )

        # Save the change to the database
        db.logs.save( self.log )

    def stopDir(self, dir):
        """ Stop actively watching a directory """
        # Remove the directory from the activeDirs list
        self.log["activeDirs"].remove( dir )

        # Save the change to the log
        db.logs.save( self.log )

    def trackDirs(self):
        # Find the set of all directories not currently marked active and iterate through them
        for d in ( set(self.log["dataDirs"]) - set(self.log["activeDirs"]) ):
            # Try to switch to the directory, but don't worry if this fails
            try:
                os.chdir( d )
            except OSError:
                pass
            else:
                # When in the directory, see if the number of .fits files in this
                # directory exceeds 0.  If it does, start the log with this as
                # the dataDir
                if len( [f for f in os.listdir(".") if fnmatch.fnmatch(f,self.fnamePattern) ] ) > 0:
                    self.startDir(d)

                    # Print output and append a log entry
                    logging.info( "Now watching"+str(d)+ "for log"+ str(logID)+ "at"+ str(datetime.utcnow())+ "UTC")
                    self.alertEntry( "Data found in "+ d +".  Now tracking." )

        # Now iterate through all the active directories
        if len(self.log["activeDirs"]) > 0:
            # Find all the tracked fits files for this log and store it
            self.trackedFITS = self.findTrackedFITS()

            # Monitor each active directory
            for d in self.log["activeDirs"]:
                self.monitorDir( d )

    def findTrackedFITS(self):
        """ Find files for the current log that are tracked by the database already """

        # Start an empty dictionary whose keys will store which directories files
        # are from, and whose values store a list of the filenames
        tFiles = {}

        for d in self.log["dataDirs"]:
            tFiles[ d ] = []

        #   Search within the working database, in the collection "fits"
        # for any documents whose "logID" key has a value matching the
        # this log's logID.  Only return value of the "filename" and
        # "directory" fields
        for f in self.db.fits.find({"logID": self.id}, {"filename": 1, "directory": 1}):
            tFiles[ f["directory"] ].append( f["filename"] )

        # Do the same thing for excluded files
        for f in self.db.entries.find({"logID": self.id, "type": "exclude"}):
            tFiles[ f["directory"] ].append( f["filename"] )

        # Return all files tracked and excluded
        return tFiles

    def monitorDir(self, dir):
        """ Find any new fits files in this log's data directory and track them """
        # Try to change to the data directory for this log
        try:
            os.chdir(dir)
        except OSError:
            # Stop trying to monitor this directory for now
            self.stopDir( dir )

            # Print output and append log entry
            logging.warning("Can no longer access"+ str(dir)+ "for log"+str(self.id)+ ".  Removed from active monitoring.")
            self.alertEntry( "Can no longer access "+ dir +". Removed it from active monitoring." )

            return

        # Create a list of files in the current directory which end in ".fits"
        curFiles = [f for f in os.listdir(".") if  fnmatch.fnmatch(f,self.fnamePattern) ]
        if self.trackedFITS[dir] != curFiles:
            # Find the set of new files
            newFiles = set( curFiles )-set( self.trackedFITS[dir] )

            for f in newFiles:
                logging.info( "Found file " + f + ". Attempting to add to database")
                # esclude files with "mask" in their name
                if 'mask' in f:
                    continue
                # check file length:
                if os.path.getsize(f) == 0:
                    logging.warning('file %s has zero lengh. skipping for now...' % str(f))
                    continue
                # Find the time of most recent modification
                modOn = datetime.fromtimestamp( os.stat(f).st_mtime )

                # Try to open the fits file in pyfits
                logging.info("Attempting to add file %s" % (str(f)))
                for t in range(3):
                    logging.info( "Try add number "+str(t+1))
                    try:
                        time.sleep(5)
                        if self.missing_end_card:
                            fitsHdrs = pyfits.getheader(f,ignore_missing_end=True)
                        else:
                            fitsHdrs = pyfits.getheader(f)
                    except UserWarning:
                        if t != 2:
                            logging.warning( "Truncation caught, retrying in 5 seconds")
                        else:
                            logging.warning( "Giving up on reading " + f + ".  Adding to exclusion list")
                            self.excludeEntry(f, dir, "Repeated truncate error")
                    except IOError:
                        if t != 2:
                            logging.warning( "IOError caught, retrying in 5 seconds")
                        else:
                            logging.warning( "Giving up on reading " + f + ".  Adding to exclusion list")
                            self.excludeEntry(f, dir, "Repeated IOError")
                    except:
                        self.excludeEntry(f,dir,"Something wrong with this file: %s")
                    else:
                        # Successful, don't retry
                        break
                    time.sleep(5)

                # If fitsHdrs is now defined, go ahead
                if 'fitsHdrs' in locals():
                    #   Create a list representing all the headers in the fits file,
                    # each element of which is a dictionary containing all the header information
                    # as key, value pairs.
                    #
                    #   For instance, to access the tag "AIRMASS" in the 0th header of a fits file:
                    # headers[0]["airmass"]

                    headers = []
                    #for h in fitsHdrs:
                    headDict = {}
                    #try:
                    #print(fitsHdrs.keys())
                    for k in fitsHdrs.keys():
                        if k == "COMMENT" and list(fitsHdrs.keys()).count("COMMENT")>1:
                            continue
                        if k =="":
                            continue
                        if "HEART" in k or "TARGEL" in k or "TARGAZ" in k:
                            continue
                        key = str.replace(k,".","-")
                        try:
                            v = fitsHdrs[k]
                            if type(v) is str or k == "COMMENT":
                                v = str(v).strip()
                                v = str.replace(v,"'","")
                        except:
                            v='!KeyError!'
                        if isinstance(v, Undefined):
                            v = 'UNDEFINED'

                        headDict[key]=v

                    #for k, v in fitsHdrs.iteritems():
                    #            # Dictionary keys must not have "." for mongoDB, make sure none do
                    #            key = str.replace(k, ".", "-")
                    #            if type(v) is str:
                    #               v = v.strip()
                    #            headDict[key] = v
                    headers.append( headDict )
                    #except:
                    #        print "Error parsing a keyword for file "+str(f)
                    #        print key
                    #        #raise RuntimeError

                    # Make sure this fits file belongs to the correct instrument
                    try:
                        fitsInstr =functools.reduce(lambda memo, i: memo[i], self.instrAttr, headers)
                    except KeyError:
                        self.alertEntry( "Warning: " + str( self.instrAttr ) + " attribute not found for " + f)
                    else:
                        if self.instrument.lower() not in str(fitsInstr).lower():
                            if self.alternateName != "None" and self.alternateName not in str(fitsInstr):
                                self.alertEntry( "Warning: Neither " + self.instrument+" nor " + self.alternateName + " in instrument keyword of " + f)
                            elif self.alternateName == "None":
                                self.alertEntry( "Warning: " + self.instrument+" not in instrument keyword of " + f)
                    # Create a record to be stored in the database
                    fRecord = {"filename": f,
                        "directory": dir,
                        "logID": self.id,
                        "last_modified": modOn,
                        "headers": headers }

                    # Insert record into the database
                    #try:
                    sys.stdout.write( "adding file "+str(f) + "\n")
                    #print ("header: "+str(fRecord))
                    self.db.fits.insert_one( fRecord )
                    #except:
                    #    self.alertEntry("Warning: file %s has been skipped because of a bad header" % (str(f)))
                    #    print "Skipping file "+str(f)
                    # Insert new entry for frontend showing a new file was found
                    #   Inserting the fits ID
                    fEntry = {"logID": self.id,
                        "type": "file",
                        "name": f,
                        "directory": dir,
                        "utcDate": datetime.utcnow(),
                        "fitsID": fRecord["_id"] }
                    self.db.entries.insert_one( fEntry )

                    del fitsHdrs

### Main Program ###

# Convert pyfits file truncation warning into an error so we can catch it
warnings.filterwarnings('error', '.*truncated.*');

# Connect to MongoDB database (default connection options work for now)
#conn = pymongo.Connection()
conn = pymongo.MongoClient('observinglogs,observinglogs2,observinglogs3',replicaSet='KEOLA')
db = conn.obsLog

# Instatiate two getWeather.Weather()s to pull data from meteorolgical logs
# (One for each telescope)
weather = {1: getWeather.Weather(1), 2: getWeather.Weather(2) }

# Create global startPoll and endPoll times, based on the
# sunset and sunrise times +- and hour.  They will be
# updated every time a log with twilight information
# is added.  This will be used for determining
# when weather polling should start
# (Default to False to make sure they are only
#  ued when defined properly)
startPoll = False
endPoll = False

# Empty dictionary whose keys will be logIDs
# and whose values will be the corresponding instance of ObsLog
curLogs = {}

# ... same as above, but for proto logs
curPLogs = {}

# Continuously monitor this directory until forced to exit
while True:

    ### Handle active logs ###

    #####
    # Respond to changes in what logs are marked as active

    # Get a list of active logIDs from the database
    activeLogIDs = [ l["logID"] for l in db.activeLogs.find() ]

    # Get a list of currently tracked logIDs
    curLogIDs = [ id for id in curLogs.keys() ]

    # Instantiate a new ObsLog for each new logID found
    for logID in set(activeLogIDs) - set(curLogIDs):
        curLogs[ logID ] = ObsLog(db, logID)
        logging.info( "Tracking new log "+str(logID)+ " at "+ str(datetime.utcnow())+ "UTC")

    # Remove any logs that have become inactive (removed from the activeLogs db)
    for logID in set(curLogIDs) - set(activeLogIDs):
        del curLogs[ logID ]
        logging.info( "Ended tracking of log "+ str(logID)+ " at "+ str(datetime.utcnow())+ "UTC")

    #####
    # Weather requests

    # Get weather for every log that has a weatherRequest outstanding
    # ( Store a list of logs that we've responded too so that we don't
    #   respond to them more than once. )
    responded = []
    for req in db.entries.find({"type": "weatherRequest"}):
        logID = req["logID"]
        if logID not in responded:
            try:
                curLogs[ logID ].weatherEntry( weather )
            except:
                logging.info("Error parsing weather info %s" % (str(weather)))
            responded.append( logID )
        db.entries.remove( req )

    # Get the current time for use with further weather polling
    now = datetime.utcnow()

    # Determine if we are within sundown if possible, and set
    # whether we should be polling weather for the logs or not
    if startPoll and endPoll:
        if (now.time() > startPoll) and (now.time() < endPoll):
            pollWeather = True
        else:
            pollWeather = False
    else:
        pollWeather = True

    #####
    # Cycle through all active logs and monitor

    for obslog in curLogs.values():
        # Monitor the directories of each active log
        obslog.trackDirs()

        # Check if this log shoudld poll for new weather
        if pollWeather and (now - obslog.weatherUpdated) > timedelta( minutes=weatherPollInterval ):
            obslog.weatherEntry( weather )

    ### Sleep ###

    # sleep for sleepTime seconds until next check
    time.sleep( sleepTime )

    # DEBUG OUTPUT
    # print datetime.utcnow(), "cycle complete"


def edit_distance(s1, s2):
    time = 0
    if(len(s1) != 0):
        if(s1[0] != s2[0]):
            time += 1
        time += edit_distance(s1[1:], s2[1:])
    return time

def subsequence(s1, s2):
    if(len(s1) == 0):
        result = True
    elif(len(s2) == 0):
        result = False
    else:
        if(s1[0] != s2[0]):
            result = subsequence(s1, s2[1:])
        else:
            result = subsequence(s1[1:], s2[1:])
    return result

def perms(s):
    if(len(s) <= 1):
        result = {s}
    else:
        permutation = perms(s[1:])
        result = set()
        char = s[0]
        for perm in permutation:
            for index in range(len(perm) + 1):
                result.add(perm[:index] + char + perm[index:])
    return result


def quicksort(array, left, right):
    if left < right:
        partition_pos = partition(array, left, right)
        quicksort(array, left, partition_pos - 1)
        quicksort(array, partition_pos + 1, right)

def partition(array, left, right):
    i = left
    j = right - 1
    pivot = array[right]

    while i < j:
        while i < right and array[i] < pivot:
            i += 1
        while j > left and array[j] >= pivot:
            j -= 1

        if i < j:
            array[i], array[j] = array[j], array[i]

    if array[i] > pivot:
        array[i], array[right] = array[right], array[i]

    return i

input_str = input("Elementos da array: ")
arr = [int(x) for x in input_str.split(',')]

quicksort(arr, 0, len(arr) - 1)
print("Array ordenado:", arr)


# Hashmap: O((n-wordLen * wordsLen) * wordsLen)
class Solution:
    def findSubstring(self, s: str, words: List[str]) -> List[int]:
        n = len(s)
        wordLen = len(words[0])
        substrLen = wordLen * len(words)

        def check(substring):
            match = 0
            counter = Counter(words)
            for i in range(0, len(substring), wordLen):
                if counter[substring[i:i+wordLen]] > 0:
                    counter[substring[i:i+wordLen]] -= 1
                    match += 1
                else:
                    return False
            return match == len(words)

        res = []
        for i in range(0, n-substrLen+1):
            substr = s[i:i+substrLen]
            if check(substr):
                res.append(i)
        return res

# Sliding Window
class Solution:
    def findSubstring(self, s: str, words: List[str]) -> List[int]:
        n = len(s)
        wordLen = len(words[0])
        wordsLen = len(words)
        counter = Counter(words)
        res = []

        for start in range(wordLen):
            found = defaultdict(int)
            i = start
            count = 0
            head = i
            while i < n:
                if i + wordLen > n or s[i:i+wordLen] not in counter: # skip invalid word
                    found.clear()
                    count = 0
                    head = i+wordLen
                    i = head
                elif found[s[i:i+wordLen]] == counter[s[i:i+wordLen]]: # already has enough current word. current word is excess
                    found.clear()
                    count = 0
                    head += wordLen
                    i = head
                else: # found valid word and not a excess of current count
                    found[s[i:i+wordLen]] += 1
                    i += wordLen
                    count += 1

                if count == wordsLen:
                    res.append(head)
                    found.clear()
                    count = 0
                    head += wordLen
                    i = head
        return res

# Sliding Window: TLE
class Solution:
    def findSubstring(self, s: str, words: List[str]) -> List[int]:
        n = len(s)
        wordLen = len(words[0])
        substrSize = wordLen * len(words)
        res = []

        l, r = 0, 0
        while r < n:
            r += 1

            while r-l == wordLen:
                counter = Counter(words)
                match = 0
                offset = 0
                while counter[s[l+offset:r+offset]] > 0:
                    counter[s[l+offset:r+offset]] -= 1
                    match += 1
                    offset += wordLen
                    if match == len(words):
                        res.append(l)
                l += wordLen

        return res

        # Brute Force, find all permutation
        # permutations = set()
        # visited = set()
        # def dfs(state):
        #     if len(state) == len(words):
        #         permutations.add("".join(state))
        #         return
        #     for i in range(len(words)):
        #         if i in visited: continue
        #         visited.add(i)
        #         state.append(words[i])
        #         dfs(state)
        #         state.pop()
        #         visited.remove(i)
        # dfs([])

        # res = []
        # length = len(words) * len(words[0])
        # for i in range(len(s)-length):
        #     if s[i:i+length] in permutations:
        #         res.append(i)
        # return res

Sliding Window/30. Substring with Concatenation of All Words/solution.py


#coding=utf-8
import re
import json

import sys
version = sys.version_info
major_version = version[0]
if major_version == 3:
    from urllib import request
    urlopen = request.urlopen
    Request = request.Request
elif major_version == 2:
    from urllib2 import urlopen
    from urllib2 import Request

def __crawler__():
    headers = {
        'user-agent': "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36"
    }
    req = Request("http://www.stats.gov.cn/tjsj/tjbz/xzqhdm/201703/t20170310_1471429.html",
                  headers=headers)
    r = urlopen(req)
    return r.read().decode('utf-8')

def __process__(text):
    matched_obj = re.findall(r'
.*?
', text, re.M | re.I)

    data = {
        'province': [],
        'city': [],
        'district': []
    }
    for html in matched_obj:
        print(html)
        searched_obj = re.search(r'(\d+).*?\s*(\w+)',
                                 html, re.M | re.I)
        if searched_obj:
            result_l = searched_obj.groups()
            if result_l and len(result_l) == 2:
                region_id, region_name = result_l
                code = int(region_id)
                if code % 10000 == 0:
                    data['province'].append({'code': region_id, 'name': region_name})
                elif code % 100 == 0:
                    data['city'].append({'code': region_id, 'name': region_name})
                else:
                    data['district'].append({'code': region_id, 'name': region_name})
    return data

class RegionCrawler(object):
    def __init__(self):
        self._region_data = __process__(__crawler__())

    @property
    def data(self):
        return self._region_data

    def to_json(self):
        return json.dumps(self.data)

if __name__ == '__main__':
    print(RegionCrawler().data)


import  multiprocessing
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.figure import Figure
import time
import sys
import numpy as np
x = 15
tiempoG,escalonG,salidaG= [0],[0],[0]
class PlotCanvas(FigureCanvas):
    def __init__(self, parent=None, width=5, height=4.5, dpi=100):
        self.fig = Figure(figsize=(width, height), dpi=dpi)
        self.axes = self.fig.add_subplot(111)
        self.axes.set_xscale = 'linear'
        FigureCanvas.__init__(self, self.fig)
        self.setParent(parent)
        # FigureCanvas.setSizePolicy(self, QSizePolicy.Expanding, QSizePolicy.Expanding)
        # FigureCanvas.updateGeometry(self)

class App(QMainWindow):
    def __init__(self):
        super().__init__()
        self.title = 'Simulacion'
        self.width = 900
        self.height = 530
        self.left = 10
        self.top = 40
        self.b0 = 0

        self.initUI()

    def initUI(self):
        self.setWindowTitle(self.title)
        self.setGeometry(self.left, self.top, self.width, self.height)
        self.panel()
        self.b0.clicked.connect(self.hola)
        self.b1.clicked.connect(self.adios)
        self.m = PlotCanvas(self, dpi=80, width=10.4, height=4.2)
        self.m.axes.grid()
        self.m.move(26, 25)

        self.show()

    def panel(self):
        self.b0 = QPushButton('Hola', self)
        self.b0.move(150,450)
        self.b1 = QPushButton('adios', self)
        self.b1.move(300,450)

    @pyqtSlot()
    def hola(self):

        self.P1 = multiprocessing.Process(target=App.f1, args=(self,i))
        self.P2 = multiprocessing.Process(target=self.plot, args = (tiempo, salida, escalon,a))
        a.value, tiempo.value, salida.value, escalon.value = 1, 0, 0, 0
        self.P1.start()
        self.P2.start()

    @pyqtSlot()
    def adios(self):
        a.value = 0
        self.P1.join()
        self.P2.join()

    def plot(self,tiempo,salida,escalon,a):
        global tiempoG,escalonG,salidaG
        while a.value:
            tiempoG = np.append(tiempoG, tiempo.value)
            salidaG = np.append(salidaG, salida.value)
            escalonG = np.append(escalonG, escalon.value)
            self.m.axes.set_ylim(0, 1)
            # Se desabilita el autosacle
            self.m.axes.set_autoscale_on(False)
            # se crean las lineas vacias
            self.m.axes.plot(tiempoG, salidaG, 'r', tiempoG, escalonG, 'b')
            self.m.axes.legend(['Salida', 'Escalon'], shadow=True, fontsize='medium', fancybox='True', loc=1)
            self.m.axes.set_title(u'Control Adaptativo')
            self.m.axes.set_ylabel(u'Amplitud [%]')
            self.m.axes.set_xlabel(u'Tiempo [s]')
            self.m.axes.minorticks_on()
            self.m.draw()
            time.sleep(0.5)

    def f1(self,i):
        global x
        i.value = 0.0
        while 1:
            i.value += 1
            print("i: ", i.value*x)
            time.sleep(1)

if __name__ == '__main__':
    app = QApplication(sys.argv)
    ex = App()
    q= multiprocessing.Queue()
    a = multiprocessing.Value('i', 0)
    i = multiprocessing.Value('d', 0.0)
    tiempo = multiprocessing.Value('d',0.0)
    salida = multiprocessing.Value('d', 0.0)
    escalon = multiprocessing.Value('d', 0.0)
    sys.exit(app.exec_())


from Source.Logic_Gates.Mux import Mux
from Source.Pre_Built_Gates.Power import Power
class Mux16:
    def __init__(self,a,b,sel) -> None:
        self.a=a
        self.b=b
        self.sel=sel
        self.out=[Power(False) for _ in range(16)]
        self()
    def __call__(self) -> None:
        for i in range(16):
            self.out[i].out=Mux(self.a.out[i],self.b.out[i],self.sel).out


"""Scrape deepl via pyppeteer.

org deepl4a

set PYTHONPATH=../get-ppbrowser

from pathlib import Path
import os
os.environ['PYTHONPATH'] = Path(r"../get-ppbrowser")
"""
# pylint: disable=too-many-arguments, too-many-locals, too-many-branches, too-many-statements, broad-except
import asyncio

# import os
import re
import sys
from random import randint
from typing import Any, Callable, Optional, Union
from urllib.parse import quote

import logzero

# import pyppeteer
from about_time import about_time
from get_ppbrowser.get_ppbrowser import get_ppbrowser
from logzero import logger
from pyquery import PyQuery as pq

URL = r"https://www.deepl.com/translator"

_ = """
with CodeTimer(name="loading BROWER", unit="s"):
    # from deepl_tr_pp.deepl_tr_pp import deepl_tr_pp, LOOP, BROWSER, get_ppbrowser
    from get_ppbrowser.get_ppbrowser import LOOP, BROWSER

with CodeTimer(name="start a page", unit="s"):
    # URL = 'https://www.deepl.com/translator#auto/zh/'
    PAGE = LOOP.run_until_complete(BROWSER.newPage())
    try:
        LOOP.run_until_complete(PAGE.goto(URL, timeout=45 * 1000))
    except Exception as exc:
        logger.error("exc: %s, exiting", exc)
        raise SystemExit("Unable to make initial connection to deelp") from exc
# """

def with_func_attrs(**attrs: Any) -> Callable:
    """with_func_attrs"""

    def with_attrs(fct: Callable) -> Callable:
        for key, val in attrs.items():
            setattr(fct, key, val)
        return fct

    return with_attrs

@with_func_attrs(from_lang="", to_lang="", text="")
async def deepl_tr(
    text: str,
    from_lang: str = "auto",
    to_lang: str = "zh",
    page=None,
    verbose: Union[bool, int] = False,
    timeout: float = 5,
    headless: Optional[bool] = None,
):
    """Deepl via pyppeteer.

    text = "Test it and\n\n more"
    from_lang="auto"
    page=None
    to_lang="zh"
    verbose=True
    """
    #

    # set verbose=40 to turn most things off
    if isinstance(verbose, bool):
        if verbose:
            logzero.setup_default_logger(level=10)
        else:
            logzero.setup_default_logger(level=20)
    else:  # integer: log_level
        logzero.setup_default_logger(level=verbose)

    logger.debug(" Entry ")

    try:
        text = text.strip()
    except Exception as exc:
        logger.error(exc)
        logger.info(" not a string?")
        raise

    # if text remains the same but from_lang or to_lang changed, attach random string \d_
    # if text.strip() == deepl_tr.strip() and (deepl_tr.from_lang
    logger.debug(
        "text==deepl_tr.text: %s==%s, from_lang==deepl_tr.from_lang: "
        "%s==%s, to_lang==deepl_tr.to_lang: %s==%s",
        text,
        deepl_tr.text,
        from_lang,
        deepl_tr.from_lang,
        to_lang,
        deepl_tr.to_lang,
    )

    same_langs = from_lang == deepl_tr.from_lang and to_lang == deepl_tr.to_lang

    if text == deepl_tr.text:
        if not same_langs:
            deepl_tr.text = text
            _ = randint(1, 1000)
            logger.debug("attaching extra")
            text = f"{text} {_}_"
    logger.debug("text: %s", text)

    deepl_tr.from_lang = from_lang
    deepl_tr.to_lang = to_lang

    # reuse page
    try:
        _ = deepl_tr.page  # run previously
        page = deepl_tr.page
    except AttributeError:
        if page is None:
            try:
                if headless is None:
                    browser = get_ppbrowser()
                else:
                    browser = get_ppbrowser(headless=headless)
            except Exception as exc:
                logger.error(exc)
                raise

            try:
                page = await browser.newPage()
            except Exception as exc:
                logger.error(exc)
                raise

            url = r"https://www.deepl.com/translator"
            try:
                await page.goto(url, timeout=45 * 1000)
            except Exception as exc:
                logger.error(exc)
                raise

            deepl_tr.page = page
        else:
            deepl_tr.page = page

    page = deepl_tr.page

    url0 = f"{URL}#{from_lang}/{to_lang}/"

    url_ = f"{URL}#{from_lang}/{to_lang}/{quote(text)}"

    # selector = ".lmt__language_select--target > button > span"

    if verbose < 11 or verbose is True:
        _ = False  # silent
    else:
        _ = True
    # with CodeTimer(name="fetching", unit="s", silent=_):
    with about_time() as dur:
        _ = """
        await page.goto(url0)

        try:
            await page.waitForSelector(selector, timeout=8000)
        except Exception as exc:
            raise
        # """

        try:
            content = await page.content()
        except Exception as exc:
            logger.error(exc)
            raise

        doc = pq(content)
        text_old = doc("#source-dummydiv").html()
        logger.debug("Old source: %s", text_old)

        try:
            deepl_tr.first_run
        except AttributeError:
            deepl_tr.first_run = 1
            text_old = "_some unlikely random text_"

        logger.debug(
            "text.strip(): %s, text_old.strip(): %s", text.strip(), text_old.strip()
        )

        # selector = "div.lmt__translations_as_text"
        if text.strip() == text_old.strip() and same_langs:
            logger.debug(" ** early result: ** ")
            logger.debug(
                "%s, %s", text, doc(".lmt__translations_as_text__text_btn").text()
            )
            doc = pq(await page.content())
            # content = doc('.lmt__translations_as_text__text_btn').text()
            content = doc(".lmt__translations_as_text__text_btn").html()
        else:
            # record content
            try:
                # page.goto(url_)
                await page.goto(url0)
            except Exception as exc:
                logger.error(exc)
                raise

            try:
                # await page.waitForSelector(".lmt__translations_as_text", timeout=20000)
                await page.waitForSelector(".lmt__target_textarea", timeout=20000)
            except Exception as exc:
                logger.error(exc)
                raise

            doc = pq(await page.content())
            # content_old = doc('.lmt__translations_as_text__text_btn').text()
            content_old = doc(".lmt__translations_as_text__text_btn").html()

            # selector = ".lmt__translations_as_text"
            # selector = ".lmt__textarea.lmt__target_textarea.lmt__textarea_base_style"

            # selector = ".lmt__textarea.lmt__target_textarea"
            # selector = '.lmt__translations_as_text__text_btn'
            try:
                await page.goto(url_)
            except Exception as exc:
                logger.error(exc)
                raise

            try:
                # await page.waitForSelector(".lmt__translations_as_text", timeout=20000)
                await page.waitForSelector(".lmt__target_textarea", timeout=20000)
            except Exception as exc:
                logger.error(exc)
                raise

            doc = pq(await page.content())
            content = doc(".lmt__translations_as_text__text_btn").text()

            logger.debug("content_old: [%s], \n\t content: [%s]", content_old, content)

            # loop until content changed
            idx = 0
            # bound = 50  # 5s
            while idx < timeout / 0.1:
                idx += 1
                await asyncio.sleep(0.1)
                doc = pq(await page.content())
                content = doc(".lmt__translations_as_text__text_btn").html()
                logger.debug(
                    "content_old: (%s), \n\tcontent: (%s)", content_old, content
                )

                if content_old != content and bool(content):
                    break

            logger.debug(" loop: %s", idx)

    # deepl_tr.dur = dur
    deepl_tr.dur = dur.duration_human

    logger.debug(" Fini ")

    # await page.close()
    # await browser.close()
    # browser.process.communicate()

    # remove possible attached suffix
    content = re.sub(r"[\d]+_$", "", content.strip()).strip()

    return content

async def main():
    """Main."""
    text = "test this and that and more"
    res = deepl_tr(text)
    logger.info("%s, %s, time elased: %s", text, res, deepl_tr.dur)

    res = await deepl_tr(text, to_lang="de")

    logger.info("%s, %s, time elased: %s", text, res, deepl_tr.dur)

    # input("Press Enter to continue...")

    if len(sys.argv) > 1:
        text = " ".join(sys.argv[1:])
    else:
        text = "test this and that"

    res = await deepl_tr(text)
    logger.info("%s, %s,", text, res)

if __name__ == "__main__":
    try:
        loop = asyncio.get_event_loop()
    except Exception as exc_:
        logger.error(exc_)
        loop = asyncio.new_event_loop()
        asyncio.set_event_loop(loop)

    try:
        loop.run_until_complete(main())
    except Exception as exc_:
        logger.error(exc_)
    finally:
        loop.close()

    _ = """
    import sys

    text = "test this and that and more"
    res = LOOP.run_until_complete(deepl_tr(text))
    logger.info("%s, %s,", text, res)

    if len(sys.argv) > 1:
        text = " ".join(sys.argv[1:])
    else:
        text = "test this and that"

    res = LOOP.run_until_complete(deepl_tr(text))
    logger.info("%s, %s,", text, res)

    # """


#!/usr/bin/env python
# -*- coding: utf-8 -*-

from setuptools import setup
import os

# local wordlist
local = "local{sep}*.txt".format(sep=os.sep)
# remote wordlist
remote = "remote{sep}*.py".format(sep=os.sep)
# lib
lib = "lib{sep}*.py".format(sep=os.sep)

setup(
	name="knockpy",
	version="6.1.0",
	description="Knock is a Knockpy is a portable and modular python3 tool designed to quickly enumerate subdomains on a target domain through passive reconnaissance and dictionary attack.",
	url="https://github.com/guelfoweb/knock",
	author="Gianni 'guelfoweb' Amato",
	license="GPL-3.0",
	packages=["knockpy"],
	package_data={
		"knockpy": [lib, local, remote],
	},
	include_package_data=True,
	install_requires = [
			"requests",
			"beautifulsoup4",
			"colorama",
			],
	python_requires=">=3.6",
	entry_points={
		'console_scripts': [
			'knockpy=knockpy.knockpy:main',
		],
	}
)


import json

from django.forms import model_to_dict
from django.views.decorators.csrf import csrf_exempt
from django.http.response import JsonResponse
from api.models import Product, Category, Like

# CRUD - CRATE, READ, UPDATE, DELETE
from api.serializers import CategorySerializer1, CategorySerializer2, ProductSerializer1, ProductSerializer2, ProductSerializer3

@csrf_exempt
def category_list(request):
    if request.method == 'GET':
        categories = Category.objects.all()
        serializer = CategorySerializer1(categories, many=True)
        return JsonResponse(serializer.data, safe=False)
    if request.method == 'POST':
        data = json.loads(request.body)
        serializer = CategorySerializer1(data=data)
        if serializer.is_valid():
            serializer.save()
            return JsonResponse(serializer.data)
        return JsonResponse(serializer.errors, status=400)

@csrf_exempt
def category_detail(request, category_id):
    try:
        category = Category.objects.get(id=category_id)
    except Category.DoesNotExist as e:
        return JsonResponse({'error': str(e)}, status=400)

    if request.method == 'GET':
        serializer = CategorySerializer2(category)
        return JsonResponse(serializer.data)
    elif request.method == 'PUT':
        data = json.loads(request.body)
        serializer = CategorySerializer2(instance=category, data=data)
        if serializer.is_valid():
            serializer.save()
            return JsonResponse(serializer.data)
        return JsonResponse(serializer.errors, status=400)
    elif request.method == 'DELETE':
        category.delete()
        return JsonResponse({'deleted': True})

@csrf_exempt
def product_list(request):
    if request.method == 'GET':
        title = request.GET.get('title')
        if title:
            products = Product.objects.filter(name__icontains=title)
            print(products)
        else:
            products = Product.objects.all()
        for product in products:
            if Like.objects.filter(product=product).exists():
                product.liked = True
        products_list = [model_to_dict(product) for product in products]
        return JsonResponse(products_list, safe=False)
        # serializer = ProductSerializer1(products, many=True)
        # return JsonResponse(serializer.data, safe=False)

    if request.method == 'POST':
        data = json.loads(request.body)
        serializer = ProductSerializer1(data=data)
        if serializer.is_valid():
            serializer.save()
            return JsonResponse(serializer.data)
        return JsonResponse(serializer.errors, status=400)

@csrf_exempt
def product_detail(request, product_id):
    try:
        product = Product.objects.get(id=product_id)
    except Product.DoesNotExist as e:
        return JsonResponse({'error': str(e)}, status=400)

    if request.method == 'GET':
        serializer = ProductSerializer2(product)
        return JsonResponse(serializer.data)

    elif request.method == 'PUT':
        data = json.loads(request.body)
        serializer = ProductSerializer3(instance=product, data=data)
        if serializer.is_valid():
            serializer.save()
            return JsonResponse(serializer.data)
        return JsonResponse(serializer.errors, status=400)

    elif request.method == 'DELETE':
        product.delete()
        return JsonResponse({'deleted': True})


from turtle import forward, goto, left, pen, pendown, penup, right, back, exitonclick, speed
import turtle

speed(0)

xi=input("Zadejte rozměr x:")
yi=input("Zadejte rozměr y:")

x=int(xi)
y=int(yi)

penup()
goto(-300,-250)
pendown()

a=600//x

for _o in range(500//y):
    for _i in range(600//x):
        for _p in range(2):
            forward(x)
            left(90)
            forward(y)
            left(90)
        forward(x)
    left(90)
    forward(y)
    left(90)
    forward(a*x)
    left(180)

exitonclick()


import logging; log = logging.getLogger(__name__)
import production
from production.comms import online_mainloop, online_mainloop_pseudoasync
from production import scraper, json_format
from production.dumb_bots import FirstMoveBot
from production.cpp_bot import CppBot

json_format.REPORT_UNKNOWN_FIELDS = True

def check_FirstMoveBot():
    bot = FirstMoveBot()

    def predicate(g: scraper.Game):
        return scraper.only_eagers_p(g) and g.map_name == 'randomMedium.json'

    game = scraper.wait_for_game(predicate=predicate, extensions={'futures', 'splurges', 'options'})

    log.info(f'Joining {game}')
    scores = online_mainloop('punter.inf.ed.ac.uk', game.port, 'tbd testbot', bot, game=game)
    log.info(f'Scores: id={scores.state.get("my_id")} {scores.score_by_punter}')

def check_CppBot():
    bot = CppBot()

    def predicate(g: scraper.Game):
        return scraper.only_eagers_p(g) and g.map_name == 'randomMedium.json'

    game = scraper.wait_for_game(predicate=predicate, extensions={'futures', 'splurges', 'options'})

    log.info(f'Joining {game}')
    scores = online_mainloop('punter.inf.ed.ac.uk', game.port, 'tbd testbot', bot, game=game)
    log.info(f'Scores: id={scores.state.get("my_id")} {scores.score_by_punter}')

def check_FirstMove_and_CppBot(orgy=False):
    bots = [FirstMoveBot(), CppBot()]
    if orgy:
        bots += [FirstMoveBot(), CppBot()]

    def predicate(g: scraper.Game):
        return (g.map_name == ('randomMedium.json' if orgy else 'sample.json') and
                g.punters_num == 0)

    game = scraper.wait_for_game(predicate=predicate, patience=1000, extensions={'futures', 'splurges', 'options'})
    log.info(f'Joining {game}')

    loops = [online_mainloop_pseudoasync('punter.inf.ed.ac.uk', game.port, 'tbd testbot', bot, game=game) for bot in bots]
    while not all(loop is None for loop in loops):
        for i, loop in enumerate(loops):
            if loop is None:
                continue
            scores = next(loop)
            if scores is not None:
                log.info(f'Scores: id={scores.state.get("my_id")} {scores.score_by_punter}')
                loops[i] = None

def check_FirstMove_and_CppBot_orgy():
    return check_FirstMove_and_CppBot(True)

def main():
    from production.utils import config_logging
    config_logging()
    log.setLevel(logging.DEBUG)

    for check in (
                check_FirstMoveBot,
                check_CppBot,
                check_FirstMove_and_CppBot,
                check_FirstMove_and_CppBot_orgy,
                ):
        check()
        log.warn('')
        log.warn('-' * 50)
        log.warn('')

if __name__ == '__main__':
    main()


#!/usr/bin/env python

import six

from csvkit.convert.csvitself import csv2csv
from csvkit.convert.fixed import fixed2csv
from csvkit.convert.geojs import geojson2csv
from csvkit.convert.js import json2csv
from csvkit.convert.xls import xls2csv
from csvkit.convert.xlsx import xlsx2csv

SUPPORTED_FORMATS = ['fixed', 'xls', 'xlsx', 'csv', 'json', 'geojson']

# DBF is supported for Python 2 only
if six.PY2:
    from csvkit.convert.dbase import dbf2csv

    SUPPORTED_FORMATS.append('dbf')

def convert(f, format, schema=None, key=None, **kwargs):
    """
    Convert a file of a specified format to CSV.
    """
    if not f:
        raise ValueError('f must not be None')

    if not format:
        raise ValueError('format must not be None')

    if format == 'fixed':
        if not schema:
            raise ValueError('schema must not be null when format is "fixed"')

        return fixed2csv(f, schema, **kwargs)
    elif format == 'xls':
        return xls2csv(f, **kwargs)
    elif format == 'xlsx':
        return xlsx2csv(f, **kwargs)
    elif format == 'json':
        return json2csv(f, key, **kwargs)
    elif format == 'geojson':
        return geojson2csv(f, **kwargs)
    elif format == 'csv':
        return csv2csv(f, **kwargs)
    elif format == 'dbf':
        if six.PY3:
            raise ValueError('format "dbf" is not supported forthis version of Python.')
        return dbf2csv(f, **kwargs)
    else:
        raise ValueError('format "%s" is not supported' % format)

def guess_format(filename):
    """
    Try to guess a file's format based on its extension (or lack thereof).
    """
    last_period = filename.rfind('.')

    if last_period == -1:
        # No extension: assume fixed-width
        return 'fixed'

    extension = filename[last_period + 1:]

    if extension == 'xls':
        return extension
    elif extension == 'xlsx':
        return extension
    elif extension in ['json', 'js']:
        return 'json'
    elif extension == 'csv':
        return extension
    elif extension == 'fixed':
        return extension
    elif extension == 'dbf':
        return extension

    return None


import tkinter as tk
from datetime import datetime, timedelta

class CountdownTimer:
    def __init__(self, master):
        self.master = master
        self.master.title("Countdown Timer")

        # set up labels and entry boxes for user input
        self.day_label = tk.Label(master, text="Day:")
        self.day_label.grid(row=0, column=0)
        self.day_entry = tk.Entry(master)
        self.day_entry.grid(row=0, column=1)

        self.month_label = tk.Label(master, text="Month:")
        self.month_label.grid(row=1, column=0)
        self.month_entry = tk.Entry(master)
        self.month_entry.grid(row=1, column=1)

        self.year_label = tk.Label(master, text="Year:")
        self.year_label.grid(row=2, column=0)
        self.year_entry = tk.Entry(master)
        self.year_entry.grid(row=2, column=1)

        self.hour_label = tk.Label(master, text="Hour:")
        self.hour_label.grid(row=3, column=0)
        self.hour_entry = tk.Entry(master)
        self.hour_entry.grid(row=3, column=1)

        self.submit_button = tk.Button(master, text="Start Countdown", command=self.start_countdown)
        self.submit_button.grid(row=4, column=0, columnspan=2)

        # set up the countdown timer label
        self.timer_label = tk.Label(master, font=("Arial", 20, "bold"), text="00:00:00")
        self.timer_label.grid(row=5, column=0, columnspan=2)

    def start_countdown(self):
        # get user input and create datetime object
        day = int(self.day_entry.get())
        month = int(self.month_entry.get())
        year = int(self.year_entry.get())
        hour = int(self.hour_entry.get())
        countdown_datetime = datetime(year, month, day, hour)

        # check if entered time has already passed
        if datetime.now() > countdown_datetime:
            self.timer_label.configure(text="Please enter a valid future date and time.")
            return

        # update the countdown timer label every second
        def update_timer():
            time_remaining = countdown_datetime - datetime.now()
            if time_remaining <= timedelta():
                self.timer_label.configure(text="Countdown Finished!")
                return
            time_string = str(time_remaining).split(".")[0]
            self.timer_label.configure(text=time_string)
            self.timer_label.after(1000, update_timer)

        update_timer()

if __name__ == "__main__":
    root = tk.Tk()
    root.configure(bg="yellow")
    countdown = CountdownTimer(root)
    root.mainloop()


from ast import Str
from pymongo import MongoClient
from bson import ObjectId

class DepartmentBL:
  def __init__(self):
    self.__mongo_client = MongoClient(port=27017)
    self.__db = self.__mongo_client["Factory"]

  def get_all_departments(self):
    deps = []
    deps_cursor = self.__db["departments"].find({})
    for dep in deps_cursor:
      deps.append(dep)
    return deps

  def get_department(self,id):
    dep = self.__db["departments"].find_one({"_id":ObjectId(id)})
    return dep

  def add_department(self,obj):
    dep = {}
    dep["Name"] = obj["Name"]
    dep["Manager"] = obj["Manager"]

    self.__db["departments"].insert_one(dep)
    return "Created with ID: " + str(dep["_id"])

  def update_department(self,id,obj):
    dep = {}
    dep["Name"] = obj["Name"]
    dep["Manager"] = obj["Manager"]

    depp = self.__db["departments"].find_one({"_id":ObjectId(id)})
    all_emp = self.__db["employees"].find({})
    for e in all_emp:
      if "DepartmentId" in e:
        # for d in e["DepartmentId"]:
        for d in range(0,len(e["DepartmentId"])):
          if e["DepartmentId"][d]["Name"] == depp["Name"]:
          # if d["Name"] == depp["Name"]:
            self.__db["employees"].update_one({"_id":e["_id"]},{"$set":{"DepartmentId."+str(d)+".Name":obj["Name"]}})
            if e["DepartmentId"][d]["Manager"] == depp["Manager"]:
              self.__db["employees"].update_one({"_id":e["_id"]},{"$set":{"DepartmentId."+str(d)+".Manager":obj["Manager"]}})

    self.__db["departments"].update_one({"_id":ObjectId(id)},{"$set":dep})

    return "Updated!"

  def delete_department(self,id):
    dep = self.__db["departments"].find_one({"_id":ObjectId(id)})
    self.__db["departments"].delete_one({"_id":ObjectId(id)})
    all_emp = self.__db["employees"].find({})
    for e in all_emp:
      if "DepartmentId" in e:
        # for d in e["DepartmentId"]:
        for d in range(0,len(e["DepartmentId"])):
          if e["DepartmentId"][d]["Name"] == dep["Name"]:
          # if d["Name"] == dep["Name"]:
            self.__db["employees"].update_one({"_id":e["_id"]},{"$pull":{"DeparartmentId":{"$in":e["DepartmentId"][d]}}})
    return "Deleted!"


"""Optional type annotation transformations."""

import ast
import functools
import re
import sys
from typing import (
    cast,
    Dict,
    Union,
    Optional,
    Tuple,
    Sequence,
    NamedTuple,
    Pattern,
    List,
)

import docutils.nodes
import sphinx.application
import sphinx.domains.python
import sphinx.environment
import sphinx.util.logging
from sphinx import version_info

# `ast.unparse` added in Python 3.9
if sys.version_info >= (3, 9):
    from ast import unparse as ast_unparse
else:
    from sphinx.pycode.ast import unparse as ast_unparse
    from sphinx.pycode.ast import _UnparseVisitor

    def _monkey_patch_sphinx_ast_unparse():
        """Monkey patch Sphinx's `ast_unparse`.

        This adds support for some additional ast nodes that we require.
        """

        def visit_Module(self: _UnparseVisitor, node: ast.Module) -> str:
            return "\n".join(self.visit(el) for el in node.body)

        def visit_Expr(self: _UnparseVisitor, node: ast.Expr) -> str:
            return self.visit(node.value)

        _UnparseVisitor.visit_Module = visit_Module  # type: ignore[assignment]
        _UnparseVisitor.visit_Expr = visit_Expr  # type: ignore[assignment]

    _monkey_patch_sphinx_ast_unparse()

logger = sphinx.util.logging.getLogger(__name__)

PEP585_ALIASES = {
    "typing.Tuple": "tuple",
    "typing.List": "list",
    "typing.Dict": "dict",
    "typing.DefaultDict": "collections.defaultdict",
    "typing.OrderedDict": "collections.OrderedDict",
    "typing.Counter": "collections.Counter",
    "typing.Set": "set",
    "typing.Callable": "collections.abc.Callable",
    "typing.Deque": "collections.deque",
    "typing.FrozenSet": "frozenset",
    "typing.Type": "type",
    "typing.AbstractSet": "collections.abc.Set",
    "typing.ByteString": "collections.abc.ByteString",
    "typing.Collection": "collections.abc.Collection",
    "typing.Container": "collections.abc.Container",
    "typing.ItemsView": "collections.abc.ItemsView",
    "typing.KeysView": "collections.abc.KeysView",
    "typing.Mapping": "collections.abc.Mapping",
    "typing.MappingView": "collections.abc.MappingView",
    "typing.MutableMapping": "collections.abc.MutableMapping",
    "typing.MutableSequence": "collections.abc.MutableSequence",
    "typing.MutableSet": "collections.abc.MutableSet",
    "typing.Sequence": "collections.abc.Sequence",
    "typing.ValuesView": "collections.abc.ValuesView",
    "typing.Iterable": "collections.abc.Iterable",
    "typing.Iterator": "collections.abc.Iterator",
    "typing.Generator": "collections.abc.Generator",
    "typing.Hashable": "collections.abc.Hashable",
    "typing.Reversible": "collections.abc.Reversible",
    "typing.Sized": "collections.abc.Sized",
    "typing.Coroutine": "collections.abc.Coroutine",
    "typing.AsyncGenerator": "collections.abc.AsyncGenerator",
    "typing.AsyncIterable": "collections.abc.AsyncIterable",
    "typing.AsyncIterator": "collections.abc.AsyncIterator",
    "typing.Awaitable": "collections.abc.Awaitable",
    "typing.ContextManager": "contextlib.AbstractContextManager",
    "typing.AsyncContextManager": "contextlib.AbstractAsyncContextManager",
    "typing.Pattern": "re.Pattern",
    "typing.re.Pattern": "re.Pattern",
    "typing.Match": "re.Match",
    "typing.re.Match": "re.Match",
}

TYPING_NAMES = [
    "Any",
    "Tuple",
    "Optional",
    "Union",
    "Literal",
    "Callable",
    "List",
    "Dict",
    "Set",
    "FrozenSet",
    "Sequence",
    "Type",
]

def _get_ast_dotted_name(node: Union[ast.Name, ast.Attribute]) -> Optional[str]:
    if isinstance(node, ast.Name):
        return node.id
    parent = _get_ast_dotted_name(cast(Union[ast.Name, ast.Attribute], node.value))
    if parent is None:
        return None
    return f"{parent}.{node.attr}"

def _dotted_name_to_ast(
    name: str, ctx: ast.expr_context
) -> Union[ast.Name, ast.Attribute]:
    parts = name.split(".")
    tree: Union[ast.Name, ast.Attribute] = ast.Name(parts[0], ctx)
    for part in parts[1:]:
        tree = ast.Attribute(tree, part, ctx)
    return tree

if sys.version_info < (3, 8):
    _CONSTANT_AST_NODE_TYPES = (
        ast.Constant,
        ast.Num,
        ast.Str,
        ast.Bytes,
        ast.Ellipsis,
        ast.NameConstant,
    )
else:
    _CONSTANT_AST_NODE_TYPES = (ast.Constant,)

_CONFIG_ATTR = "_sphinx_immaterial_python_type_transform_config"

class TypeTransformConfig(NamedTuple):
    transform: bool
    transform_names: bool
    aliases: Dict[str, str]
    module_aliases: Dict[str, str]
    module_replacements_pattern: Optional[Pattern[str]]
    concise_literal: bool
    pep604: bool
    strip_modules_from_xrefs_pattern: Optional[Pattern[str]]

    def transform_dotted_name(self, dotted_name: str) -> str:
        aliases = self.aliases
        if aliases:
            new_name = aliases.get(dotted_name)
            if new_name is not None:
                return new_name
        module_replacements_pattern = self.module_replacements_pattern
        if module_replacements_pattern:
            dotted_name = module_replacements_pattern.sub(
                lambda m: self.module_aliases[m.group(0)], dotted_name
            )
        return dotted_name

def _retain_explicit_literal(node: ast.AST) -> bool:
    """Checks if the concise literal syntax cannot be used.

    Since constants cannot be types, there is no ambiguity.
    """
    return not isinstance(node, _CONSTANT_AST_NODE_TYPES)

class TypeAnnotationTransformer(ast.NodeTransformer):
    """Transforms the AST of a type annotation to improve readability.

    - Converts Union/Optional/Literal to "|" syntax allowed by PEP 604.  This
      syntax is not actually supported until Python 3.10 but displays better in
      the documentation.
    """

    config: TypeTransformConfig

    def visit_Name(self, node: ast.Name) -> ast.AST:
        if self.config.transform_names:
            dotted_name = node.id
            new_dotted_name = self.config.transform_dotted_name(dotted_name)
            if dotted_name != new_dotted_name:
                return _dotted_name_to_ast(new_dotted_name, node.ctx)
        return self.generic_visit(node)

    def visit_Attribute(self, node: ast.Attribute) -> ast.AST:
        if self.config.transform_names:
            dotted_name = _get_ast_dotted_name(node)
            if dotted_name is not None:
                new_dotted_name = self.config.transform_dotted_name(dotted_name)
                if new_dotted_name != dotted_name:
                    return _dotted_name_to_ast(new_dotted_name, node.ctx)
        return self.generic_visit(node)

    def visit_UnaryOp(self, node: ast.UnaryOp) -> ast.AST:
        if not isinstance(node.op, ast.Invert) or not isinstance(
            node.operand, ast.Subscript
        ):
            return self.generic_visit(node)
        operand, pep604_transformed = self._transform_subscript_pep604(node.operand)
        if pep604_transformed:
            return operand
        return ast.UnaryOp(node.op, operand)

    def _transform_subscript_pep604(self, node: ast.Subscript) -> Tuple[ast.AST, bool]:
        if not self.config.pep604:
            return self.generic_visit(node), False
        value = self.visit(node.value)
        id_str = _get_ast_dotted_name(value)
        if id_str in ("typing.Optional", "typing.Union", "typing.Literal"):
            slice_expr: ast.AST = node.slice
            elts: Sequence[ast.AST]
            if isinstance(slice_expr, ast.Index):
                slice_expr = slice_expr.value  # type: ignore
            if isinstance(slice_expr, ast.Tuple):
                elts = slice_expr.elts
            else:
                elts = [slice_expr]
            elts = [self.visit(x) for x in elts]
            if id_str == "typing.Optional":
                elts.append(ast.Constant(value=None))
            elif id_str == "typing.Literal":
                elts = [
                    ast.Subscript(value, x, node.ctx)
                    if not self.config.concise_literal or _retain_explicit_literal(x)
                    else x
                    for x in elts
                ]
            result = functools.reduce(
                (lambda left, right: ast.BinOp(left, ast.BitOr(), right)), elts
            )
            return result, True
        return ast.Subscript(value, self.visit(node.slice), node.ctx), False

    def visit_Subscript(self, node: ast.Subscript) -> ast.AST:
        return self._transform_subscript_pep604(node)[0]

def _monkey_patch_python_domain_to_transform_type_annotations():
    orig_parse_annotation = sphinx.domains.python._parse_annotation

    def _parse_annotation(annotation: str, env: sphinx.environment.BuildEnvironment):
        transformer_config = getattr(env, _CONFIG_ATTR, None)
        if transformer_config is None or not transformer_config.transform:
            return orig_parse_annotation(annotation, env)

        try:
            tree = ast.parse(annotation, type_comments=True)
        except SyntaxError:
            return orig_parse_annotation(annotation, env)

        transformer = TypeAnnotationTransformer()
        transformer.config = cast(TypeTransformConfig, transformer_config)
        tree = ast.fix_missing_locations(transformer.visit(tree))
        annotation = ast_unparse(tree)
        return orig_parse_annotation(annotation, env)

    sphinx.domains.python._parse_annotation = _parse_annotation  # type: ignore[assignment]

def _builder_inited(app: sphinx.application.Sphinx):
    config = app.config

    aliases: Dict[str, str] = {}
    module_aliases: Dict[str, str] = {}

    if config.python_transform_type_annotations_pep585:
        aliases.update(PEP585_ALIASES)

    if config.python_resolve_unqualified_typing:
        for name in TYPING_NAMES:
            full_name = f"typing.{name}"
            aliases[name] = aliases.get(full_name, full_name)

    if config.python_transform_typing_extensions:
        module_aliases["typing_extensions."] = "typing."

    for source_name, target_name in config.python_type_aliases.items():
        if source_name.endswith("."):
            if target_name and not target_name.endswith("."):
                logger.error(
                    "Invalid python_type_aliases entry %r -> %r: "
                    "source names ending in '.' must map to either "
                    "the empty string or a target name ending in '.'",
                    source_name,
                    target_name,
                )
                continue
            module_aliases[source_name] = target_name
        else:
            aliases[source_name] = target_name

    module_replacements_pattern: Optional[Pattern[str]] = None

    if module_aliases:
        module_replacements_pattern = re.compile(
            "|".join(f"(?:^{re.escape(name)})" for name in module_aliases)
        )

    if (
        config.python_transform_type_annotations_concise_literal
        and not config.python_transform_type_annotations_pep604
    ):
        logger.error(
            "python_transform_type_annotations_concise_literal=True "
            "requires python_transform_type_annotations_pep604=True"
        )

    strip_modules_from_xrefs_pattern: Optional[Pattern[str]] = None

    if config.python_module_names_to_strip_from_xrefs:
        strip_modules_from_xrefs_pattern = re.compile(
            "|".join(
                f"(?:^{re.escape(x)}\\.)"
                for x in config.python_module_names_to_strip_from_xrefs
            )
        )

    setattr(
        app.env,
        _CONFIG_ATTR,
        TypeTransformConfig(
            transform=bool(
                aliases
                or config.python_transform_type_annotations_pep604
                or module_aliases
            ),
            transform_names=bool(aliases or module_aliases),
            aliases=aliases,
            module_aliases=module_aliases,
            module_replacements_pattern=module_replacements_pattern,
            concise_literal=config.python_transform_type_annotations_concise_literal,
            pep604=config.python_transform_type_annotations_pep604,
            strip_modules_from_xrefs_pattern=strip_modules_from_xrefs_pattern,
        ),
    )

def _monkey_patch_python_domain_to_transform_xref_titles():
    orig_type_to_xref = sphinx.domains.python.type_to_xref

    def type_to_xref(
        target: str,
        env: sphinx.environment.BuildEnvironment,
        *args,
        suppress_prefix: bool = False,
    ) -> sphinx.addnodes.pending_xref:
        if version_info < (7, 2):
            # suppress_prefix may not have been used like a kwarg before v7.2.0 as
            # there was only 3 params for type_to_xref() prior to v7.2.0
            if args:
                suppress_prefix = args[0]
            node = orig_type_to_xref(target, env, suppress_prefix=suppress_prefix)
        else:
            node = orig_type_to_xref(  # type: ignore[misc]
                target, env, *args, suppress_prefix=suppress_prefix
            )
        if (
            not suppress_prefix
            and len(node.children) == 1
            and node.children[0].astext() == target
        ):
            transformer_config = getattr(env, _CONFIG_ATTR, None)
            if transformer_config is not None:
                strip_modules_from_xrefs_pattern = (
                    transformer_config.strip_modules_from_xrefs_pattern
                )
                if strip_modules_from_xrefs_pattern is not None:
                    new_target = strip_modules_from_xrefs_pattern.sub("", target)
                    if new_target != target:
                        del node.children[:]
                        node.append(docutils.nodes.Text(new_target))
        return node

    sphinx.domains.python.type_to_xref = type_to_xref  # type: ignore[assignment]

def setup(app: sphinx.application.Sphinx):
    _monkey_patch_python_domain_to_transform_type_annotations()
    _monkey_patch_python_domain_to_transform_xref_titles()

    app.add_config_value(
        "python_type_aliases",
        default={},
        types=(Dict[str, str],),
        rebuild="env",
    )

    app.add_config_value(
        "python_resolve_unqualified_typing",
        default=True,
        types=(bool,),
        rebuild="env",
    )

    app.add_config_value(
        "python_transform_typing_extensions",
        default=True,
        types=(bool,),
        rebuild="env",
    )

    app.add_config_value(
        "python_transform_type_annotations_pep585",
        default=True,
        types=(bool,),
        rebuild="env",
    )

    app.add_config_value(
        "python_transform_type_annotations_pep604",
        default=True,
        types=(bool,),
        rebuild="env",
    )

    app.add_config_value(
        "python_transform_type_annotations_concise_literal",
        default=True,
        types=(bool,),
        rebuild="env",
    )

    app.add_config_value(
        "python_module_names_to_strip_from_xrefs",
        default=[],
        types=(List[str],),
        rebuild="env",
    )

    app.connect("builder-inited", _builder_inited)

    return {
        "parallel_read_safe": True,
        "parallel_write_safe": True,
    }


import sys, heapq

scores_W, scores_K = [], []
sum_W, sum_K = 0, 0

heapq.heapify(scores_W)
heapq.heapify(scores_K)

for _ in range(10):
    heapq.heappush(scores_W, -int(sys.stdin.readline().rstrip()))

for _ in range(10):
    heapq.heappush(scores_K, -int(sys.stdin.readline().rstrip()))

for _ in range(3):
    sum_W += -heapq.heappop(scores_W)
    sum_K += -heapq.heappop(scores_K)

print(sum_W, sum_K)


'''
LDA 线性判别分析
通过将原数据集投影到新的区间（直线、平面等），实现同类聚集、异类分散的目的，同时可以降维
LDA区别与PCA主成分分析
'''

import  pandas as  pd
from sklearn.preprocessing import LabelEncoder
import numpy as np

def LoadData():
    feature_dict = {i: label for i, label in zip(
        range(4),
        ('sepal length in cm',
         'sepal width in cm',
         'petal length in cm',
         'petal width in cm',))}
    df = pd.io.parsers.read_csv(
        filepath_or_buffer='https://archive.ics.uci.edu/ml/machine-learning-databases/iris/iris.data',
        header=None,
        sep=',',
    )
    df.columns = [l for i, l in sorted(feature_dict.items())] + ['class label']
    df.dropna(how="all", inplace=True)  # to drop the empty line at file-end
    X = X = df.loc[:, ['sepal length in cm', 'sepal width in cm', 'petal length in cm', 'petal width in cm']].values
    y = df['class label'].values

    enc = LabelEncoder()
    label_encoder = enc.fit(y)
    y = label_encoder.transform(y) + 1
    label_dict = {1: 'Setosa', 2: 'Versicolor', 3: 'Virginica'}
    return X, y

def LDA():
    X, y = LoadData()

    # 计算均值向量
    np.set_printoptions(precision=4)
    mean_vectors = []
    for cl in range(1, 4):
        mean_vectors.append(np.mean(X[y == cl], axis=0))
        print('Mean Vector class %s: %s\n' % (cl, mean_vectors[cl - 1]))

    # 计算散度矩阵 S_W 和 S_B
    S_W = np.zeros((4, 4))
    for cl, mv in zip(range(1, 4), mean_vectors):
        class_sc_mat = np.zeros((4, 4))  # scatter matrix for every class
        for row in X[y == cl]:
            row, mv = row.reshape(4, 1), mv.reshape(4, 1)  # make column vectors
            class_sc_mat += (row - mv).dot((row - mv).T)
        S_W += class_sc_mat
    print('within-class Scatter Matrix:\n', S_W)

    overall_mean = np.mean(X, axis=0) #全局均值
    S_B = np.zeros((4, 4))
    for i, mean_vec in enumerate(mean_vectors):
        n = X[y == i + 1, :].shape[0]
        mean_vec = mean_vec.reshape(4, 1)  # make column vector
        overall_mean = overall_mean.reshape(4, 1)  # make column vector
        S_B += n * (mean_vec - overall_mean).dot((mean_vec - overall_mean).T)
    print('between-class Scatter Matrix:\n', S_B)

    # 计算特征向量和特征值
    eig_vals, eig_vecs = np.linalg.eig(np.linalg.inv(S_W).dot(S_B))

    # 取前K个特征向量
    eig_pairs = [(np.abs(eig_vals[i]), eig_vecs[:, i]) for i in range(len(eig_vals))]
    eig_pairs = sorted(eig_pairs, key=lambda k: k[0], reverse=True) #排序
    W = np.hstack((eig_pairs[0][1].reshape(4, 1), eig_pairs[1][1].reshape(4, 1))) #取前两个

    # 将样本集X按照W进行映射, X_lda即为新的样本集
    X_lda = X.dot(W)
    return  X_lda

if __name__ == '__main__':
    result = LDA()
    print(result)


"""Unit test for the geo module"""

import pytest
from floodsystem.station import MonitoringStation
from floodsystem.geo import *

# Create a global list of test stations
a = MonitoringStation("test-s-id1","test-m-id2","some station1",\
(0.0,0.0),(-2.3, 3.4445),"River 1","Town 1")

b = MonitoringStation("test-s-id1","test-m-id2","some station1",\
(-1.0,0.0),(5, -2),"River 742","Town 1")

c = MonitoringStation("test-s-id1","test-m-id2","some station1",\
(43.0,20),None,"River fhu","Town 1")

d = MonitoringStation("test-s-id1","test-m-id2","some station1",\
(100.654654, 100.6541),(45, 100),"65464","Town 1")

e = MonitoringStation("test-s-id1","test-m-id2","some station1",\
(-2.0, -1.0),(6, 0),"65464","Town 1")

test_stations = [a,b,c,d,e]

def test_stations_by_distance():

    test_res = stations_by_distance(test_stations,(0.0,0.0))

    assert [i[0] for i in test_res] == [a,b,e,c,d]

def test_stations_within_radius():

    test_res = stations_within_radius(test_stations,(0.0,0.0),1000)

    assert test_res == [a,b,e]

def test_rivers_with_station():

    test_res = rivers_with_station(test_stations)

    assert test_res == set([a.river,b.river,c.river,d.river])

def test_stations_by_river():

    test_res = stations_by_river(test_stations)

    assert test_res == {a.river:[a.name],b.river:[b.name],\
    c.river:[c.name],d.river:[d.name,e.name]}

def test_rivers_by_station_number():

    test_res = rivers_by_station_number(test_stations,1)
    assert test_res == [(d.river,2)]

    ###### I would do another test for this function but the results for
    ###### multiple rivers with same number of stations can be unpredictable


#!/usr/bin/env python

"""The setup script."""

from setuptools import find_packages, setup

with open('README.md') as readme_file:
    readme = readme_file.read()

with open('HISTORY.rst') as history_file:
    history = history_file.read()

with open('requirements.txt') as requirements_file:
    requirements = requirements_file.read()

setup_requirements = ['setuptools_scm', ]

test_requirements = ['pytest>=3', 'pytest-runner']

setup(
    author="USDA ARS Northwest Watershed Research Center",
    author_email='snow@ars.usda.gov',
    python_requires='>=3.6',
    classifiers=[
        'Development Status :: 2 - Pre-Alpha',
        'Intended Audience :: Developers',
        'License :: CC0 1.0 Universal (CC0 1.0) Public Domain Dedication',
        'Natural Language :: English',
        'Programming Language :: Python :: 3',
        'Programming Language :: Python :: 3.6',
        'Programming Language :: Python :: 3.7',
        'Programming Language :: Python :: 3.8',
    ],
    description="Take 2 for pysnobal in pure python",
    entry_points={
        'console_scripts': [
            'pysnobal=pysnobal.cli:main',
        ],
    },
    install_requires=requirements,
    license="CC0 1.0",
    long_description=readme,
    long_description_content_type="text/markdown",
    include_package_data=True,
    keywords='pysnobal',
    name='pysnobal',
    packages=find_packages(include=['pysnobal', 'pysnobal.*']),
    package_data={
        'pysnobal': [
            './pysnobal_core_config.ini'
        ]
    },
    use_scm_version={
        'local_scheme': 'node-and-date',
    },
    setup_requires=setup_requirements,
    test_suite='pysnobal.tests',
    tests_require=test_requirements,
    url='https://github.com/scotthavens/pysnobal',
    zip_safe=False,
)