import csv
from sys import platform
import pickle
import math
import os
import json

data_stored = False
data = []

file_path_MacOS = 'tools/SampleData.csv'
file_path_Windows = 'SampleData.csv'
file_path = ''

# Open SampleData file store data into data variable
def openSampleData():
    global data_stored

    # Check OS for file path
    if platform == "darwin":
        file_path = file_path_MacOS
    elif platform == "win32":
        file_path = file_path_Windows
    else:
        print("ERROR: Operating system not supported for file open")
        file_path = file_path_MacOS

    try:
        with open(file_path, 'r', encoding='utf-8-sig') as file:
            csv_reader = csv.reader(file)
            data = [row for row in csv_reader]
            data_stored = True
        return data
    except FileNotFoundError:
        print("File tools/SampleData.csv not found.")
        return []

# Returns a full row sample packet
def getSamplePacket():
    # Aquire data into data variable
    if not data_stored:
        data = openSampleData()

    return data[0]

# Returns a cleaned up sample packet (first portion of data in the packet)
def getCleanedSamplePacket():
    # Aquire data into data variable
    if not data_stored:
        data = openSampleData()

    packet = data[0]            # Value is an array
    packet_string = packet[0]   # Value is the string inside the array (full packet data)

    # Parse to get first portion of data
    start_index = packet_string.find("BrainBitSignalData(")
    end_index = packet_string.find(")")

    return packet_string[start_index:end_index + 1]

def parseUserData(user_id):
    # Initialize variables to accumulate values
    o1_sum = 0
    o2_sum = 0
    t3_sum = 0
    t4_sum = 0
    sample_count = 0

    user_id = 'temp'

    create_user_directory(user_id)  # Creating user directory if it has not been created
    in_filename = f"{user_id}_raw.pkl" # Will change to User ID specific file when connection to front end is made
    out_filename = os.path.join("user_data", user_id, f"{user_id}_parsed.pkl")
    #in_filename = "SampleData.pkl" # Comment in for debug purposes

    # Edit this in to print the data
    # with open(filename, 'rb') as file:
    #     data = pickle.load(file)
    #     print(data)
    #     while data:
    #         data = pickle.load(file)
    #         print(data)

    try:
        with open(in_filename, 'rb') as file: # Opens file in read binary mode
            data = pickle.load(file) # Will return one packet
            while data: # While data is still being read from the .pkl file
                o1_sum += sum(sample.O1 for sample in data) # Sum will add up all the values for o1 given for ONE packet and the will add that sum to a running total for O1
                o2_sum += sum(sample.O2 for sample in data)
                t3_sum += sum(sample.T3 for sample in data)
                t4_sum += sum(sample.T4 for sample in data)
                sample_count += len(data) # Will count the amount of samples given per packet (can be 2 4 or 6 samples per packet)
                data = pickle.load(file) # Load the new packet
    except FileNotFoundError:
        print(f"File '{in_filename}' not found.")
    except Exception as e:
        print(e) # Exists to notify when data can no longer be read

    # Calculate the averages
    if sample_count > 0:
        o1_avg = o1_sum / sample_count
        o2_avg = o2_sum / sample_count
        t3_avg = t3_sum / sample_count
        t4_avg = t4_sum / sample_count
        averages = [o1_avg, o2_avg, t3_avg, t4_avg]
        # Store the list of averages using pickle
        with open(out_filename, 'wb') as file:
            pickle.dump(averages, file)

        # Comment in for debug purposes
        # print(f"Average O1: {o1_avg}")
        # print(f"Average O2: {o2_avg}")
        # print(f"Average T3: {t3_avg}")
        # print(f"Average T4: {t4_avg}")
    else:
        print("No data available to calculate averages.")

# User matching using euclidean distance ( user_data_x is a list for averages [O1, O2, T3, T4] )
def calculate_user_match(user_data_1, user_data_2):
    # Calculate difference between both users data
    o1_difference = user_data_1[0] - user_data_2[0]
    o2_difference = user_data_1[1] - user_data_2[1]
    t3_difference = user_data_1[2] - user_data_2[2]
    t4_difference = user_data_1[3] - user_data_2[3]

    # Calculate euclidean distance using difference calculations
    euclidean_distance = math.sqrt( (o1_difference)**2 +
                                    (o2_difference)**2 +
                                    (t3_difference)**2 +
                                    (t4_difference)**2 )

    # lower distance = better match
    return euclidean_distance

# Return list of subdirectories from a root directory
def get_subdirectories(root_dir):
    subdir = []

    # Go through each file/folder in the root directory
    for item in os.listdir(root_dir):
        # Check if the item is a sub-directory
        full_path = os.path.join(root_dir, item)
        if os.path.isdir(full_path):
            subdir.append(item)

    return subdir

# Returns data from pkl file (check for file exist done before function call)
def get_data_from_pkl(pkl_path):
    pkl_data = None

    with open(pkl_path, 'rb') as file:
            pkl_data = pickle.load(file)

    return pkl_data

# Create json file to save matches if not already created
def create_matches_json():
    path_to_json = os.path.join('user_data', 'user_matches.json')

    # Create empty json if doesnt exist
    if not os.path.exists(path_to_json):
        matches = {}

        # Write the empty dictionary to the file
        with open(path_to_json, 'w') as file:
            json.dump(matches, file)

# Loads existing matches from json and returns them as dictionary
def load_existing_matches():
    path_to_json = os.path.join('user_data', 'user_matches.json')
    matches = {}

    # Create empty json if doesnt exist
    if os.path.exists(path_to_json):
        with open(path_to_json, 'r') as file:
            matches = json.load(file)
    else:
        print("ERROR: JSON does not exists ", path_to_json)
        return None

    return matches

# Add a match to the json dictionary
def add_to_matches(matches, cur_user_id, another_user, euclidean_distance):
    # Check if cur_user_id is existing as a key
    if cur_user_id in matches:
        # The other user is being added or if already exists, euclidean is updated
        matches[cur_user_id][another_user] = euclidean_distance  # Add to list of users (matches)
    else:
        # Create a new dictionary for this user_id
        matches[cur_user_id] = {}
        # Add other user as a match
        matches[cur_user_id][another_user] = euclidean_distance

# Save the matches dictionary to the matches json
def save_matches_to_json(matches):
    path_to_json = os.path.join('user_data', 'user_matches.json')

    # Write the updated dictionary back to the file
    with open(path_to_json, 'w') as file:
        json.dump(matches, file, indent=4)

# Function will go through other users data to find matches for current user
def find_user_matches(current_user_id):
    root_directory = 'user_data'
    subdir = get_subdirectories(root_directory)

    current_user_data_path = os.path.join(root_directory, current_user_id, f'{current_user_id}_parsed.pkl')
    current_user_data = None

    create_matches_json()   # Create json file to save matches if not already created
    existing_matches = load_existing_matches()  # Load existing saved matches dict from json

    # Check if current user has parsed data
    if os.path.exists(current_user_data_path):
        # Save current user's data
        current_user_data = get_data_from_pkl(current_user_data_path)
    else:
        print("ERROR: Current user path, ", current_user_data_path, " not found.")
        return None

    # Loop through each subdir in user_data directory ( user_id is a subdirectory name )
    for other_user_id in subdir:
        # Create full path to user parsed data
        other_user_path = os.path.join(root_directory, other_user_id, f'{other_user_id}_parsed.pkl')

        # Run calculation to find matches
        if os.path.exists(other_user_path) and other_user_id != current_user_id:
            other_user_data = get_data_from_pkl(other_user_path) # get other user's data

            # Call function to calculate euclidean distance between both users
            euclidean_distance = calculate_user_match(current_user_data, other_user_data)

            # If criteria for a match is met and it is not a rejected match, add the match
            if euclidean_distance < 5 and not is_rejected_match(current_user_id, other_user_id):
                add_to_matches(existing_matches, current_user_id, other_user_id, euclidean_distance)

        elif other_user_id != current_user_id:
            print("ERROR: ", other_user_path, " not found.")

    # saves all changes back to user_matches.json
    save_matches_to_json(existing_matches)

# Creating a new user directory, user_id is a string
def create_user_directory(user_id):
    path_to_user_dir = os.path.join('user_data', user_id)
    os.makedirs(path_to_user_dir, exist_ok=True)    # If directory already exists, it will not be replaced

#
#   Reject User utils
#

# Allowing a user to reject a match
def reject_match(user_id, user_to_reject_id):
    # Create json to save rejected matches if not already created
    create_rejected_matches_json()

    # Load existing rejected matches from json
    rejected_matches = load_existing_rejected_matches()

    # Add the new rejected matches to variable
    add_to_rejected_matches(rejected_matches, user_id, user_to_reject_id)

    # Saved rejected matches variable to json
    save_rejected_matches_to_json(rejected_matches)

    # Update matches json based on the rejection
    update_matches_from_reject(user_id, user_to_reject_id)

# Check rejected_matches.json to see if a user is rejected or other user rejected current user,return bool
def is_rejected_match(user1_id, user2_id):
    rejected_matches = load_existing_rejected_matches()
    if user2_id in rejected_matches.get(user1_id, []) or user1_id in rejected_matches.get(user2_id, []):
        return True
    else:
        return False

# Removes the match from both users
def update_matches_from_reject(user1_id, user2_id):
    matches = load_existing_matches()

    # Check if user is a key
    if user1_id in matches:
        # Check if user to be removed is an existing value
        if user2_id in matches[user1_id]:
            matches[user1_id].pop(user2_id)

    # Check if user is a key
    if user2_id in matches:
        # Check if user to be removed is an existing value
        if user1_id in matches[user2_id]:
            matches[user2_id].pop(user1_id)

    save_matches_to_json(matches)

# Create json file to save rejected matches if not already created
def create_rejected_matches_json():
    path_to_json = os.path.join('user_data', 'rejected_matches.json')

    # Create empty json if doesnt exist
    if not os.path.exists(path_to_json):
        rejected_matches = {}

        # Write the empty dictionary to the file
        with open(path_to_json, 'w') as file:
            json.dump(rejected_matches, file)

# Loads existing rejected matches from json and returns them as dictionary
def load_existing_rejected_matches():
    path_to_json = os.path.join('user_data', 'rejected_matches.json')
    rejected_matches = {}

    # Create empty json if doesnt exist
    if os.path.exists(path_to_json):
        with open(path_to_json, 'r') as file:
            rejected_matches = json.load(file)
    else:
        print("ERROR: JSON does not exists ", path_to_json)
        return None

    return rejected_matches

# Add a rejected_match to the json dictionary
def add_to_rejected_matches(rejected_matches, cur_user_id, rejected_user):
    # Check if cur_user_id is existing as a key
    if cur_user_id in rejected_matches:
        # Check if rejection already exists
        if rejected_user not in rejected_matches[cur_user_id]:
            # The other user is being added or if exists nothing changes
            rejected_matches[cur_user_id].append(rejected_user)
    else:
        # Add other user as a rejected_match
        rejected_matches[cur_user_id] = [rejected_user]

# Save the rejected matches dictionary to the matches json
def save_rejected_matches_to_json(rejected_matches):
    path_to_json = os.path.join('user_data', 'rejected_matches.json')

    # Write the updated dictionary back to the file
    with open(path_to_json, 'w') as file:
        json.dump(rejected_matches, file, indent=4)


import cv2
import numpy as np
import matplotlib.pyplot as plt

# get HOG
def HOG(img):
    # Grayscale
    def BGR2GRAY(img):
        gray = 0.2126 * img[..., 2] + 0.7152 * img[..., 1] + 0.0722 * img[..., 0]
        return gray

    # Magnitude and gradient
    def get_gradXY(gray):
        H, W = gray.shape

        # padding before grad
        gray = np.pad(gray, (1, 1), 'edge')

        # get grad x
        gx = gray[1:H+1, 2:] - gray[1:H+1, :W]
        # get grad y
        gy = gray[2:, 1:W+1] - gray[:H, 1:W+1]
        # replace 0 with
        gx[gx == 0] = 1e-6

        return gx, gy

    # get magnitude and gradient
    def get_MagGrad(gx, gy):
        # get gradient maginitude
        magnitude = np.sqrt(gx ** 2 + gy ** 2)

        # get gradient angle
        gradient = np.arctan(gy / gx)

        gradient[gradient < 0] = np.pi / 2 + gradient[gradient < 0] + np.pi / 2

        return magnitude, gradient

    # Gradient histogram
    def quantization(gradient):
        # prepare quantization table
        gradient_quantized = np.zeros_like(gradient, dtype=np.int)

        # quantization base
        d = np.pi / 9

        # quantization
        for i in range(9):
            gradient_quantized[np.where((gradient >= d * i) & (gradient <= d * (i + 1)))] = i

        return gradient_quantized

    # get gradient histogram
    def gradient_histogram(gradient_quantized, magnitude, N=8):
        # get shape
        H, W = magnitude.shape

        # get cell num
        cell_N_H = H // N
        cell_N_W = W // N
        histogram = np.zeros((cell_N_H, cell_N_W, 9), dtype=np.float32)

        # each pixel
        for y in range(cell_N_H):
            for x in range(cell_N_W):
                for j in range(N):
                    for i in range(N):
                        histogram[y, x, gradient_quantized[y * 4 + j, x * 4 + i]] += magnitude[y * 4 + j, x * 4 + i]

        return histogram

		# histogram normalization
    def normalization(histogram, C=3, epsilon=1):
        cell_N_H, cell_N_W, _ = histogram.shape
        ## each histogram
        for y in range(cell_N_H):
    	    for x in range(cell_N_W):
       	    #for i in range(9):
                histogram[y, x] /= np.sqrt(np.sum(histogram[max(y - 1, 0) : min(y + 2, cell_N_H),
                                                            max(x - 1, 0) : min(x + 2, cell_N_W)] ** 2) + epsilon)

        return histogram

    # 1. BGR -> Gray
    gray = BGR2GRAY(img)

    # 1. Gray -> Gradient x and y
    gx, gy = get_gradXY(gray)

    # 2. get gradient magnitude and angle
    magnitude, gradient = get_MagGrad(gx, gy)

    # 3. Quantization
    gradient_quantized = quantization(gradient)

    # 4. Gradient histogram
    histogram = gradient_histogram(gradient_quantized, magnitude)

    # 5. Histogram normalization
    histogram = normalization(histogram)

    return histogram

# draw HOG
def draw_HOG(img, histogram):
    # Grayscale
    def BGR2GRAY(img):
        gray = 0.2126 * img[..., 2] + 0.7152 * img[..., 1] + 0.0722 * img[..., 0]
        return gray

    def draw(gray, histogram, N=8):
        # get shape
        H, W = gray.shape
        cell_N_H, cell_N_W, _ = histogram.shape

        ## Draw
        out = gray[1 : H + 1, 1 : W + 1].copy().astype(np.uint8)

        for y in range(cell_N_H):
            for x in range(cell_N_W):
                cx = x * N + N // 2
                cy = y * N + N // 2
                x1 = cx + N // 2 - 1
                y1 = cy
                x2 = cx - N // 2 + 1
                y2 = cy

                h = histogram[y, x] / np.sum(histogram[y, x])
                h /= h.max()

                for c in range(9):
                    #angle = (20 * c + 10 - 90) / 180. * np.pi
                    # get angle
                    angle = (20 * c + 10) / 180. * np.pi
                    rx = int(np.sin(angle) * (x1 - cx) + np.cos(angle) * (y1 - cy) + cx)
                    ry = int(np.cos(angle) * (x1 - cx) - np.cos(angle) * (y1 - cy) + cy)
                    lx = int(np.sin(angle) * (x2 - cx) + np.cos(angle) * (y2 - cy) + cx)
                    ly = int(np.cos(angle) * (x2 - cx) - np.cos(angle) * (y2 - cy) + cy)

                    # color is HOG value
                    c = int(255. * h[c])

                    # draw line
                    cv2.line(out, (lx, ly), (rx, ry), (c, c, c), thickness=1)

        return out

    # get gray
    gray = BGR2GRAY(img)

    # draw HOG
    out = draw(gray, histogram)

    return out

# Read image
img = cv2.imread("imori.jpg").astype(np.float32)

# get HOG
histogram = HOG(img)

# draw HOG
out = draw_HOG(img, histogram)

# Save result
cv2.imwrite("out.jpg", out)
cv2.imshow("result", out)
cv2.waitKey(0)
cv2.destroyAllWindows()


import numpy as np
from abc import ABCMeta, abstractmethod
from glmnet import LogitNet
from scipy.stats import gaussian_kde, rankdata, norm
from sklearn.covariance import ledoit_wolf

from abcpy.graphtools import GraphTools

class Approx_likelihood(metaclass=ABCMeta):
    """This abstract base class defines the approximate likelihood
    function.
    """

    @abstractmethod
    def __init__(self, statistics_calc):
        """
        The constructor of a sub-class must accept a non-optional statistics
        calculator; then, it must call the __init__ method of the parent class. This ensures that the
        object is initialized correctly so that the _calculate_summary_stat private method can be called when computing
        the distances.

        Parameters
        ----------
        statistics_calc : abcpy.statistics.Statistics
            Statistics extractor object that conforms to the Statistics class.
        """
        self.statistics_calc = statistics_calc

        # Since the observations do always stay the same, we can save the
        #  summary statistics of them and not recalculate it each time
        self.stat_obs = None
        self.data_set = None
        self.dataSame = False

    @abstractmethod
    def loglikelihood(self, y_obs, y_sim):
        """To be overwritten by any sub-class: should compute the approximate loglikelihood
        value given the observed data set y_obs and the data set y_sim simulated from
        model set at the parameter value.

        Parameters
        ----------
        y_obs: Python list
            Observed data set.
        y_sim: Python list
            Simulated data set from model at the parameter value.

        Returns
        -------
        float
            Computed approximate loglikelihood.
        """

        raise NotImplemented

    def likelihood(self, y_obs, y_sim):
        """Computes the likelihood by taking the exponential of the loglikelihood method.

        Parameters
        ----------
        y_obs: Python list
            Observed data set.
        y_sim: Python list
            Simulated data set from model at the parameter value.

        Returns
        -------
        float
            Computed approximate likelihood.

        """
        return np.exp(self.loglikelihood(y_obs, y_sim))

    def _calculate_summary_stat(self, y_obs, y_sim):
        """Helper function that extracts the summary statistics s_obs and s_sim from y_obs and
        y_y_sim using the statistics object stored in self.statistics_calc. This stores s_obs for the purpose of checking
        whether that is repeated in next calls to the function, and avoiding computing the statitistics for the same
        dataset several times.

        Parameters
        ----------
        y_obs : array-like
            d1 contains n_obs data sets.
        y_sim : array-like
            d2 contains n_sim data sets.

        Returns
        -------
        tuple
            Tuple containing numpy.ndarray's with the summary statistics extracted from d1 and d2.
        """
        if not isinstance(y_obs, list):
            raise TypeError('Observed data is not of allowed types')

        if not isinstance(y_sim, list):
            raise TypeError('simulated data is not of allowed types')

        # Check whether y_obs is same as the stored dataset.
        if self.data_set is not None:
            # check that the the observations have the same length; if not, they can't be the same:
            if len(y_obs) != len(self.data_set):
                self.dataSame = False
            elif len(np.array(y_obs[0]).reshape(-1, )) == 1:
                self.dataSame = self.data_set == y_obs
            else:  # otherwise it fails when y_obs[0] is array
                self.dataSame = all(
                    [(np.array(self.data_set[i]) == np.array(y_obs[i])).all() for i in range(len(y_obs))])

        if self.stat_obs is None or self.dataSame is False:
            self.stat_obs = self.statistics_calc.statistics(y_obs)
            self.data_set = y_obs

        # Extract summary statistics from the simulated data
        stat_sim = self.statistics_calc.statistics(y_sim)

        if self.stat_obs.shape[1] != stat_sim.shape[1]:
            raise ValueError("The dimension of summaries in the two datasets is different; check the dimension of the"
                             " provided observations and simulations.")

        return self.stat_obs, stat_sim

class SynLikelihood(Approx_likelihood):

    def __init__(self, statistics_calc):
        """This class implements the approximate likelihood function which computes the approximate
        likelihood using the synthetic likelihood approach described in Wood [1].
        For synthetic likelihood approximation, we compute the robust precision matrix using Ledoit and Wolf's [2]
        method.

        [1] S. N. Wood. Statistical inference for noisy nonlinear ecological
        dynamic systems. Nature, 466(7310):1102–1104, Aug. 2010.

        [2] O. Ledoit and M. Wolf, A Well-Conditioned Estimator for Large-Dimensional Covariance Matrices,
        Journal of Multivariate Analysis, Volume 88, Issue 2, pages 365-411, February 2004.

        Parameters
        ----------
        statistics_calc : abcpy.statistics.Statistics
            Statistics extractor object that conforms to the Statistics class.
        """

        super(SynLikelihood, self).__init__(statistics_calc)

    def loglikelihood(self, y_obs, y_sim):
        """Computes the loglikelihood.

        Parameters
        ----------
        y_obs: Python list
            Observed data set.
        y_sim: Python list
            Simulated data set from model at the parameter value.

        Returns
        -------
        float
            Computed approximate loglikelihood.

        """

        stat_obs, stat_sim = self._calculate_summary_stat(y_obs, y_sim)

        # Compute the mean, robust precision matrix and determinant of precision matrix
        mean_sim = np.mean(stat_sim, 0)
        lw_cov_, _ = ledoit_wolf(stat_sim)
        robust_precision_sim = np.linalg.inv(lw_cov_)
        sign_logdet, robust_precision_sim_logdet = np.linalg.slogdet(robust_precision_sim)  # we do not need sign
        # print("DEBUG: combining.")
        # we may have different observation; loop on those now:
        # likelihoods = np.zeros(stat_obs.shape[0])
        # for i, single_stat_obs in enumerate(stat_obs):
        #     x_new = np.einsum('i,ij,j->', single_stat_obs - mean_sim, robust_precision_sim, single_stat_obs - mean_sim)
        #     likelihoods[i] = np.exp(-0.5 * x_new)
        # do without for loop:
        diff = stat_obs - mean_sim.reshape(1, -1)
        x_news = np.einsum('bi,ij,bj->b', diff, robust_precision_sim, diff)
        logliks = -0.5 * x_news
        logfactor = 0.5 * self.stat_obs.shape[0] * robust_precision_sim_logdet
        return np.sum(logliks) + logfactor  # compute the sum of the different loglikelihoods for each observation

class SemiParametricSynLikelihood(Approx_likelihood):

    def __init__(self, statistics_calc, bw_method_marginals="silverman"):
        """
        This class implements the approximate likelihood function which computes the approximate
        likelihood using the semiparametric Synthetic Likelihood (semiBSL) approach described in [1]. Specifically, this
        represents the likelihood as a product of univariate marginals and the copula components (exploiting Sklar's
        theorem).
        The marginals are approximated from simulations using a Gaussian KDE, while the copula is assumed to be a Gaussian
        copula, whose parameters are estimated from data as well.

        This does not yet include shrinkage strategies for the correlation matrix.

        [1] An, Z., Nott, D. J., & Drovandi, C. (2020). Robust Bayesian synthetic likelihood via a semi-parametric approach.
        Statistics and Computing, 30(3), 543-557.

        Parameters
        ----------
        statistics_calc : abcpy.statistics.Statistics
            Statistics extractor object that conforms to the Statistics class.
        bw_method_marginals : str, scalar or callable, optional
            The method used to calculate the estimator bandwidth, passed to `scipy.stats.gaussian_kde`. Following the docs
            of that method, this can be 'scott', 'silverman', a scalar constant or a callable. If a scalar, this will be
            used directly as `kde.factor`. If a callable, it should take a `gaussian_kde` instance as only parameter
            and return a scalar. If None (default), 'silverman' is used. See the Notes in `scipy.stats.gaussian_kde`
            for more details.
        """
        super(SemiParametricSynLikelihood, self).__init__(statistics_calc)
        # create a dict in which store the denominator of the correlation matrix for the different n values;
        # this saves from repeating computations:
        self.corr_matrix_denominator = {}
        self.bw_method_marginals = bw_method_marginals  # the bw method to use in the gaussian_kde

    def loglikelihood(self, y_obs, y_sim):
        """Computes the loglikelihood. This implementation aims to be equivalent to the `BSL` R package,
        but the results are slightly different due to small differences in the way the KDE is performed

        Parameters
        ----------
        y_obs: Python list
            Observed data set.
        y_sim: Python list
            Simulated data set from model at the parameter value.

        Returns
        -------
        float
            Computed approximate loglikelihood.
        """

        stat_obs, stat_sim = self._calculate_summary_stat(y_obs, y_sim)
        n_obs, d = stat_obs.shape
        if d < 2:
            raise RuntimeError("The dimension of the statistics need to be at least 2 in order to apply semiBSL.")

        # first: estimate the marginal KDEs for each coordinate
        logpdf_obs = np.zeros_like(stat_obs)  # this will contain the estimated pdf at the various observation points
        u_obs = np.zeros_like(stat_obs)  # this instead will contain the transformed u's using the estimated CDF
        for j in range(d):
            # estimate the KDE using the data in stat_sim for coordinate j. This leads to slightly different results
            # from the R package implementation due to slightly different way to estimate the factor as well as
            # different way to evaluate the kernel (they use a weird interpolation there).
            kde = gaussian_kde(stat_sim[:, j], bw_method=self.bw_method_marginals)
            logpdf_obs[:, j] = kde.logpdf(stat_obs[:, j])
            for i in range(n_obs):  # loop over the different observations
                u_obs[i, j] = kde.integrate_box_1d(-np.infty, stat_obs[i, j])  # compute the CDF
        etas_obs = norm.ppf(u_obs)

        # second: estimate the correlation matrix for the gaussian copula using gaussian rank correlation
        R_hat = self._estimate_gaussian_correlation(stat_sim)
        R_hat_inv = np.linalg.inv(R_hat)
        R_sign_det, R_inv_logdet = np.linalg.slogdet(R_hat_inv)  # sign not used

        # third: combine the two to compute the loglikelihood;
        # for each observation:
        # logliks = np.zeros(n_obs)
        # for i in range(n_obs):
        #     logliks[i] = np.sum(logpdf_obs[i])  # sum along marginals along dimensions
        #     # add the copula density:
        #     logliks[i] += 0.5 * R_inv_logdet
        #     logliks[i] -= 0.5 * np.einsum("i,ij,j->", etas_obs[i], R_hat_inv - np.eye(d), etas_obs[i])

        # do jointly:
        loglik = np.sum(logpdf_obs)  # sum along marginals along dimensions
        # add the copula density:
        copula_density = -0.5 * np.einsum("bi,ij,bj->b", etas_obs, R_hat_inv - np.eye(d), etas_obs)
        loglik += np.sum(copula_density) + 0.5 * n_obs * R_inv_logdet

        return loglik

    def _estimate_gaussian_correlation(self, x):
        """Estimates the correlation matrix using data in `x` in the way described in [1]. This implementation
        gives the same results as the `BSL` R package.

        Parameters
        ----------
        x: np.ndarray
            Data set.

        Returns
        -------
        np.ndarray
            Estimated correlation matrix for the gaussian copula.
        """
        n, d = x.shape
        r = np.zeros_like(x)
        for j in range(d):
            r[:, j] = rankdata(x[:, j])

        rqnorm = norm.ppf(r / (n + 1))

        if n not in self.corr_matrix_denominator.keys():
            # compute the denominator:
            self.corr_matrix_denominator[n] = np.sum(norm.ppf((np.arange(n) + 1) / (n + 1)) ** 2)
        denominator = self.corr_matrix_denominator[n]

        R_hat = np.einsum('ki,kj->ij', rqnorm, rqnorm) / denominator

        return R_hat

class PenLogReg(Approx_likelihood, GraphTools):

    def __init__(self, statistics_calc, model, n_simulate, n_folds=10, max_iter=100000, seed=None):
        """This class implements the approximate likelihood function which computes the approximate
        likelihood up to a constant using penalized logistic regression described in
        Dutta et. al. [1]. It takes one additional function handler defining the
        true model and two additional parameters n_folds and n_simulate correspondingly defining number
        of folds used to estimate prediction error using cross-validation and the number
        of simulated dataset sampled from each parameter to approximate the likelihood
        function. For lasso penalized logistic regression we use glmnet of Friedman et.
        al. [2].

        [1] Thomas, O., Dutta, R., Corander, J., Kaski, S., & Gutmann, M. U. (2020).
        Likelihood-free inference by ratio estimation. Bayesian Analysis.

        [2] Friedman, J., Hastie, T., and Tibshirani, R. (2010). Regularization
        paths for generalized linear models via coordinate descent. Journal of Statistical
        Software, 33(1), 1–22.

        Parameters
        ----------
        statistics_calc : abcpy.statistics.Statistics
            Statistics extractor object that conforms to the Statistics class.
        model : abcpy.models.Model
            Model object that conforms to the Model class.
        n_simulate : int
            Number of data points to simulate for the reference data set; this has to be the same as n_samples_per_param
            when calling the sampler. The reference data set is generated by drawing parameters from the prior and
            samples from the model when PenLogReg is instantiated.
        n_folds: int, optional
            Number of folds for cross-validation. The default value is 10.
        max_iter: int, optional
            Maximum passes over the data. The default is 100000.
        seed: int, optional
            Seed for the random number generator. The used glmnet solver is not
            deterministic, this seed is used for determining the cv folds. The default value is
            None.
        """

        super(PenLogReg, self).__init__(statistics_calc)  # call the super init to initialize correctly

        self.model = model
        self.n_folds = n_folds
        self.n_simulate = n_simulate
        self.seed = seed
        self.rng = np.random.RandomState(seed)
        self.max_iter = max_iter
        # Simulate reference data and extract summary statistics from the reference data
        self.ref_data_stat = self._simulate_ref_data(rng=self.rng)[0]

    def loglikelihood(self, y_obs, y_sim):
        """Computes the loglikelihood.

        Parameters
        ----------
        y_obs: Python list
            Observed data set.
        y_sim: Python list
            Simulated data set from model at the parameter value.

        Returns
        -------
        float
            Computed approximate loglikelihood.
        """
        stat_obs, stat_sim = self._calculate_summary_stat(y_obs, y_sim)

        if not stat_sim.shape[0] == self.n_simulate:
            raise RuntimeError("The number of samples in the reference data set is not the same as the number of "
                               "samples in the generated data. Please check that `n_samples` in the `sample()` method"
                               "for the sampler is equal to `n_simulate` in PenLogReg.")

        # Compute the approximate likelihood for the y_obs given theta
        y = np.append(np.zeros(self.n_simulate), np.ones(self.n_simulate))
        X = np.array(np.concatenate((stat_sim, self.ref_data_stat), axis=0))
        # define here groups for cross-validation:
        groups = np.repeat(np.arange(self.n_folds), np.int(np.ceil(self.n_simulate / self.n_folds)))
        groups = groups[:self.n_simulate].tolist()
        groups += groups  # duplicate it as groups need to be defined for both datasets
        m = LogitNet(alpha=1, n_splits=self.n_folds, max_iter=self.max_iter, random_state=self.seed, scoring="log_loss")
        m = m.fit(X, y, groups=groups)
        result = -np.sum((m.intercept_ + np.sum(np.multiply(m.coef_, stat_obs), axis=1)), axis=0)

        return result

    def _simulate_ref_data(self, rng=np.random.RandomState()):
        """
        Simulate the reference data set. This code is run at the initialization of
        Penlogreg

        Parameters
        ----------
        rng: Random number generator, optional
            Defines the random number generator to be used. If None, a newly initialized one is used

        Returns
        -------
        list
            The simulated list of datasets.

        """

        ref_data_stat = [[None] * self.n_simulate for i in range(len(self.model))]
        self.sample_from_prior(rng=rng)
        for model_index, model in enumerate(self.model):
            ind = 0
            while ref_data_stat[model_index][-1] is None:
                data = model.forward_simulate(model.get_input_values(), 1, rng=rng)
                # this is wrong, it applies the computation of the statistic independently to the element of data[0]:
                # print("data[0]", data[0].tolist())
                # data_stat = self.statistics_calc.statistics(data[0].tolist())
                # print("stat of data[0]", data_stat)
                # print("data", data)
                data_stat = self.statistics_calc.statistics(data)
                # print("stat of data", data_stat)
                ref_data_stat[model_index][ind] = data_stat
                ind += 1
            ref_data_stat[model_index] = np.squeeze(np.asarray(ref_data_stat[model_index]))
        return ref_data_stat


import pytest

from iolanta.models import Space
from iolanta.exceptions import MissingVertex, MissingEdge

def test_create_vertex_id():
    assert Space().add_vertex('Kitty').id is not None

def test_create_vertex_name():
    assert Space().add_vertex('Kitty').name == 'Kitty'

def test_create_edge():
    trek = Space()
    captain = trek.add_vertex('Captain')
    kirk = trek.add_vertex('James Kirk')

    rank = trek.add_edge(kirk, captain, 'has_rank')

    assert rank.start == kirk
    assert rank.end == captain
    assert rank.name == 'has_rank'
    assert rank.id is not None

def test_find_vertex_by_id():
    trek = Space()
    kirk = trek.add_vertex(name='James T. Kirk')
    assert trek.vertex_by_id(kirk.id) == kirk

def test_find_edge_by_id():
    trek = Space()
    kirk = trek.add_vertex(name='James T. Kirk')
    captain = trek.add_vertex('Captain')
    rank = trek.add_edge(kirk, captain, 'has_rank')
    assert trek.edge_by_id(rank.id) == rank

def test_missing_vertex():
    with pytest.raises(MissingVertex):
        Space().vertex_by_id('abc')

def test_missing_edge():
    with pytest.raises(MissingEdge):
        Space().edge_by_id('abc')

def test_adjacent_edges():
    trek = Space()
    captain = trek.add_vertex('Captain')

    kirk = trek.add_vertex(name='James T. Kirk')
    pike = trek.add_vertex(name='Christopher Pike')

    edges = set()
    for person in [kirk, pike]:
        edges.add(trek.add_edge(person, captain, 'has_rank'))

    assert trek.adjacent_edges(captain) == edges

def test_remove_edge():
    trek = Space()
    captain = trek.add_vertex('Captain')
    kirk = trek.add_vertex(name='James T. Kirk')
    rank = trek.add_edge(kirk, captain, 'has_rank')

    trek.remove_edge(rank.id)

    with pytest.raises(MissingEdge):
        trek.edge_by_id(rank.id)

def test_remove_vertex():
    trek = Space()
    captain = trek.add_vertex('Captain')

    kirk = trek.add_vertex(name='James T. Kirk')
    pike = trek.add_vertex(name='Christopher Pike')

    edges = []
    for person in [kirk, pike]:
        edges.append(trek.add_edge(person, captain, 'has_rank'))

    trek.remove_vertex(captain.id)

    for edge in edges:
        with pytest.raises(MissingEdge):
            trek.edge_by_id(edge.id)

    assert trek.vertex_by_id(kirk.id) == kirk
    assert trek.vertex_by_id(pike.id) == pike


import socket
import threading
from threading import Thread
import atexit
from os import listdir
from os import stat
from os.path import isfile, join
import time
SERVER_PORT = 9016

def exit_handler():
    s.close()

def split_bin(dat, mark):
    result = []
    current = ''
    for i in range(len(dat)//1024):
        block = dat[i*1024:min((i+1)*1024, len(dat))]
        current += block
        while 1:
            markerpos = current.find(mark)
            if markerpos == -1:
                break
            result.append(current[:markerpos])
            current = current[markerpos + len(mark):]
    result.append(current)
    return result

class s_thread(Thread):
    """
    Extends Thread class
    One thread for each connecected client
    """
    def __init__(self, client_id, sock, c, addr, clients, *args, **kwargs):
        self.client_id = client_id
        self.sock = sock
        self.c = c
        self.addr = addr
        self.clients = clients
        super(s_thread, self).__init__(*args, **kwargs)
        self._stop_event = threading.Event()

    def stop(self):
        self._stop_event.set()

    def stopped(self):
        return self._stop_event.is_set()

    def run(self):
        while True:
            rd = c.recv(5000)
            try:
                if rd[:len("POST /file_upload_parser HTTP/1.1")] == b"POST /file_upload_parser HTTP/1.1": raise UnicodeError
                rd = rd.decode()
                break
            except UnicodeError:
                # case upload
                if rd[:len("POST /file_upload_parser HTTP/1.1")] == b"POST /file_upload_parser HTTP/1.1":
                    boundary = rd.split(b'; boundary=', 1)[1].split(b'\r\n')[0]
                    tmp = rd.split(boundary, 3)
                    # For large files: fo buffering and check for boundary
                    if len(tmp) < 4:
                        buf = c.recv(100000)
                        rd += buf
                        tmp = rd.split(boundary, 3)
                        while len(tmp) < 4:
                            buf = c.recv(100000)
                            rd += buf
                            tmp = rd.split(boundary, 3)
                    tmp1 = tmp[2].split(b'filename="', 1)[1]
                    tmp2 = tmp1.split(b'"\r\n', 1)
                    fl_name = tmp2[0].decode('utf-8')
                    cont = tmp2[1].split(b'\r\n\r\n', 1)[1][:-4]
                    with open(join("public", "data", fl_name), "wb") as f:
                        f.write(cont)
                    # send success
                    data = "HTTP/1.1 201 OK\r\n"
                    data += "Content-Type: text/html; charset=utf-8\r\n"
                    data += "Location: /\r\n"
                    data += "\r\n"
                    data += "
 Upload completed Succesfully!
"
                    data += "\r\n\r\n"
                    c.sendall(data.encode())
                    c.shutdown(socket.SHUT_WR)
                    print('New file uploaded and connection closed: ', addr, 'Client ID: ', c_id)
                    return None
                continue
        print('New data: ', rd[:50], ['...', ''][len(rd)<50])
        pieces = rd.split("\n")
        print('New connection: ', addr, 'Client ID: ', c_id)
        if len(pieces) > 0:
            print('client: ', pieces[0][:50], ['...', ''][len(pieces[0][:50])<50], '\n')
            if pieces[0][:len("GET / HTTP/1.1\r")] == "GET / HTTP/1.1\r":
                data = "HTTP/1.1 200 OK\r\n"
                data += "Content-Type: text/html; charset=utf-8\r\n"
                data += "\r\n"
                with open("public/index1.html", "r") as f:
                    data += "".join(f.readlines())
                dfiles = [f for f in listdir(join("public", "data")) if isfile(join("public", "data", f))]
                dfiles.sort()
                for i in dfiles:
                    url = "file/" + i
                    data += "
" + i + ""
                    if stat(join("public", "data", i)).st_size < 1024:
                        data += " (" + str(stat(join("public", "data", i)).st_size) + " Bytes, "
                    elif stat(join("public", "data", i)).st_size < 1024 * 1024:
                        data += " (" + str(stat(join("public", "data", i)).st_size//1024) + " KB, "
                    else:
                        data += " (" + str(stat(join("public", "data", i)).st_size//1048576) + " MB, "
                    data += "Last modified: " + str(time.strftime('%H:%M:%S %d-%m-%Y', time.localtime(stat(join("public", "data", i)).st_mtime))) + " ) "
                    data += "<input class=\"btn btn-default\" type=\"button\" value=\"Download\" " \
                            "onclick=\"window.open('" + url + "', '_blank');\"> "
                    data += "
"
                with open("public/index2.html", "r") as f:
                    data += "".join(f.readlines())
                data += "\r\n\r\n"
                c.sendall(data.encode())
            elif pieces[0][:len("GET /style.css HTTP/1.1\r")] == "GET /style.css HTTP/1.1\r":
                data = "HTTP/1.1 200 OK\r\n"
                data += "Content-Type: text/css; charset=utf-8\r\n"
                data += "\r\n"
                with open("public/style.css", "r") as f:
                    data += "".join(f.readlines())
                data += "\r\n\r\n"
                c.sendall(data.encode())
            elif pieces[0][:10] == "GET /file/file_name"[:10]:
                data = b"HTTP/1.1 200 OK\r\n"
                data += b"Content-Type: application/octet-stream;\r\n"
                data += b"\r\n"
                fname = pieces[0][10:].split(' HTTP/1.1', 1)[0]
                try:
                    with open(join("public", "data", fname), "rb") as f:
                        data += f.read()
                except FileNotFoundError:
                    print('Error from client: File not found on server')
                data += b""
                c.sendall(data)
        c.shutdown(socket.SHUT_WR)
        print('connection closed: ', addr, 'Client ID: ', c_id)

if __name__ == '__main__':
    atexit.register(exit_handler)
    host = '0.0.0.0'
    port = SERVER_PORT
    clients = {}
    c_id = 1
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.bind((host, port))
    s.listen(5)
    print('Server Started on port ' + str(SERVER_PORT) + '\n(use ifconfig to find IP of this machine. And use http not https)')
    while True:
        c, addr = s.accept()
        rcv_thread = s_thread(client_id=c_id, sock=s, c=c, addr=addr, clients=clients)
        clients[c_id] = rcv_thread
        rcv_thread.start()
        c_id += 1


import argparse

def unpack(xlf_path, src_lang, tgt_lang):
    """ Parses the weirdly formatted RAPID corpus into an actually useful format """

    # Parse
    src_lines = list()
    tgt_lines = list()
    with open(xlf_path, 'r', encoding='utf8') as in_f:
        for line in in_f:
            if line.startswith('<source') or line.startswith('<target'):
                line = line.replace('<', '|').replace('>', '|')
                segments = [seg.strip() for seg in line.split('|') if len(seg.strip()) > 0]
                if "lang=\"{:s}\"".format(src_lang) in segments[0]:
                    src_lines.append(segments[1])
                if "lang=\"{:s}\"".format(tgt_lang) in segments[0]:
                    tgt_lines.append(segments[1])

    assert len(src_lines) == len(tgt_lines), 'Source and target sentences differ in number!'

    # Write
    src_path = '.'.join(xlf_path.split('.')[:-1]) + '.{:s}'.format(src_lang)
    tgt_path = '.'.join(xlf_path.split('.')[:-1]) + '.{:s}'.format(tgt_lang)

    print('-' * 20)
    with open(src_path, 'w', encoding='utf8') as src_f:
        for line_id, line in enumerate(src_lines):
            src_f.write(line)
            if line_id < len(src_lines) - 1:
                src_f.write('\n')
    print('Wrote {:d} source lines to {:s}'.format(line_id + 1, src_path))

    with open(tgt_path, 'w', encoding='utf8') as tgt_f:
        for line_id, line in enumerate(tgt_lines):
            tgt_f.write(line)
            if line_id < len(tgt_lines) - 1:
                tgt_f.write('\n')
    print('Wrote {:d} target lines to {:s}'.format(line_id + 1, tgt_path))

if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument('--xlf_path', type=str, required=True,
                        help='path to the .xlf file containing the corpus')
    parser.add_argument('--src_lang', type=str, required=True,
                        help='source language ID')
    parser.add_argument('--tgt_lang', type=str, required=True,
                        help='target language ID')
    args = parser.parse_args()

    unpack(args.xlf_path, args.src_lang, args.tgt_lang)


import socket
from threading import Thread
import os

BUFFER_SIZE = 1024

class ClientThread(Thread):

    def __init__(self,addr,sock, data):
        Thread.__init__(self)
        self.data = data.decode("ascii")
        self.addr = addr
        self.sock = sock
        print ("New client connected: " + self.addr[0] + ":" + str(self.addr[1]))

    def run(self):
        filename = "./File/" + self.data
        if (os.path.isfile(filename)):
            with open(filename, "rb") as f:
                while True:
                    bytesToSend = f.read(BUFFER_SIZE)
                    if bytesToSend:
                        self.sock.sendto(bytesToSend, self.addr)
                    else:
                        self.sock.sendto(b"", self.addr)
                        break
        else:
            print("ERR.")
            self.sock.sendto("ERR".encode(), self.addr)


import json

from django.contrib.auth.models import User
from rest_framework import status
from rest_framework.generics import ListAPIView, ListCreateAPIView, DestroyAPIView
from rest_framework.response import Response
from datetime import datetime
import pytz
from rest_framework.views import APIView
from bookmeeting.api.public import week_range
from .api_serializer import MeetingRoomSerializer, UserSerializer, BookingInfoSerializer
from bookmeeting.models import MeetingRoom, BookingInfo
import logging
from django.db import transaction

logger = logging.getLogger('book-meeting')

class MeetRoomView(ListAPIView):
    serializer_class = MeetingRoomSerializer
    queryset = MeetingRoom.objects.all()

class UserListView(ListAPIView):
    serializer_class = UserSerializer
    queryset = User.objects.exclude(username__in=['admin', 'oamanager'])

class BookView(ListCreateAPIView, DestroyAPIView):
    serializer_class = BookingInfoSerializer

    def get_queryset(self):
        queryset = BookingInfo.objects.all()
        return queryset

    def perform_create(self, serializer):
        # 保存外键表的方法
        serializer.save(meeting_room=MeetingRoom.objects.get(name=self.request.data.get('meeting_room')))

    def get(self, request, *args, **kwargs):
        return self.list(request, *args, **kwargs)

    def post(self, request, *args, **kwargs):
        # TODO 预定的时候会出现覆盖的情况，目前没想好怎么处理
        today = datetime.today()
        wek = week_range(today)
        # 只允许预定本周的会议室
        st, ed = wek[0].strftime('%Y-%m-%d 00:00:00'), wek[1].strftime('%Y-%m-%d 23:59:59')

        request_data = request.data
        start_time = request_data.get('start_time')
        end_time = request_data.get('end_time')
        book_user = request_data.get('user')
        location = request_data.get('meeting_room')
        subject = request_data.get('subject')
        members = request_data.get('member')

        # 回滚操作
        # def __rollback(id):
        #     d = BookingInfo.objects.get(id=id)
        #     d.delete()

        # invitation = request_data.get('invitation') 必须邀请
        if start_time < st or start_time > ed or end_time < st or end_time > ed:
            return Response({
                'message': '只允许预定本周的会议室',
                'status': 901
            })

        save = self.create(request, *args, **kwargs)
        if save.status_code == 201:
            logger.debug('meeting room book success, now send invitation to members.')
            from bookmeeting.api.mail import send_invitation
            logger.debug('request data: {}'.format(request_data))
            for you in members.split(';'):
                if len(you) == 0: continue
                logger.debug('send invitation info: {}'.format(
                    json.dumps({
                        'you': you, 'book_user': book_user, 'subject': subject, 'start_time': start_time,
                        'end_time': end_time,
                        'member': members, 'meeting_room': location
                    }, indent=4)))
                try:
                    send_invitation(you, book_user, subject, start_time, end_time, members, location)
                except Exception as e:
                    save_id = save.data.get('id')
                    logger.error('send invitation error, book success, error:{}'.format(e))
                    logger.error('rollback database id: {}'.format(save_id))
                    return Response({
                        'message': '预定成功，邮件失败',
                        'status': 209
                    })
        return save

    def delete(self, request, *args, **kwargs):
        request_data = request.data
        id = request_data.get('id', None)
        book_user = request_data.get('bookUser', None)
        if id:
            b = BookingInfo.objects.get(id=id)
            if b.user != book_user:
                return Response({
                    'message': '您无权删除他人的预定',
                    'status': 900
                })
            else:
                b.delete()
                return Response({
                    'message': '取消预定成功',
                    'status': status.HTTP_204_NO_CONTENT
                })

class BookCollectionView(APIView):
    serializer_class = BookingInfoSerializer

    @property
    def time_deadline(self):
        today = datetime.today()
        end = {
            'start': '08:00:00',
            'forenoon': '12:00:00',
            'afternoon': '18:00:00',
            'evening': '23:59:59'
        }
        today_fmt = '{}-{}-{}'.format(today.year, today.month, today.day)
        return {
            'start': datetime.strptime('{} {}'.format(today_fmt, end.get('start')), "%Y-%m-%d %H:%M:%S").replace(
                tzinfo=pytz.timezone('Asia/Shanghai')),

            'forenoon': datetime.strptime('{} {}'.format(today_fmt, end.get('forenoon')), "%Y-%m-%d %H:%M:%S").replace(
                tzinfo=pytz.timezone('Asia/Shanghai')),

            'afternoon': datetime.strptime('{} {}'.format(today_fmt, end.get('afternoon')),
                                           "%Y-%m-%d %H:%M:%S").replace(
                tzinfo=pytz.timezone('Asia/Shanghai')),

            'evening': datetime.strptime('{} {}'.format(today_fmt, end.get('evening')), "%Y-%m-%d %H:%M:%S").replace(
                tzinfo=pytz.timezone('Asia/Shanghai')),
        }

    @staticmethod
    def fmt(minutes):
        hour = int(minutes / 60)
        minutes = int(minutes % 60)
        return '{}小时{}分'.format(hour, minutes)

    def get(self, request):
        meeting_room = request.GET.get('meetingroom', None)
        if not meeting_room:
            return Response({
                'error': 'meetingroom arguments miss.'
            })
        forenoon = BookingInfo.objects.filter(start_time__gte=self.time_deadline.get('start'),
                                              end_time__lte=self.time_deadline.get('forenoon'),
                                              meeting_room__name=meeting_room)
        afternoon = BookingInfo.objects.filter(start_time__gte=self.time_deadline.get('forenoon'),
                                               end_time__lte=self.time_deadline.get('afternoon'),
                                               meeting_room__name=meeting_room)
        evening = BookingInfo.objects.filter(start_time__gte=self.time_deadline.get('afternoon'),
                                             end_time__lte=self.time_deadline.get('evening'),
                                             meeting_room__name=meeting_room)
        forenoon_book, afternoon_book, evening_book = 0, 0, 0
        for f in forenoon: forenoon_book += f.duration
        for a in afternoon: afternoon_book += a.duration
        for e in evening: evening_book += e.duration

        response = Response({
            'forenoon_book': self.fmt(forenoon_book),
            'forenoon_rest': self.fmt(240 - forenoon_book),
            'afternoon_book': self.fmt(afternoon_book),
            'afternoon_rest': self.fmt(360 - afternoon_book),
            'evening_book': self.fmt(evening_book),
            'evening_rest': self.fmt(360 - evening_book)
        })
        return response


from transformers import AdapterTrainer, TrainingArguments
from transformers import AutoModelForCausalLM, GPT2Tokenizer

import os
import json
import logging
import argparse
from datasets import Dataset
from datasets import load_dataset
import datasets
import transformers
print(datasets.__version__)
print(transformers.__version__)

import torch
print(torch.cuda.is_available())
print(torch.cuda.device_count())
print(torch.cuda.current_device())
print(torch.cuda.device(0))
print(torch.cuda.get_device_name(0))

logging.basicConfig(filename=os.path.splitext(
    os.path.basename(__file__))[0]+'.log', level=logging.INFO)

parser = argparse.ArgumentParser(
    description='tool for training adapters for project_cc')

parser.add_argument('-path_to_processed', type=str,
                    default='/netscratch/fonseca/project_cc/datasets/processed/emotions_ds.json', help='path to processed dataset')
parser.add_argument('-mood', type=str, choices=['happy', 'surprised', 'sad', 'angry', 'neutral'],
                    help="""list of possible moods.
                    ACHTUNG: If you select more than one they'll be trained sequentially""")
parser.add_argument('--out_dir', type=str, default=os.path.dirname(__file__),
                    help='Path to output file ')

args = parser.parse_args()

path_to_processed = args.path_to_processed
mood = args.mood
out_path = args.out_dir + (mood)

def jsonl_generator(shards):
    for shard in shards:
        with open(shard) as json_obj:
            for line in json_obj.readlines():
                yield json.loads(line)

def emotions_generator():
    with open(path_to_processed) as json_obj:
        for line in json_obj.readlines():
            yield json.loads(line)

# jsonl_paths = []
# for root, dir, files in os.walk(path_to_processed):
#     for file in files:
#         jsonl_paths.append(os.path.join(root, file))

def add_special_tokens_(model, tokenizer):
    """ Add special tokens to the tokenizer and the model if they have not already been added. """
    orig_num_tokens = len(tokenizer.encoder)
    num_added_tokens = tokenizer.add_special_tokens(
        ATTR_TO_SPECIAL_TOKEN)  # doesn't add if they are already there

    model.resize_token_embeddings(len(tokenizer))
    # if num_added_tokens - orig_num_tokens > 0:
    #     print("resizing my tokens embeddings")

# Dataset processing for training and trainig functions
# Source:
# https://colab.research.google.com/github/Adapter-Hub/adapter-transformers/blob/master/notebooks/06_Text_Generation.ipynb#scrollTo=ioLpFbOfnPE6
# https://adapterhub.ml/blog/2021/04/adapters-for-generative-and-seq2seq-models-in-nlp/

# Tokenize the entries in the dataset

def encode_batch(batch):
    """Encodes a batch of input data using the model tokenizer."""
    encoding = tokenizer(batch["text"], truncation=True, max_length=1024)
    # encoding = tokenizer(batch["text"])
    # For language modeling the labels need to be the input_ids
    # encoding["labels"] = encoding["input_ids"]
    return encoding

# Main data processing function that will concatenate all texts from our dataset and generate chunks of block_size.
def group_texts(examples):
    # Concatenate all texts.
    concatenated_examples = {k: sum(examples[k], []) for k in examples.keys()}
    total_length = len(concatenated_examples[list(examples.keys())[0]])
    # We drop the small remainder, we could add padding if the model supported it instead of this drop, you can
    # customize this part to your needs.
    total_length = (total_length // block_size) * block_size
    # Split by chunks of max_len.
    result = {
        k: [t[i: i + block_size] for i in range(0, total_length, block_size)]
        for k, t in concatenated_examples.items()
    }
    result["labels"] = result["input_ids"].copy()
    return result

# for line in jsonl_generator(jsonl_paths):
    # for k, v in line.items():
    #     if type(v) == float:
    #         logging.info('nan lines:\n{} : {}'.format(k, v))

print(path_to_processed)
moody_dataset = Dataset.from_generator(emotions_generator)
# moody_dataset = load_dataset('json',data_files=path_to_processed, split=['train','test'])
# print(type(moody_dataset))

cur_ds = moody_dataset.filter(
    lambda example: example["EmotionTag"] == mood)
print(cur_ds.column_names)

cur_ds = cur_ds.train_test_split(test_size=0.2)

del moody_dataset

print('Loading pre_trained gpt2 tokenizer')
tokenizer = GPT2Tokenizer.from_pretrained("gpt2")
print("tokenizer len: {}".format(len(tokenizer)))
# The GPT-2 tokenizer does not have a padding token. In order to process the data
# in batches we set one here
# tokenizer.pad_token = tokenizer.eos_token

SPECIAL_TOKENS = ["<bos>", "<eos>", "<speaker1>", "<speaker2>", "<pad>"]
ATTR_TO_SPECIAL_TOKEN = {'bos_token': '<bos>', 'eos_token': '<eos>', 'pad_token': '<pad>',
                         'additional_special_tokens': ['<speaker1>', '<speaker2>']}
tokenizer.add_special_tokens(ATTR_TO_SPECIAL_TOKEN)
print("tokenizer len: {}".format(len(tokenizer)))
print('set pad token')
column_names = cur_ds["train"].column_names

dataset = cur_ds.map(encode_batch, remove_columns=column_names, batched=True)

# reate chunks with a length of block_size.
print('Creating chunks')
block_size = 50
dataset = dataset.map(group_texts, batched=True,)

dataset.set_format(type="torch", columns=[
                   "input_ids", "attention_mask", "labels"])

print(len(dataset['test'][0]['input_ids']))
###############################################################

# config = AutoConfig.from_json_file("./model/config.json")
model = AutoModelForCausalLM.from_pretrained("/netscratch/fonseca/project_cc/model")
a = model.config
print(a)
add_special_tokens_(model, tokenizer)
b = model.config
print(b)
assert a == b
# add new adapter
model.add_adapter(mood)
# activate adapter for training
model.train_adapter(mood)

##############################################################
training_args = TrainingArguments(
    output_dir="./examples",
    do_train=True,
    remove_unused_columns=False,
    learning_rate=5e-4,
    num_train_epochs=15,
)

trainer = AdapterTrainer(
    model=model,
    args=training_args,
    tokenizer=tokenizer,
    train_dataset=dataset["train"],
    eval_dataset=dataset["test"],
)
try:
    trainer.train()
except:
    # print("didn't train")
    logging.WARNING('Did not train')

model.save_adapter("adapter_"+mood, mood)


from rest_framework import viewsets, exceptions
from biohub.forum.serializers.post_serializers import PostSerializer
from biohub.utils.rest import pagination, permissions
from biohub.forum.models import Post

class PostViewSet(viewsets.ModelViewSet):
    serializer_class = PostSerializer
    pagination_class = pagination.factory('PageNumberPagination', page_size=10)
    permission_classes = [permissions.C(permissions.IsAuthenticatedOrReadOnly) &
                          permissions.check_owner('author', ('PATCH', 'PUT', 'DELETE'))]

    # override this function to provide "request" as "None"
    def get_serializer_context(self):
        """
        Extra context provided to the serializer class.
        """
        return {
            'request': None,
            'format': self.format_kwarg,
            'view': self
        }

    def get_queryset(self):
        author = self.request.query_params.get('author', None)

        if author is not None:
            queryset = Post.objects.filter(author__username=author)
            if self.request.user.username != author:
                queryset = queryset.filter(is_visible=True)
        else:
            queryset = Post.objects.filter(is_visible=True)

        if 'experience_id' in self.kwargs:
            queryset = queryset.filter(experience__id=self.kwargs['experience_id'])

        return queryset

    def perform_create(self, serializer):
        serializer.save(author=self.request.user)

    def create(self, request, *args, **kwargs):
        from biohub.core.conf import settings as biohub_settings
        from datetime import timedelta
        from django.utils.timezone import now

        user = self.request.user
        if Post.objects.filter(
            author=user,
            pub_time__gte=now() - timedelta(seconds=biohub_settings.THROTTLE['post'])
        ).exists():
            raise exceptions.Throttled()

        return super(PostViewSet, self).create(request, *args, **kwargs)


# Manish Balakrishnan
# EE551 Final Project

# MNIST Digit Hand Classifier

# Please refer to github and Readme for background on project and how to run properly.

# ********************** Libraries used ***********************************
import tensorflow as tf
from keras.models import load_model
import matplotlib.pyplot as plt
import random
import os
# ********************** Libraries used ***********************************

def test():
    nmodel = load_model("model.h5")

    # Outputting a summary of the model detailing various layers.

    nmodel.summary()

    # Loading the dataset into various portions and then randomly taking an image from the datset and storing it in list
    # to test

    (x_train, y_train), (x_test, y_test) = tf.keras.datasets.mnist.load_data()
    my_randoms = random.sample(range(x_test.shape[0]), 9)
    print(my_randoms)

    # Keeping track of which values were classified correctly/incorrectly

    correct = []
    wrong = []

    # Plotting the randomly selected images in a 3x3 matrix and displaying the predicted value
    # If the predicted value matches the actual value it is appended to the appropriate list

    fig, axis = plt.subplots(3, 3, figsize=(32, 32))
    for i, ax in enumerate(axis.flat):
        ax.imshow(x_test[my_randoms[i]], cmap='Greys')
        pred = nmodel.predict(x_test[my_randoms[i]].reshape(1, 28, 28, 1))
        val = pred.argmax()
        ax.set(title="\n\nPredicted value= {}".format(val) )
        actual = y_test[my_randoms[i]]
        # print(actual)

        if (val == actual):
            correct.append(val)
        else:
            wrong.append(val)

    print(len(correct),'/9 images shown have been classified correctly.')

    plt.show()

if __name__ == '__main__':

    print("\nWelcome to testDigits.py. The digit classifier model will be tested against randomly selected")
    print("images and compared with the known values.\n\n")
    input("Press any key to continue.")

    # checks if a model.h5 file is present.

    if os.path.isfile('model.h5'):
        test()

    else:
        print("Trained Model not found!")
        print("Run classifier.py or download model.h5 from repository and place in current directory.")


import json
import logging
from util import rest_client

logger = logging.getLogger("grafeas.auth_util")

class Subject(object):
    def __init__(self, kind, id, account_id, email=None):
        self.kind = kind
        self.id = id
        self.account_id = account_id
        self.email = email

    def __str__(self):
        return "{{kind:{}, id:{}, account:{}, email:{}}}".format(self.kind, self.id, self.account_id, self.email)

    def to_dict(self):
        return {
            'kind': self.kind,
            'id': self.id,
            'account_id': self.account_id,
            'email': self.email
        }

def get_subject(decoded_auth_token):
    if 'sub_type' not in decoded_auth_token:
        kind = 'user'
    else:
        sub_type = decoded_auth_token['sub_type']
        if sub_type == 'ServiceId':
            kind = 'service-id'
        else:
            raise ValueError("Invalid IAM token: unsupported '{}' subject type".format(sub_type))

    iam_id = decoded_auth_token.get('iam_id')
    if iam_id is None:
        raise ValueError("Invalid IAM token: missing 'iam_id' field")

    account = decoded_auth_token.get('account')
    if not account:
        raise ValueError("Invalid IAM token: missing 'account' field")

    account_id = account.get('bss')
    if not account_id:
        raise ValueError("Invalid IAM token: missing 'account.bss' field")

    email = decoded_auth_token.get('email')
    # email could be missing. For example, in subjects of 'service-id' kind

    return Subject(kind, iam_id, account_id, email)

def get_identity_token(iam_base_url, api_key):
    with rest_client.RestClient() as client:
        client.add_header("Accept", "application/json")
        client.add_header("Content-Type", "application/x-www-form-urlencoded")

        body = {
            "grant_type": "urn:ibm:params:oauth:grant-type:apikey",
            "apikey": api_key
        }

        response = client.post(
            url="{}/identity/token".format(iam_base_url),
            data=body)

        if response.status_code != 200:
            response.raise_for_status()

        content = json.loads(response.content.decode('utf-8'))
        return content['access_token']


"""Module with the classes that manage the authorStats
and paperStats plots.

This file is part of the physbiblio package.
"""
import datetime
import traceback

import matplotlib
import matplotlib.pyplot as plt
import numpy as np
from matplotlib.backends.backend_qtagg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.lines import Line2D
from matplotlib.patches import Rectangle
from PySide6.QtCore import Qt
from PySide6.QtGui import QFont
from PySide6.QtWidgets import QDialog, QGridLayout, QLineEdit, QPushButton

plt.switch_backend("QtAgg")

try:
    from physbiblio.config import pbConfig
    from physbiblio.database import pBDB
    from physbiblio.gui.basicDialogs import askDirName, infoMessage
    from physbiblio.gui.commonClasses import PBDialog, PBLabel
    from physbiblio.gui.errorManager import pBGUILogger
    from physbiblio.inspireStats import pBStats
    from physbiblio.strings.gui import InspireStatsGUIStrings as igstr
except ImportError:
    print("Could not find physbiblio and its modules!")
    print(traceback.format_exc())

figTitles = [
    igstr.paperNumber,
    igstr.paperYear,
    igstr.totalCitations,
    igstr.citationsYear,
    igstr.meanCitations,
    igstr.citationsPaper,
]

class AuthorStatsPlots(PBDialog):
    """Class that constructs a window to show
    the results of `authorStats`
    """

    def __init__(self, figs, title=None, parent=None):
        """Constructor.

        Parameters:
            figs: the list of figures
            title (optional): the window title
            parent (default None): the parent object,
                which should have a property `lastAuthorStats`
        """
        super(AuthorStatsPlots, self).__init__(parent)
        self.figs = figs
        self.canvas = None
        if title is not None:
            self.setWindowTitle(title)
        layout = QGridLayout(self)
        layout.setSpacing(1)
        self.setLayout(layout)
        self.updatePlots()

        nlines = int(len(figs) / 2)
        self.layout().addWidget(PBLabel(igstr.linesMoreInfo), nlines + 1, 0)

        try:
            hIndex = "%d" % self.parent().lastAuthorStats["h"]
        except (TypeError, AttributeError):
            hIndex = igstr.hIndexE
        self.hIndex = PBLabel(igstr.hIndexV % hIndex)
        largerFont = QFont("Times", 15, QFont.Bold)
        self.hIndex.setFont(largerFont)
        self.layout().addWidget(self.hIndex, nlines + 1, 2, 1, 2)

        self.textBox = QLineEdit("")
        self.textBox.setReadOnly(True)
        self.layout().addWidget(self.textBox, nlines + 2, 0, 1, 4)

        self.allcits = np.array(pBStats.allCitations)
        self.layout().addWidget(PBLabel(igstr.yearsForAvgY), nlines + 3, 0)
        defyrs = "3"
        self.yearsBox = QLineEdit(defyrs)
        self.yearsBox.textChanged.connect(self.onUpdateYears)
        self.layout().addWidget(self.yearsBox, nlines + 3, 1)
        self.layout().addWidget(PBLabel(igstr.yearsForAvgC), nlines + 3, 2)
        self.citperyearBox = QLineEdit("")
        self.citperyearBox.setReadOnly(True)
        self.layout().addWidget(self.citperyearBox, nlines + 3, 3)

        self.saveButton = QPushButton(igstr.save, self)
        self.saveButton.clicked.connect(self.saveAction)
        self.layout().addWidget(self.saveButton, nlines + 4, 0, 1, 2)

        self.clButton = QPushButton(igstr.close, self)
        self.clButton.clicked.connect(self.onClose)
        self.clButton.setAutoDefault(True)
        self.layout().addWidget(self.clButton, nlines + 4, 2, 1, 2)

        self.onUpdateYears(defyrs)

    def onUpdateYears(self, string):
        """When the number of years is changed,
        update the text reporting
        the average citations per year and total citations
        in the given amount of years

        Parameters:
            string: the new number of years to consider
        """
        try:
            yrs = int(string)
        except ValueError:
            self.citperyearBox.setText(igstr.yearsForAvgI)
            return
        if len(self.allcits) == 0:
            self.citperyearBox.setText(igstr.yearsForAvgT % (0, 0, yrs))
        else:
            today = datetime.datetime.now(self.allcits[0].tzinfo)
            ref = today.replace(year=today.year - yrs)
            tot = len(np.where(self.allcits >= ref)[0])
            self.citperyearBox.setText(igstr.yearsForAvgT % (tot / yrs, tot, yrs))

    def onClose(self):
        """Close dialog"""
        QDialog.close(self)

    def saveAction(self):
        """Save the plot into a file,
        after asking the directory where to save them
        """
        savePath = askDirName(self, igstr.whereSavePlots)
        if savePath != "":
            try:
                self.parent().lastAuthorStats["figs"] = pBStats.plotStats(
                    author=True, save=True, path=savePath
                )
            except AttributeError:
                pBGUILogger.warning("", exc_info=True)
            else:
                infoMessage(igstr.plotsSaved)
                self.saveButton.setDisabled(True)

    def onPress(self, event):
        """Print the plot coordinates where a click was performed.
        To be connected through `mpl_connect`.
        Used for testing.

        Parameter:
            a `matplotlib.backend_bases.Event`
        """
        print(event.xdata, event.ydata)

    def pickEvent(self, event):
        """Save into `self.textBox` the coordinates
        of the clicked object (`Line2D` or `Rectangle`) in the plot.

        Parameter:
            a `matplotlib.backend_bases.Event`
        """
        ob = event.artist
        ix = -1
        for i, f in enumerate(self.figs):
            if f == ob.figure:
                ix = i
        if isinstance(ob, Rectangle):
            self.textBox.setText(
                igstr.xInYearIs % (figTitles[ix], int(ob.get_x()), int(ob.get_height()))
            )
        elif isinstance(ob, Line2D):
            xdata = ob.get_xdata()
            ydata = ob.get_ydata()
            ind = event.ind
            if ix == 4:
                formatString = igstr.xInDateIsF
            else:
                formatString = igstr.xInDateIsD
            self.textBox.setText(
                formatString
                % (
                    figTitles[ix],
                    np.take(xdata, ind)[0].strftime(igstr.datefmt),
                    np.take(ydata, ind)[0],
                )
            )

    def updatePlots(self):
        """Reset the dialog window removing all the previous items
        and create new canvas for the figures.
        """
        i = 0
        while True:
            item = self.layout().takeAt(i)
            if item is None:
                break
            del item
        if hasattr(self, "canvas"):
            del self.canvas
        self.canvas = []
        for fig in self.figs:
            if fig is not None:
                self.canvas.append(FigureCanvas(fig))
                self.layout().addWidget(self.canvas[-1], int(i / 2), (i % 2) * 2, 1, 2)
                self.canvas[-1].mpl_connect("pick_event", self.pickEvent)
                self.canvas[-1].draw()
                i += 1

class PaperStatsPlots(PBDialog):
    """Class that constructs a window
    to show the results of `paperStats`
    """

    def __init__(self, fig, title=None, parent=None):
        """Constructor.
        Defines some properties and buttons

        Parameters:
            fig: the figure to be shown
            title (optional): the window title
            parent (default None): the parent object,
                which should have a property lastPaperStats
        """
        super(PaperStatsPlots, self).__init__(parent)
        self.fig = fig
        self.canvas = None
        if title is not None:
            self.setWindowTitle(title)
        layout = QGridLayout(self)
        layout.setSpacing(1)
        self.setLayout(layout)
        self.updatePlots()

        nlines = 1
        self.layout().addWidget(PBLabel(igstr.lineMoreInfo), nlines + 1, 0)

        self.textBox = QLineEdit("")
        self.textBox.setReadOnly(True)
        self.layout().addWidget(self.textBox, nlines + 2, 0, 1, 2)
        self.saveButton = QPushButton(igstr.save, self)
        self.saveButton.clicked.connect(self.saveAction)
        self.layout().addWidget(self.saveButton, nlines + 3, 0)

        self.clButton = QPushButton(igstr.close, self)
        self.clButton.clicked.connect(self.onClose)
        self.clButton.setAutoDefault(True)
        self.layout().addWidget(self.clButton, nlines + 3, 1)

    def onClose(self):
        """Close dialog"""
        QDialog.close(self)

    def saveAction(self):
        """Save the plot into a file,
        after asking the directory where to save them
        """
        savePath = askDirName(self, igstr.whereSavePlot)
        if savePath != "":
            try:
                self.parent().lastPaperStats["fig"] = pBStats.plotStats(
                    paper=True, save=True, path=savePath
                )
            except AttributeError:
                pBGUILogger.warning("", exc_info=True)
            else:
                infoMessage(igstr.plotSaved)
                self.saveButton.setDisabled(True)

    def pickEvent(self, event):
        """Save into `self.textBox` the coordinates
        of the clicked object (`Line2D`) in the plot.

        Parameter:
            a `matplotlib.backend_bases.Event`
        """
        ob = event.artist
        ix = -1
        if isinstance(ob, Line2D):
            xdata = ob.get_xdata()
            ydata = ob.get_ydata()
            ind = event.ind
            formatString = igstr.xInDateIsD
            self.textBox.setText(
                formatString
                % (
                    igstr.citations,
                    np.take(xdata, ind)[0].strftime(igstr.datefmt),
                    np.take(ydata, ind)[0],
                )
            )

    def updatePlots(self):
        """Reset the dialog window removing all the previous items
        and create a new canvas for the figure.
        """
        i = 0
        while True:
            item = self.layout().takeAt(i)
            if item is None:
                break
            del item
        if hasattr(self, "canvas"):
            del self.canvas
        if self.fig is not None:
            self.canvas = FigureCanvas(self.fig)
            self.layout().addWidget(self.canvas, 0, 0, 1, 2)
            self.canvas.mpl_connect("pick_event", self.pickEvent)
            self.canvas.draw()


K = int(input())
K_list = list() # 돈을 부르는 리스트

for i in range(K):
    M = int(input())

    if M == 0:
        K_list.pop()
    else:
        K_list.append(M)

answer = sum(K_list)

print(answer)


# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.

from taskgraph.util.attributes import (
    match_run_on_git_branches,
    match_run_on_projects,
    match_run_on_tasks_for,
)

_target_task_methods = {}

_GIT_REFS_HEADS_PREFIX = "refs/heads/"

def _target_task(name):
    def wrap(func):
        _target_task_methods[name] = func
        return func

    return wrap

def get_method(method):
    """Get a target_task_method to pass to a TaskGraphGenerator."""
    return _target_task_methods[method]

def filter_out_cron(task, parameters):
    """
    Filter out tasks that run via cron.
    """
    return not task.attributes.get("cron")

def filter_for_project(task, parameters):
    """Filter tasks by project.  Optionally enable nightlies."""
    run_on_projects = set(task.attributes.get("run_on_projects", []))
    return match_run_on_projects(parameters["project"], run_on_projects)

def filter_for_tasks_for(task, parameters):
    run_on_tasks_for = set(task.attributes.get("run_on_tasks_for", ["all"]))
    return match_run_on_tasks_for(parameters["tasks_for"], run_on_tasks_for)

def filter_for_git_branch(task, parameters):
    """Filter tasks by git branch.
    If `run_on_git_branch` is not defined, then task runs on all branches"""
    # We cannot filter out on git branches if we not on a git repository
    if parameters.get("repository_type") != "git":
        return True

    # Pull requests usually have arbitrary names, let's not filter git branches on them.
    if parameters["tasks_for"] == "github-pull-request":
        return True

    run_on_git_branches = set(task.attributes.get("run_on_git_branches", ["all"]))
    git_branch = parameters["head_ref"]
    if git_branch.startswith(_GIT_REFS_HEADS_PREFIX):
        git_branch = git_branch[len(_GIT_REFS_HEADS_PREFIX) :]

    return match_run_on_git_branches(git_branch, run_on_git_branches)

def filter_out_shipping_phase(task, parameters):
    return task.attributes.get("shipping_phase") in (None, "build")

def standard_filter(task, parameters):
    return all(
        filter_func(task, parameters)
        for filter_func in (
            filter_out_cron,
            filter_out_shipping_phase,
            filter_for_project,
            filter_for_tasks_for,
            filter_for_git_branch,
        )
    )

@_target_task("default")
def target_tasks_default(full_task_graph, parameters, graph_config):
    """Target the tasks which have indicated they should be run on this project
    via the `run_on_projects` attributes."""
    return [
        l for l, t in full_task_graph.tasks.items() if standard_filter(t, parameters)
    ]

@_target_task("codereview")
def target_tasks_codereview(full_task_graph, parameters, graph_config):
    """Target the tasks which have indicated they should be run on this project
    via the `run_on_projects` attributes."""
    return [
        l
        for l, t in full_task_graph.tasks.items()
        if standard_filter(t, parameters) and t.attributes.get("code-review")
    ]

@_target_task("nothing")
def target_tasks_nothing(full_task_graph, parameters, graph_config):
    """Select nothing, for DONTBUILD pushes"""
    return []


import json

def read_data(file_path):
    with open(file_path, "r", encoding='utf-8-sig') as f:
        data = json.load(f)
    datas = []

    for item in data['data']:
        if 'topic' in item:
            topic = item['topic']

        sentences = []
        if 'utterance' in item:
            sentence = item['utterance']
        datas.append((sentence, topic))
    return datas

read_data("combined_data.json")


# Understanding Try - Except - Else block

# Sometimes in python, a scenario arises where your program
# might give an error and get crash. eg converting a non-
# integer based string into a integer gives ValueError

a = "10"

try:
    # Code which might give an error
    b = int(a)
    print(b)
except ValueError:    # Error which might be arised
    # Code which should be executed if error arises
    print("a does not contain integer")
# Optionally else block is also there
else:
    # Code to be executed if no error arises
    print("Successfully converted into integer")

# Thank You !!!


unitNames = {
    'Alioni': ['Alioni'],
    'Arden': ['Arden'],
    'Arthur': ['Arthur'],
    'Athena': ['Athena'],
    'Ban': ['Ban'],
    'Beatrice': ['Beatrice'],
    'Bellion': ['Bellion'],
    'Benimaru': ['Benimaru'],
    'Brunhild': ['Brunhild'],
    'Cain': ['Cain'],
    'Camila': ['Camila'],
    'Chandler': ['Chandler'],
    'Cusack': ['Cusack'],
    'Deathpierce': ['Deathpierce'],
    'Deldry': ['Deldry'],
    'Demon King':['Demon_king'],
    'Denzel': ['Denzel'],
    'Derieri': ['Derieri'],
    'Diane': ['Diane'],
    'Dogedo': ['Dogedo'],
    'Dreyfus': ['Dreyfus'],
    'Drole': ['Drole'],
    'Eastin': ['Eastin'],
    'Echidna': ['Echidna'],
    'Elaine': ['Elaine'],
    'Eleven': ['Eleven'],
    'Elizabeth': ['Elizabeth'],
    'ElizabethHawk': ['ElizabethHawk'],
    'Ellatte': ['Ellatte'],
    'Emilia': ['Emilia'],
    'Eren': ['Eren'],
    'Eris':['Eris'],
    'Escanor': ['Escanor'],
    'Estarossa': ['Estarossa'],
    'Filo': ['Filo'],
    'Fraudrin': ['Fraudrin'],
    'Freesia': ['Freesia'],
    'Freya':['Freya'],
    'Freyr': ['Freyr'],
    'Galland': ['Galland'],
    'Gerharde': ['Gerharde'],
    'Ghislaine':['Ghislaine'],
    'Gilthunder': ['Gilthunder'],
    'Gloxinia': ['Gloxinia'],
    'Golgius': ['Golgius'],
    'Gowther': ['Gowther'],
    'Griamore': ['Griamore'],
    'Guila': ['Guila'],
    'Gustaf': ['Gustaf'],
    'Hawk': ['Hawk', 'Hawkslo'],
    'Helbram': ['Helbram'],
    'Hendrickson': ['Hendrickson'],
    'Howzer': ['Howzer'],
    'Hugo': ['Hugo'],
    'Jormungandr': ['Jormungandr'],
    'Jericho': ['Jericho'],
    'Jenna': ['Jenna\d','(?!mave_)jenna\w*'],
    'Jenna (Mave)':['mave_jenna'],
    'Jillian': ['Jillian'],
    'Jim': ['Jim'],
    'Jude': ['Jude'],
    'King': ['(?!demon_)king\w*'],
    'Kizuna':['Kizuna'],
    'Kyo': ['Kyo'],
    'Levi': ['Levi'],
    'Lillia': ['Lillia'],
    'Ludociel': ['Ludociel'],
    'Liz': ['Liz\d'],
    'Mai': ['Mai'],
    'Marmas': ['Marmas'],
    'Matrona': ['Matrona'],
    'Mael':['Mael'],
    'Megellda': ['Megellda'],
    'Melascula': ['Melascula'],
    'Meliodas': ['Meliodas'],
    'Merlin': ['Merlin'],
    'Mikasa': ['Mikasa'],
    'Mike': ['Mike'],
    'Milim': ['Milim'],
    'Mono': ['Mono'],
    'Monspeet': ['Monspeet'],
    'Nanashi': ['Nanashi'],
    'Naofumi': ['Naofumi'],
    'Ram': ['Ram'],
    'Raphtalia': ['Raphtalia'],
    'Reinhard': ['Reinhard'],
    'Rem': ['Rem'],
    'Rimuru': ['Rimuru', 'Slimuru'],
    'Roxy': ['Roxy\d','roxy(?!_migurdia)\w*'],
    'Roxy Migurdia':['Roxy_Migurdia'],
    'Rudeus':['Rudeus'],
    'Rugal': ['Rugal'],
    'Ruin': ['Ruin'],
    'Sariel': ['Sariel'],
    'Shin': ['Shin'],
    'Shuna': ['Shuna'],
    'Simon': ['Simon'],
    'Sigurd': ['Sigurd'],
    'Skadi': ['Skadi'],
    'Slater': ['Slater'],
    'Taizoo': ['Taizoo'],
    'Tarmiel': ['Tarmiel'],
    'Terry': ['Terry'],
    'Tristan': ['Tristan'],
    'Twigo': ['Twigo'],
    'Thonar': ['Thonar'],
    'Tyr':['Tyr'],
    'Valenti': ['Valenti'],
    'Vivian': ['Vivian'],
    'Waillo': ['Waillo'],
    'Weinheidt': ['Weinheidt'],
    'Will': ['Will'],
    'Iori Yagami': ['Yagami'],
    'Zaneri': ['Zaneri'],
    'Zaratras': ['Zaratras'],
    'Zeldris': ['Zeldris']
}
incompatibilities = [
    ['Fraudrin', 'Dreyfus'],
    ['ElizabethHawk', 'Elizabeth', 'Liz'],
    ['ElizabethHawk', 'Hawk'],
    ['Mael','Estarossa'],
    ['Zeldris','Demon King']
]

attributeColors = {
    'Vitality': 'Green',
    'Strength': 'Red',
    'Speed': 'Blue',
    'Dark': 'Dark',
    'Light': 'Light'
}


li=eval(input("Enter the list you want"))
li.sort()
s=0
e=len(li)
key=int(input("Enter the element to be serached in the binary list"))
while(s<=e):
    mid=(s+e)//2
    if(li[mid]==key):
        print("ELEMENT FOUND AT A INDEX",mid)
        break
    elif(li[mid]>key):
        e=mid-1
    else:
        s=mid+1


import tensorflow as tf
import numpy as np
import model3 as M
import network
import util
import config
import datasets
from text.symbols import symbols
from tqdm import tqdm
import time

def create_gta(model, trainset, savepath):
	for i in range(trainset.maxiters):
		x, m, ids, m_lens = trainset.get_next()
		_, gta, _ = model(x, m)
		gta = gta.numpy()
		for j in range(len(ids)):
			mel = gta[j][:,:m_lens[j]]
			mel = (mel + 4) / 8
			ID = ids[j]
			np.save(f'{savepath}{ID}.npy', mel, allow_pickle=False)
		print(f'{i}/{iters}')

model = network.Tacotron(embed_dim=config.tts_embed_dims,
						num_chars=len(symbols),
						enc_dim=config.tts_encoder_dims,
						dec_dim=config.tts_decoder_dims,
						n_mels=config.num_mels,
						fft_bins=config.num_mels,
						postnet_dim=config.tts_postnet_dims,
						enc_K=config.tts_encoder_K,
						lstm_dim=config.tts_lstm_dims,
						postnet_K=config.tts_postnet_K,
						num_highway=config.tts_num_highways,
						dropout=config.tts_dropout)

saver = M.Saver(model)
saver.restore(config.model_folder)

# @tf.function
def grad_loss(x,m):
	with tf.GradientTape() as tape:
		m1_hat, m2_hat, att = model(x, m)
		m1_ls = tf.reduce_mean(tf.abs(m1_hat - m))
		m2_ls = tf.reduce_mean(tf.abs(m2_hat - m))
		loss = m1_ls + m2_ls
	t1 = time.time()
	grads = tape.gradient(loss, model.trainable_variables)
	t2 = time.time()
	# print('Time grad:', t2-t1)
	return grads, loss

def tts_train_loop(optim, trainset, epochs):
	for e in range(epochs):
		bar = tqdm(range(trainset.maxiters))
		for i in bar:
			x, m, ids, _ = trainset.get_next()
			grads, loss = grad_loss(x,m)
			optim.apply_gradients(zip(grads, model.trainable_variables))

			lsmsg = 'Epoch:%d Iter:%d Loss:%.4f'%(e, i, loss)
			bar.set_description(lsmsg)
			# print()

for r,lr,maxepoch,bsize in config.schedule:
	optim = tf.optimizers.Adam(lr)
	model.set_r(r)
	trainset = datasets.get_tts_dataset(config.data_path, bsize, r)

	tts_train_loop(optim, trainset, maxepoch)

print('Training complete')
print('Create GroundTruth Aligned Dataset..')
trainset = datasets.get_tts_dataset(config.data_path, 8, model.get_r())
create_gta(model, trainset, config.gta_path)


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

av_catalog = {
    "欧美": {
        "www.youporn.com": ["很多免费的,世界最大的", "质量一般"],
        "www.pornhub.com": ["很多免费的,也很大", "质量比yourporn高点"],
        "letmedothistoyou.com": ["多是自拍,高质量图片很多", "资源不多,更新慢"],
        "x-art.com": ["质量很高,真的很高", "全部收费,屌比请绕过"]
    },
    "日韩": {
        "tokyo-hot": ["质量怎样不清楚,个人已经不喜欢日韩范了", "听说是收费的"]
    },
    "大陆": {
        "1024": ["全部免费,真好,好人一生平安", "服务器在国外,慢"]
    }
}

av_catalog['大陆']['1024'][1] = '可以在国内做镜像'

print(av_catalog['大陆']['1024'][1])

print(av_catalog.values())
print(av_catalog.keys())
av_catalog.setdefault('台湾', {'www.baidu.com': ['1', '2']})
print(av_catalog)
av_catalog.setdefault('大陆', {'www.baidu.com': ['1', '2']})  # 没有的添加进去，已有的不做更改。
print(av_catalog)