from PyQt5 import QtCore, QtGui
from PyQt5.QtCore import QSize
import qtawesome as qta
from PyQt5.QtWidgets import QPushButton, QStyle

class CopyCodeBtn(QPushButton):

    def __init__(self, parent):
        super(CopyCodeBtn, self).__init__()

        self.setParent(parent)
        self.setText(' Arduino Code')
        self.setIcon(qta.icon('mdi.code-braces-box'))
        self.setIconSize(QSize(30, 30))
        self.adjustSize()
        self.move(parent.width() - 15 - self.width(), parent.height() - 10 - self.height())

        self.clicked.connect(self.copyCode)

    def copyCode(self):
        self.openUrl()

    def openUrl(self):
        parent = self.parent()
        url = QtCore.QUrl('https://github.com/ShreyanshJF/Open-Source-Optics-Lab/blob/main/controlling_motor_with_python.ino')
        if not QtGui.QDesktopServices.openUrl(url):
            self.setText('Open Url Could not open url')
            self.adjustSize()
            self.move(parent.width() - 15 - self.width(), parent.height() - 10 - self.height())


from django.db import models
from users.models import CustomUser

class Private_Message(models.Model):
    sender = models.ForeignKey(CustomUser, related_name="message_sender", on_delete=models.CASCADE)
    receiver = models.ForeignKey(CustomUser, related_name="message_receiver", on_delete=models.CASCADE)
    message = models.CharField(default="", max_length=100)
    datetime = models.DateTimeField(auto_now_add=True)
    def __str__(self):
        return "sender: " + str(self.sender.username) + " receiver: " + str(self.receiver.username) + " message: " + str(self.message) + " datetime: " + str(self.datetime)
    # date = models.DateField(auto_now_add=True)
    # time = models.TimeField(auto_now_add=True)

def getAllMessages(user1, user2):
    messages = list(Private_Message.objects.filter(sender=user1, receiver=user2) | Private_Message.objects.filter(sender=user2, receiver=user1))
    messages = sorted(messages, key=lambda x:x.datetime)
    # messages.order_by('datetime')
    #messages.sort(key=lambda x: (x.date, x.time))
    return messages


#!/usr/bin/python3
import pyaudio
import os
import fnmatch
import shutil
import sys

def play_pcm(filename):
    p = pyaudio.PyAudio()
    stream = p.open(format = pyaudio.paInt16,
                channels = 2,
                rate = 24000,
                output = True)

    with open(filename, 'rb') as pcm_file:
        pcm_data = pcm_file.read()
        stream.write(pcm_data)
    stream.stop_stream()

    stream.close()
    p.terminate()

def menu_show():
    print('MENU:')
    print('1 - Play pcm file')
    print('2 - View decoded string')
    print('3 - Edit decoded string')
    print('4 - Add pcm file to test dataset')
    print('5 - Next pcm file')
    print('6 - Quit')

def process_file(path, copy_path, pcm_file, ds_file):
    flag = True
    decoded_string = ''
    while(flag):
        print('File in process:' + pcm_file)
        menu_show()
        value = input('Choose item:')
        menu_item = int(value)
        if (menu_item == 1):
            play_pcm(path + pcm_file)

        elif (menu_item == 2):
            with open(path + ds_file, 'r') as fd:
                decoded_string = fd.read()
            print(decoded_string)

        elif (menu_item == 3):
            decoded_string = input('Enter string for pcm file:')

        elif (menu_item == 4):
            shutil.copy(path + pcm_file, copy_path + pcm_file)
            file_name = ds_file.split('.')[0]
            with open(copy_path + file_name + '.ds', 'w') as fd:
                print(decoded_string)
                fd.write(decoded_string)
            fd.close()

        elif (menu_item == 5):
            flag = False

        elif (menu_item == 6):
            os._exit(0)

def main(pcm_path, copy_path, start_index):
    dir_name = pcm_path

    pcm_list = []
    decoded_string_list = []
    for file_name in os.listdir(dir_name):

        if fnmatch.fnmatch(file_name, '*.pcm'):
            pcm_file = file_name
            data_file = file_name.split('.')[0]
            bad_file = data_file + '.bad'
            good_file = data_file + '.good'
            if os.path.isfile(dir_name + bad_file):
                pcm_list.append(pcm_file)
                decoded_string_list.append(bad_file)
            if os.path.isfile(dir_name + good_file):
                pcm_list.append(pcm_file)
                decoded_string_list.append(good_file)

    print('pcm list len - ' + str(len(pcm_list)))
    print('ds list len - ' + str(len(decoded_string_list)))
    for index in range(start_index,len(pcm_list)):
        print('index - ', index)
        print(pcm_list[index])
        print(decoded_string_list[index])
        process_file(dir_name, copy_path, pcm_list[index],
                decoded_string_list[index])

if __name__ == '__main__':
    abs_path_name = os.path.abspath(os.getcwd()) + '/'
    if (len(sys.argv) != 4):
        print('\nUsage: ' + sys.argv[0] + ' dir_with_pcm_files dir_to_copy start_index\n')
        os._exit(-1)
    path1 = abs_path_name + sys.argv[1] + '/'
    path2 = abs_path_name + sys.argv[2] + '/'
    start_index = int(sys.argv[3])
    main(path1, path2, start_index)


from utils.admin_functions import admin_functions
from utils.user_functions import user_functions

class FoodDeliveryApp:
    """
    A simple Food Delivery App that allows users to place orders and admins to manage the food items.
    """

    def __init__(self):
        """
        Initializes the FoodDeliveryApp class and starts the application.
        """
        self.run()

    def welcome_screen(self):
        """
        Displays the welcome screen of the app and prompts the user to choose an option.
        """
        print("Welcome to the Food Delivery App!")
        print("1. Admin Login")
        print("2. User Login")
        print("3. Exit")

        choice = input("Please enter your choice: ")

        if choice == "1":
            self.admin_login()
        elif choice == "2":
            self.user_login()
        elif choice == "3":
            self.exit_program()
        else:
            print("Invalid choice. Please try again.")
            self.welcome_screen()

    def admin_login(self):
        """
        Prompts the admin to log in or register.
        """
        admin_functions.admin(self)

    def user_login(self):
        """
        Prompts the user to log in or register.
        """
        user_functions.user(self)

    def exit_program(self):
        """
        Exits the program.
        """
        print("Exiting the program. Goodbye!")

    def run(self):
        """
        Runs the Food Delivery App by displaying the welcome screen.
        """
        self.welcome_screen()

if __name__ == "__main__":
    app = FoodDeliveryApp()


import torch

box1 = torch.tensor([[-0.1725, -0.2910,  0.2296,  0.3694],
        [-0.2984, -0.1456,  0.3558,  0.1891]])

box2 = torch.tensor([[-0.4034, -0.3760,  0.4146,  0.5000]])

def compute_iou(box1, box2):
    """Compute the intersection over union of two set of boxes, each box is [x1,y1,x2,y2].
    Args:
      box1: (tensor) bounding boxes, sized [N,4].
      box2: (tensor) bounding boxes, sized [M,4].
    Return:
      (tensor) iou, sized [N,M].
    """
    N = box1.size(0)
    M = box2.size(0)

    print('box1[:, :2].unsqueeze(1).expand(N, M, 2)', box1[:, :2].unsqueeze(1).expand(N, M, 2))
    print('box2[:, :2].unsqueeze(0).expand(N, M, 2)', box2[:, :2].unsqueeze(0).expand(N, M, 2))
    lt = torch.max(
        box1[:, :2].unsqueeze(1).expand(N, M, 2),  # [N,2] -> [N,1,2] -> [N,M,2]
        box2[:, :2].unsqueeze(0).expand(N, M, 2),  # [M,2] -> [1,M,2] -> [N,M,2]
    )

    rb = torch.min(
        box1[:, 2:].unsqueeze(1).expand(N, M, 2),  # [N,2] -> [N,1,2] -> [N,M,2]
        box2[:, 2:].unsqueeze(0).expand(N, M, 2),  # [M,2] -> [1,M,2] -> [N,M,2]
    )

    wh = rb - lt  # [N,M,2]
    wh[wh < 0] = 0  # clip at 0
    inter = wh[:, :, 0] * wh[:, :, 1]  # [N,M]

    area1 = (box1[:, 2] - box1[:, 0]) * (box1[:, 3] - box1[:, 1])  # [N,]
    area2 = (box2[:, 2] - box2[:, 0]) * (box2[:, 3] - box2[:, 1])  # [M,]
    area1 = area1.unsqueeze(1).expand_as(inter)  # [N,] -> [N,1] -> [N,M]
    area2 = area2.unsqueeze(0).expand_as(inter)  # [M,] -> [1,M] -> [N,M]

    iou = inter / (area1 + area2 - inter)
    return iou

iou = compute_iou(box1, box2)

print(iou)


# Add the root path of the dmrgpy library
import os ; import sys ; sys.path.append(os.getcwd()+'/../../../src')

import numpy as np
from dmrgpy import spinchain,fermionchain
n = 6

site = 0

def get_spin():
    # create a random spin chain
    spins = ["S=1/2" for i in range(n)] # spin 1/2 heisenberg chain
    # create first neighbor exchange
    sc = spinchain.Spin_Chain(spins) # create the spin chain
    h = 0
    for i in range(n-1):
        h = h + sc.Sx[i]*sc.Sx[i+1]
        h = h + sc.Sy[i]*sc.Sy[i+1]
    sc.set_hamiltonian(h)
    name = (sc.Sx[site],sc.Sx[site]) # correlator to compute
    es = np.linspace(-0.5,3,2000)
    delta = 5e-2
    (x,y) = sc.get_dynamical_correlator(name=name,es=es,delta=delta)
    return (x,y)

def get_fermion():
    sc = fermionchain.Fermionic_Chain(n) # create the spin chain
    h = 0
    for i in range(n-1):
        h = h + sc.Cdag[i]*sc.C[i+1]/2.
    h = h + h.get_dagger()
    sc.set_hamiltonian(h)
    name = (sc.Cdag[site],sc.C[site]) # correlator to compute
    es = np.linspace(-0.5,3,2000)
    delta = 5e-2
    (x,y) = sc.get_dynamical_correlator(name=name,es=es,delta=delta)
    return (x,y/2)

(xs,ys) = get_spin()
(xf,yf) = get_fermion()

import matplotlib.pyplot as plt
plt.plot(xf,yf.real,c="blue",label="Fermion")
plt.scatter(xs,ys.real,c="red",label="Spin")
plt.legend()
plt.show()


import torch
import torch.nn as nn
import torch.nn.functional as F

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

class VolumetricFeatureSampler(nn.Module):

    def __init__(self, padding_mode='zeros', feature_fusion=''):
        super(VolumetricFeatureSampler, self).__init__()

        """ define a volumetric feature sampler
        """
        self.padding_mode = padding_mode

        # note: the two operations will cumulate the feature and squared feature, independently among the feature channels
        # later in self.compute_stats(), we convert the results into means and standard deviations.
        # currently these are hardcoded operations, and all tensors in this class with some dimension "2F" are also due to this reason
        self.fuse_ops = [
            lambda feat, base: feat if base is None else feat + base,
            lambda feat, base: feat.pow(2.0) if base is None else feat.pow(2.0) + base,
        ]
        self.fuse_ops_num = len(self.fuse_ops)

        if feature_fusion == 'mean_var':
            self.compute_feature_volume = self.mean_var
        elif 'visibility_filtered' in feature_fusion:
            self.compute_feature_volume = self.visibility_filtered_mean_var
        else:
            raise RuntimeError( "Unrecognizable feature_fusion: %s" % ( self.feature_fusion ) )

    @staticmethod
    def project(points, camera_intrinsics, camera_extrinsics, camera_distortions, height, width, eps=1e-7):
        """ project the grid points into images (full perspective projection)
        Args:
        - points: (B, N, 3)
        - camera_intrinsics: (B, 3, 4)
        - camera_extrinsics: (B, 3, 3)
        - camera_distortions: (B, 2)
        - height: int
        - width: int

        Return:
        - u_coord: (B, N), value range in [-1, 1]
        - v_coord: (B, N), value range in [-1, 1]
        """

        device = points.device
        batch_size, num_points, _ = points.shape
        points = points.transpose(1, 2).contiguous()

        ones = torch.ones(batch_size, 1, num_points).to(device)
        points_homogeneous = torch.cat((points, ones), axis=-2) # (batch_size, 4, num_points)

        # Transformation from the world coordinate system to the image coordinate system using the camera extrinsic rotation (R) and translation (T)
        points_image = camera_extrinsics.bmm(points_homogeneous) # (batch_size, 3, num_points)

        # Transformation from 3D camera coordinate system to the undistorted image plane
        mask = (points_image.abs() < eps)
        mask[:,:2,:] = False
        points_image[mask] = 1.0 # Avoid division by zero

        points_image_x = points_image[:,0,:] / points_image[:,2,:]
        points_image_y = points_image[:,1,:] / points_image[:,2,:]

        # Transformation from undistorted image plane to distorted image coordinates
        K1, K2 = camera_distortions[:,0], camera_distortions[:,1]       # (batch_size)
        r2 = points_image_x**2 + points_image_y**2            # (batch_size, num_points)
        r4 = r2**2
        radial_distortion_factor = (1 + K1[:, None]*r2 + K2[:, None]*r4)  # (batch_size, num_points)

        points_image_x = points_image_x*radial_distortion_factor
        points_image_y = points_image_y*radial_distortion_factor
        points_image_z = torch.ones_like(points_image[:,2,:])
        points_image = torch.cat((points_image_x[:, None, :], points_image_y[:, None, :], points_image_z[:, None, :]), dim=1)

        # Transformation from distorted image coordinates to the final image coordinates with the camera intrinsics
        points_image = camera_intrinsics.bmm(points_image)      # (batch_size, 3, num_points)

        # Convert the range to [-1, 1]
        u_coord = 2. * points_image[:, 0, :] / (width - 1.) - 1.
        v_coord = 2. * points_image[:, 1, :] / (height - 1.) - 1.
        return u_coord, v_coord

    def mean_var(self, feature_maps, camera_intrinsics, camera_extrinsics, camera_distortions, grids, **kwargs):
        batch_size, num_views, fd, height, width = feature_maps.shape
        _, grid_num, _, grid_h, grid_w, grid_d = grids.shape
        xyzs = grids.transpose(1, 2).contiguous() # (B, 3, G, GH, GW, GD)
        xyzs = xyzs.view(batch_size, 3, -1)               # (B, 3, G*GH*GW*GD)
        xyzs = xyzs.transpose(1, 2).contiguous() # (B, G*GH*GW*GD, 3)

        # projection
        xyzs = xyzs.unsqueeze(1).repeat(1,num_views,1,1).view(batch_size*num_views, -1, 3)
        u_coord, v_coord = self.project(xyzs, camera_intrinsics.view(-1,3,3), camera_extrinsics.view(-1,3,4), camera_distortions.view(-1,2), height, width)

        # sample
        grid2d_uv = torch.stack((u_coord, v_coord), dim=2) # (B*V, G*GH*GW*GD, 2)
        grid2d_uv = grid2d_uv.view(batch_size*num_views, grid_num, -1, 2) # (B*V, G, GH*GW*GD, 2)
        feat2d_uv = F.grid_sample(feature_maps.view(-1, fd, height, width), grid2d_uv, padding_mode=self.padding_mode, align_corners=False)  # (B*V, F, G, GH*GW*GD)
        feat2d_uv = feat2d_uv.transpose(1, 2)    # (B*V, G, F, GH*GW*GD)
        feat2d_uv = feat2d_uv.view(batch_size, num_views, grid_num, -1, grid_h, grid_w, grid_d)  # (B, V, G, F, GH, GW, GD)

        # voxels = torch.cat((feat2d_uv.mean(dim=1), feat2d_uv.std(dim=1, unbiased=False)), dim=2).contiguous()   # (B, G, 2F, GH, GW, GD)
        feature_volume = torch.cat((feat2d_uv.mean(dim=1), feat2d_uv.var(dim=1, unbiased=True)), dim=2).contiguous()   # (B, G, 2F, GH, GW, GD)
        return feature_volume

    def visibility_filtered_mean_var(self, feature_maps, camera_intrinsics, camera_extrinsics, camera_distortions, grids, visibilities, normals, camera_centers, **kwargself):
        '''
        Args:
            feature_maps: (B, V, F, H, W), image feature maps
            camera_intrinsics: (B, V, 3, 3)
            camera_extrinsics: (B, V, 3, 3)
            camera_distortions: (B, V, 3)
            grids: (B, G, 3, GH, GW, GD)
            visibilities: (B, V, G)
            normals: (B, G, 3)
            camera_centers: (B, V, 3)
        '''

        batch_size, num_views, fd, height, width = feature_maps.shape
        _, grid_num, _, grid_h, grid_w, grid_d = grids.shape
        xyzs = grids.transpose(1, 2).contiguous() # (B, 3, G, GH, GW, GD)
        xyzs = xyzs.view(batch_size, 3, -1)      # (B, 3, G*GH*GW*GD)
        xyzs = xyzs.transpose(1, 2).contiguous() # (B, G*GH*GW*GD, 3)

        # projection
        xyzs = xyzs.unsqueeze(1).repeat(1,num_views,1,1).view(batch_size*num_views, -1, 3)
        u_coord, v_coord = self.project(xyzs, camera_intrinsics.view(-1,3,3), camera_extrinsics.view(-1,3,4), camera_distortions.view(-1,2), height, width)  # (B*V, G*GH*GW*GD)

        # sample feature maps
        grid2d_uv = torch.stack((u_coord, v_coord), dim=2) # (B*V, G*GH*GW*GD, 2)
        grid2d_uv = grid2d_uv.view(batch_size*num_views, grid_num, -1, 2) # (B*V, G, GH*GW*GD, 2)
        feat2d_uv = F.grid_sample(feature_maps.view(-1, fd, height, width), grid2d_uv, padding_mode=self.padding_mode, align_corners=False)  # (B*V, F, G, GH*GW*GD)
        feat2d_uv = feat2d_uv.transpose(1, 2).contiguous()    # (B*V, G, F, GH*GW*GD)
        feat2d_uv = feat2d_uv.view(batch_size, num_views, grid_num, -1, grid_h, grid_w, grid_d)  # (B, V, G, F, GH, GW, GD)

        # mask for points that project inside the images
        inside_mask = torch.logical_and(torch.logical_and(u_coord>=-1.0, u_coord<=1.0), torch.logical_and(v_coord>=-1.0, v_coord<=1.0)).contiguous()    # (B*V, G*GH*GW*GD)
        inside_mask = inside_mask.view(batch_size, num_views, grid_num, grid_h, grid_w, grid_d)     # (B, V, G, GH, GW, GD)

        # view_direction = grids - camera_centers
        view_directions = xyzs - camera_centers.contiguous().view(-1,1,3)     # (B*V, G*GH*GW*GD, 3)

        # cos_angle = <view_directions, normals>
        view_directions = view_directions.contiguous().view(batch_size, num_views, grid_num, -1, 3)     # (B, V, G, GH*GW*GD, 3)
        view_directions = view_directions.transpose(1,2).contiguous()  # (B, G, V, GH*GW*GD, 3)
        view_directions = view_directions.view(batch_size*grid_num, -1, 3)  # (B*G, V*GH*GW*GD, 3)
        view_directions = torch.nn.functional.normalize(view_directions, dim=-1)   # (B*G, V*GH*GW*GD, 3)
        view_normal_cos_angles = torch.bmm(view_directions, normals.contiguous().view(-1,3,1)) # (B*G, V*GH*GW*GD, 1)
        view_normal_cos_angles = view_normal_cos_angles.view(batch_size, grid_num, num_views, -1)   # (B, G, V, GH*GW*GD)
        view_normal_cos_angles = view_normal_cos_angles.transpose(1,2).contiguous()  # (B, V, G, GH*GW*GD)

        # Positive angles get zero weights
        view_normal_cos_angles[view_normal_cos_angles>0] = 0.0      # (B, V, G, GH*GW*GD)
        view_normal_cos_angles = view_normal_cos_angles.view((batch_size, num_views, grid_num, grid_h, grid_w, grid_d))   # (B, V, G, GH, GW, GD)

        # Weight negative cosine angles with visibility
        visibilities = visibilities.contiguous().view(batch_size, num_views, grid_num, 1, 1, 1)  # (B, V, G, 1, 1, 1)
        feature_weights = torch.multiply(visibilities, -view_normal_cos_angles)   # (B, V, G, GH, GW, GD)
        feature_weights = torch.multiply(feature_weights, inside_mask.float())   # (B, V, G, GH, GW, GD)

        # Make weights strictly positive and normalize them to sum to 1 across all views
        feature_weights = torch.nn.Softplus(beta=50, threshold=5)(feature_weights)  # (B, V, G, GH, GW, GD)
        feature_weights = feature_weights/feature_weights.sum(1).unsqueeze(1)   # (B, V, G, GH, GW, GD)
        feature_weights = feature_weights.unsqueeze(3)  # (B, V, G, 1, GH, GW, GD)

        # Computed weighted mean and standard deviation and concatenate them
        weighted_mean = torch.mul(feat2d_uv, feature_weights).sum(dim=1)   # (B, G, F, GH, GW, GD)
        weighted_var = torch.mul(feat2d_uv.pow(2), feature_weights).sum(dim=1)-weighted_mean.pow(2) # (B, G, F, GH, GW, GD)
        feature_volume = torch.cat((weighted_mean, weighted_var), dim=2).contiguous()        # (B, G, 2F, GH, GW, GD)
        return feature_volume

    def forward(self, feature_maps, camera_intrinsics, camera_extrinsics, camera_distortions, grids, normals=None, visibilities=None, camera_centers=None):
        """ the full forward process
        Args:
        - feature_maps: tensor in (B, V, F, H, W), batched feature map
        - camera_intrinsics: tensor in (B, V, 3, 3), batched intrisic matrices
        - camera_extrinsics: tensor in (B, V, 3, 4), batched rigid transformation (camera poses)
        - camera_distortions: tensor in (B, V, 2), batched radial camera distortions
        - grids: (B, G, 3, GH, GW, GD), batched grid coordinates

        B: batch size; F: feature dim; V: view num;
        G: grid num (global stage = 1, local stage = input vertex number)
        GH, GW, GD: shape of the grid, currently all equal to grid dim D

        Return:
        - voxels: tensor in (B, G, 2F, GH, GW, GD), sampled volumetric features
        """

        feature_volume = self.compute_feature_volume(feature_maps, camera_intrinsics, camera_extrinsics, camera_distortions, grids, normals=normals, visibilities=visibilities, camera_centers=camera_centers)
        return feature_volume


from typing import List

class Solution:
    def maxProduct(self, nums: List[int]) -> int:
        res = nums[0]
        curMin, curMax = 1, 1
        for n in nums:
            tmp = curMax * n
            curMax = max(n * curMax, n * curMin, n)
            curMin = min(tmp, n * curMin, n)
            res = max(res, curMax)
        return res


'''
file: cmdParser.py

brief: cmdParser validates command line args and parses them into a dict object

https://github.com/AlexanderJDupree/GithubNetwork
'''

import argparse

VIS_LAYOUTS = ['spring', 'kamada-kawai', 'random', 'spectral', 'circular', 'shell']

FILE_FORMATS = [ 'graphml', 'pickle', 'adjacency_list', 'gexf', 'yaml', 'edge_list' ]

COLOR_MAPS = ['rainbow', 'purples', 'greys', 'blues', 'greens', 'yellow-red',
              'spring', 'summer', 'cool', 'hot', 'gnuplot', 'twilight', 'coolwarm']

def validateInteger(arg, lbound, ubound):
    value = int(arg)
    if value < lbound or value > ubound:
        raise argparse.ArgumentTypeError(
                f'{arg} is not within range {lbound}..{ubound}'
                )
    return value

def validateDiameter(arg):
    return validateInteger(arg, 1, 100)

def validateMaxNodes(arg):
    return validateInteger(arg, 1, 5000)

def validateArrowSize(arg):
    return validateInteger(arg, 1, 20)

# TODO Flags require an argument when they shouldn't.
def parse(argv):

    parser = argparse.ArgumentParser(
            description="Visualize your your GitHub social network!"
            )
    parser.add_argument(
            'user',
            metavar='USERNAME',
            help="<USERNAME> of a Github profile"
            )
    parser.add_argument(
            '-d', '--diameter',
            type=validateDiameter,
            metavar='',
            default=5,
            help="<NUMBER> length of the longest shortest path from the user. Default=5"
            )
    parser.add_argument(
            '-m', '--max',
            type=validateMaxNodes,
            metavar='',
            default=500,
            help="max <NUMBER> of nodes in the graph. Default=500"
            )
    parser.add_argument(
            '-v', '--vis',
            choices=VIS_LAYOUTS,
            metavar='',
            default=VIS_LAYOUTS[0],
            help="Graph visualization <LAYOUT>. Default={}. Layouts are \n\t{}".format(
                VIS_LAYOUTS[0], '\n\t'.join(VIS_LAYOUTS))
            )
    parser.add_argument(
            '-o', '--output',
            metavar='',
            default='network.png',
            help='Desired <FILE NAME> of output. Default=network.png'
            )
    parser.add_argument(
            '-l', '--labels',
            metavar='',
            default=False,
            help="Display labels with each node. Default=False"
            )
    parser.add_argument(
            '-a', '--arrowsize',
            type=validateArrowSize,
            metavar='',
            default=10,
            help="Specify size of arrows. <NUMBER>. Default=10"
            )
    parser.add_argument(
            '-s', '--scale',
            type=float,
            metavar='',
            default=1.0,
            help="Scale the size of each nodes. <FLOAT>. Default=1.0"
            )
    parser.add_argument(
            '-n', '--normalize',
            type=bool,
            metavar='',
            default=False,
            help="Normalize the size of each node. Default=False"
            )
    parser.add_argument(
            '-w', '--width',
            type=float,
            metavar='',
            default=1.0,
            help="Width of edge lines <FLOAT>. Default=1.0"
            )
    parser.add_argument(
            '-f', '--figsize',
            type=int,
            nargs=2,
            metavar='',
            choices=range(1, 100),
            default=(20,20),
            help="Figure size tuple: (<WIDTH>,<HEIGHT>), default=(20,20)"
            )
    parser.add_argument(
            '-x', '--axis',
            type=bool,
            metavar='',
            default=False,
            help="Display graphs x/y axis. Default=False"
            )
    parser.add_argument(
            '-b', '--bar',
            type=bool,
            metavar='',
            default=False,
            help="Add a colorbar to the table. Default=False"
            )
    parser.add_argument(
            '-c', '--colormap',
            metavar='',
            choices=COLOR_MAPS,
            default=COLOR_MAPS[0],
            help="Color Mapping palette. Default=rainbow. Options: {}".format(
                '\n'.join(COLOR_MAPS)
                )
            )
    parser.add_argument(
            '--format',
            choices=FILE_FORMATS,
            default=FILE_FORMATS[0],
            help="Graph output file format. Default={}.".format(
                FILE_FORMATS[0]
            ))

    # Returns a dict object
    return vars(parser.parse_args(argv))


import torch
from torch.autograd import Variable
from tqdm import tqdm as progressbar
from auto_encoder.model import Autoencoder
from auto_encoder.dataset import AutoEncoderDataset
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

def plot_data(x, y, title):
    """
    Plots scatterplot
    """
    x1 = range(x.shape[0])
    plt.clf()
    plt.title(title)
    plt.scatter(x1, x, marker='o', c=y, s=20, edgecolor='k')
    plt.show()

def to_var(x, use_gpu=True):
    if torch.cuda.is_available() and use_gpu:
        x = x.cuda()
    return Variable(x)

def _get_inputs(iterator):
    next_batch = next(iterator)  # here we assume data type torch.Tensor
    inputs, targets = next_batch["inputs"], next_batch["targets"]
    y = next_batch["y"]
    inputs, targets = to_var(inputs), to_var(targets)
    return inputs, targets, y

def calc_mse(data_loader, model, loss_fn):
    iter_per_epoch = len(data_loader)
    data_iter = iter(data_loader)
    losses = []
    for i in progressbar(range(iter_per_epoch)):
        inputs, targets, y = _get_inputs(data_iter)

        predictions, _ = model.predict(inputs)
        features = model.predict_encoder(inputs)
        np_features = features.data.cpu().numpy()
        # code specific for batch_size = 1
        loss = loss_fn(predictions, targets)
        loss1 = loss.data.cpu().numpy()
        y = y.numpy()
        first_part = [i for i in np_features[0]]
        second = first_part + [loss1[0], y[0][0]]
        losses.append(second)
    return losses

def get_encoder_repr(data_loader, model):
    iter_per_epoch = len(data_loader)
    data_iter = iter(data_loader)
    result = []
    for i in progressbar(range(iter_per_epoch)):
        inputs, targets, y = _get_inputs(data_iter)
        # targets and inputs here should be the same
        outputs = model.predict(targets)
        np_outputs = outputs.data.cpu().numpy()
        features = model.predict_encoder(targets)
        np_features = features.data.cpu().numpy()
        y = y.numpy()
        first_part = [i for i in np_features[0]]
        second = first_part + [y[0][0]]
        result.append(second)
    return result

def gather_positive(path):
    data = pd.read_csv(path)
    true_rows = data["target"] == 1
    data = data[true_rows]
    data.to_csv("../data/train_pos.csv", index=False)

if __name__ == "__main__":
    gather_positive("../data/one-hot-train.csv")
    # from auto_encoder.dataset import ToTensor
    # from torch.utils.data import DataLoader
    # import seaborn as sns
    # import matplotlib.pyplot as plt
    #
    # # sns.set(style="white")
    #
    # top = None
    #
    # train_ds = AutoEncoderDataset("../data/for_train.csv", is_train=False, transform=ToTensor(), top=top)
    # test_dataset = AutoEncoderDataset("../data/for_test.csv", is_train=False, transform=ToTensor(), top=top)
    #
    # dataloader = DataLoader(train_ds, batch_size=1, shuffle=False, num_workers=12)
    # val_dataloader = DataLoader(test_dataset, batch_size=1, shuffle=False, num_workers=1)
    #
    # autoenc = Autoencoder.load("ready/adam_autoenc_20.mdl")
    # autoenc.eval()
    #
    # train_features = get_encoder_repr(dataloader, autoenc)
    # test_features = get_encoder_repr(val_dataloader, autoenc)
    # np.save("train", train_features)
    # np.save("test", test_features)


from flask import Flask, render_template
from flask_bootstrap import Bootstrap
from flask_wtf import FlaskForm
from wtforms import StringField, SubmitField, SelectField
from wtforms.fields.html5 import URLField, TimeField, IntegerField
from wtforms.validators import DataRequired, URL
import csv

app = Flask(__name__)
app.config['SECRET_KEY'] = '8BYkEfBA6O6donzWlSihBXox7C0sKR6b'
Bootstrap(app)

class CafeForm(FlaskForm):
    cafe = StringField('Cafe name', validators=[DataRequired()])
    url_location = URLField('Google Maps URL', validators=[DataRequired(), URL(message="Must be valid URL")])
    open_time = TimeField('Opening Time', validators=[DataRequired()])
    close_time = TimeField('Closing Time', validators=[DataRequired()])
    coffee_rating = SelectField('Coffee Rating', validators=[DataRequired()], choices=[('✘', '✘'), ('☕', '☕'), ('☕☕', '☕☕'), ('☕☕☕', '☕☕☕'), ('☕☕☕☕', '☕☕☕☕'), ('☕☕☕☕☕', '☕☕☕☕☕')])
    wifi_rating = SelectField('WIFI Rating', validators=[DataRequired()], choices=[('✘', '✘'), ('💪', '💪'), ('💪💪', '💪💪'), ('💪💪💪', '💪💪💪'), ('💪💪💪💪', '💪💪💪💪'), ('💪💪💪💪💪', '💪💪💪💪💪')])
    power_rating = SelectField('Power Rating', validators=[DataRequired()], choices=[('✘', '✘'), ('🔌', '🔌'), ('🔌🔌', '🔌🔌'), ('🔌🔌🔌', '🔌🔌🔌'), ('🔌🔌🔌🔌', '🔌🔌🔌🔌'), ('🔌🔌🔌🔌🔌', '🔌🔌🔌🔌🔌')])
    submit = SubmitField('Submit')

# Exercise:
# add: Location URL, open time, closing time, coffee rating, wifi rating, power outlet rating fields
# make coffee/wifi/power a select element with choice of 0 to 5.
#e.g. You could use emojis ☕/💪/✘/🔌
# make all fields required except submit
# use a validator to check that the URL field has a URL entered.
# ---------------------------------------------------------------------------

# all Flask routes below
@app.route("/")
def home():
    return render_template("index.html")

@app.route('/add', methods=["GET", "POST"])
def add_cafe():
    success = False
    form = CafeForm()
    if form.validate_on_submit():
        open_time = f"{form.open_time.data.strftime('%I:%M %p')}"
        close_time = form.close_time.data.strftime('%I:%M %p')
        success = True
        cafe_data = [form.cafe.data, form.url_location.data, open_time, close_time, form.coffee_rating.data, form.wifi_rating.data, form.power_rating.data]
        with open(file="cafe-data.csv", mode="a", encoding="utf-8") as f:
            writer = csv.writer(f)
            writer.writerow(cafe_data)
    return render_template('add.html', form=form, success=success)

@app.route('/cafes')
def cafes():
    with open('cafe-data.csv', newline='', encoding="utf-8") as csv_file:
        csv_data = csv.reader(csv_file, delimiter=',')
        list_of_rows = []
        for row in csv_data:
            list_of_rows.append(row)
    return render_template('cafes.html', cafes=list_of_rows)

if __name__ == '__main__':
    app.run(debug=True)

Python Projects/062 - Flask WTForms Coffee and Wifi Proj/main.py


from rest_framework import serializers
from rest_framework.validators import UniqueTogetherValidator
from ...models import Booked

#For everything without join (Create, Update, Delete)

class BookedSerializer(serializers.ModelSerializer):
    class Meta:
        model = Booked
        fields =  ('__all__')
        read_only_fields = ['id']

    # def validate_status(self, value):

    #         if self.instance:
    #             qs = Booked.objects.filter(status__iexact=value).filter(pk=self.instance.pk)

    #             #qs =  qs.exclude(pk=self.instance.pk)

    #             if qs.exists():
    #                 raise serializers.ValidationError("Le statut que vous essayé d'appliqué est déjà utilisé pour ce même équipement")
    #         return value
#For reading only with join (List)

class ListBookedSerializer(serializers.ModelSerializer):
    class Meta:
        model = Booked
        fields = ('__all__')
        read_only_fields = ['id']
        depth = 1
        # validators = [
        #     UniqueValidator(
        #         querySet = Booked.objects.all(),
        #         fields=('equipment_id')
        #         )
        # ]


import torch.nn as nn
from rl_games.algos_torch.models import ModelA2CContinuousLogStd
import torch
class ModelAMPContinuous(ModelA2CContinuousLogStd):
    def __init__(self, network):
        super().__init__(network)
        return

    def build(self, config):
        net = self.network_builder.build('amp', **config)
        for name, _ in net.named_parameters():
            print(name)
        return ModelAMPContinuous.Network(net)

    class Network(ModelA2CContinuousLogStd.Network):
        def __init__(self, a2c_network):
            super().__init__(a2c_network)
            return

        def forward(self, input_dict):
            is_train = input_dict.get('is_train', True)
            amp_dropout = input_dict.get("amp_dropout", False)
            amp_steps = input_dict.get("amp_steps", 2)
            env_cfg = input_dict.get("env_cfg", None)
            result = super().forward(input_dict)

            if (is_train):
                amp_obs, amp_obs_replay, amp_demo_obs = input_dict['amp_obs'],  input_dict['amp_obs_replay'], input_dict['amp_obs_demo']
                if amp_dropout:
                    dropout_mask = self.get_dropout_mask(input_dict['amp_obs'], amp_steps, env_cfg)
                    amp_obs, amp_obs_replay, amp_demo_obs = self.dropout_amp_obs(amp_obs, dropout_mask[..., 0]), \
                        self.dropout_amp_obs(amp_obs_replay, dropout_mask[..., 1]), self.dropout_amp_obs(amp_demo_obs, dropout_mask[..., 2])
                    del dropout_mask

                disc_agent_logit = self.a2c_network.eval_disc(amp_obs)
                result["disc_agent_logit"] = disc_agent_logit

                disc_agent_replay_logit = self.a2c_network.eval_disc(amp_obs_replay)
                result["disc_agent_replay_logit"] = disc_agent_replay_logit

                disc_demo_logit = self.a2c_network.eval_disc(amp_demo_obs)
                result["disc_demo_logit"] = disc_demo_logit

            return result

        def dropout_amp_obs(self, amp_obs, dropout_mask):
            return amp_obs * dropout_mask

        def get_dropout_mask(self,
                             amp_obs,
                             steps,
                             env_cfg,
                             num_masks=3,
                             dropout_rate=0.3):
            # ZL Hack: amp_obs_dims, should drop out whole joints
            # [root_rot 6, root_vel 3, root_ang_vel 3, dof_pos 23 * 6 - 4 * 6, dof_vel 69 - 12, key_body_pos 3 * 4, shape_obs_disc 11]
            # [root_rot 6, root_vel 3, root_ang_vel 3, dof_pos 23 * 6 - 4 * 6, dof_vel 69 - 12, key_body_pos 3 * 4, shape_obs_disc 47]
            # 6 + 3 + 3 + 19 * 6 + 19 * 3 + 3 * 4 + 11 = 206 # normal with betas
            # 6 + 3 + 3 + 19 * 6 + 19 * 3 + 3 * 4 + 10 = 205 # concise limb weight
            # 6 + 3 + 3 + 19 * 6 + 19 * 3 + 3 * 4 + 59 = 254 # masterfoot
            B, F = amp_obs.shape
            B, _, amp_f = amp_obs.view(B, steps, -1).shape
            masterfoot, remove_neck = env_cfg["env"].get("masterfoot", False), env_cfg["env"].get("remove_neck", False)

            try:
                assert (F / steps == 205 or F / steps == 254 or F / steps == 242 or F / steps == 206 or F / steps == 197 or F / steps == 188 or F / steps == 187 or F / steps == 195 or F / steps == 196 or F / steps == 207)
            except:
                print(F/steps)
                import ipdb; ipdb.set_trace()
                print(F/steps)

            dof_joints_offset = 12  # 6 + 3 + 3
            num_joints = 19

            if F / steps == 197:  # Remove neck
                num_joints = 18
            elif F / steps == 188:  # Remove hands
                num_joints = 17
            elif F / steps == 196 or F / steps == 207:
                dof_joints_offset = 13  # 1 + 6 + 3 + 3

            dof_vel_offsets = dof_joints_offset + num_joints * 6  # 12 + 19 * 6

            dropout_mask = torch.ones([B, amp_f, num_masks])

            for idx_joint in range(num_joints):
                has_drop_out = torch.rand(B, num_masks) > dropout_rate
                dropout_mask[:, dof_joints_offset + idx_joint * 6:dof_joints_offset + idx_joint * 6 + 6, :] = has_drop_out[:, None]
                dropout_mask[:, dof_vel_offsets + idx_joint * 3:dof_vel_offsets + idx_joint * 3 + 3, :] = has_drop_out[:, None]
            return dropout_mask.repeat(1, steps, 1).to(amp_obs)


# -*- coding: utf-8 -*-
import findspark
import gc
from joblib import dump, load
import numpy as np
findspark.init()
from pyspark.sql import SparkSession
from pyspark.sql.types import StructField, StructType, LongType, StringType, IntegerType
import pyspark.sql.functions as F
from pyspark import SparkContext, SparkConf
from pyspark.serializers import PickleSerializer
from tqdm import tqdm
from itertools import permutations
from collections import defaultdict
import time

# conf = SparkConf(serializer=PickleSerializer())
spark = SparkSession.builder.appName("user cf on spark").master("local[8]").config('serializer', PickleSerializer()).getOrCreate()

sc = spark.sparkContext

schema = StructType([StructField('userId', IntegerType(), True),
            StructField('movieId', IntegerType(), True),
            StructField('rating', LongType(), True),
            StructField('timestamp', IntegerType(), True)])
ratings = spark.read.csv(r'D:\Users\hao.guo\比赛代码提炼\推荐系统\movielen\ml-20m\ratings.csv', header=True)

ratings = ratings.withColumn('rating', ratings['rating'].cast('int'))
ratings_rdd = ratings.select(['userId', 'movieId', 'rating']).rdd
# ratings_rdd = ratings_rdd.sample(withReplacement=False, fraction=0.1, seed=2020)
train_rdd, test_rdd = ratings_rdd.randomSplit([0.7, 0.3], seed=2020)
train_rdd = train_rdd.cache()
test_rdd = test_rdd.cache()

print('user cf start......')
s = time.perf_counter()

createCombiner = lambda v: [v]
mergeValue = lambda agg, v: agg + [v]
mergeCombiners = lambda agg1, agg2: agg1 + agg2
train_item_users = train_rdd.map(lambda s: ('item_' + s['movieId'], ('user_' + s['userId'], s['rating']))).combineByKey(createCombiner, mergeValue, mergeCombiners)
train_user_norm_dict = train_rdd.map(lambda s: ('user_' + s['userId'], s['rating'] ** 2)).reduceByKey(lambda p1, p2: p1 + p2).mapValues(lambda v: np.sqrt(v)).collectAsMap()

train_user_norm_dict = sc.broadcast(train_user_norm_dict)

'''
        获得2个用户所有的item-item对得分组合:
        (user1_id,user2_id) -> [(rating1,rating2),
                                (rating1,rating2),
                                (rating1,rating2),
                                ...]
'''
def findpairs(pairs):
    res = []
    # 考虑热门物品的影响, 冷门的物品兴趣才更加有把握相似
    m = len(pairs)
    for u1, u2 in permutations(pairs, 2):
        res.append(((u1[0], u2[0]), (u1[1] / np.log1p(m), u2[1] / np.log1p(m))))
    return res
pairwise_users = train_item_users.filter(lambda p: len(p[1]) > 1).map(lambda p: p[1]).flatMap(lambda p: findpairs(p)).combineByKey(createCombiner, mergeValue, mergeCombiners)

'''
    计算余弦相似度，找到最近的N个邻居:
    (user1,user2) ->    (similarity,co_raters_count)
'''

def cosine(product, r1_norm, r2_norm):
    fenmu = r1_norm * r2_norm
    return product / fenmu if fenmu else 0.0

def calcSim(pairs, user_norm_dict):
    '''
        对每个user对，根据打分计算余弦距离，并返回共同打分的item个数
    '''
    # 其他位置为0
    sum_xy, n = 0.0, 0

    for rating_pair in pairs[1]:
        sum_xy += rating_pair[0] * rating_pair[1]
        n += 1

    cos_sim = cosine(sum_xy, user_norm_dict[pairs[0][0]], user_norm_dict[pairs[0][1]])
    return pairs[0], (cos_sim, n)

def keyOnFirstUser(pairs):
    '''
        对于每个user-user对，用第一个user做key(好像有点粗暴...)
    '''
    (user1_id, user2_id) = pairs[0]
    return user1_id,(user2_id, pairs[1])

def nearestNeighbors(pairs, n):
    '''
        选出相似度最高的N个邻居
    '''
    pairs[1].sort(key=lambda x: x[1][0], reverse=True)
    return pairs[0], pairs[1][:n]

def user_sim(pairwise_users, train_user_norm_dict, n):
    user_sims = pairwise_users.map(lambda p: calcSim(p, train_user_norm_dict.value)).map(keyOnFirstUser).combineByKey(createCombiner, mergeValue, mergeCombiners).map(lambda p: nearestNeighbors(p, n))
    return user_sims

'''
    对每个用户的打分记录整理成如下形式
    user_id -> [(item_id_1, rating_1),
                [(item_id_2, rating_2),
                ...]
'''

train_user_items = sc.broadcast(train_rdd.map(lambda s: ('user_' + s['userId'], ('item_' + s['movieId'], s['rating']))).combineByKey(createCombiner, mergeValue, mergeCombiners).collectAsMap())

'''
    为每个用户计算Top N的推荐
    user_id -> [item1,item2,item3,...]
'''
def topNRecommendations(user_id, user_sims, users_with_rating, n):
    '''
        根据最近的N个邻居进行推荐
    '''

    totals = defaultdict(int)
    sim_sums = defaultdict(int)

    user_items = users_with_rating.get(user_id, [])
    if user_items != []:
        user_items = [i for i, r in user_items]

    for ind, (neighbor,(sim,count)) in enumerate(user_sims):

        # 遍历邻居的打分
        unscored_items = users_with_rating.get(neighbor,None)

        if unscored_items:
            for (item,rating) in unscored_items:
                if item not in user_items:

                # 更新推荐度和相近度
                    totals[item] += sim * rating
                    sim_sums[item] += sim

    # 归一化
    # scored_items = [(total/(1e-10 if sim_sums[item] == 0 else sim_sums[item]), item) for item,total in totals.items()]
    scored_items = [(total, item) for item,total in totals.items()]

    # 按照推荐度降序排列
    scored_items.sort(reverse=True)

    # 推荐度的item
    ranked_items = [x[1] for x in scored_items]

    return user_id, ranked_items[:n]

def Precision(user_id, pui, test, n):
    hit = 0
    all = 0
    tui = test[user_id]
    for item in pui:
        if item in tui:
            hit += 1
    all += n
    return (hit, all)

def Recall(user_id, pui, test):
    hit = 0
    all = 0
    tui = test[user_id]
    for item in pui:
        if item in tui:
            hit += 1
    all += len(tui)
    return (hit, all)

def Coverage(user_id, pui, train_items, test):
    recommend_items = set()
    all_items = set()
    tui = test[user_id]
    for item, rating in train_items[user_id]:
        all_items.add(item)
    for item in pui:
        recommend_items.add(item)
    return recommend_items, all_items

def Popularity(user_id, pui, item_popularity):
    ret = 0
    n = 0
    for item in pui:
        ret += np.log1p(item_popularity[item])
        n += 1
    return ret, n

def popularity(pairs):
    popular = set()
    for user, rating in pairs[1]:
        popular.add(user)
    return pairs[0], len(popular)

item_popularity = sc.broadcast(train_item_users.map(popularity).collectAsMap())

def eval(user_sims, item_popularity, train_user_items, test, n):
    user_item = test.map(lambda s: ('user_' + s['userId'], 'item_' + s['movieId'])).combineByKey(createCombiner, mergeValue, mergeCombiners)
    user_item_hist = user_item.collectAsMap()
    test_users = list(user_item_hist.keys())
    test_users_items = sc.broadcast(user_item_hist)

    '''
        为每个用户计算Top N的推荐
        user_id -> [item1,item2,item3,...]
    '''
    # choose test recs
    user_item_recs = user_sims.filter(lambda p: p[0] in test_users).map(
        lambda p: topNRecommendations(p[0], p[1], train_user_items.value, n)).cache()

    # precision
    hit, all = user_item_recs.map(lambda p: Precision(p[0], p[1], test_users_items.value, n)).reduce(lambda x, y: (x[0] + y[0], x[1] + y[1]))
    p = hit / (all * 1.0)
    # recall
    hit, all = user_item_recs.map(lambda p: Recall(p[0], p[1], test_users_items.value)).reduce(lambda x, y: (x[0] + y[0], x[1] + y[1]))
    r = hit / (all * 1.0)
    # Coverage
    recommend_items, all_items = user_item_recs.map(lambda p: Coverage(p[0], p[1], train_user_items.value, test_users_items.value)).reduce(lambda x, y: (x[0].union(y[0]), x[1].union(y[1])))
    c = len(recommend_items) / (len(all_items) * 1.0)
    # popularity
    recom_popularity, all = user_item_recs.map(lambda p: Popularity(p[0], p[1], item_popularity.value)).reduce(lambda x, y: (x[0] + y[0], x[1] + y[1]))
    popularity = recom_popularity / (all * 1.0)
    del user_item_recs, user_item, user_item_hist, test_users, test_users_items
    gc.collect()
    return p, r, c, popularity

# 生成训练集各用户的相似矩阵
user_sims = user_sim(pairwise_users, train_user_norm_dict, 5)
print('eval model start......')
p5, r5, c5, popularity5 = eval(user_sims, item_popularity, train_user_items, test_rdd, 50)
print('top 5 model: %s, %s, %s, %s' % (p5, r5, c5, popularity5))
del user_sims
gc.collect()

user_sims = user_sim(pairwise_users, train_user_norm_dict, 10)
p10, r10, c10, popularity10 = eval(user_sims, item_popularity, train_user_items, test_rdd, 50)
print('top 10 model: %s, %s, %s, %s' % (p10, r10, c10, popularity10))
del user_sims
gc.collect()

user_sims = user_sim(pairwise_users, train_user_norm_dict, 20)
p20, r20, c20, popularity20 = eval(user_sims, item_popularity, train_user_items, test_rdd, 50)
print('top 20 model: %s, %s, %s, %s' % (p20, r20, c20, popularity20))
del user_sims
gc.collect()

user_sims = user_sim(pairwise_users, train_user_norm_dict, 40)
p40, r40, c40, popularity40 = eval(user_sims, item_popularity, train_user_items, test_rdd, 50)
print('top 40 model: %s, %s, %s, %s' % (p40, r40, c40, popularity40 ))
del user_sims
gc.collect()

user_sims = user_sim(pairwise_users, train_user_norm_dict, 80)
p80, r80, c80, popularity80 = eval(user_sims, item_popularity, train_user_items, test_rdd, 50)
print('top 80 model: %s, %s, %s, %s' % (p80, r80, c80, popularity80))
del user_sims
gc.collect()
print('cost time %s min' % ((time.perf_counter() - s) / 60))


#!/usr/bin/env python3
# encoding:utf-8
import copy
import random
import bisect #bisect_left　これで二部探索の大小検索が行える
import fractions #最小公倍数などはこっち
import math
import sys
import collections
from decimal import Decimal # 10進数で考慮できる
import numpy as np

mod = 10**9+7
sys.setrecursionlimit(mod) # 再帰回数上限はでdefault1000

d = collections.deque()
def LI(): return list(map(int, sys.stdin.readline().split()))

N = int(input())
pos = {
    "U":[],
    "R":[],
    "D":[],
    "L":[]
    }
xyu =[]
for i in range(N):
    x, y, u = input().split()
    x = int(x)
    y = int(y)
    u = str(u)
    xyu.append([x,y,u])

direction = {
    "U":[0,1],
    "D":[0, -1],
    "R":[1, 0],
    "L":[-1,0]
}
directions = np.zeros((N, 2))
positions = np.zeros((N, 2))
for i, (x, y, u) in enumerate(xyu):
    if u == "U":
        directions[i, 1] = 1
    elif u == "D":
        directions[i, 1] = -1
    elif u == "R":
        directions[i, 0] = 1
    else:
        directions[i, 0] = -1
    positions[i, 0] = x
    positions[i, 1] = y

ans = -1
for time in range(1, 200000):
    positions += directions
    positions.tolist()

    if len(set(positions.tolist())) < N:
        ans = time
        break
if ans == -1:
    print("SAFE")
else:
    print(ans)


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

import sys
import io
import nltk
from nltk.tree import Tree

def tokenize(text):
    return list(text)
#'A' Q | 'B' Q |
def parse(s):
    grammarString = """
    S -> E S | '*' C | '_' N | E
    C -> E C | '*' S | '*'
    N -> E N | '_' S | '_'
    E -> '.'|' '|','|')'|'('|'a'|'b'|'c'|'d'|'e'|'f'|'g'|'h'|'i'|'j'|'k'|'l'|'m'|'n'|'o'|'p'|'q'|'r'|'s'|'t'|'u'|'v'|'w'|'x'|'y'|'z'|'A'|'B'|'C'|'D'|'E'|'F'|'J'|'H'|'I'|'J'|'K'|'L'|'M'|'N'|'O'|'P'|'Q'|'R'|'S'|'T'|'U'|'V'|'W'|'X'|'Y'|'Z'

    """
    grammar = nltk.CFG.fromstring(grammarString)
    s_tok = tokenize(s.strip())
    parser = nltk.LeftCornerChartParser(grammar)
    tree = [t for t in parser.parse(s_tok)][:1]
    return tree

if __name__ == '__main__':
    archivo_entrada = sys.argv[1]
    archivo_salida = sys.argv[2]
    f = io.open(archivo_entrada, 'r', newline='\n', encoding='utf-8')
    s = f.read()
    f.close()
    try:
      separator=""
      tree = parse(s)
      if tree:
        t=tree[0]
        contAster=0;
        contGuion=0;
        for leafPos in t.treepositions('leaves'):

            if t[leafPos] == '*':
                if contAster % 2 == 0:
                    t[leafPos] = "\\textbf{"
                else:
                     t[leafPos] ="}"
                contAster+=1

            if t[leafPos] == '_':
                if contGuion % 2 == 0:
                    t[leafPos] = "\\emph{"
                else:
                     t[leafPos] ="}"
                contGuion+=1

            if t[leafPos] == '(':
                t[leafPos] = "\\("

            if t[leafPos] == ')':
                t[leafPos] = "\\)"

        salida=separator.join(t.leaves())
      else:
          salida = "NO PERTENECE"
    except ValueError:
      salida = "NO CUBRE"
    f = io.open(archivo_salida, 'w', newline='\n', encoding='utf-8')
    f.write(salida)
    f.close()


import matplotlib.pyplot as plt
import numpy
from plotter import Plotter
from dimensionality_reduction import DimensionalityReduction
from validator import Validation
from evaluator import Evaluator
from mlFunc import *

def validation(DTR,LTR, VA, dimRed):
    print("##################################")
    print("VALIDATION")
    print("##################################")
    print("***MVG VALIDATION***")
    VA.MVG_validation(DTR,LTR, 0.5, 1,10)
    for i in range (7,10):
         print("PCA con", i)
         DPA = dimRed.PCA(DTR, i)
         VA.MVG_validation(DPA.T, LTR, 0.5, 1, 10)
    print("***LR VALIDATION***")
    VA.LR_validation(DTR, LTR, 0.5, 1, 10, plot=True)
    for i in range (7,10):
         print("PCA con", i)
         DPA = dimRed.PCA(DTR, i)
         VA.LR_validation(DPA.T,LTR, 0.1,1,10, False)

    K_arr = [0.1, 1.0, 10.0]
    C_arr = [0.01, 0.1, 1.0, 10.0]
    for k in K_arr:
        for c in C_arr:
            print("SVM, K: ",k," C: ", c)
            VA.SVM_validation(DTR, LTR, 0.9, 1, 10, k, c)
    VA.SVM_validation(DTR, LTR, 0.5, 1, 10, 10, 10, False)

    VA.GMM_validation(DTR,LTR, 0.5,1,10, 1,4, 0.1, 0.01, True)
    for i in range (7,10):
         print("PCA con", i)
         DPA = dimRed.PCA(DTR, i)
         VA.GMM_validation(DPA.T,LTR, 0.5,1,10, 1,4, 0.1, 0.01)

    VA.plot_ROC(DTR, LTR, 0.5)
    print("Comparing DCF")
    VA.plot_minDCF_cal_score(DTR, LTR, 0.5)
    return

def evaluation(DTE, LTE, DTR, LTR, EV,  dimRed):
    print("##################################")
    print("EVALUATION")
    print("##################################")
    print("***MVG EVALUATION***")
    EV.MVG_evaluation(DTE, LTE, DTR, LTR, 0.5, 1, 10)
    for i in range(7, 10):
       print("PCA con", i)
       DPA = dimRed.PCA(DTR, i)
       DPE = dimRed.PCA_DTE(DTR, i,DTE)
       EV.MVG_evaluation(DPE.T, LTE, DPA.T, LTR, 0.5, 1, 10)

    print("***LR EVALUATION***")

    EV.LR_evaluation(DTE, LTE, DTR, LTR, 0.1, 1, 10, False)
    for i in range(7, 10):
        print("PCA con", i)
        DPA = dimRed.PCA(DTR, i)
        DPE = dimRed.PCA_DTE(DTR, i,DTE)
        EV.LR_evaluation(DPE.T, LTE, DPA.T, LTR, 0.5, 1, 10)
    print("***SVM EVALUATION***")
    EV.SVM_evaluation(DTE.T, LTE, DTR.T, LTR, 0.5, 1, 10)
    for i in range(7, 10):
       print("PCA con", i)
       DPA = dimRed.PCA(DTR, i)
       DPE = dimRed.PCA_DTE(DTR, i,DTE)
       EV.SVM_evaluation(DPE, LTE, DPA, LTR, 0.9, 1, 10)

    print("***GMM EVALUATION***")
    EV.GMM_evaluation(DTE, LTE, DTR, LTR, 0.9, 1, 10, 1, 16, 0.1, 0.01)
    for i in range(7, 10):
        print("PCA con", i)
        DPA = dimRed.PCA(DTR, i)
        DPE = dimRed.PCA_DTE(DTR, i,DTE)
        EV.GMM_evaluation(DPE.T, LTE, DPA.T, LTR, 0.9, 1, 10, 1, 16, 0.1, 0.01)

    EV.plot_ROC(DTR, LTR, DTE,LTE,0.5)
    print("Comparing DCF")
    EV.plot_minDCF_cal_score(DTR, LTR, DTE,LTE,0.5)

if __name__ == "__main__":

    DTR,LTR = load("Train.txt")

    DTE, LTE = load("Test.txt")

    print("TRAINING AUTHENTIC: ", DTR.T[:,LTR==1].shape[1])
    print("TRAINING SPOFFED", DTR.T[:, LTR==0].shape[1])

    print("TEST AUTHENTIC: ", DTE.T[:, LTE == 1].shape[1])
    print("TEST SPOFFED", DTE.T[:, LTE == 0].shape[1])

    plt = Plotter()
    dimRed = DimensionalityReduction()
    VA = Validation()
    EV = Evaluator()

    plt.plot_correlations(DTR.T, "heatmap")
    plt.plot_correlations(DTR.T[:, LTR == 0], "heatmap_spoofed_", cmap="Reds")
    plt.plot_correlations(DTR.T[:, LTR == 1], "heatmap_authentic_", cmap="Blues")

    validation(DTR, LTR, VA, dimRed)
    evaluation(DTE, LTE, DTR, LTR, EV, dimRed)


from __future__ import annotations

import base64
import io
import json
import os
import signal
import socket
import sys
import tempfile
import threading
import uuid
from abc import ABC, abstractmethod
from pathlib import Path
from time import time
from typing import Any

import numpy as np
from dash import Dash, callback_context, dcc, no_update
from dash.dependencies import Input, Output, State
from dash.development.base_component import Component
from flask import Flask
from geoh5py.data import Data
from geoh5py.groups import PropertyGroup
from geoh5py.objects import ObjectBase
from geoh5py.shared import Entity
from geoh5py.shared.utils import fetch_active_workspace, is_uuid
from geoh5py.ui_json import InputFile
from geoh5py.workspace import Workspace
from PySide2 import QtCore, QtWebEngineWidgets, QtWidgets

from geoapps_utils.application.layout import object_selection_layout
from geoapps_utils.driver.params import BaseParams

class BaseDashApplication(ABC):
    """
    Base class for geoapps dash applications
    """

    _params = None
    _param_class = BaseParams
    _driver_class = None
    _workspace = None
    _app_initializer: dict | None = None
    _ui_json_data: dict | None = None

    def __init__(
        self,
        ui_json: InputFile | None = None,
        ui_json_data: dict | None = None,
        params: BaseParams | None = None,
    ):
        """
        Set initial ui_json_data from input file and open workspace.
        """
        if params is not None:
            # Launched from notebook
            # Params for initialization are coming from params
            # ui_json_data is provided
            self.params = params
        elif (
            ui_json is not None
            and getattr(ui_json, "path", None) is not None
            and Path(ui_json.path).exists()
        ):
            # Launched from terminal
            # Params for initialization are coming from ui_json
            # ui_json_data starts as None
            self.params = self._param_class(ui_json)
            input_file = self.params.input_file
            if input_file is not None:
                ui_json_data = input_file.demote(self.params.to_dict())
        self._ui_json_data = ui_json_data

        assert self.params is not None, "No parameters provided."
        self.workspace = self.params.geoh5
        self.workspace.open()
        if self._driver_class is not None:
            self.driver = self._driver_class(self.params)

    @property
    @abstractmethod
    def app(self) -> Dash:
        """Dash app"""

    def get_data_options(
        self,
        ui_json_data: dict,
        object_uid: str | None,
        object_name: str = "objects",
        trigger: str | None = None,
    ) -> list:
        """
        Get data dropdown options from a given object.

        :param ui_json_data: Uploaded ui.json data to read object from.
        :param object_uid: Selected object in object dropdown.
        :param object_name: Object parameter name in ui.json.
        :param trigger: Callback trigger.

        :return options: Data dropdown options.
        """
        obj = None
        if trigger == "ui_json_data" and object_name in ui_json_data:
            if is_uuid(ui_json_data[object_name]):
                object_uid = ui_json_data[object_name]
            elif self.workspace.get_entity(ui_json_data[object_name])[0] is not None:
                object_uid = self.workspace.get_entity(ui_json_data[object_name])[0].uid

        if object_uid is not None and is_uuid(object_uid):
            for entity in self.workspace.get_entity(uuid.UUID(object_uid)):
                if isinstance(entity, ObjectBase):
                    obj = entity

        if obj:
            options = []
            for child in obj.children:
                if isinstance(child, Data):
                    if child.name != "Visual Parameters":
                        options.append(
                            {"label": child.name, "value": "{" + str(child.uid) + "}"}
                        )
            options = sorted(options, key=lambda d: d["label"])

            return options
        return []

    def get_params_dict(self, update_dict: dict) -> dict:
        """
        Get dict of current params.

        :param update_dict: Dict of parameters with new values to convert to a params dict.

        :return output_dict: Dict of current params.
        """
        if self.params is None:
            return {}

        output_dict: dict[str, Any] = {}
        # Get validations to know expected type for keys in self.params.
        validations = self.params.validations

        # Loop through self.params and update self.params with locals_dict.
        for key in self.params.to_dict():
            if key not in update_dict:
                continue
            if validations is not None:
                if bool in validations[key]["types"] and isinstance(
                    update_dict[key], list
                ):
                    # Convert from dash component checklist to bool
                    if not update_dict[key]:
                        output_dict[key] = False
                    else:
                        output_dict[key] = True
                    continue
                if (
                    float in validations[key]["types"]
                    and int not in validations[key]["types"]
                    and isinstance(update_dict[key], int)
                ):
                    # Checking for values that Dash has given as int when they should be floats.
                    output_dict[key] = float(update_dict[key])
                    continue
            if is_uuid(update_dict[key]):
                output_dict[key] = self.workspace.get_entity(
                    uuid.UUID(update_dict[key])
                )[0]
            else:
                output_dict[key] = update_dict[key]
        return output_dict

    @staticmethod
    def init_vals(layout: list[Component], ui_json_data: dict):
        """
        Initialize dash components in layout from ui_json_data.

        :param layout: Dash layout.
        :param ui_json_data: Uploaded ui.json data.
        """
        for comp in layout:
            BaseDashApplication._init_component(comp, ui_json_data)

    @staticmethod
    def _init_component(comp: Component, ui_json_data: dict):
        if hasattr(comp, "children") and not isinstance(comp, dcc.Markdown):
            BaseDashApplication.init_vals(comp.children, ui_json_data)
            return

        if hasattr(comp, "id") and comp.id in ui_json_data:
            if isinstance(comp, dcc.Store):
                comp.data = ui_json_data[comp.id]
                return

            if isinstance(comp, dcc.Dropdown):
                comp.value = ui_json_data[comp.id]
                if comp.value is None:
                    comp.value = "None"
                if not hasattr(comp, "options"):
                    comp_option = ui_json_data[comp.id]
                    if comp_option is None:
                        comp_option = "None"
                    comp.options = [comp_option]
                return

            if isinstance(comp, dcc.Checklist):
                if ui_json_data[comp.id]:
                    comp.value = [True]
                else:
                    comp.value = []
            else:
                comp.value = ui_json_data[comp.id]

    @staticmethod
    def update_visibility_from_checklist(checklist_val: list[bool]) -> dict:
        """
        Update visibility of a component from a checklist value.

        :param checklist_val: Checklist value.

        :return visibility: Component style.
        """
        if checklist_val:
            return {"display": "block"}
        return {"display": "none"}

    @property
    def params(self) -> BaseParams | None:
        """
        Application parameters
        """
        return self._params

    @params.setter
    def params(self, params: BaseParams):
        assert isinstance(
            params, BaseParams
        ), f"Input parameters must be an instance of {BaseParams}"

        self._params = params

    @property
    def workspace(self):
        """
        Current workspace.
        """
        return self._workspace

    @workspace.setter
    def workspace(self, workspace):
        # Close old workspace
        if self._workspace is not None:
            self._workspace.close()
        self._workspace = workspace

class ObjectSelection:
    """
    Dash app to select workspace and object.

    Creates temporary workspace with the object, and
    opens a Qt window to run an app.
    """

    _app_initializer: dict | None = None

    def __init__(
        self,
        app_name: str,
        app_initializer: dict,
        app_class: type[BaseDashApplication],
        param_class: type[BaseParams],
        **kwargs,
    ):
        self._app_name = None
        self._app_class = BaseDashApplication
        self._param_class = BaseParams
        self._workspace = None

        self.app_name = app_name
        self.app_class = app_class
        self.param_class = param_class

        app_initializer.update(kwargs)
        self.params = self.param_class(**app_initializer)
        self._app_initializer = {
            key: value
            for key, value in app_initializer.items()
            if key not in self.params.param_names
        }
        self.workspace = self.params.geoh5

        external_stylesheets = ["https://codepen.io/chriddyp/pen/bWLwgP.css"]
        server = Flask(__name__)
        self.app = Dash(
            server=server,
            url_base_pathname=os.environ.get("JUPYTERHUB_SERVICE_PREFIX", "/"),
            external_stylesheets=external_stylesheets,
        )
        self.app.layout = object_selection_layout

        # Set up callbacks
        self.app.callback(
            Output(component_id="objects", component_property="options"),
            Output(component_id="objects", component_property="value"),
            Output(component_id="ui_json_data", component_property="data"),
            Output(component_id="upload", component_property="filename"),
            Output(component_id="upload", component_property="contents"),
            Input(component_id="ui_json_data", component_property="data"),
            Input(component_id="upload", component_property="filename"),
            Input(component_id="upload", component_property="contents"),
            Input(component_id="objects", component_property="value"),
        )(self.update_object_options)
        self.app.callback(
            Output(component_id="launch_app_markdown", component_property="children"),
            State(component_id="objects", component_property="value"),
            Input(component_id="launch_app", component_property="n_clicks"),
        )(self.launch_qt)

    def update_object_options(
        self,
        ui_json_data: dict,
        filename: str,
        contents: str,
        objects: str,
        trigger: str | None = None,
    ) -> tuple:
        """
        This function is called when a file is uploaded. It sets the new workspace, sets the dcc
        ui_json_data component, and sets the new object options and values.

        :param filename: Uploaded filename. Workspace or ui.json.
        :param contents: Uploaded file contents. Workspace or ui.json.
        :param trigger: Dash component which triggered the callback.

        :return object_options: New object dropdown options.
        :return object_value: New object value.
        :return ui_json_data: Uploaded ui_json data.
        :return filename: Return None to reset the filename so the same file can be chosen twice
            in a row.
        :return contents: Return None to reset the contents so the same file can be chosen twice
            in a row.
        """
        if trigger is None:
            trigger = callback_context.triggered[0]["prop_id"].split(".")[0]

        if trigger != "":
            # Remove entities from ui_json_data
            inp_ui_json_data = ui_json_data.copy()
            for key, value in inp_ui_json_data.items():
                if is_uuid(value) or isinstance(value, Entity):
                    setattr(self.params, key, None)
                    del ui_json_data[key]
        if trigger == "objects":
            return no_update, objects, ui_json_data, None, None

        object_options, object_value = no_update, None
        if contents is not None and filename is not None:
            if filename.endswith(".ui.json"):
                # Uploaded ui.json
                _, content_string = contents.split(",")
                ui_json = json.loads(base64.b64decode(content_string))
                self.workspace = Workspace(ui_json["geoh5"], mode="r")
                # Create ifile from ui.json
                ifile = InputFile(ui_json=ui_json)
                self.params = self.param_class(ifile)
                # Demote ifile data so it can be stored as a string
                if getattr(ifile, "data", None) is not None:
                    ui_json_data = ifile.demote(ifile.data.copy())
                    # Get new object value for dropdown from ui.json
                    object_value = ui_json_data["objects"]
            elif filename.endswith(".geoh5"):
                # Uploaded workspace
                _, content_string = contents.split(",")
                self.workspace = Workspace(
                    io.BytesIO(base64.b64decode(content_string)), mode="r"
                )
                # Update self.params with new workspace, but keep unaffected params the same.
                new_params = self.params.to_dict()
                for key, value in new_params.items():
                    if isinstance(value, Entity):
                        new_params[key] = None
                new_params["geoh5"] = self.workspace
                self.params = self.param_class(**new_params)
        elif trigger == "":
            ui_json_data = self._ui_json_data_from_params()
            object_value = ui_json_data["objects"]

            # Get new options for object dropdown
            if self.workspace is not None:
                object_options = [
                    {
                        "label": obj.parent.name + "/" + obj.name,
                        "value": "{" + str(obj.uid) + "}",
                    }
                    for obj in self.workspace.objects
                ]

        return object_options, object_value, ui_json_data, None, None

    def _ui_json_data_from_params(self) -> dict[str, Any]:
        """Returns app json data initialized from self.params"""
        assert (
            self.params.input_file is not None
        ), "No input file provided in parameters."

        ifile = InputFile(
            ui_json=self.params.input_file.ui_json,
            validate=False,
        )
        ifile.update_ui_values(self.params.to_dict())
        ui_json_data = ifile.demote(ifile.data)
        if self._app_initializer is not None:
            ui_json_data.update(self._app_initializer)
        return ui_json_data

    @staticmethod
    def get_port() -> int:
        """
        Loop through a list of ports to find an available port.

        :return port: Available port.
        """
        open_port = None
        for port in np.arange(8050, 8101):
            with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock:
                in_use = sock.connect_ex(("localhost", port)) == 0
            if in_use is False:
                open_port = port
                break
        if open_port is None:
            raise RuntimeError("No open port found.")
        return open_port

    @staticmethod
    def start_server(
        port: int,
        app_class: type[BaseDashApplication],
        ui_json: InputFile | None = None,
        ui_json_data: dict | None = None,
        params: BaseParams | None = None,
    ):
        """
        Launch dash app server using given port.

        :param port: Port for where to launch server.
        :param app_class: Type of app to create.
        :param ui_json: ifile corresponding to the ui_json_data.
        :param ui_json_data: Dict of current params to provide to app init.
        :param params: Current params to pass to new app.
        """
        app = app_class(ui_json=ui_json, ui_json_data=ui_json_data, params=params)
        app.app.run(jupyter_mode="external", host="127.0.0.1", port=port)

    @staticmethod
    def make_qt_window(app_name: str | None, port: int):
        """
        Make Qt window and load dash url with the given port.

        :param app_name: App name to display as Qt window title.
        :param port: Port where the dash app has been launched.
        """
        app = QtWidgets.QApplication(sys.argv)
        browser = QtWebEngineWidgets.QWebEngineView()

        browser.setWindowTitle(app_name)
        browser.load(QtCore.QUrl("http://127.0.0.1:" + str(port)))
        # Brings Qt window to the front
        browser.setWindowFlags(QtCore.Qt.WindowStaysOnTopHint)
        # Setting window size
        browser.resize(1200, 800)
        browser.show()

        app.exec_()  # running the Qt app
        os.kill(os.getpid(), signal.SIGTERM)  # shut down dash server and notebook

    def launch_qt(self, objects: str, n_clicks: int) -> str:
        """
        Launch the Qt app when launch app button is clicked.

        :param objects: Selected object uid.
        :param n_clicks: Number of times button has been clicked; triggers callback.

        :return launch_app_markdown: Empty string since callbacks must have output.
        """
        del n_clicks  # unused argument

        triggers = [c["prop_id"].split(".")[0] for c in callback_context.triggered]
        if not (
            "launch_app" in triggers
            and objects is not None
            and self.workspace is not None
        ):
            return ""

        # Make new workspace with only the selected object
        obj = self.workspace.get_entity(uuid.UUID(objects))[0]
        if not isinstance(obj, Entity):
            return ""

        temp_geoh5 = self.workspace.name + "_" + f"{time():.0f}.geoh5"
        with tempfile.TemporaryDirectory() as tempdir_name:
            tempdir = Path(tempdir_name)
            temp_workspace = Workspace.create(tempdir / temp_geoh5)

            # Update ui.json with temp_workspace to pass initialize scatter plot app
            param_dict = self.params.to_dict()
            param_dict["geoh5"] = temp_workspace

            with fetch_active_workspace(temp_workspace), fetch_active_workspace(
                self.workspace
            ):
                param_dict["objects"] = obj.copy(
                    parent=temp_workspace, copy_children=True
                )

                if hasattr(obj, "property_groups"):
                    self._copy_property_groups(obj.property_groups, param_dict)

            new_params = self.param_class(**param_dict)

            temp_ui_json_name = temp_geoh5.replace(".geoh5", ".ui.json")
            new_params.write_input_file(
                name=temp_ui_json_name,
                path=tempdir_name,
                validate=False,
            )

            ifile = InputFile.read_ui_json(tempdir / temp_ui_json_name)
            ui_json_data = ifile.demote(ifile.data)

        # Start server
        port = ObjectSelection.get_port()
        threading.Thread(
            target=self.start_server,
            args=(port, self.app_class, ifile, ui_json_data, new_params),
            daemon=True,
        ).start()

        # Make Qt window
        self.make_qt_window(self.app_name, port)
        return ""

    @staticmethod
    def _copy_property_groups(source_groups: ObjectBase, param_dict: dict):
        """Copy any property groups over to param_dict of temporary workspace"""
        temp_prop_groups = param_dict["objects"].property_groups
        for group in source_groups:
            if not isinstance(group, PropertyGroup):
                continue
            for temp_group in temp_prop_groups:
                if temp_group.name != group.name:
                    continue
                for key, value in param_dict.items():
                    if hasattr(value, "uid") and value.uid == group.uid:
                        param_dict[key] = temp_group.uid

    @staticmethod
    def run(app_name: str, app_class: BaseDashApplication, ui_json: InputFile):
        """
        Launch Qt app from terminal.

        :param app_name: Name of app to display as Qt window title.
        :param app_class: Type of app to create.
        :param ui_json: Input file to pass to app for initialization.
        """
        # Start server
        port = ObjectSelection.get_port()
        threading.Thread(
            target=ObjectSelection.start_server,
            args=(port, app_class, ui_json),
            daemon=True,
        ).start()

        # Make Qt window
        ObjectSelection.make_qt_window(app_name, port)

    @property
    def app_name(self) -> str | None:
        """
        Name of app that appears as Qt window title.
        """
        return self._app_name

    @app_name.setter
    def app_name(self, val):
        if not isinstance(val, str) and (val is not None):
            raise TypeError("Value for attribute `app_name` should be 'str' or 'None'")
        self._app_name = val

    @property
    def app_class(self) -> type[BaseDashApplication]:
        """
        The kind of app to launch.
        """
        return self._app_class

    @app_class.setter
    def app_class(self, val):
        if not issubclass(val, BaseDashApplication):
            raise TypeError(
                "Value for attribute `app_class` should be a subclass of "
                ":obj:`geoapps_utils.application.BaseDashApplication`"
            )
        self._app_class = val

    @property
    def param_class(self) -> type[BaseParams]:
        """
        The param class associated with the launched app.
        """
        return self._param_class

    @param_class.setter
    def param_class(self, val):
        if not issubclass(val, BaseParams):
            raise TypeError(
                "Value for attribute `param_class` should be a subclass of "
                ":obj:`geoapps_utils.driver.params.BaseParams`"
            )
        self._param_class = val

    @property
    def workspace(self) -> Workspace | None:
        """
        Input workspace.
        """
        return self._workspace

    @workspace.setter
    def workspace(self, val):
        if not isinstance(val, Workspace) and (val is not None):
            raise TypeError(
                "Value for attribute `workspace` should be :obj:`geoh5py.workspace.Workspace`"
                " or 'None'"
            )
        if self._workspace is not None:
            # Close old workspace
            self._workspace.close()
        self._workspace = val


# IMPORTATION STANDARD
import json
import logging

# IMPORTATION THIRD PARTY
import grpc
from google.protobuf.empty_pb2 import Empty

# from google.protobuf.wrappers_pb2 import *

# IMPORTATION INTERNAL
from degiro_connector.quotecast.models.quotecast_pb2 import Chart, Quotecast
from degiro_connector.quotecast.models.quotecast_relay_pb2 import SetConfig
from degiro_connector.quotecast.models.quotecast_relay_pb2_grpc import (
    QuotecastRelayStub,
)

# SETUP LOGS
logging.basicConfig(level=logging.DEBUG)

# SETUP CONFIG DICT
with open("config/config.json") as config_file:
    config_dict = json.load(config_file)

# SETUP CREDENTIALS
user_token = config_dict.get("user_token")

# SETUP RELAY
relay_channel = grpc.insecure_channel("localhost:50051")
relay_stub = QuotecastRelayStub(channel=relay_channel)

# RESPONSES DICT
responses = dict()

# CALL : set_config
set_config = SetConfig()
set_config.user_token = user_token
set_config.auto_connect = True

responses["set_config"] = relay_stub.set_config(request=set_config)

# CALL : connect
responses["connect"] = relay_stub.connect(request=Empty())

# CALL : subscribe
request = Quotecast.Request()
request.subscriptions["AAPL.BATS,E"].extend(
    [
        "LastDate",
        "LastTime",
        "LastPrice",
        "LastVolume",
        "AskPrice",
        "BidPrice",
    ]
)

responses["subscribe"] = relay_stub.subscribe(request=request)

# CALL : fetch_data
responses["fetch_data"] = relay_stub.fetch_data(request=Empty())

# CALL : get_chart
request = Chart.Request()
request.culture = "fr-FR"
request.period = Chart.Interval.PT1H
request.requestid = "1"
request.resolution = Chart.Interval.P1D
# request.series.append("issueid:360148977")
# request.series.append("price:issueid:360148977")
request.series.append("ohlc:issueid:360148977")
# request.series.append("volume:issueid:360148977")
# request.series.append("vwdkey:AAPL.BATS,E")
# request.series.append("price:vwdkey:AAPL.BATS,E")
# request.series.append("ohlc:vwdkey:AAPL.BATS,E")
# request.series.append("volume:vwdkey:AAPL.BATS,E")
request.tz = "Europe/Paris"
request.tz = "Europe/Paris"
request.override["resolution"] = "P1D"
request.override["period"] = "P1W"

responses["get_chart"] = relay_stub.get_chart(
    request=request,
)
# DISPLAY RESPONSES DICT
print(responses)


from django.utils.dateparse import parse_datetime
from django_cron import CronJobBase, Schedule
from django.utils.timezone import make_aware
from datetime import datetime

from tasks import states
from tasks.clients import CloudMLClient
from tasks.models import Task

class UpdateCloudMLTasksCronJob(CronJobBase):
    help = 'Update status of running Cloud ML-based tasks'

    RUN_EVERY_MINS = 5
    INVALID_TASK_EXPIRATION_TIME = 15 * 60
    JOBS_CREATE_TIME_BASE = make_aware(datetime(2020, 7, 31))

    schedule = Schedule(run_every_mins=RUN_EVERY_MINS)
    code = 'tasks.cron.update_cloudml_tasks'  # a unique code

    def do(self):
        client = CloudMLClient()

        # Look for running Tasks of type TRAIN or PREDICT
        cloudml_tasks = Task.objects.filter(
            internal_metadata__uses_cloudml=True,
            state__in=[states.PENDING, states.STARTED])
        count = cloudml_tasks.count()

        if count == 0:
            return
        print("Running tasks:", count)

        # For each task, get the corresponding Cloud ML Job
        # If CloudML job has finished, update state of task
        for task in cloudml_tasks:
            # Ref: https://cloud.google.com/ai-platform/training/docs/reference/rest/v1/projects.jobs#State
            job = client.get_job(
                task.internal_metadata.get("cloudml_job_name"))
            task_is_too_old = task.age > self.INVALID_TASK_EXPIRATION_TIME
            if not job:
                if task_is_too_old:
                    print(
                        f'Task {task.pk} has no related CloudML and is old (started at {task.created_at}). Mark as failed.'
                    )
                    task.mark_as_failed(reason='Task failed to start')
                    return
                else:
                    continue

            state = job['state']
            print(f'Task {task.pk} has a CloudML job with state {state}')

            # Use real endTime as finished_at, not current time
            job_end_time = job.get('endTime')
            finished_at = parse_datetime(
                job_end_time) if job_end_time else None

            if state == 'SUCCEEDED':
                print(f'Task {task.pk}: Mark as finished at {finished_at}')
                task.mark_as_finished(finished_at=finished_at)
            if state in ['CANCELLING', 'CANCELLED']:
                print(f'Job {task.pk}: Mark as canceled at {finished_at}')
                task.mark_as_canceled(finished_at=finished_at)
            if state == 'FAILED':
                print(f'Job {task.pk}: Mark as failed at {finished_at}')
                task.mark_as_failed(finished_at=finished_at)


from zoom_out import *
import constants
from pymongo import MongoClient
client = MongoClient()
db = client.MyDB
collection = db.FirstCollection

class DistortionData:
    """Class DistortionData computes the distortion units for the selected trajectories and finds the preferable
    episode if there is one to include."""

    def __init__(self, area_step=0, time_step=0, distort_area_only=False, distort_time_only=False,
                 distort_area_time=False):
        self.area_step = area_step
        self.time_step = time_step
        self.area_distortion_limit = 10000.0
        self.time_distortion_limit = 1
        self.area_time_distortion_limit = 100.0
        self.subqueries = []
        self.distort_area_only = distort_area_only
        self.distort_time_only = distort_time_only
        self.distort_area_time = distort_area_time

    def find_subqueries_not_in_row(self, row):
        """This function finds and returns a list (found[]) with the subqueries who do not contain episode of the
        trajectory (they are not included in the SQueries[] list for the trajectory we examine)"""
        found = []

        for subq in range(len(self.subqueries)):
            if row.subquery_exists(self.subqueries[subq].qid) is True:
                continue
            else:
                found.append(self.subqueries[subq])
        return found

    def set_subqueries(self, subqueries):
        """Initializes the subqueries[] list (we use this in the driver code to load the user's subqueries"""

        if subqueries is None or subqueries == []:
            raise Exception("Invalid subqueries list")
        self.subqueries = subqueries

    def check_by_distort_area_time(self, row):

        trace_id = row.get_trace_id()
        subqueries_ = self.find_subqueries_not_in_row(row)
        discard_trc_id = False
        to_add = []

        for subq in range(len(subqueries_)):

            if discard_trc_id is True:
                break

            query_ = subqueries_[subq]
            start_area = (query_.realx2 - query_.realx1) * (query_.realy2 - query_.realy1)
            x1 = query_.realx1
            x2 = query_.realx2
            y1 = query_.realy1
            y2 = query_.realy2
            steps = 1
            new_area = (x2 - x1 + 2 * steps * self.area_step) * (y2 - y1 + 2 * steps * self.area_step)
            start_time = query_.duration
            new_time = start_time + self.time_step * steps
            area_time_distortion_unit = (((new_area - start_area)/start_area) + ((new_time - start_time)/start_time))/2

            while area_time_distortion_unit < self.area_time_distortion_limit:
                if query_.episodes == 'Null':
                    q_r = db.FirstCollection.find({"loc": {"$geoWithin": {"$box": [
                        [x1 - steps * self.area_step, y1 - steps * self.area_step],
                        [x2 + steps * self.area_step, y2 + steps * self.area_step]]}}, "duration": {"$lt": new_time},
                        'MOid': trace_id})
                else:
                    q_r = db.FirstCollection.find({"loc": {"$geoWithin": {"$box": [
                        [x1-steps*self.area_step, y1-steps*self.area_step], [x2+steps*self.area_step,
                                                                             y2+steps*self.area_step]]}}, "duration": {
                        "$lt": new_time}, "episodes": query_.episodes, 'MOid': trace_id})

                query_rslt = []
                for i in q_r:
                    query_rslt.append(i['MOid'])
                q_reslt = set(query_rslt)
                query_result = list(q_reslt)
                out = False
                for i in query_result:
                    if query_result is not None and i == trace_id:
                        elements = [subqueries_[subq].qid, area_time_distortion_unit, steps]
                        to_add.append(elements)
                        out = True
                        break
                if out is True:
                    break
                steps += 1
                new_area = (x2 - x1 + 2 * steps * self.area_step) * (y2 - y1 + 2 * steps * self.area_step)
                new_time = start_time + self.time_step * steps
                area_time_distortion_unit = (((new_area - start_area)/start_area) + ((new_time - start_time)/start_time)
                                             )/2

                if area_time_distortion_unit > self.area_time_distortion_limit:
                    discard_trc_id = True

        if discard_trc_id is not True:
            for i in to_add:
                row.set_subquery_dist_area_time_unit(i[0], i[1], i[2])

    def check_by_distort_area(self, row):

        # loop over the subqueries of the row and for each subquery iteratively enlarge the area of the subquery
        # for each iteration check with the db by using the enlarged area if the trajectory is contained in the modified
        # subquery. The inner enlargement iterations finish when the overall area_distortion_unit  exceeds a certain
        # area_distortion_limit. If the trajectory id is found before reaching the area_distortion_limit meaning
        # area_distortion_unit < area_distortion_limit the algorithm continues to examine the next subquery, otherwise
        # it marks the whole row as invalid. If the all subqueries are found after distorting the area to contain the
        # trajectory then the smallest distortion will be chosen.

        trace_id = row.get_trace_id()
        subqueries_ = self.find_subqueries_not_in_row(row)
        discard_trc_id = False
        to_add = []

        for subq in range(len(subqueries_)):

            if discard_trc_id is True:
                break

            query_ = subqueries_[subq]
            start_area = (query_.realx2 - query_.realx1)*(query_.realy2 - query_.realy1)
            x1 = query_.realx1
            x2 = query_.realx2
            y1 = query_.realy1
            y2 = query_.realy2
            steps = 1
            new_area = (x2 - x1 + 2*steps*self.area_step)*(y2 - y1 + 2*steps*self.area_step)
            area_distortion_unit = (new_area - start_area)/start_area

            while area_distortion_unit < self.area_distortion_limit:
                # haven't reached the distortion limit yet so query the db by using the new_area
                if query_.episodes == 'Null':
                    q_r = db.FirstCollection.find({"loc": {"$geoWithin": {"$box": [
                        [x1 - steps * self.area_step, y1 - steps * self.area_step], [x2 + steps * self.area_step,
                                                                                y2 + steps * self.area_step]]}},
                        "duration":
                            {"$lt": query_.duration}, 'MOid': trace_id})
                else:
                    q_r = db.FirstCollection.find({"loc": {"$geoWithin": {"$box": [
                        [x1-steps*self.area_step, y1-steps*self.area_step], [x2+steps*self.area_step,
                                                                             y2+steps*self.area_step]]}}, "duration":
                        {"$lt": query_.duration}, "episodes": query_.episodes, 'MOid': trace_id})

                query_rslt = []
                for i in q_r:
                    query_rslt.append(i['MOid'])
                q_reslt = set(query_rslt)
                query_result = list(q_reslt)
                out = False
                for i in query_result:
                    if query_result is not None and i == trace_id:
                        elements = [subqueries_[subq].qid, area_distortion_unit, steps]
                        to_add.append(elements)
                        out = True
                        break
                if out is True:
                    break
                steps += 1
                new_area = (x2 - x1 + 2*steps*self.area_step)*(y2 - y1 + 2*steps*self.area_step)
                area_distortion_unit = (new_area - start_area) / start_area

                if area_distortion_unit > self.area_distortion_limit:
                    discard_trc_id = True

        if discard_trc_id is not True:
            for i in to_add:
                row.set_subquery_dist_area_unit(i[0], i[1], i[2])

    def check_by_distort_time(self, row):

        trace_id = row.get_trace_id()
        subqueries_ = self.find_subqueries_not_in_row(row)
        discard_trc_id = False
        to_add = []

        for subq in range(len(subqueries_)):

            if discard_trc_id is True:
                break

            query_ = subqueries_[subq]
            x1 = query_.realx1
            x2 = query_.realx2
            y1 = query_.realy1
            y2 = query_.realy2
            start_time = query_.duration
            steps = 1
            new_time = start_time + self.time_step * steps
            time_distortion_unit = (new_time - start_time)/start_time

            while time_distortion_unit < self.time_distortion_limit:
                if query_.episodes == 'Null':
                    q_r = db.FirstCollection.find({"loc": {"$geoWithin": {"$box": [[x1, y1], [x2, y2]]}},
                                                   "duration": {"$lt": new_time}, 'MOid': trace_id})
                else:
                    q_r = db.FirstCollection.find({"loc": {"$geoWithin": {"$box": [[x1, y1], [x2, y2]]}}, "duration": {
                        "$lt": new_time}, "episodes": query_.episodes, 'MOid': trace_id})

                query_rslt = []
                for i in q_r:
                    query_rslt.append(i['MOid'])
                q_reslt = set(query_rslt)
                query_result = list(q_reslt)
                out = False
                for i in query_result:
                    if query_result is not None and i == trace_id:
                        elements = [subqueries_[subq].qid, time_distortion_unit, steps]
                        to_add.append(elements)
                        out = True
                        break
                if out is True:
                    break
                steps += 1
                new_time = start_time + self.time_step * steps
                time_distortion_unit = (new_time - start_time)/start_time

                if time_distortion_unit > self.time_distortion_limit:
                    discard_trc_id = True

        if discard_trc_id is not True:
            for i in to_add:
                row.set_subquery_dist_time_unit(i[0], i[1], i[2])

    def check_by_distortion(self, row):

        if self.distort_area_only is True:
            self.check_by_distort_area(row)
            min_dist_area_unit = row.get_min_area_dist_unit()

            if min_dist_area_unit[0] != constants.INVALID_ID:
                return [row.get_trace_id(), min_dist_area_unit[0], min_dist_area_unit[1], min_dist_area_unit[2]]
            return [-1, -1, -1, -1]

        elif self.distort_time_only is True:
            self.check_by_distort_time(row)
            min_dist_time_unit = row.get_min_time_dist_unit()

            if min_dist_time_unit[0] != constants.INVALID_ID:
                return [row.get_trace_id(), min_dist_time_unit[0], min_dist_time_unit[1], min_dist_time_unit[2]]
            return [-1, -1, -1, -1]

        elif self.distort_area_time is True:
            self.check_by_distort_area_time(row)
            min_dist_area_time_unit = row.get_min_area_time_dist_unit()

            if min_dist_area_time_unit[0] != constants.INVALID_ID:
                return [row.get_trace_id(), min_dist_area_time_unit[0], min_dist_area_time_unit[1],
                        min_dist_area_time_unit[2]]
            return [-1, -1, -1, -1]

        else:
            raise Exception("No valid distortion type. Set either distort_area_only or distort_time_only or "
                            "distort_area_time flag to True. ")

    def compute_rows_distortions(self, rows, ran_num):
        episode_found = []
        minimum_dist_unit = constants.LARGE_VALUE
        steps_ = constants.INVALID_ID
        subquery = constants.INVALID_ID
        for r in range(len(rows)):
            episode_found.append(self.check_by_distortion(rows[r]))
        # loop over episode_found list if a True exists return True else False
        for x in episode_found:
            if x[2] != -1 and x[2] < minimum_dist_unit:
                minimum_dist_unit = x[2]
                steps_ = x[3]
                subquery = x[1]

        if minimum_dist_unit != constants.LARGE_VALUE:
            if self.distort_area_only is True:
                for q in self.subqueries:
                    if q.qid == subquery:
                        q.distort_area(steps_, self.area_step, ran_num)
            elif self.distort_time_only is True:
                for q in self.subqueries:
                    if q.qid == subquery:
                        q.distort_time(steps_, self.time_step)
            else:
                for q in self.subqueries:
                    if q.qid == subquery:
                        q.distort_area_time(steps_, self.area_step, self.time_step, ran_num)
            return True
        return False


#!/usr/bin/python
# encoding: utf-8
"""
tests.py
"""
import unittest
import base64
import argparse

from google.appengine.ext import testbed, deferred, ndb

from inbox import app

USAGE = """
Path to your sdk must be the first argument. To run type:

$ utrunner.py tests.py path/to/your/appengine/installation

Remember to set environment variable FLASK_CONF to TEST.
Loading configuration depending on the value of
environment variable allows you to add your own
testing configuration in src/birthday/settings.py

"""

class AppEngineFlaskTestCase(unittest.TestCase):

    def setUp(self):
        # Flask apps testing. See: http://flask.pocoo.org/docs/testing/
        self.app = app.test_client()
        app.config['TESTING'] = True
        app.config['CSRF_ENABLED'] = False
        self._ctx = app.test_request_context()
        self._ctx.push()

        # Setups app engine test bed. See: http://code.google.com/appengine/docs/python/tools/localunittesting.html#Introducing_the_Python_Testing_Utilities
        self.testbed = testbed.Testbed()
        self.testbed.activate()
        self.testbed.init_datastore_v3_stub()
        self.testbed.init_user_stub()
        self.testbed.init_memcache_stub()
        self.testbed.init_taskqueue_stub(root_path=".")
        self.task_stub = self.testbed.get_stub(testbed.TASKQUEUE_SERVICE_NAME)

    def tearDown(self):
        self.testbed.deactivate()
        if getattr(self, '_ctx') and self._ctx is not None:
            self._ctx.pop()
        del self._ctx

    def run_queue_tasks(self, queue='default'):
        api_tasks = self.task_stub.GetTasks(queue)
        while len(api_tasks) >0:
            self.task_stub.FlushQueue(queue)
            for api_task in api_tasks:
                deferred.run(base64.b64decode(api_task['body']))
            api_tasks = self.task_stub.GetTasks(queue)

    def set_current_user(self, email, user_id, is_admin=False):
        self.testbed.setup_env(
            USER_EMAIL=email or '',
            USER_ID=user_id or '',
            USER_IS_ADMIN='1' if is_admin else '0'
        )

class DemoTestCase(AppEngineFlaskTestCase):

    def test_home_redirects(self):
        rv = self.app.get('/')
        assert rv.status == '302 FOUND'

    def test_says_hello(self):
        rv = self.app.get('/hello/world')
        assert 'Hello world' in rv.data

    def test_displays_no_data(self):
        rv = self.app.get('/examples')
        assert 'No examples yet' in rv.data

    def test_inserts_data(self):
        self.set_current_user(u'john@example.com', u'123')
        rv = self.app.post('/example/new', data=dict(
            example_name='An example',
            example_description='Description of an example'
        ), follow_redirects=True)
        assert 'Example successfully saved' in rv.data

        rv = self.app.get('/examples')
        assert 'No examples yet' not in rv.data
        assert 'An example' in rv.data

    def test_admin_login(self):
        #Anonymous
        rv = self.app.get('/admin_index')
        assert rv.status == '302 FOUND'
        #Normal user
        self.set_current_user(u'john@example.com', u'123')
        rv = self.app.get('/admin_index')
        assert rv.status == '302 FOUND'
        #Admin
        self.set_current_user(u'john@example.com', u'123', True)
        rv = self.app.get('/admin_index')
        assert rv.status == '200 OK'

    def test_404(self):
        rv = self.app.get('/missing')
        assert rv.status == '404 NOT FOUND'
        assert '
Not found
' in rv.data

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


from datetime import timedelta
import os
import airflow
from airflow.decorators import dag, task

START_DATE = airflow.utils.dates.days_ago(1)
PROJECT_ID = os.environ.get("GCP_PROJECT_ID", "##########")

default_args = {
    'owner': 'airflow',
}
@dag(default_args=default_args, schedule_interval="@daily", start_date=START_DATE, tags=['daily'])

def fetch_crypto():
    @task()
    def update_data(symbol,date="2017-01-01"):
        import requests
        address="https://###########.a.run.app/"

        j={'symbol':symbol,'start_date':date}

        r = requests.post(address, json=j,headers={"TOKEN": "hunter2"},)
        print(r.status_code)
        print(r.text)

    [update_data("BINANCE:BTCUSDT"),update_data("BINANCE:ETHUSDT")]

taskflowfetch_crypto_dag = fetch_crypto()