#coding:utf-8
from sklearn.feature_extraction.text import CountVectorizer
from sklearn.feature_extraction.text import TfidfTransformer
import numpy as np
# corpus = ['This is the first document.',
#           'This is the second second document.']
#
# vectorizer = CountVectorizer()
# X = vectorizer.fit_transform(corpus)
# # print(X.toarray())
# counts = X.toarray()
# transformer = TfidfTransformer(smooth_idf=True)
# tfidf = transformer.fit_transform(counts)
# print(tfidf.toarray())

def data_for_train():
    with open('data/amazon_cells_labelled.txt','r')as f,\
            open('data/train.txt','w') as w1,\
            open('data/test.txt','w') as w2:
        data_list = []
        count = 0
        line = f.readline()
        while count < 800:
            line = ''.join(line)
            # print(line[:-2])
            # print(line[-2:-1])
            w1.write(line)
            line = f.readline()
            count = count + 1
        while 800 <= count < 1000:
            line = ''.join(line)
            # print(line[:-2])
            w2.write(line)
            line = f.readline()
            count = count + 1

def data_to_list(new_string):
    with open('data/train.txt','r') as r1,\
         open('data/test.txt','r') as r2:
        raw_list = []
        train_line = r1.readline()
        test_line = r2.readline()
        while train_line:
            train_line = ''.join(train_line)
            raw_list.append(train_line[:-3])
            train_line = r1.readline()
        while test_line:
            test_line = ''.join(test_line)
            raw_list.append(test_line[:-3])
            test_line = r2.readline()
        raw_list.append(new_string)
        return raw_list
# data_to_list("111")
def list_to_tfidf(new_string):
    vectorizer = CountVectorizer()
    raw_list = data_to_list(new_string)
    One_hot = vectorizer.fit_transform(raw_list)
    # print(One_hot.toarray().shape)
    counts = One_hot.toarray()
    transformer = TfidfTransformer(smooth_idf=True)
    tfidf = transformer.fit_transform(counts)
    train_tfidf = np.array(tfidf.toarray()[:800])
    test_tfidf = np.array(tfidf.toarray()[800:1000])
    new_tfidf = np.array(tfidf.toarray()[1000:1001])
    return  train_tfidf,test_tfidf,new_tfidf
# list_to_tfidf("111")
def get_label():
    with open('data/train.txt', 'r') as r1, \
            open('data/test.txt', 'r') as r2:
        label_list = []
        train_line = r1.readline()
        test_line = r2.readline()
        while train_line:
            train_line = ''.join(train_line)
            label_list.append(train_line[-2:-1])
            train_line = r1.readline()
        while test_line:
            test_line = ''.join(test_line)
            label_list.append(test_line[-2:-1])
            test_line = r2.readline()
        label_list = np.array(label_list)
        train_label = label_list[:800]
        test_label = label_list[800:1000]
    return train_label,test_label
# get_label()


from PIL import Image
import numpy as np
from numpy.typing import NDArray
import pandas as pd
import matplotlib
import matplotlib.pyplot as plt
import texfig

def white_background_highlight(
    ax: matplotlib.axes.Axes, x: NDArray, y: NDArray
) -> None:
    ax.plot(x, y, alpha=0.1, linewidth=6, color="white")
    ax.plot(x, y, alpha=0.2, linewidth=5, color="white")
    ax.plot(x, y, alpha=0.3, linewidth=4, color="white")
    ax.plot(x, y, alpha=0.4, linewidth=3, color="white")
    ax.plot(x, y, alpha=0.8, linewidth=2, color="white")

def plot_distribution_single_model(
    predicted_labels: list[NDArray],
    true_labels: list[NDArray],
    image_paths: list[str],
) -> None:
    plt.close("all")
    fig, ax = texfig.subplots(
        ratio=0.32,
        nrows=1,
        ncols=3,
    )

    suction_side = np.linspace(0, 1, num=len(predicted_labels[0]))

    white_background_highlight(ax[0], suction_side, predicted_labels[0])
    white_background_highlight(ax[0], suction_side, true_labels[0])
    ax[0].plot(suction_side, predicted_labels[0], color="royalblue", label="Predicted")
    ax[0].plot(
        suction_side,
        true_labels[0],
        color="tomato",
        label="True",
    )
    ax[0].set_xlim(xmin=0, xmax=1)
    ax[0].set_ylabel(r"$C_p$", rotation="horizontal", labelpad=1.0)
    ax[0].yaxis.set_label_coords(0, 1.02, transform=ax[0].transAxes)
    ax[0].set_ylim([-6, 0])
    ax[0].set_xlabel(r"$x/c$", labelpad=1.0)
    ax[0].set_xticks([0, 0.5, 1])
    ax[0].set_facecolor("none")

    ax_img1 = ax[0].inset_axes([0.0, 0.0, 1.0, 1.0], zorder=-50)
    img = Image.open(image_paths[0])
    img = img.rotate(8)
    img = img.crop((152, 100, 440, 340))
    ax_img1.imshow(img, aspect="equal", alpha=1.0)
    ax_img1.set_axis_off()

    white_background_highlight(ax[1], suction_side, predicted_labels[1])
    white_background_highlight(ax[1], suction_side, true_labels[1])
    ax[1].plot(suction_side, predicted_labels[1], color="royalblue", label="Predicted")
    ax[1].plot(suction_side, true_labels[1], color="tomato", label="True")
    ax[1].yaxis.set_ticklabels([])
    ax[1].set_ylim([-6, 0])
    ax[1].set_xlabel(r"$x/c$", labelpad=1.0)
    ax[1].set_xlim([0, 1])
    ax[1].set_xticks([0, 0.5, 1])
    ax[1].set_facecolor("none")

    ax_img2 = ax[1].inset_axes([0.0, 0.0, 1.0, 1.0], zorder=-50)
    img = Image.open(image_paths[1])
    img = img.rotate(8)
    img = img.crop((152, 100, 440, 340))
    ax_img2.imshow(img, aspect="equal", alpha=1.0)
    ax_img2.set_axis_off()

    white_background_highlight(ax[2], suction_side, predicted_labels[2])
    white_background_highlight(ax[2], suction_side, true_labels[2])
    ax[2].plot(suction_side, predicted_labels[2], color="royalblue")
    ax[2].plot(suction_side, true_labels[2], color="tomato")
    ax[2].yaxis.set_ticklabels([])
    ax[2].set_ylim([-6, 0])
    ax[2].set_xlabel(r"$x/c$", labelpad=1.0)
    ax[2].set_xlim([0, 1])
    ax[2].set_xticks([0, 0.5, 1])
    ax[2].set_facecolor("none")

    ax_img3 = ax[2].inset_axes([0.0, 0.0, 1.0, 1.0], zorder=-50)
    img = Image.open(image_paths[2])
    img = img.rotate(8)
    img = img.crop((152, 100, 440, 340))
    ax_img3.imshow(img, aspect="equal", alpha=1.0)
    ax_img3.set_axis_off()

    ax[0].legend(
        loc="upper right",
        bbox_to_anchor=(1.0, 0.7),
        frameon=False,
        handlelength=0.5,
        handletextpad=0.2,
    )

    @matplotlib.ticker.FuncFormatter
    def major_formatter(x, _):
        label = "{:.2f}".format(0 if round(x, 2) == 0 else x).rstrip("0").rstrip(".")
        return label

    @matplotlib.ticker.FuncFormatter
    def major_formatter2(x, _):
        label = "{:.5f}".format(0 if round(x, 5) == 0 else x).rstrip("0").rstrip(".")
        return label

    # Remove pointless zeros from ticks
    ax[0].xaxis.set_major_formatter(matplotlib.ticker.FuncFormatter(major_formatter))
    ax[1].xaxis.set_major_formatter(matplotlib.ticker.FuncFormatter(major_formatter))
    ax[2].xaxis.set_major_formatter(matplotlib.ticker.FuncFormatter(major_formatter))

    fig.subplots_adjust(
        left=0.03, right=0.97, top=0.92, bottom=0.2, hspace=0.2, wspace=0.2
    )

    texfig.make_fancy_axis(ax[0])
    texfig.make_fancy_axis(ax[1])
    texfig.make_fancy_axis(ax[2])

    texfig.savefig(
        "Predicted_Cp_distribution", dpi=1000, bbox_inches="tight", pad_inches=0
    )

def main() -> None:
    dataframe = pd.read_csv(
        # "./individual_dataframes/dataset_M02_Re60k_span04_g480_heave_periodic_k025.csv"
        # "./individual_dataframes/dataset_M01_Re200k_span01_g720_pitch_ramp_k005.csv"
        # "./individual_dataframes/dataset_M04_Re60k_span01_g480_pitch_ramp_k005.csv"
        # "./loader.csv"
        "./dataset.csv"
    )

    predictions = np.fromfile(
        "./outputs/predictions_DS1_2_Cp_Cp_distribution.npy",
        dtype=np.float32,
    ).reshape([-1, 300])

    targets = np.fromfile(
        "./outputs/targets_2_Cp_distribution.npy", dtype=np.float64
    ).reshape([-1, 300])

    # selected_indices = [400, 450, 480]  # DS1 2
    # selected_indices = [80, 640, 1300]  # DS1 17
    # selected_indices = [300, 650, 850]  # DS3 13
    # selected_indices = [200, 500, 600]  # DS1 test
    # selected_indices = [500, 800, 1390]  # Fig

    # selected_indices = [30, 20, 10]  # Fig 3
    # selected_indices = [200, 800, 1100]  # Fig 4
    # selected_indices = [200, 500, 600]  # Fig 5
    # selected_indices = [0, 650, 1300]  # Fig 6
    # selected_indices = [300, 650, 1300]  # Fig 7

    selected_indices = [300, 600, 729]  # Reviwer - instantaneous snapshots
    selected_indices = [30, 20, 40]

    selected_predictions = []
    selected_targets = []
    selected_image_paths = []

    for index in selected_indices:
        selected_predictions.append(predictions[index])
        selected_targets.append(targets[index])
        selected_image_paths.append(dataframe["images_pressure"][index])

    plot_distribution_single_model(
        selected_predictions, selected_targets, selected_image_paths
    )

if __name__ == "__main__":
    main()


import os
import shutil
from PySub import utils as _utils
from PySub import memory as _memory

import matplotlib.pyplot as plt
class ProjectFolder(object):
    """Class for managing a project folder
    """
    def __init__(self, folder, subfolders = []):
        """Initialize the ProjectFolder object. Also checks of the folder exists
        and creates it (if possible) when it doesn't exist. Does the same for any
        indicated subfolders.

        Parameters
        ----------
        folder : str
            Path to a folder.
        subfolders : list str, optional
            List of strings with folder names. Not paths!. The default is [],
            indicating no subfolders will be created.

        Raises
        ------
        Exception
            with invalid input.

        """
        if isinstance(folder, str):
            _utils.make_folder(folder)
            self.project_folder = folder
            for subfolder in subfolders:
                if isinstance(subfolder, str):
                    self.make_folder(subfolder)
        elif folder is None:
            self.project_folder = folder
        else:
            raise Exception(f"Invalid input type: {type(folder)}. Use a string representing a path.")

    @property
    def input_folder(self):
        return self._get_folder('input')

    @property
    def output_folder(self):
        return self._get_folder('output')

    @property
    def save_folder(self):
        return self._get_folder('save')

    def __repr__(self):
        return self.__str__()

    def __str__(self):
        return str('Project folder at:\n' + str(self.project_folder))

    def write_to_input(self, file, rename = None):
        """Copy an exisiting file to the input folder in the project tree.

        Parameters
        ----------
        file : str
            Location of an exisiting file.
        rename : str, optional
            New file name. The default is None.

        Raises
        ------
        Exception
            If the file does not exist.

        """
        if self.project_folder is not None:
            if os.path.isfile(file):
                file_basename, ext = os.path.splitext(file)
                if rename is None:
                    file_name = os.path.basename(file_basename)
                else:
                    _, rename_ext = os.path.splitext(rename)
                    if rename_ext:
                        ext = rename_ext
                    file_name = rename
                shutil.copyfile(file, self.input_file(file_name + ext))
            else:
                raise Exception('Invalid file. Cannot copy.')

    def move(self, new_folder):
        """Copy all the files in the project tree to a new location

        Parameters
        ----------
        new_folder : path
            Path to a folder.

        """

        if os.path.isdir(self.project_folder):
            old_folder = self.project_folder
            self.project_folder = new_folder
            _memory._move_tree(old_folder, self.project_folder)

    def _get_file(self, name, folder):
        if os.path.isdir(os.path.dirname(name)):
            return name
        self._get_folder(folder)
        if self.project_folder is not None:
            return os.path.join(getattr(self, f'{folder}_folder'), name)

    def _get_folder(self, folder):
        if self.project_folder is not None:
            folder_path = os.path.join(self.project_folder, folder)
            if not os.path.isdir(folder_path):
                os.makedirs(folder_path)
            return os.path.join(self.project_folder, folder)

    def input_file(self, name):
        """Get the path for a file in the input folder, given the name of the file.

        Parameters
        ----------
        name : str
            Name of the input file. Can have an extension (i.e.: .jpg or .txt).
            THe file does not have to exist, which is useful for saving files in
            this folder.

        Returns
        -------
        str
            Path to the file in the input folder of the project tree.

        """
        return self._get_file(name, 'input')

    def output_file(self, name):
        """Get the path for a file in the output folder, given the name of the file.

        Parameters
        ----------
        name : str
            Name of the output file. Can have an extension (i.e.: .jpg or .txt).
            THe file does not have to exist, which is useful for saving files in
            this folder.

        Returns
        -------
        str
            Path to the file in the output folder of the project tree.

        """
        output_file = self._get_file(name, 'output')

        return output_file

    def save_file(self, name):
        """Get the path for a file in the save folder, given the name of the file.

        Parameters
        ----------
        name : str
            Name of the save file. Can have an extension (i.e.: .jpg or .txt).
            THe file does not have to exist, which is useful for saving files in
            this folder.

        Returns
        -------
        str
            Path to the file in the save folder of the project tree.

        """
        return self._get_file(name, 'save')

    def savefig(self, name):
        """Save the current figure to the output file with a certain name.

        Parameters
        ----------
        name : str
            save name of the figure.

        """
        if self.project_folder is not None:
            file_name = self.output_file(name)
            add = 1
            while os.path.isfile(file_name + '.png'):
                file_name = self._get_file(f'{name}_{add :03d}', 'output')
                add+=1
            plt.savefig(file_name, dpi = 'figure', bbox_inches = 'tight')

    def make_folder(self, folder):
        """Create a folder with a certain name

        Parameters
        ----------
        folder : str
            Name of the folder. This folder will be created as a part of the
            project file tree.

        """
        if self.project_folder is not None:
            folder_location = os.path.join(self.project_folder, folder)
            setattr(self, f'{folder}_folder', folder_location)
            _utils.make_folder(getattr(self, f'{folder}_folder'))


import config
from fastapi import FastAPI, HTTPException
from fastapi.middleware.cors import CORSMiddleware
from routes.questionares import router as QRouter
from routes.records import router as RRouter

app = FastAPI()

origins = [
    config.Settings().GATE
]

app.add_middleware(
    CORSMiddleware,
    allow_origins=origins,
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

app.include_router(QRouter, tags=["Questionare"], prefix="/questionare")
app.include_router(RRouter, tags=["Records"], prefix="/records")

@app.get("/", tags=["Root"])
async def read_root():
    return {"message": "Questionare Service API"}


from PyQt5.QtWidgets import*
from main_python import Ui_MainWindow
from liste import ListelePage

import sqlite3

#connection = sqlite3.connect("Ariza.db")

class ArizaPage(QMainWindow):
    baglanti = sqlite3.connect("Ariza.db")
    islem = baglanti.cursor()
    table = islem.execute("create table if not exists urun (musteriAd text, urunAdi text, tel int, adres text, arizaAciklama text, marka text, kategori text)")
    baglanti.commit()
    def __init__(self)-> None:
        super().__init__()
        self.arizaform =Ui_MainWindow()
        self.arizaform.setupUi(self)
        self.listeac = ListelePage()
        self.arizaform.btnekle.clicked.connect(self.KayitYap)
    def KayitYap(self):
        urun =self.arizaform.cmbUrun.currentText()
        marka =self.arizaform.cmbMarka.currentText()
        arizaAciklama =self.arizaform.lineEditArizaAciklama.text()
        print(urun," ",marka," ",arizaAciklama)
        self.hide ()
        self.listeac.show()


from fractions import Fraction
from math import ceil
from typing import Any, Dict

from pytorchvideo.data.clip_sampling import ClipInfo, ClipSampler

class MinimumFullCoverageClipSampler(ClipSampler):
    """Find the minmimum number of clips to cover the full video.

    Args:
        clip_duration: Duration of a clip.
        augs_per_clip: Number of augmentations to be applied on each clip.
    """

    def __init__(self, clip_duration: float, augs_per_clip: int = 1) -> None:
        super().__init__(clip_duration)
        self._augs_per_clip = augs_per_clip

    def __call__(
        self, last_clip_time: float, video_duration: float, annotation: Dict[str, Any]
    ) -> ClipInfo:
        """
        Args:
            last_clip_time: Not used.
            video_duration:: The duration (in seconds) for the video that's
                being sampled.
            annotation: Not used by this sampler.
        Returns:
            includes the clip information of (clip_start_time,
                clip_end_time, clip_index, aug_index, is_last_clip). The times are in seconds.
                ``is_last_clip`` is ``True`` after the end of the video is reached.

        """
        max_possible_clip_start = Fraction(max(video_duration - self._clip_duration, 0))
        clips_per_video = ceil(Fraction(video_duration / self._clip_duration))

        uniform_clip = Fraction(max_possible_clip_start, max(clips_per_video - 1, 1))

        clip_start_sec = uniform_clip * self._current_clip_index
        clip_index = self._current_clip_index
        aug_index = self._current_aug_index

        self._current_aug_index += 1
        if self._current_aug_index >= self._augs_per_clip:
            self._current_clip_index += 1
            self._current_aug_index = 0

        # Last clip is True if sampled self._clips_per_video or if end of video is reached.
        is_last_clip = False
        if (
            self._current_clip_index >= clips_per_video
            or uniform_clip * self._current_clip_index > max_possible_clip_start
        ):
            self._current_clip_index = 0
            is_last_clip = True

        if is_last_clip:
            self.reset()

        return ClipInfo(
            clip_start_sec,
            clip_start_sec + self._clip_duration,
            clip_index,
            aug_index,
            is_last_clip,
        )

    def reset(self):
        self._current_clip_index = 0
        self._current_aug_index = 0


"""
Filename:   wcsmatching.py
Author(s):  Peter Quigley
Contact:    pquigley@uwo.ca
Created:    June 19, 2023
Updated:    June 20, 2023

Usage: python wcsmatching.py <obs_date>
       *This script is intended to run only on BLUEBIRD
"""

# Module Imports
import os,sys
import argparse
import re
import itertools
import numpy as np
import time as timer
from pathlib import Path
from datetime import datetime,timedelta
from copy import deepcopy

# Custom Script Imports
#import getRAdec
import colibri_image_reader as cir
import colibri_photometry as cp
from coordsfinder import getTransform, updateNPY_RAdec

# Disable Warnings
import warnings
import logging

#-------------------------------global vars-----------------------------------#

# Path variables
BASE_PATH = Path('D:/')
DATA_PATH = BASE_PATH / 'ColibriData'
IMGE_PATH = BASE_PATH / 'ColibriImages'
ARCHIVE_PATH = BASE_PATH / 'ColibriArchive'

# Timestamp format
OBSDATE_FORMAT = '%Y%m%d'
MINDIR_FORMAT  = '%Y%m%d_%H.%M.%S.%f'
TIMESTAMP_FORMAT = '%Y-%m-%dT%H:%M:%S.%f'
BARE_FORMAT = '%Y-%m-%d_%H%M%S_%f'

# Verbose print statement
verboseprint = lambda *a, **k: None

#----------------------------------class--------------------------------------#

class Telescope:

    def __init__(self, name, base_path, obs_date):

        # Telescope identifiers
        print(f"Initializing {name}...")
        self.name = name

        # Error logging
        self.errors = []

        # Path variables
        self.base_path = Path(base_path)
        self.obs_archive = self.base_path / "ColibriArchive" / hyphonateDate(obs_date)
        self.npy_file_list = sorted(self.obs_archive.glob('*pos.npy'))
        self.medstack_file_list = sorted(self.obs_archive.glob('*medstacked.fits'))

        # Check that star tables exist
        if (not self.obs_archive.exists()) or (len(self.npy_file_list) == 0):
            self.addError(f"ERROR: No star tables exist for {name} on {obs_date}!")
            self.star_tables = False
        else:
            self.star_tables = True

    def addError(self, error_msg):

        self.errors.append(error_msg)
        print(error_msg)

    def genDatetimeList(self):

        # Initialize datetime list
        self.dt_dict = {}

        # Confirm that star tables exist
        if self.star_tables is False:
            return []

        # Iterate through all npy_files and get the datetime str from the name
        for npy_file in self.npy_file_list:
            self.dt_dict[regexNPYName(npy_file.name)[1]] = npy_file.name
        else:
            return sorted(list(self.dt_dict.keys()))

#--------------------------------functions------------------------------------#

def npyFileWCSUpdate(npy_file_list, medstack_file_list):

    # Iterate through npy files and generate a WCS transformation to write
    # back into the WCS file
    for npy_file in npy_file_list:

        verboseprint(f"Processing {npy_file.name}...")

        # Read in data from npy file
        # Format x | y | half-light radius
        star_table = np.load(npy_file)

        # If npy file already contains ra/dec information
        if star_table.shape[1] == 5:
            verboseprint("  Already proccessed.")
            continue

        # Get minute string from filename using regex
        timestamp,_ = regexNPYName(npy_file.name)
        verboseprint(f"  -> Associated timestamp: {timestamp}")

        # Generate WCS transformation and the RA/Dec
        transform  = getTransform(timestamp, medstack_file_list, {})
        star_radec = updateNPY_RAdec(transform, npy_file)
        verboseprint("  Successfully generated RA/DEC.")

        # Save the array of star positions as an .npy file again
        # Format: x  |  y  |  r  |  ra  |  dec
        npy_file.unlink()
        np.save(npy_file, star_radec)

def matchNight(obsdate):
    """
    Match stars between telescopes for a given night. Substitute for main().

    Parameters
    ----------
        obsdate (str): Date of observation in YYYYMMDD format.

    Returns
    ----------
        starhours (float): Number of star hours matched between telescopes.
                           Returns nan if no matching stars found, but minutes are.

    """

    # Initialize telescope classes
    Red   = Telescope("RED", "R:", obsdate)
    Green = Telescope("GREEN", "G:", obsdate)
    Blue  = Telescope("BLUE", "D:", obsdate)

    ## Minute matching ##

    print("\n## Minute Matching ##")

    # Generate datetime objects for all telescopes.
    # Save list of keys for use later in order.
    keys_list = []
    for machine in (Blue,Red,Green):
        keys_list.append(machine.genDatetimeList())
        print(f"{machine.name} has {len(machine.dt_dict)} minutes of data.")

    # Pair minutes between all 3 telescopes
    time_triplets = getMinuteTriplets(*keys_list)
    if len(time_triplets) == 0:
        print("ERROR: No matching minutes between telescopes!")
        return 0
    else:
        print(f"RGB = {len(time_triplets)}")

    ## Star matching ##

    print("\n## Star Matching ##")

    # Match stars from each telescope's star lists
    star_minutes = 0
    for minute in time_triplets:

        # Get npy file from each telescope
        Blue_file  = Blue.obs_archive / Blue.dt_dict[minute[0]]
        Red_file   = Red.obs_archive / Red.dt_dict[minute[1]]
        Green_file = Green.obs_archive / Green.dt_dict[minute[2]]

        # Get ra/dec from each npy file
        # TODO: WCS mapping if not already done
        try:
            Red_stars   = np.load(Red_file)[:,[3,4]]
        except IndexError:
            print(f"ERROR: {Red_file} has not been updated!")
            continue
        try:
            Green_stars = np.load(Green_file)[:,[3,4]]
        except IndexError:
            print(f"ERROR: {Green_file} has not been updated!")
            continue
        try:
            Blue_stars  = np.load(Blue_file)[:,[3,4]]
        except IndexError:
            print(f"ERROR: {Blue_file} has not been updated!")
            continue

        # Match stars between 2 and then 3
        BR_matched = sharedStars(Blue_stars, Red_stars)
        BG_matched = sharedStars(Blue_stars, Green_stars)
        shared_stars = np.intersect1d(BR_matched[0], BG_matched[0])

        star_minutes += len(shared_stars)

    # Check that we matched some stars
    if star_minutes == 0:
        print("ERROR: No stars matched! Check that all files have been updated.")
        star_hours = np.nan
    else:
        print(f"\nDone star matching! {star_minutes/60.} star-hours detected.")
        star_hours = star_minutes/60.

    return star_hours

def pairMinutes(minute_list1, minute_list2, spacing=60):
    """

    """

    # Cartesian product of the two sorted minute lists
    minute_pairs = list(itertools.product(minute_list1,minute_list2))
    minute_pairs = np.array(minute_pairs, dtype=object)

    # Find time difference between two times
    time_diff = np.array([abs((time_tuple[0] - time_tuple[1]).total_seconds()) \
                          for time_tuple in minute_pairs],
                          dtype=object)

    # Identify minute pairs within our timing tolerance
    valid_pair_inds = np.where(time_diff < spacing)[0]

    # Of the timestamps identified, find unique timestamps.
    # In the case of duplicates, default to earliest time in minute_list1 then minute_list2.
    _,unique1_inds = np.unique(minute_pairs[[valid_pair_inds],0],
                               return_index=True)
    _,unique2_inds = np.unique(minute_pairs[[valid_pair_inds[unique1_inds]],1],
                               return_index=True)
    paired_inds = valid_pair_inds[unique1_inds][unique2_inds]

    # Return only valid, unique minute pairs that satisfy our timing tolerance
    print(f"Minutes successfully paired. {len(paired_inds)} minute pairs found.")
    return minute_pairs[paired_inds]

def getMinuteTriplets(minute_list1, minute_list2, minute_list3, spacing=60):
    """

    """

    # Iterate through minute_list1 and find all pairs with minute_list2 and minute_list3.
    # Save index of last matched minute in minute_list2 and minute_list3 to avoid duplicates.
    # Assumes a sorted list of datetime objects.
    minute_triplets = []
    last_matched2 = 0
    last_matched3 = 0
    for timestamp1 in minute_list1:
        # Check that neither minute_list2 or minute_list3 are over-indexed
        if (last_matched2 >= len(minute_list2)) or (last_matched3 >= len(minute_list3)):
            print("No more minutes to match!")
            break

        # Compare to minute_list2 and find first match within spacing
        for ind2, timestamp2 in enumerate(minute_list2[last_matched2:]):
            if abs((timestamp1 - timestamp2).total_seconds()) < spacing:

                # Compare to minute_list3 and find first match within spacing
                for ind3, timestamp3 in enumerate(minute_list3[last_matched3:]):

                    # If match found, save triplet and update last matched minute in minute_list3
                    if abs((timestamp1 - timestamp3).total_seconds()) < spacing:
                        verboseprint(f"Matched {timestamp1} with {timestamp2} and {timestamp3}!")
                        minute_triplets.append([timestamp1, timestamp2, timestamp3])
                        last_matched3 += ind3 + 1
                        break

                # Update last matched minute in minute_list2
                last_matched2 += ind2 + 1
                break

    else:
        print("All minutes matched!")

    return minute_triplets

def sharedStars(telescope1, telescope2, tolerance=1E-2):
    """
    Find matching stars between telescope pairs and between the three (if supplied).

    This alorithm should be upgraded to the "sophisticated solution" of the following:
    https://www.cs.ubc.ca/~liorma/cpsc320/files/closest-points.pdf

    telescope1 (arr):
    telescope2 (arr):

    """

    # Get number of stars in each array
    num_stars1 = telescope1.shape[0]
    num_stars2 = telescope2.shape[0]

    # Broadcast star coordinates to do numpy operations later
    star1_broadcast = np.tile(telescope1, (num_stars2,1,1))
    star2_broadcast = np.tile(telescope2, (num_stars1,1,1))

    # Subtract the star coordinates from one another, then calculate hypotenuse
    coord_diff = star1_broadcast - star2_broadcast.transpose((1,0,2))
    hypot = np.hypot(coord_diff[:,:,0], coord_diff[:,:,1])

    # Find any stars within tolerance
    # Return two arrays of indices
    close_star_inds = np.where(hypot < tolerance)
    verboseprint(f"Stars successfully matched. {len(close_star_inds[0])} matched stars found.")
    return close_star_inds[0],close_star_inds[1]

def regexNPYName(npy_file_name):

    # Strip significance and file ext from filename
    time_str = npy_file_name[:21]

    # Convert to datetime object
    time_obj = datetime.strptime(time_str + "000", MINDIR_FORMAT)

    return time_str, time_obj

def hyphonateDate(obsdate):

    # Convert the date to a datetime object
    obsdate = datetime.strptime(obsdate, OBSDATE_FORMAT)

    # Convert the date to a hyphonated string
    obsdate = obsdate.strftime('%Y-%m-%d')

    return obsdate

#------------------------------------main-------------------------------------#

def updateNPYwithWCS(current_name, obsdate):

    # Process npy files for the current machine
    print("Processing current machine...\n")
    current = Telescope(current_name, BASE_PATH, obsdate)
    if (current.star_tables) and (current.medstack_file_list != []):
        npyFileWCSUpdate(current.npy_file_list,
                            current.medstack_file_list)
    else:
        print("ERROR: Could not process for current telescope!")

    '''-----------write signal file---------------'''
    signal_path = ARCHIVE_PATH.joinpath(hyphonateDate(obsdate),'done.txt')
    if not signal_path.exists():
        signal_path.touch()

if __name__ == '__main__':

###########################
## Argument Parser Setup
###########################

    # Generate argument parser
    description = "Generate WCS transform of observed stars and match to other telescopes"
    arg_parser = argparse.ArgumentParser(description=description,
                                         formatter_class=argparse.RawTextHelpFormatter)

    # Available argument functionality
    arg_parser.add_argument('date', help='Observation date (YYYYMMDD) of data to be processed.')
    arg_parser.add_argument('-m', '--match', help='Mode: Match stars between telescopes. Blue only.',
                            action='store_true')
    arg_parser.add_argument('-v', '--verbose', help='Increase output verbosity.',
                            action='store_true')

    # Process argparse list as useful variables
    cml_args  = arg_parser.parse_args()
    obsdate   = cml_args.date
    match_all = cml_args.match

    # Update verboseprint function
    if cml_args.verbose:
        verboseprint = print

    # Environment variable to ensure BLUEBIRD is used when required
    current_name = os.environ['COMPUTERNAME']

###########################
## Main Processing
###########################

    # Process npy files for the current machine
    if match_all is False:
        print("Mode: WCS Transform\n")
        updateNPYwithWCS(current_name, obsdate)

    # Calculate matched star hours for all telescopes
    elif (match_all is True) and (current_name != "BLUEBIRD"):
        print("ERROR: Matching is only designed to run on Blue!")
        sys.exit()
    else:
        print("Mode: Starhour calculation\n")

        starhours = matchNight(obsdate)

        # Write to file
        for starhour_file in (ARCHIVE_PATH / hyphonateDate(obsdate)).glob('starhours_*.txt'):
            starhour_file.unlink()
        (ARCHIVE_PATH / hyphonateDate(obsdate)/ f'starhours_{starhours}.txt').touch()


# coding: utf-8

"""
    Apache NiFi Registry REST API

    The REST API provides an interface to a registry with operations for saving, versioning, reading NiFi flows and components.

    OpenAPI spec version: 1.19.0
    Contact: dev@nifi.apache.org
    Generated by: https://github.com/swagger-api/swagger-codegen.git
"""

from pprint import pformat
from six import iteritems
import re

class VersionedFlowSnapshot(object):
    """
    NOTE: This class is auto generated by the swagger code generator program.
    Do not edit the class manually.
    """

    """
    Attributes:
      swagger_types (dict): The key is attribute name
                            and the value is attribute type.
      attribute_map (dict): The key is attribute name
                            and the value is json key in definition.
    """
    swagger_types = {
        'snapshot_metadata': 'VersionedFlowSnapshotMetadata',
        'flow_contents': 'VersionedProcessGroup',
        'external_controller_services': 'dict(str, ExternalControllerServiceReference)',
        'parameter_providers': 'dict(str, ParameterProviderReference)',
        'parameter_contexts': 'dict(str, VersionedParameterContext)',
        'flow_encoding_version': 'str',
        'flow': 'VersionedFlow',
        'bucket': 'Bucket',
        'latest': 'bool'
    }

    attribute_map = {
        'snapshot_metadata': 'snapshotMetadata',
        'flow_contents': 'flowContents',
        'external_controller_services': 'externalControllerServices',
        'parameter_providers': 'parameterProviders',
        'parameter_contexts': 'parameterContexts',
        'flow_encoding_version': 'flowEncodingVersion',
        'flow': 'flow',
        'bucket': 'bucket',
        'latest': 'latest'
    }

    def __init__(self, snapshot_metadata=None, flow_contents=None, external_controller_services=None, parameter_providers=None, parameter_contexts=None, flow_encoding_version=None, flow=None, bucket=None, latest=None):
        """
        VersionedFlowSnapshot - a model defined in Swagger
        """

        self._snapshot_metadata = None
        self._flow_contents = None
        self._external_controller_services = None
        self._parameter_providers = None
        self._parameter_contexts = None
        self._flow_encoding_version = None
        self._flow = None
        self._bucket = None
        self._latest = None

        self.snapshot_metadata = snapshot_metadata
        self.flow_contents = flow_contents
        if external_controller_services is not None:
          self.external_controller_services = external_controller_services
        if parameter_providers is not None:
          self.parameter_providers = parameter_providers
        if parameter_contexts is not None:
          self.parameter_contexts = parameter_contexts
        if flow_encoding_version is not None:
          self.flow_encoding_version = flow_encoding_version
        if flow is not None:
          self.flow = flow
        if bucket is not None:
          self.bucket = bucket
        if latest is not None:
          self.latest = latest

    @property
    def snapshot_metadata(self):
        """
        Gets the snapshot_metadata of this VersionedFlowSnapshot.
        The metadata for this snapshot

        :return: The snapshot_metadata of this VersionedFlowSnapshot.
        :rtype: VersionedFlowSnapshotMetadata
        """
        return self._snapshot_metadata

    @snapshot_metadata.setter
    def snapshot_metadata(self, snapshot_metadata):
        """
        Sets the snapshot_metadata of this VersionedFlowSnapshot.
        The metadata for this snapshot

        :param snapshot_metadata: The snapshot_metadata of this VersionedFlowSnapshot.
        :type: VersionedFlowSnapshotMetadata
        """
        if snapshot_metadata is None:
            raise ValueError("Invalid value for `snapshot_metadata`, must not be `None`")

        self._snapshot_metadata = snapshot_metadata

    @property
    def flow_contents(self):
        """
        Gets the flow_contents of this VersionedFlowSnapshot.
        The contents of the versioned flow

        :return: The flow_contents of this VersionedFlowSnapshot.
        :rtype: VersionedProcessGroup
        """
        return self._flow_contents

    @flow_contents.setter
    def flow_contents(self, flow_contents):
        """
        Sets the flow_contents of this VersionedFlowSnapshot.
        The contents of the versioned flow

        :param flow_contents: The flow_contents of this VersionedFlowSnapshot.
        :type: VersionedProcessGroup
        """
        if flow_contents is None:
            raise ValueError("Invalid value for `flow_contents`, must not be `None`")

        self._flow_contents = flow_contents

    @property
    def external_controller_services(self):
        """
        Gets the external_controller_services of this VersionedFlowSnapshot.
        The information about controller services that exist outside this versioned flow, but are referenced by components within the versioned flow.

        :return: The external_controller_services of this VersionedFlowSnapshot.
        :rtype: dict(str, ExternalControllerServiceReference)
        """
        return self._external_controller_services

    @external_controller_services.setter
    def external_controller_services(self, external_controller_services):
        """
        Sets the external_controller_services of this VersionedFlowSnapshot.
        The information about controller services that exist outside this versioned flow, but are referenced by components within the versioned flow.

        :param external_controller_services: The external_controller_services of this VersionedFlowSnapshot.
        :type: dict(str, ExternalControllerServiceReference)
        """

        self._external_controller_services = external_controller_services

    @property
    def parameter_providers(self):
        """
        Gets the parameter_providers of this VersionedFlowSnapshot.
        Contains basic information about parameter providers referenced in the versioned flow.

        :return: The parameter_providers of this VersionedFlowSnapshot.
        :rtype: dict(str, ParameterProviderReference)
        """
        return self._parameter_providers

    @parameter_providers.setter
    def parameter_providers(self, parameter_providers):
        """
        Sets the parameter_providers of this VersionedFlowSnapshot.
        Contains basic information about parameter providers referenced in the versioned flow.

        :param parameter_providers: The parameter_providers of this VersionedFlowSnapshot.
        :type: dict(str, ParameterProviderReference)
        """

        self._parameter_providers = parameter_providers

    @property
    def parameter_contexts(self):
        """
        Gets the parameter_contexts of this VersionedFlowSnapshot.
        The parameter contexts referenced by process groups in the flow contents. The mapping is from the name of the context to the context instance, and it is expected that any context in this map is referenced by at least one process group in this flow.

        :return: The parameter_contexts of this VersionedFlowSnapshot.
        :rtype: dict(str, VersionedParameterContext)
        """
        return self._parameter_contexts

    @parameter_contexts.setter
    def parameter_contexts(self, parameter_contexts):
        """
        Sets the parameter_contexts of this VersionedFlowSnapshot.
        The parameter contexts referenced by process groups in the flow contents. The mapping is from the name of the context to the context instance, and it is expected that any context in this map is referenced by at least one process group in this flow.

        :param parameter_contexts: The parameter_contexts of this VersionedFlowSnapshot.
        :type: dict(str, VersionedParameterContext)
        """

        self._parameter_contexts = parameter_contexts

    @property
    def flow_encoding_version(self):
        """
        Gets the flow_encoding_version of this VersionedFlowSnapshot.
        The optional encoding version of the flow contents.

        :return: The flow_encoding_version of this VersionedFlowSnapshot.
        :rtype: str
        """
        return self._flow_encoding_version

    @flow_encoding_version.setter
    def flow_encoding_version(self, flow_encoding_version):
        """
        Sets the flow_encoding_version of this VersionedFlowSnapshot.
        The optional encoding version of the flow contents.

        :param flow_encoding_version: The flow_encoding_version of this VersionedFlowSnapshot.
        :type: str
        """

        self._flow_encoding_version = flow_encoding_version

    @property
    def flow(self):
        """
        Gets the flow of this VersionedFlowSnapshot.
        The flow this snapshot is for

        :return: The flow of this VersionedFlowSnapshot.
        :rtype: VersionedFlow
        """
        return self._flow

    @flow.setter
    def flow(self, flow):
        """
        Sets the flow of this VersionedFlowSnapshot.
        The flow this snapshot is for

        :param flow: The flow of this VersionedFlowSnapshot.
        :type: VersionedFlow
        """

        self._flow = flow

    @property
    def bucket(self):
        """
        Gets the bucket of this VersionedFlowSnapshot.
        The bucket where the flow is located

        :return: The bucket of this VersionedFlowSnapshot.
        :rtype: Bucket
        """
        return self._bucket

    @bucket.setter
    def bucket(self, bucket):
        """
        Sets the bucket of this VersionedFlowSnapshot.
        The bucket where the flow is located

        :param bucket: The bucket of this VersionedFlowSnapshot.
        :type: Bucket
        """

        self._bucket = bucket

    @property
    def latest(self):
        """
        Gets the latest of this VersionedFlowSnapshot.

        :return: The latest of this VersionedFlowSnapshot.
        :rtype: bool
        """
        return self._latest

    @latest.setter
    def latest(self, latest):
        """
        Sets the latest of this VersionedFlowSnapshot.

        :param latest: The latest of this VersionedFlowSnapshot.
        :type: bool
        """

        self._latest = latest

    def to_dict(self):
        """
        Returns the model properties as a dict
        """
        result = {}

        for attr, _ in iteritems(self.swagger_types):
            value = getattr(self, attr)
            if isinstance(value, list):
                result[attr] = list(map(
                    lambda x: x.to_dict() if hasattr(x, "to_dict") else x,
                    value
                ))
            elif hasattr(value, "to_dict"):
                result[attr] = value.to_dict()
            elif isinstance(value, dict):
                result[attr] = dict(map(
                    lambda item: (item[0], item[1].to_dict())
                    if hasattr(item[1], "to_dict") else item,
                    value.items()
                ))
            else:
                result[attr] = value

        return result

    def to_str(self):
        """
        Returns the string representation of the model
        """
        return pformat(self.to_dict())

    def __repr__(self):
        """
        For `print` and `pprint`
        """
        return self.to_str()

    def __eq__(self, other):
        """
        Returns true if both objects are equal
        """
        if not isinstance(other, VersionedFlowSnapshot):
            return False

        return self.__dict__ == other.__dict__

    def __ne__(self, other):
        """
        Returns true if both objects are not equal
        """
        return not self == other


import argparse
import os
import shutil
import tempfile
import unittest
from contextlib import contextmanager
from pathlib import Path
from typing import Generator
from unittest.mock import MagicMock, patch

from torchx.cli.cmd_run import CmdBuiltins, CmdRun, _parse_run_config

@contextmanager
def cwd(path: str) -> Generator[None, None, None]:
    orig_cwd = os.getcwd()
    os.chdir(path)
    try:
        yield
    finally:
        os.chdir(orig_cwd)

class CmdRunTest(unittest.TestCase):
    def setUp(self) -> None:
        self.tmpdir = Path(tempfile.mkdtemp())
        self.parser = argparse.ArgumentParser()
        self.cmd_run = CmdRun()
        self.cmd_run.add_arguments(self.parser)

    def tearDown(self) -> None:
        shutil.rmtree(self.tmpdir)

    def test_run_with_user_conf_abs_path(self) -> None:
        args = self.parser.parse_args(
            [
                "--scheduler",
                "local",
                str(Path(__file__).parent / "components.py:touch"),
                "--file",
                str(self.tmpdir / "foobar.txt"),
            ]
        )
        self.cmd_run.run(args)
        self.assertTrue(os.path.isfile(str(self.tmpdir / "foobar.txt.test")))

    def test_run_with_relpath(self) -> None:
        # should pick up test/examples/touch.torchx (not the builtin)
        with cwd(str(Path(__file__).parent)):
            args = self.parser.parse_args(
                [
                    "--scheduler",
                    "local",
                    str(Path(__file__).parent / "components.py:touch_v2"),
                    "--file",
                    str(self.tmpdir / "foobar.txt"),
                ]
            )

            self.cmd_run.run(args)
            self.assertTrue(os.path.isfile(str(self.tmpdir / "foobar.txt.testv2")))

    def test_run_missing(self) -> None:
        with self.assertRaises(ValueError):
            args = self.parser.parse_args(
                [
                    "--scheduler",
                    "local",
                    "1234_does_not_exist.torchx",
                ]
            )
            self.cmd_run.run(args)

    @patch("torchx.runner.Runner.run")
    def test_run_dryrun(self, mock_runner_run: MagicMock) -> None:
        args = self.parser.parse_args(
            [
                "--dryrun",
                "--scheduler",
                "local",
                "utils.echo",
            ]
        )
        self.cmd_run.run(args)
        mock_runner_run.assert_not_called()

    def test_parse_run_config(self) -> None:
        args = "key=value,foo=bar"
        cfg = _parse_run_config(args)
        self.assertEqual("value", cfg.get("key"))
        self.assertEqual("bar", cfg.get("foo"))

class CmdBuiltinTest(unittest.TestCase):
    def test_run(self) -> None:
        # nothing to assert, just make sure the supported schedulers print runopts

        parser = argparse.ArgumentParser()
        cmd_builtins = CmdBuiltins()
        cmd_builtins.add_arguments(parser)
        args = parser.parse_args([])
        cmd_builtins.run(args)

    def test_builtins(self) -> None:
        cmd_builtins = CmdBuiltins()
        builtins = cmd_builtins._builtins()
        # make sure there's at least one
        # there will always be one (example.torchx)
        self.assertTrue(len(builtins) > 0)


import requests
from bs4 import BeautifulSoup
import smtplib
import text_to_speech as speech
import time
URL = "https://www.rokomari.com/book/202772/hate-kolome-javascript"

headers ={"User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.75 Safari/537.36" }

def  find_price():

    page =  requests.get(URL,headers=headers)

    soup = BeautifulSoup(page.content,'html.parser')

    price = soup.find("span", {"class": "sell-price"}).get_text()
    # print(soup.prettify())

    convertedprice = float(price[4:])

    if convertedprice > 300:
        speech.speak("Hey Alif you can buy this", "en")

    print(convertedprice)

while True:

    find_price()
    time.sleep(60*60)


from django.urls import reverse_lazy
from django.views.generic import ListView, CreateView, UpdateView

from score.forms import CreateRestaurantForm, CreateMenuForm, CreateEmployeeForm, VoteMenuForm
from score.models import Restaurant, Employee, Menu, Scores

class RestaurantListView(ListView):
    model = Restaurant
    template_name = 'restaurant/list.html'

class EmployeeListView(ListView):
    model = Employee
    template_name = 'employee/list.html'

class MenuListView(ListView):
    model = Menu
    template_name = 'menu/list.html'

class CreateRestaurantView(CreateView):
    model = Restaurant
    form_class = CreateRestaurantForm
    success_url = reverse_lazy('restaurant:list')
    template_name = 'restaurant/create.html'

class CreateMenuView(CreateView):
    model = Menu
    form_class = CreateMenuForm
    template_name = 'menu/create.html'
    success_url = reverse_lazy('menu:list')

    def get_initial(self):
        initial = super().get_initial()
        try:
            initial['restaurant_field'] = self.object.restaurant.pk
        except AttributeError:
            initial['restaurant_field'] = 0

        return initial

    def form_valid(self, form):
        response = super().form_valid(form)
        pk = int(form.cleaned_data['restaurant_field'])
        if pk:
            form.instance.restaurant = Restaurant.objects.get(pk=pk)
        else:
            form.instance.restaurant = None
        form.save()

        return response

class VoteMenuView(CreateView):
    model = Scores
    form_class = VoteMenuForm
    success_url = reverse_lazy('menu:list')
    template_name = 'menu/vote.html'

    # def get_initial(self):
    #     initial = super().get_initial()
    #     try:
    #         initial['vote_field'] = self.object.score.pk
    #     except AttributeError:
    #         initial['vote_field'] = 0
    #
    #     return initial
    #
    # def form_valid(self, form):
    #     response = super().form_valid(form)
    #     pk = int(form.cleaned_data['vote_field'])
    #     if pk:
    #         form.instance.score = Menu.objects.get(pk=pk)
    #     else:
    #         form.instance.score = None
    #     form.save()
    #
    #     return response

class CreateEmployeeView(CreateView):
    model = Employee
    form_class = CreateEmployeeForm
    template_name = 'employee/create.html'
    success_url = reverse_lazy('employee:list')


from PyQt5 import QtWidgets, QtCore, QtGui

class SearchParameterWidget(QtWidgets.QWidget):
    removeSelfRequest = QtCore.pyqtSignal(QtCore.QVariant)
    searchParamFieldUpdate = QtCore.pyqtSignal((str, str, QtCore.QVariant))

    def __init__(self, parent=None):
        super(SearchParameterWidget, self).__init__(parent=parent)
        self.paramType = None # Will use to track which field to use when building SQL queries from these widgets
        self.parent = parent
        self.currentfield = ""
        self.setupWidget()

    def setupWidget(self):
        #HLayout to contain our widgets
        self.searchTemplateHLayout = QtWidgets.QHBoxLayout(self)
        self.searchTemplateHLayout.setObjectName("searchTemplateHLayout")

        #First widget is the dropdown to select which param to search with
        self.paramSelectionDropdown = QtWidgets.QComboBox(self)
        sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.paramSelectionDropdown.sizePolicy().hasHeightForWidth())
        self.paramSelectionDropdown.setSizePolicy(sizePolicy)
        self.paramSelectionDropdown.setMinimumSize(QtCore.QSize(90, 0))
        self.paramSelectionDropdown.setObjectName("paramSelectionDropdown")
        self.paramSelectionDropdown.setEditable(False)
        self.paramSelectionDropdown.activated["QString"].connect(self.changedFieldType)
        self.searchTemplateHLayout.addWidget(self.paramSelectionDropdown)

        #AND/OR checkbox. Multiple values can be searched for in a single field by separating them with a semicolon
        #This checkbox controls whether we use AND or OR in our SQL query. OR'ing has been the default behavior.
        #With dialog searches we change the behavior to switch between exact and fuzzy searching
        self.andorCheckbox = QtWidgets.QCheckBox(self)
        if self.currentfield == "dialog":
            self.andorCheckbox.setToolTip("Checked = Fuzzy, inexact searching (slow)\nUnchecked = Exact match searching only")
        else:
            self.andorCheckbox.setToolTip("Checked = multiple entries for this field are AND'd together, unchecked they are OR'd together. ")
        self.searchTemplateHLayout.addWidget(self.andorCheckbox)

        #spacerItem2 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Minimum)
        #self.searchTemplateHLayout.addItem(spacerItem2)

        #Text box entry for selected parameter. In the future this could be dynamically updated for the selected param
        # e.g. dropdown for genre, dual input for number range w/ runtime and year
        self.searchTemplateEntry = QtWidgets.QLineEdit(self)
        sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Fixed)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.searchTemplateEntry.sizePolicy().hasHeightForWidth())
        self.searchTemplateEntry.setSizePolicy(sizePolicy)
        self.searchTemplateEntry.setMinimumSize(QtCore.QSize(0, 25))
        font = QtGui.QFont()
        font.setPointSize(12)
        self.searchTemplateEntry.setFont(font)
        self.searchTemplateEntry.setClearButtonEnabled(True)
        self.searchTemplateEntry.setObjectName("searchTemplateEntry")
        self.searchTemplateHLayout.addWidget(self.searchTemplateEntry)

        #Delete button to remove param
        self.searchTemplateRemoveButton = QtWidgets.QPushButton(self)
        sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.searchTemplateRemoveButton.sizePolicy().hasHeightForWidth())
        self.searchTemplateRemoveButton.setSizePolicy(sizePolicy)
        self.searchTemplateRemoveButton.setMinimumSize(QtCore.QSize(25, 25))
        self.searchTemplateRemoveButton.setMaximumSize(QtCore.QSize(25, 25))
        self.searchTemplateRemoveButton.setText("")
        icon = QtGui.QIcon()
        icon.addPixmap(QtGui.QPixmap("../icons/delete-icon.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
        self.searchTemplateRemoveButton.setIcon(icon)
        self.searchTemplateRemoveButton.setIconSize(QtCore.QSize(16, 16))
        self.searchTemplateRemoveButton.setFlat(True)
        self.searchTemplateRemoveButton.setObjectName("searchTemplateRemoveButton")
        self.searchTemplateRemoveButton.clicked.connect(lambda: self.removeSelfRequest.emit(self))
        self.searchTemplateHLayout.addWidget(self.searchTemplateRemoveButton)

    def returnData(self):
        #Just simply access to our field value
        return self.searchTemplateEntry.text()

    def andorState(self):
        #return the AND/OR checkbox state
        return "AND" if self.andorCheckbox.isChecked() else "OR"

    def updateFieldList(self, updatedstringlist):
        #Preserve whatever selection we had before because our model will change the indices
        self.paramSelectionDropdown.clear()
        updatedstringlist[self.currentfield] = True
        for field, enabled in updatedstringlist.items():
            if enabled:
                self.paramSelectionDropdown.addItem(field)
        if self.currentfield == "":
            self.changedFieldType(self.paramSelectionDropdown.itemText(0))
        QtWidgets.QApplication.processEvents()
        self.paramSelectionDropdown.setCurrentText(self.currentfield)  # Will only change index if QComboBox.editable==False

    def changedFieldType(self, fieldname):
        self.searchParamFieldUpdate.emit(self.currentfield, fieldname, self)
        self.currentfield = fieldname


from django.urls import path
from . import views
from .views import MapView

urlpatterns = [
    path('', views.home, name = "HOME"),
    #path('newPage/', views.users, name = "USER"),
    #path('editPage/<int:user_id>/', views.edit, name = "EDIT"),
    #path('delete/<int:user_id>/', views.delete_user, name='DELETE'),
    path('mysignup/', views.myregister, name = "REGISTER"),
    path('mylogin/', views.mylogin, name = "LOGIN"),
    path('userhome/<int:user_id>/', views.UserHomePage, name = "UserHomePage"),
    path('adminhome/<int:user_id>/', views.AdminHomePage, name = "AdminHomePage"),
    path('arrest/<int:admin_id>/', views.ArrestPage, name = "ArrestPage"),
    path('applyCIS/', views.applyCISLoader, name = "applyCISLoad"),
    path('criminalpage/<int:admin_id>', views.allCriminalPage, name = "CriminalPage"),
    path('p1complain/<int:user_id>/<int:FIR_id>', views.complain1, name = "UseComplainPage1"),
    path('p2complain/<int:user_id>/<int:FIR_id>', views.complain2, name = "UseComplainPage2"),
    path('p3complain/<int:user_id>/<int:FIR_id>', views.complain3, name = "UseComplainPage3"),
    path('p4complain/<int:user_id>/<int:FIR_id>', views.complain4, name = "UseComplainPage4"),
    path('saveContents/<int:user_id>/', views.saveComplain_1, name = "SAVE1"),
    path('search_req_user/<int:user_id>/', views.goto_search_page, name = "Search_Page"),
    path('activate/<uidb64>/<token>',views.activatefunction, name="ACTIVATE"),
    path('fetch_user_data/',views.fetch_user_data, name="fetch_user_data"),
    path('fetch_victim_data/',views.fetch_victim_data, name="fetch_victim_data"),
    path('Upload_Victim_Record/',views.upload_victim_record, name="upload_victim_record"),
    path('Upload_WITHNESS_Record/',views.upload_witeness_record, name="upload_witeness_record"),
    path('Upload_Offender_Record/',views.upload_offender_record, name="upload_offender_record"),
    path('your_complaint_view/',views.pdf_view, name="pdf_view"),
    #path('map/', MapView.as_view(), name='map-view'),

    path('map/', views.context_date, name='map-view'),
    path('get-station/', views.near_stations),
]


import numpy as np
import cv2 as cv
from matplotlib import pyplot as plt
from argparse import ArgumentParser

def parse_args_for_settings_file():
    """Parse the single argument (the settings JSON file) for scripts that
    require it.
    """

    parser = ArgumentParser(description="Script with JSON Settings File")
    parser.add_argument("file_name", help="The JSON settings file.")
    args = parser.parse_args()

    return args.file_name

# Note: Lower AFD is better
def compute_feature_distance(image_ref: np.ndarray, image_curr: np.ndarray) -> float:
    # Code adapted from OpenCV documentation example
    # https://docs.opencv.org/master/da/de9/tutorial_py_epipolar_geometry.html
    sift = cv.SIFT_create()
    # find the keypoints and descriptors with SIFT
    kp1, des1 = sift.detectAndCompute(image_ref, None)
    kp2, des2 = sift.detectAndCompute(image_curr, None)
    # FLANN parameters for nearest neighbor search
    FLANN_INDEX_KDTREE = 1
    index_params = dict(algorithm=FLANN_INDEX_KDTREE, trees=5)
    search_params = dict(checks=50)
    flann = cv.FlannBasedMatcher(index_params, search_params)
    matches = flann.knnMatch(des1, des2, k=2)
    good = []
    pts1 = []
    pts2 = []

    # Ratio test as per Lowe's paper
    for i, (m, n) in enumerate(matches):
        if m.distance < 0.70 * n.distance:
            good.append(m)
            pts2.append(kp2[m.trainIdx].pt)
            pts1.append(kp1[m.queryIdx].pt)

    pts1 = np.int32(pts1)
    pts2 = np.int32(pts2)

    # The findHomography function implicitly uses RANSAC to correct matches based on
    # the backprojection error. Thus, use the mask returned from this function
    # to filter down the matches and make the method 'robust'
    _, mask = cv.findHomography(pts1, pts2, cv.RANSAC)
    mask = mask.astype("bool")
    mask = mask.squeeze(1)
    pts1 = pts1[mask]
    pts2 = pts2[mask]

    # Compute AFD based on the formula using these filtered match points
    running_sum = 0.0
    for i in range(len(pts1)):
        running_sum += np.linalg.norm(pts1[i] - pts2[i])

    afd = running_sum / len(pts1)

    return afd, pts1, pts2

def is_rotation_matrix(R: np.ndarray) -> bool:
    # Check for the correct type and shape.
    if not (isinstance(R, np.ndarray) and R.shape == (3, 3) and R.dtype == np.float64):
        return False

    # Check that it's a rotation matrix.
    return np.allclose(np.eye(3), R @ R.T, atol=1e-2) and np.allclose(
        np.linalg.det(R), 1, atol=1e-2
    )

def is_translation_vector(t: np.ndarray) -> bool:
    return isinstance(t, np.ndarray) and t.shape == (3,) and t.dtype == np.float64

def is_image(image: np.ndarray) -> bool:
    return (
        isinstance(image, np.ndarray)
        and image.dtype == np.uint8
        and image.shape[2] == 3
    )

def convert_angles_to_matrix(
    x_angle: float, y_angle: float, z_angle: float
) -> np.ndarray:
    # Takes angles in degrees of a rotation about x, y and z axes respectively
    # and returns a matrix!
    x_angle = np.deg2rad(x_angle)
    y_angle = np.deg2rad(y_angle)
    z_angle = np.deg2rad(z_angle)

    x_matrix = np.array(
        [
            [1.0, 0.0, 0.0],
            [0.0, np.cos(x_angle), -np.sin(x_angle)],
            [0.0, np.sin(x_angle), np.cos(x_angle)],
        ]
    )

    y_matrix = np.array(
        [
            [np.cos(y_angle), 0.0, np.sin(y_angle)],
            [0.0, 1.0, 0.0],
            [-np.sin(y_angle), 0.0, np.cos(y_angle)],
        ]
    )

    z_matrix = np.array(
        [
            [np.cos(z_angle), -np.sin(z_angle), 0.0],
            [np.sin(z_angle), np.cos(z_angle), 0.0],
            [0.0, 0.0, 1.0],
        ]
    )

    return np.matmul(z_matrix, np.matmul(y_matrix, x_matrix))

def make_rotation_matrix(location, target):
    """Make a rotation matrix for a camera at location that's pointing towards
    target. This assumes that up is (0, 0, -1) like it is in OpenCV.
    """
    y_up = np.array([0, 0, -1])
    camera_to_target = target - location
    z = camera_to_target
    z /= np.linalg.norm(z)
    x = np.cross(y_up, z)
    x /= np.linalg.norm(x)
    y = np.cross(z, x)
    y /= np.linalg.norm(y)
    return np.stack([x, y, z], axis=1)


import apache_beam as beam

with beam.Pipeline() as p:
  icon_pairs = p | 'Create icons' >> beam.Create([
      ('Apple', '🍎'),
      ('Apple', '🍏'),
      ('Eggplant', '🍆'),
      ('Tomato', '🍅'),
  ])

  duration_pairs = p | 'Create durations' >> beam.Create([
      ('Apple', 'perennial'),
      ('Carrot', 'biennial'),
      ('Tomato', 'perennial'),
      ('Tomato', 'annual'),
  ])

  plants = (({
      'icons': icon_pairs, 'durations': duration_pairs
  })
            | 'Merge' >> beam.CoGroupByKey()
            | beam.Map(print))

  #Results
#('Apple', {'icons': ['🍎', '🍏'], 'durations': ['perennial']})
#('Eggplant', {'icons': ['🍆'], 'durations': []})
#('Tomato', {'icons': ['🍅'], 'durations': ['perennial', 'annual']})
#('Carrot', {'icons': [], 'durations': ['biennial']})


import utils
from starlette.applications import Starlette
from starlette.responses import JSONResponse
from starlette.routing import Route
from starlette.requests import Request

async def homepage(request):
    return JSONResponse({"hello": "Hello welcome"})

async def readsheet(request: Request):
    try:
       data = await request.json()
       response_data = utils.read_gsheet(data)

    except RuntimeError:
        return "Data not received"

    return JSONResponse({"status": 'true', "data": response_data})

routes = [
    Route('/', homepage),
    Route('/readsheet', readsheet, methods=['POST'])
]

app = Starlette(debug=True, routes=routes)


import logging
import os
import re
import yaml

from PIL import Image
from pelican import signals
from jinja2 import Template

logger = logging.getLogger(__name__)

pswipe_regex = re.compile(r'(\[pswipe:([^,]+),([^.,]+)(\.[^,]+),([^\]]+)\])')
pswipe_template = """<img src='/images/{{album}}/{{image_root}}_thumbnail_tall{{image_ext}}' title='{{caption}}' onclick='pswipe("{{album}}",{{image_index}});'/>"""

def initialized(pelican):
    pelican.settings['GALLERIES'] = {}

def article_generator_finalized(generator):
    galleries = generator.context.get('GALLERIES')
    template = Template(pswipe_template)
    for article in reversed(generator.articles):
        for match in pswipe_regex.findall(article._content):
            album = match[1]
            image_root = match[2]
            image_ext = match[3]
            caption = match[4]
            if album not in galleries: galleries[album] = []
            gallery = galleries[album]
            image_id = len(gallery)
            image_uri = '/images/' + album + '/' + image_root + image_ext
            image_path = os.path.join('content/images', album, image_root + image_ext)
            image = Image.open(image_path)
            image_index = next((i for (i,e) in enumerate(gallery) if e[0] == image_uri), len(gallery))
            if image_index == len(gallery): gallery.append([])
            gallery[image_index] = [image_uri, image.size, caption]
            context = generator.context.copy()
            context.update({
                'album': album,
                'image_root': image_root,
                'image_ext': image_ext,
                'caption': caption,
                'image_index': image_index
            })
            replacement = template.render(context)
            article._content = article._content.replace(match[0], replacement)

galleries_template = """\
var galleries = {
    {% for galname, items in GALLERIES.items() %}\
        {{galname}}: [
            {% for item in items %}\
                {src:"{{item[0]}}", w:{{item[1][0]}}, h:{{item[1][1]}}, title:"{{item[2]}}"},
            {% endfor %}\
        ],
    {% endfor %}\
};

"""

def article_writer_finalized(generator, writer):
    writer.write_file("galleries.js", Template(galleries_template), generator.context)

def register():
    signals.initialized.connect(initialized)
    signals.article_generator_finalized.connect(article_generator_finalized)
    signals.article_writer_finalized.connect(article_writer_finalized)


# -*- coding: utf-8 -*-

import logging

import libmc
from MySQLdb import connect, IntegrityError  # noqa
from ORZ import setup, OrzField, OrzBase  # noqa
from douban.mc import create_decorators
from douban.sqlstore import store_from_config
from redis2beansdb import Beansdb
from vilya.config import (
    MEMCACHED_HOSTS,
    MEMCACHED_CONFIG,
    MYSQL_STORE,
)

logging.getLogger().setLevel(logging.DEBUG)

# mc
ONE_MINUTE = 60
HALF_HOUR = 1800
ONE_HOUR = 3600
HALF_DAY = ONE_HOUR * 12
ONE_DAY = ONE_HOUR * 24
ONE_WEEK = ONE_DAY * 7
ONE_MONTH = ONE_DAY * 30
ONE_YEAR = ONE_DAY * 365

_clients = {}

def hashdict(d):
    """
    make dictionary becomes a immutable tuple
    """
    if isinstance(d, (tuple, list)):
        return tuple(hashdict(v) for v in d)
    elif isinstance(d, dict):
        return tuple(sorted((k, hashdict(v)) for k, v in d.iteritems()))
    else:
        return d

def Client(servers=None, *args, **kwargs):
    key = hashdict([servers, kwargs])
    mc = _clients.get(key)
    if not mc:
        mc = libmc.Client(servers, *args, **kwargs)
        _clients[key] = mc
    return mc

def get_mc():
    return Client(MEMCACHED_HOSTS, **MEMCACHED_CONFIG)

def get_db():
    return Beansdb()

def stub_cache(*args, **kws):
    pass

mc = get_mc()
bdb = get_db()

pcache = pcache2 = listcache = cache_in_obj = delete_cache = cache = stub_cache
globals().update(create_decorators(mc))

def mc_gets(mc_key, getter, ids):
    '''helpler for gets function'''
    results = mc.get_multi([mc_key % i for i in ids])
    return [results.get(mc_key % i) or getter(i) for i in ids]

# mysql
def connect_mysql():
    return connect(use_unicode=True, user='root', passwd='', db='valentine')

def make_dict(cursor, row):
    return dict(zip((str(d[0]) for d in cursor.description), row))

def reset_mc(deep=False):
    for mc in _clients.itervalues():
        getattr(mc, 'clear', lambda: True)()
        if deep:
            getattr(mc.mc, 'clear', lambda: True)()

# TODO(xutao) delete reset_beansdb?
def reset_beansdb():
    for db in _clients.itervalues():
        db.clear_cache()

# FIXME(xutao) rename to clear_mc_for_test?
def clear_beansdb_for_test():
    for db in _clients.itervalues():
        db.clear_cache()
        for s in db.db.servers:
            clear = getattr(s.mc, 'clear', None)
            if clear:
                clear()

# FIXME(xutao) I can't find any code about put beansdb client to `_clients`, and beansdb shouldn't be clear after request
def clear_local_cache():
    reset_mc()
    reset_beansdb()

store = store_from_config(MYSQL_STORE, use_cache=False)
setup(store, mc)


import json
import torch
import torch.nn as nn
import numpy as np
from tqdm import tqdm
from sklearn.metrics import roc_auc_score

from arguments import get_args
from utils import StatsTracker
from utils import load_model

from train_base import train_model

from graph import MolGraph
from models import GCN
import pdb

def main(args=None, quiet=False, splits=None, abs_output_dir=False):
    if args is None:
        args = get_args()

    train_stats = train_model(
        model_class=GCN, run_func=run_func, args=args, quiet=quiet,
        splits=splits, abs_output_dir=abs_output_dir)
    return train_stats

def run_func(model, optim, data_loader, data_type, args, write_path=None,
             quiet=False):
    is_train = data_type == 'train'
    if is_train:
        model.train()
    else:
        model.eval()

    # Keeps track of epoch stats by aggregating batch stats
    stats_tracker = StatsTracker()
    write_output = []
    all_preds, all_labels = [], []
    if args.n_labels > 1:
        for _ in range(args.n_labels):
            all_preds.append([])
            all_labels.append([])

    for _, batch_data in enumerate(tqdm(data_loader, disable=quiet)):
        if is_train:
            optim.zero_grad()
        if args.n_labels == 1:
            smiles_list, labels_list = batch_data
        else:
            smiles_list, labels_list, mask = batch_data
        n_data = len(smiles_list)

        labels = torch.tensor(labels_list, device=args.device).float()
        if args.n_labels == 1:
            labels = labels.unsqueeze(1)
        if args.n_labels > 1:
            mask = torch.tensor(mask, device=args.device).float()

        mol_graph = MolGraph(smiles_list)
        _, preds = model(mol_graph)

        if args.val_stat == 'rmse':
            loss = torch.mean((labels - preds) ** 2)
            stats_tracker.add_stat('mse', loss.item() * n_data, n_data)
        elif args.val_stat in ['auc', 'acc']:
            pred_probs = nn.Sigmoid()(preds)
            loss = nn.BCELoss()(input=pred_probs, target=labels)
            stats_tracker.add_stat('ce', loss.item() * n_data, n_data)

            # Aggregate predictions to compute Acc/AUC
            all_preds.append(pred_probs.detach().cpu().numpy())
            all_labels.append(np.array(labels_list))
        elif args.val_stat == 'mae':
            loss = torch.mean(torch.abs(labels - preds))
            stats_tracker.add_stat('mae', loss.item() * n_data, n_data)
        elif args.val_stat == 'multi_obj':
            total_loss = 0
            for i in range(args.n_labels):
                cur_preds = preds[:, i].unsqueeze(1)
                cur_labels = labels[:, i].unsqueeze(1)
                cur_mask = mask[:, i].unsqueeze(1)

                n_sum = torch.sum(cur_mask).item()
                if n_sum == 0:
                    continue

                all_preds[i].append(cur_preds[cur_mask.byte()].detach().cpu().numpy())
                all_labels[i].append(cur_labels[cur_mask.byte()].detach().cpu().numpy())
                task_stat = args.label_task_list[i]
                if task_stat == 'rmse':
                    loss = (cur_preds - cur_labels) ** 2
                    loss = torch.sum(loss * cur_mask)
                    total_loss += loss
                if task_stat in ['auc', 'acc']:
                    loss = nn.BCEWithLogitsLoss(reduction='none')(input=cur_preds, target=cur_labels)
                    loss = torch.sum(loss * cur_mask)
                    total_loss += loss
                else:
                    assert False
            loss = total_loss / n_data
            stats_tracker.add_stat('loss', loss.item() * n_data, n_data)
        else:
            assert False

        if write_path is not None and args.n_labels == 1:
            for smiles_idx, smiles in enumerate(smiles_list):
                label = labels[smiles_idx].item()
                pred = preds[smiles_idx].item()

                write_output.append({
                    'smiles': smiles,
                    'label': label,
                    'pred': pred})

        if is_train:
            loss.backward()
            nn.utils.clip_grad_norm_(model.parameters(), args.max_grad_norm)
            optim.step()

    if args.n_labels == 1:
        if args.val_stat == 'rmse':
            mse = stats_tracker.get_stats()['mse']
            stats_tracker.add_stat('rmse', mse ** 0.5, 1)
        elif args.val_stat in ['auc', 'acc']:
            all_preds = np.squeeze(np.concatenate(all_preds), axis=1)
            all_labels = np.concatenate(all_labels)

            acc = np.mean((all_preds > 0.5) == all_labels)
            stats_tracker.add_stat('acc', -1 * acc, 1)

            auc = roc_auc_score(y_true=all_labels, y_score=all_preds)
            stats_tracker.add_stat('auc', -1 * auc, 1)
    else:
        all_stats = []
        for label_idx in range(args.n_labels):
            cur_preds = np.concatenate(all_preds[label_idx])
            cur_labels = np.concatenate(all_labels[label_idx])

            data_name = args.data.split('_')[label_idx]
            if args.label_task_list[i] == 'rmse':
                mse = np.mean((cur_preds - cur_labels) ** 2)
                stats_tracker.add_stat('%s_mse' % data_name, mse, 1)
                stats_tracker.add_stat('%s_rmse' % data_name, mse ** 0.5, 1)
            elif args.label_task_list[i] in ['auc', 'acc']:
                cur_pred_probs = 1 / (1 + np.exp(-cur_preds))
                acc = np.mean((cur_pred_probs > 0.5) == cur_labels)

                auc = roc_auc_score(y_true=cur_labels, y_score=cur_pred_probs)
                stats_tracker.add_stat('%s_acc' % data_name, acc, 1)
                stats_tracker.add_stat('%s_auc' % data_name, auc, 1)

                all_stats.append(-1 * auc)
            else:
                assert False
        stats_tracker.add_stat('multi_obj', np.mean(np.array(all_stats)), 1)

    if write_path is not None and args.n_labels == 1:
        with open(write_path, 'w+') as write_file:
            for write_ele in write_output:
                json.dump(write_ele, write_file)
                write_file.write('\n')

    return stats_tracker

if __name__ == '__main__':
    main()


from flask_restful import Resource, reqparse
from flask_jwt import jwt_required, current_identity
from models.pages import PageModel
from models.site import SiteModel
from models.rank import RankModel
from datetime import datetime

class Pages(Resource):
    @jwt_required()
    def get(self, id=None, name=None):
        if id:
            stat = PageModel.find_by_id(id)
        else:
            stat = PageModel.find_by_name(name)
        if stat:
            return stat.json(current_identity.admin), 200
        return {'message': 'not found pages in this site'}, 404

class StatList(Resource):
    @jwt_required()
    def get(self):
        result = SiteModel.query.all()
        if result:
            return {
                'base statistic': [
                    PageModel.find_by_id(el.id).json(
                        current_identity.admin
                        ) for el in result if PageModel.find_by_id(el.id)]
                }, 200
        return {'message': 'not found base statistic'}, 404

class Rank(Resource):
    @jwt_required()
    def get(self, id=None, name=None):
        if id:
            stat = RankModel.find_by_id(id)
        else:
            stat = RankModel.find_by_name(name)
        if stat:
            return stat.json(), 200
        return {'message': 'not found rank in this site'}, 404

class RankList(Resource):
    @jwt_required()
    def get(self):
        result = SiteModel.query.all()
        if result:
            return {
                'base_rank statistic': [
                    RankModel.find_by_id(
                        el.id).json() for el in result if RankModel.find_by_id(
                            el.id)]
                }, 200
        return {'message': 'not found base_rank statistic'}, 404

class RankDay(Resource):
    #@jwt_required()
    def _pars_date(self, date):
        #pattern = r'\d{2}-\d{2}-\d{4}'
        #if re.match(pattern, date) is not None:
         #   return True
        #return False
        try:
            #date_str = "30-10-2016 16:18"
            #format_str = "%d-%m-%Y %H:%M"
            format_str = "%Y-%m-%d"
            return datetime.strptime(date, format_str)
        except ValueError:
            return False
    @jwt_required()
    def get(self, id=None, name=None, date=None):
        date = self._pars_date(date)
        if not date:
            return {'message': 'format of date is false ' + str(id)}, 404
        stat = 'None'
        if id and date:
            stat = RankModel.find_by_id_day(id, date)
        elif name and date:
            stat = RankModel.find_by_name_day(name, date)
        if stat:
            return stat.json_day(date), 200
        return {'message': 'not found pages in this site, day'}, 404

class RankDayList(Resource):
    @jwt_required()
    def get(self, date=None):
        result = PageModel.query.filter(PageModel.scan == date).first()
        if result:
            return {
                'base_rank_day statistic - ' + date: [
                    RankModel.find_by_id_day(
                        el.id, date).json_day(
                            date) for el in SiteModel.query.all(
                                ) if RankModel.find_by_id_day(
                                    el.id, date)]
                }, 200
        return {'message': 'not found base_rank_day statistic for this day'}, 404

class RankTime(Resource):
    def _pars_date(self, date):
        try:
            format_str = "%Y-%m-%d"
            return datetime.strptime(date, format_str)
        except ValueError:
            return False

    @jwt_required()
    def get(self, id=None, name=None, date1=None, date2=None):
        date1 = self._pars_date(date1)
        date2 = self._pars_date(date2)
        if not date1 or not date2:
            return {'message': 'format of date is false'}, 404
        stat = 'None'
        if id and date1 and date2:
            stat = RankModel.find_by_id_time(id, date1, date2)
        elif name and date1 and date2:
            stat = RankModel.find_by_name_time(name, date1, date2)
        if stat:
            return stat.json_time(date1, date2), 200
        return {'message': 'not found pages in this site, time'}, 404

class RankTimeList(Resource):
    @jwt_required()
    def get(self, date1=None, date2=None):
        result = PageModel.query.filter(
            PageModel.scan >= date1,
            PageModel.scan <= date2
            ).first()
        if result:
            return {
                'base_rank_time statistic - ' + date1 + '/' + date2: [
                    RankModel.find_by_id_time(
                        el.id, date1, date2
                        ).json_time(
                            date1, date2
                            ) for el in SiteModel.query.all() if RankModel.find_by_id_time(
                                el.id, date1, date2)]
                }, 200
        return {'message': 'not found base_rank_time statistic for this time'}, 404


from ptp2 import ParltrackSubRecord
from ptp2.dossier.doc import Doc
from ptp2.utils import make_date
from datetime import date, datetime

class Event(ParltrackSubRecord):

    def __init__(self, record):

        super().__init__(record)

        # date parsing
        if isinstance(self.date, str):
            self.date_str = self.date
        elif isinstance(self.date, (date, datetime)):
            self.date_str = make_date(self.date).isoformat()
        else:
            self.date_str = None

        try:
            self.date = make_date(self.date)
        except:
            self.date = None

        # initialize doc objects
        self.docs = [Doc(d) for d in self.docs] if hasattr(self, 'docs') and self.docs is not None else []


import json
import sqlite3
from models import Employee, Location
EMPLOYEES = [
    {
        "id": 1,
        "name": "Jenna Solis"
    }
]

def get_all_employees():
    """sql get all employees"""
    with sqlite3.connect("./kennel.sqlite3") as conn:
        conn.row_factory = sqlite3.Row
        db_cursor = conn.cursor()
        db_cursor.execute("""
        SELECT
            a.id,
            a.name,
            a.address,
            a.location_id,
            l.name location_name,
            l.address location_address
        FROM employee a
        JOIN Location l
            on l.id = a.location_id
        """)
        employees = []
        dataset = db_cursor.fetchall()
        for row in dataset:
            employee = Employee(row['id'], row['name'],
                                row['address'], row['location_id'])
            location = Location(
                row['location_id'], row['location_name'], row['location_address'])
            employee.location = location.__dict__
            employees.append(employee.__dict__)
    return employees

def get_single_employee(id):
    """sql single employee fetch"""
    with sqlite3.connect("./kennel.sqlite3") as conn:
        conn.row_factory = sqlite3.Row
        db_cursor = conn.cursor()
        db_cursor.execute("""
        SELECT
            a.id,
            a.name,
            a.address,
            a.location_id
        FROM employee a
        WHERE id = ?
        """, (id, ))
        data = db_cursor.fetchone()
        employee = Employee(data['id'], data['name'],
                            data['address'], data['location_id'])
    return employee.__dict__

def get_employee_by_location(location):
    """function for querying employee by location"""
    with sqlite3.connect("./kennel.sqlite3") as conn:
        conn.row_factory = sqlite3.Row
        db_cursor = conn.cursor()
        db_cursor.execute("""
        SELECT
            e.id,
            e.name,
            e.address,
            e.location_id
        FROM employee e
        WHERE e.location_id = ?
        """, (location, ))
        dataset = db_cursor.fetchall()
        employees = []
        for row in dataset:
            employee = Employee(row['id'], row['name'],
                                row['address'], row['location_id'])
            employees.append(employee.__dict__)
    return employees
# OLD VERSIONS
# def get_all_employees():
#     """function for viewing all employees"""
#     return EMPLOYEES

# def get_single_employee(id):
#     """function for getting individual employee by id"""
#     requested_employee = None

#     for employee in EMPLOYEES:
#         if employee["id"] == id:
#             requested_employee = employee
#     return requested_employee

def create_employee(new_employee):
    """sql function for employee post"""
    with sqlite3.connect("./kennel.sqlite3") as conn:
        db_cursor = conn.cursor()
        db_cursor.execute("""
        INSERT INTO Employee
            ( name, address, location_id )
        VALUES
            ( ?, ?, ?);
        """, (new_employee['name'], new_employee['address'], new_employee['location_id']))
        id = db_cursor.lastrowid
        new_employee['id'] = id
    return new_employee
# OLD VERSION
# def create_employee(employee):
#     """function for adding an employee to the database"""
#     # Get the id value of the last employee in the list
#     max_id = EMPLOYEES[-1]["id"]

#     # Add 1 to whatever that number is
#     new_id = max_id + 1

#     # Add an `id` property to the employee dictionary
#     employee["id"] = new_id

#     # Add the employee dictionary to the list
#     EMPLOYEES.append(employee)

#     # Return the dictionary with `id` property added
#     return employee

def delete_employee(id):
    """function for deleting an employee"""
    employee_index = -1
    for index, employee in enumerate(EMPLOYEES):
        if employee["id"] == id:
            employee_index = index
    if employee_index >= 0:
        EMPLOYEES.pop(employee_index)

def update_employee(id, new_employee):
    """function for updating a employee"""
    for index, employee in enumerate(EMPLOYEES):
        if employee["id"] == id:
            EMPLOYEES[index] = new_employee
            break


import asyncio
import re

from bs4 import BeautifulSoup
from requests import Response, Session, HTTPError

from config import debug_mode
from database.cache_manager import cache_manager
from utils.requests import session

android_app_key = 'android_app_package'

def parsing_http_page(url: str, params=None) -> BeautifulSoup:
    """简易包装的获取并解析网页操作
    Args:
        url: 目标网页
        params: 请求头
    Returns:
        由 BeautifulSoup4 解析的网页节点
    """
    headers = {
        'User-Agent': "Mozilla/5.0 (X11; Linux x86_64; rv:67.0) Gecko/20100101 Firefox/67.0"
    }
    html = http_get(url, headers=headers, params=params).text
    return BeautifulSoup(html, "html5lib")

def http_get(url: str, throw_error=True, **kwargs) -> Response or None:
    """简易包装的 get 方法
    Args:
        url: 访问的网址
        **kwargs: Optional arguments that ``request`` takes.
        throw_error: 是否抛出 HTTP 状态码异常
    Returns:
        包装网站响应的 Request 对象
    """
    try:
        response = session.get(url, **kwargs, timeout=15)
        response.raise_for_status()
        return response
    except Exception as e:
        if e is HTTPError:
            raise e
        if throw_error:
            raise e
        return None

def get_session() -> Session:
    """获取默认 Session 对象
    Returns: Session
    """
    return session

def search_version_number_string(string: str or None) -> str or None:
    """在字符串中匹配 x.y.z 版本号
    Args:
        string: 需匹配的字符串
    Returns:
        一个 Match object（详见 re 库）, 若无匹配项则返回 None
    """
    if string is None:
        return None
    pattern = "(\\d+(\\.\\d+)*)(([.|\\-|+|_| ]|[0-9A-Za-z])*)"
    return re.search(pattern, string)

def search_url_string(string: str or None) -> str or None:
    """在字符串中匹配 x.y.z 版本号
    Args:
        string: 需匹配的字符串
    Returns:
        匹配到的 URL
    """
    if string is None:
        return None
    pattern = '((ht|f)tps?:)//[-A-Za-z0-9+&@#/%?=~_|!:,.;]+[-A-Za-z0-9+&@#/%=~_|]'
    return re.search(pattern, string).lastgroup

def get_tmp_cache(key: str) -> bytes or None:
    """获取临时缓存
    Args:
        key: 缓存键值

    Returns:
        缓存的 bytes
    """
    try:
        return cache_manager.get_tmp_cache(key)
    except KeyError:
        return None

def add_tmp_cache(key: str, value: bytes):
    """添加临时缓存
    Args:
        key: 缓存键值
        value: 缓存的字符串
    Returns:
        None
    """
    if value:
        cache_manager.add_tmp_cache(key, value)

def del_tmp_cache(key: str):
    """删除临时缓存
    Args:
        key: 缓存键值
    """
    cache_manager.del_tmp_cache(key)

def get_release_by_uuid(uuid, app_id: dict, auth: dict or None = None, use_cache=True) -> list:
    """获取对应 UUID 的软件源的 get_release 函数的输出
    Args:
        uuid: 软件源的 UUID
        use_cache: 是否使用服务器缓存
        app_id: 客户端上传的软件属性
        auth: 软件源身份验证信息
    Returns:
        对应的下载地址
    """
    from getter.service.api import get_single_release
    return get_single_release(uuid, auth, app_id, use_cache=use_cache)

def get_url_from_release_fun(uuid, app_id: dict, asset_index, auth: dict or None = None, use_cache=True) -> str:
    """获取对应 UUID 的软件源的 get_release 函数输出的下载地址
    Args:
        uuid: 软件源的 UUID
        use_cache: 是否使用服务器缓存
        app_id: 客户端上传的软件属性
        asset_index: 客户端请求的下载文件的索引
        auth: 软件源身份验证信息
    Returns:
        对应的下载地址
    """
    release_list = get_release_by_uuid(uuid, app_id, auth, use_cache)
    release: dict = release_list[asset_index[0]]
    return release["assets"][asset_index[1]]["download_url"]

def get_new_asyncio_loop():
    loop = asyncio.new_event_loop()
    asyncio.set_event_loop(loop)
    if debug_mode:
        loop.set_debug(True)
    return loop

def call_def_in_loop_return_result(core, _loop=None):
    if _loop:
        loop = _loop
    else:
        loop = get_new_asyncio_loop()
    try:
        result = loop.run_until_complete(core)
    except RuntimeError:
        future = asyncio.run_coroutine_threadsafe(core, loop)
        result = future.result()
    if not _loop:
        loop.close()
    return result


import urllib.request, urllib.parse, urllib.error

from bs4 import BeautifulSoup

url = input('Enter - ')

html = urllib.request.urlopen(url).read()
soup = BeautifulSoup(html, 'html.parser')

# Retrive all of the anchor tags

tags = soup('a')
for tag in tags:
    print(tag.get('href', None))

# Python for Web Service
# Data on the web
# agreed way to represent data going between application and across networks
# two commonly used formats: XML and JSON


import argparse
from selenium import webdriver
from scrapfile import LICLIENT
import time

def parse_command_line_args():
    parser = argparse.ArgumentParser(description="""
        parse LinkedIn search parameters
        """)
    parser.add_argument('--username', type=str, required=True,
        help="""
        enter LI username
        """)
    parser.add_argument('--password', type=str, required=True,
        help="""
        enter LI password
        """)
    parser.add_argument('--jobname',nargs='*',
        help="""
        enter search keys separated by a single space. If the keyword is more
        than one word, wrap the keyword in double quotes.
        """)

    parser.add_argument('--location',  nargs='*',
        help="""
        enter search keys separated by a single space. If the keyword is more
        than one word, wrap the keyword in double quotes.
        """)

    parser.add_argument('--filename', type=str, nargs='?',
        help="""
        specify a filename to which data will be written.

        """)
    return vars(parser.parse_args())
if __name__ == "__main__":

    search_keys = parse_command_line_args()
    driver = webdriver.Chrome(r"chromedriver.exe")
    # Logging into LinkedIn
    driver.get("https://linkedin.com/uas/login")
    time.sleep(5)
    liclient = LICLIENT(driver,**search_keys)
    liclient.login()

    for jobname in search_keys["jobname"]:
        for location in search_keys["location"]:
            liclient.jobname = jobname
            liclient.location = location
            liclient.enter_search_keys()
            liclient.navigate_search_results()

    liclient.driver_quit()


from __future__ import division
import itertools
import numpy as np

def batch(iterable, n):
    it = iter(iterable)
    while True:
        chunk = tuple(itertools.islice(it, n))
        if not chunk:
            return
        yield chunk

def build_grid(shape):
    r"""
    """
    shape = np.asarray(shape)
    half_shape = np.floor(shape / 2)
    half_shape = np.require(half_shape, dtype=int)
    start = -half_shape
    end = half_shape + shape % 2
    sampling_grid = np.mgrid[start[0]:end[0], start[1]:end[1]]
    return np.rollaxis(sampling_grid, 0, 3)


import docker

client = docker.from_env()

class NetworkBuilder:
    NETWORK = None
    _DEFAULT_NETWORK = None

    def __init__(self, name='dockeranon_net', range='192.168.5.0/24', gw='192.168.5.254'):
        self.network = NetworkBuilder.NETWORK
        if self.network is not None:
            return
        # Check if network exists
        for net in client.networks.list():
            if net.attrs.get('Name') == name:
                NetworkBuilder.NETWORK = client.networks.get(net.id)
            elif net.attrs.get('Name') == 'bridge':
                NetworkBuilder._DEFAULT_NETWORK = client.networks.get(net.id)
        if NetworkBuilder.NETWORK is None:
            # Create if not exists
            ipam_pool = docker.types.IPAMPool(
                subnet=range
            )
            ipam_config = docker.types.IPAMConfig(
                pool_configs=[ipam_pool]
            )
            NetworkBuilder.NETWORK = client.networks.create(
                name,
                driver="bridge",
                ipam=ipam_config
            )
        self.network = NetworkBuilder.NETWORK

    def connect(self, container_builder, ip):
        self.network.connect(container_builder.container,
                             ipv4_address=ip)
        self._DEFAULT_NETWORK.disconnect(container_builder.container)

    @property
    def gateway(self):
        if self.network is None:
            return None
        return self.network.attrs.get('IPAM').get('Config')[0].get('Gateway')

    @property
    def range(self):
        if self.network is None:
            return None
        return self.network.attrs.get('IPAM').get('Config')[0].get('Subnet')

    @property
    def name(self):
        if self.network is None:
            return None
        return self.network.attrs.get('Name')

    @staticmethod
    def clean():
        if NetworkBuilder.NETWORK is not None:
            NetworkBuilder.NETWORK.remove()


from typing import final
import numpy as np
import matplotlib.pyplot as plt
initial_epsilon = 1
middle_epsilon = 0.25
final_epsilon = 0.07
epsilon = initial_epsilon
epsilons = []

decay = np.power(middle_epsilon/initial_epsilon, 1/1e6)
decay2 = np.power(final_epsilon/middle_epsilon, 1/3e6)
print(decay)
for i in range(int(7e6)):
    if epsilon > middle_epsilon:
        epsilon *= decay
    elif epsilon > final_epsilon:
        epsilon *= decay2
    epsilons.append(epsilon)
plt.plot(epsilons)
plt.show()