import torch
import csv
import pytorch_lightning as pl
from sys import platform
if platform == "linux":
    from pypesq import pesq
from pystoi import stoi
from math import isnan
from numpy import random

def check_inf_neginf_nan(tensor, error_msg):
    assert not torch.any(torch.isinf(tensor)), error_msg
    if tensor.dtype == torch.complex32 or tensor.dtype == torch.complex64 or tensor.dtype == torch.complex128:
        assert not torch.any(torch.isneginf(tensor.real)), error_msg
        assert not torch.any(torch.isneginf(tensor.imag)), error_msg
    else:
        assert not torch.any(torch.isneginf(tensor)), error_msg
    assert not torch.any(torch.isnan(tensor)), error_msg

def l2_norm(s1, s2):
    norm = torch.sum(s1*s2, -1, keepdim=True)

    return norm

# source https://arxiv.org/pdf/2008.00264.pdf
class SiSNR(object):
    def __call__(self, clean, estimate, eps=1e-8):
        dot = l2_norm(estimate, clean)
        norm = l2_norm(clean, clean)

        s_target =  (dot * clean)/(norm+eps)
        e_nosie = estimate - s_target

        target_norm = l2_norm(s_target, s_target)
        noise_norm = l2_norm(e_nosie, e_nosie)
        snr = 10*torch.log10((target_norm)/(noise_norm+eps)+eps)

        return torch.mean(snr)

# source https://github.com/chanil1218/DCUnet.pytorch/blob/2dcdd30804be47a866fde6435cbb7e2f81585213/train.py
class wSDR(object):
    def __call__(self, mixed, clean, clean_est, eps=2e-8):
        bsum = lambda x: torch.sum(x, dim=1)
        def mSDRLoss(orig, est):
            correlation = bsum(orig * est)
            energies = torch.norm(orig, p=2, dim=1) * torch.norm(est, p=2, dim=1)
            return -(correlation / (energies + eps))

        noise = mixed - clean
        noise_est = mixed - clean_est

        a = bsum(clean**2) / (bsum(clean**2) + bsum(noise**2) + eps)
        target_wSDR = a * mSDRLoss(clean, clean_est)
        noise_wSDR = (1 - a) * mSDRLoss(noise, noise_est)
        wSDR = target_wSDR + noise_wSDR
        return torch.mean(wSDR)

def cRM(S, Y, eps=1e-8):
    M_r_numer = (Y.real * S.real) + (Y.imag * S.imag)
    M_r_denom = torch.square(Y.real) + torch.square(Y.imag)
    M_r = M_r_numer / (M_r_denom + eps)

    M_i_numer = (Y.real * S.imag) - (Y.imag * S.real)
    M_i_denom = torch.square(Y.real) + torch.square(Y.imag)
    M_i = M_i_numer / (M_i_denom + eps)

    M = torch.complex(M_r, M_i)

    return M

def bound_cRM(cRM):
    target_noise_mask_mag = torch.abs(cRM)
    target_noise_mask_mag_tanh = torch.tanh(target_noise_mask_mag)
    target_noise_mag_tanh_real = target_noise_mask_mag_tanh * torch.cos(torch.angle(cRM))
    target_noise_mag_tanh_imag = target_noise_mask_mag_tanh * torch.sin(torch.angle(cRM))
    target_noise_mask_phase = torch.atan2(target_noise_mag_tanh_imag, target_noise_mag_tanh_real)

    target_noise_mask_real = target_noise_mask_mag_tanh * torch.cos(target_noise_mask_phase)
    target_noise_mask_imag = target_noise_mask_mag_tanh * torch.sin(target_noise_mask_phase)

    return torch.complex(target_noise_mask_real, target_noise_mask_imag)

def complex_mat_mult(A, B):
    outp_real = (A.real * B.real) - (A.imag * B.imag)
    outp_imag = (A.real * B.imag) + (A.imag * B.real)

    Y = torch.complex(outp_real, outp_imag)

    return Y

def complex_lrelu(input):
    # return torch.nn.functional.leaky_relu(input.real) + 1j*torch.nn.functional.leaky_relu(input.imag)
    return torch.complex(torch.nn.functional.leaky_relu(input.real), torch.nn.functional.leaky_relu(input.imag))

def apply_complex(fr, fi, input):
    # return (fr(input.real)[0]-fi(input.imag)[0]) + 1j*(fr(input.imag)[0]+fi(input.real)[0])
    return torch.complex(fr(input.real)-fi(input.imag), (fr(input.imag)+fi(input.real)))

# source https://github.com/huyanxin/DeepComplexCRN/blob/bc6fd38b0af9e8feb716c81ff8fbacd7f71ad82f/complexnn.py
class ComplexLSTM(torch.nn.Module):
    def __init__(self, input_size, hidden_size, num_layers, bidirectional, batch_first, projection_dim=None):
        super(ComplexLSTM, self).__init__()

        self.input_dim = input_size
        self.rnn_units = hidden_size
        self.real_lstm = torch.nn.LSTM(input_size=self.input_dim, hidden_size=self.rnn_units, num_layers=num_layers,
                        bidirectional=bidirectional, batch_first=batch_first)
        self.imag_lstm = torch.nn.LSTM(input_size=self.input_dim, hidden_size=self.rnn_units, num_layers=num_layers,
                        bidirectional=bidirectional, batch_first=batch_first)
        if bidirectional:
            bidirectional=2
        else:
            bidirectional=1
        if projection_dim is not None:
            self.projection_dim = projection_dim
            self.r_trans = torch.nn.Linear(self.rnn_units*bidirectional, self.projection_dim)
            self.i_trans = torch.nn.Linear(self.rnn_units*bidirectional, self.projection_dim)
        else:
            self.projection_dim = None

    def forward(self, inputs):
        if isinstance(inputs,list):
            real, imag = inputs.real, inputs.imag
        elif isinstance(inputs, torch.Tensor):
            real, imag = inputs.real, inputs.imag
        r2r_out = self.real_lstm(real)[0]
        r2i_out = self.imag_lstm(real)[0]
        i2r_out = self.real_lstm(imag)[0]
        i2i_out = self.imag_lstm(imag)[0]
        real_out = r2r_out - i2i_out
        imag_out = i2r_out + r2i_out
        if self.projection_dim is not None:
            real_out = self.r_trans(real_out)
            imag_out = self.i_trans(imag_out)
        return torch.complex(real_out, imag_out)

    def flatten_parameters(self):
        self.imag_lstm.flatten_parameters()
        self.real_lstm.flatten_parameters()

def mag_phase_2_wave(mag, phase, config):
    real = mag * torch.cos(phase)
    imag = mag * torch.sin(phase)
    comp = torch.complex(real, imag)
    comp = torch.nn.functional.pad(comp, (0,0,0,1))

    audio = torch.istft(comp, n_fft=config.fft_size, hop_length=config.hop_length, \
            win_length=config.window_length, normalized=config.normalise_stft)

    return audio

def calc_metric(clean_audio, predict_audio, config, metric):
    metric_arr = []
    for i in range(predict_audio.shape[0]):
        metric_i = metric(clean_audio[i,:].cpu().numpy(), predict_audio[i,:].cpu().numpy(), config.sr)
        if not isnan(metric_i):
            metric_arr.append(metric_i)
    pesq_av = float(sum(metric_arr)) / max(len(metric_arr), 1)

    return pesq_av

def calc_loss(self, target_noise_mask, predict_noise_mask, \
                predict_noise_audio, predict_clean_audio,
                noise_audio, noisy_audio, clean_audio):

    if self.hparams['noise_loss_type'] == 0:
        noise_loss_orig = self.config.L1(target_noise_mask, predict_noise_mask)
    elif self.hparams['noise_loss_type'] == 1:
        noise_loss_orig = self.config.wSDR(noisy_audio, noise_audio, predict_noise_audio)
    elif self.hparams['noise_loss_type'] == 2:
        noise_loss_orig = self.config.L1(target_noise_mask, predict_noise_mask) + \
            self.config.L1(noise_audio, predict_noise_audio)
    elif self.hparams['noise_loss_type'] == 3:
        noise_loss_orig = self.config.wSDR(noisy_audio, noise_audio, predict_noise_audio) + \
            self.config.L1(noise_audio, predict_noise_audio)
    elif self.hparams['noise_loss_type'] == 4:
        noise_loss_orig = self.config.wSDR(noisy_audio, noise_audio, predict_noise_audio) + \
            self.config.L1(target_noise_mask, predict_noise_mask)
    elif self.hparams['noise_loss_type'] == 5:
        if target_noise_mask.dtype == torch.complex32 or target_noise_mask.dtype == torch.complex64 or target_noise_mask.dtype == torch.complex128:
            noise_loss_orig = self.config.wSDR(noisy_audio, noise_audio, predict_noise_audio) + \
            self.config.mse(target_noise_mask.real, predict_noise_mask.real) + \
            self.config.mse(target_noise_mask.imag, predict_noise_mask.imag)
        else:
            noise_loss_orig = self.config.wSDR(noisy_audio, noise_audio, predict_noise_audio) + \
                self.config.mse(target_noise_mask, predict_noise_mask)
    noise_loss = (self.hparams['noise_alpha'] * noise_loss_orig)

    if self.hparams['speech_loss_type'] == 0:
        speech_loss_orig = -self.config.SiSNR(clean_audio, predict_clean_audio)
    elif self.hparams['speech_loss_type'] == 1:
        speech_loss_orig_small = torch.mean(self.config.CDPAM.forward(clean_audio, predict_clean_audio))
        speech_loss_orig = speech_loss_orig_small * 10e5
    speech_loss = (self.hparams['speech_alpha'] * speech_loss_orig)

    total_loss = noise_loss + speech_loss

    return noise_loss, speech_loss, total_loss

def train_batch_2_loss(self, train_batch, batch_idx, dtype):
    noise_data, noisy_data, clean_data, id = train_batch

    check_inf_neginf_nan(clean_data, "Found inf, neginf or nan in clean data STFT!")
    check_inf_neginf_nan(noise_data, "Found inf, neginf or nan in noise data STFT!")
    check_inf_neginf_nan(noisy_data, "Found inf, neginf or nan in noisy data STFT!")

    noise_mag = torch.abs(noise_data)
    noise_phase = torch.angle(noise_data)
    noisy_mag = torch.abs(noisy_data)
    noisy_phase = torch.angle(noisy_data)
    clean_mag = torch.abs(clean_data)
    clean_phase = torch.angle(clean_data)
    noise_audio = mag_phase_2_wave(noise_mag, noise_phase, self.config)
    noisy_audio = mag_phase_2_wave(noisy_mag, noisy_phase, self.config)
    clean_audio = mag_phase_2_wave(clean_mag, clean_phase, self.config)

    if dtype == "real":
        target_noise_mask = torch.sigmoid(noise_mag / noisy_mag)

        noisy_mag_scaled = (noisy_mag - self.config.data_minR) / (self.config.data_maxR - self.config.data_minR)
        predict_noise_mask = self(noisy_mag_scaled)

        predict_noise_mag = noisy_mag * predict_noise_mask
        predict_clean_mag = noisy_mag - predict_noise_mag
        predict_noise_audio = mag_phase_2_wave(predict_noise_mag, noisy_phase, self.config)
        predict_clean_audio = mag_phase_2_wave(predict_clean_mag, noisy_phase, self.config)

    elif dtype == "complex":
        target_noise_mask_out = cRM(noise_data, noisy_data)
        target_noise_mask = bound_cRM(target_noise_mask_out)

        # noisy_data_standardised = (noisy_data - torch.mean(noisy_data)) / torch.std(noisy_data)
        noisy_data_scaled = torch.view_as_complex((2 * ((torch.view_as_real(noisy_data) - self.config.data_minC) /
                    (self.config.data_maxC - self.config.data_minC))) - 1)
        predict_noise_mask_out = self(noisy_data_scaled)
        predict_noise_mask = bound_cRM(predict_noise_mask_out)

        predict_noise_data = complex_mat_mult(noisy_data, predict_noise_mask)
        predict_clean_data = noisy_data - predict_noise_data
        predict_noise_audio = mag_phase_2_wave(torch.abs(predict_noise_data), \
                                torch.angle(predict_noise_data), self.config)
        predict_clean_audio = mag_phase_2_wave(torch.abs(predict_clean_data), \
                                torch.angle(predict_clean_data), self.config)

    noise_loss, speech_loss, train_loss = calc_loss(self,
                                                    target_noise_mask=target_noise_mask,
                                                    predict_noise_mask=predict_noise_mask,
                                                    predict_noise_audio=predict_noise_audio,
                                                    predict_clean_audio=predict_clean_audio,
                                                    noise_audio=noise_audio,
                                                    noisy_audio=noisy_audio,
                                                    clean_audio=clean_audio)

    return noise_loss, speech_loss, train_loss

def val_batch_2_metric_loss(self, val_batch, val_idx, dtype):
    noise_data, noisy_data, clean_data, id = val_batch

    check_inf_neginf_nan(clean_data, "Found inf, neginf or nan in clean data STFT!")
    check_inf_neginf_nan(noise_data, "Found inf, neginf or nan in noise data STFT!")
    check_inf_neginf_nan(noisy_data, "Found inf, neginf or nan in noisy data STFT!")

    noise_mag = torch.abs(noise_data)
    noise_phase = torch.angle(noise_data)
    noisy_mag = torch.abs(noisy_data)
    noisy_phase = torch.angle(noisy_data)
    clean_mag = torch.abs(clean_data)
    clean_phase = torch.angle(clean_data)
    noise_audio = mag_phase_2_wave(noise_mag, noise_phase, self.config)
    noisy_audio = mag_phase_2_wave(noisy_mag, noisy_phase, self.config)
    clean_audio = mag_phase_2_wave(clean_mag, clean_phase, self.config)

    if dtype == "real":
        target_noise_mask = torch.sigmoid(noise_mag / noisy_mag)

        noisy_mag_scaled = (noisy_mag - self.config.data_minR) / (self.config.data_maxR - self.config.data_minR)
        predict_noise_mask = self(noisy_mag_scaled)

        predict_noise_mag = noisy_mag * predict_noise_mask
        predict_clean_mag = noisy_mag - predict_noise_mag

        predict_clean_audio = mag_phase_2_wave(predict_clean_mag, noisy_phase, self.config)
        predict_noise_audio = mag_phase_2_wave(predict_noise_mag, noisy_phase, self.config)

    elif dtype == "complex":
        target_noise_mask_out = cRM(noise_data, noisy_data)
        target_noise_mask = bound_cRM(target_noise_mask_out)

        # noisy_data_standardised = (noisy_data - torch.mean(noisy_data)) / torch.std(noisy_data)
        noisy_data_scaled = torch.view_as_complex((2 * ((torch.view_as_real(noisy_data) - self.config.data_minC) /
                    (self.config.data_maxC - self.config.data_minC))) - 1)
        predict_noise_mask_out = self(noisy_data_scaled)
        predict_noise_mask = bound_cRM(predict_noise_mask_out)

        predict_noise_data = complex_mat_mult(noisy_data, predict_noise_mask)
        predict_clean_data = noisy_data - predict_noise_data
        predict_clean_audio = mag_phase_2_wave(torch.abs(predict_clean_data), \
                                torch.angle(predict_clean_data), self.config)
        predict_noise_audio = mag_phase_2_wave(torch.abs(predict_noise_data), \
                                torch.angle(predict_noise_data), self.config)

    if platform == "linux":
        pesq_av = calc_metric(clean_audio, predict_clean_audio, self.config, pesq)
    else:
        pesq_av = 1
    stoi_av = calc_metric(clean_audio, predict_clean_audio, self.config, stoi)

    noise_loss, speech_loss, val_loss = calc_loss(self,
                                                    target_noise_mask=target_noise_mask,
                                                    predict_noise_mask=predict_noise_mask,
                                                    predict_noise_audio=predict_noise_audio,
                                                    predict_clean_audio=predict_clean_audio,
                                                    noise_audio=noise_audio,
                                                    noisy_audio=noisy_audio,
                                                    clean_audio=clean_audio)

    return noise_loss, speech_loss, val_loss, pesq_av, stoi_av, \
                    predict_noise_audio, predict_clean_audio, \
                    noise_audio, noisy_audio, clean_audio

def test_batch_2_metric_loss(self, test_batch, test_idx, dtype):
    noise_data, noisy_data, clean_data, id, start_point = test_batch

    noise_mag = torch.abs(noise_data)
    noise_phase = torch.angle(noise_data)
    noisy_mag = torch.abs(noisy_data)
    noisy_phase = torch.angle(noisy_data)
    clean_mag = torch.abs(clean_data)
    clean_phase = torch.angle(clean_data)
    noise_audio = mag_phase_2_wave(noise_mag, noise_phase, self.config)
    noisy_audio = mag_phase_2_wave(noisy_mag, noisy_phase, self.config)
    clean_audio = mag_phase_2_wave(clean_mag, clean_phase, self.config)

    if dtype == "real":
        target_noise_mask = torch.sigmoid(noise_mag / noisy_mag)

        noisy_mag_scaled = (noisy_mag - self.config.data_minR) / (self.config.data_maxR - self.config.data_minR)
        predict_noise_mask = self(noisy_mag_scaled)

        predict_noise_mag = noisy_mag * predict_noise_mask
        predict_clean_mag = noisy_mag - predict_noise_mag

        predict_clean_audio = mag_phase_2_wave(predict_clean_mag, noisy_phase, self.config)
        predict_noise_audio = mag_phase_2_wave(predict_noise_mag, noisy_phase, self.config)

    elif dtype == "complex":
        target_noise_mask_out = cRM(noise_data, noisy_data)
        target_noise_mask = bound_cRM(target_noise_mask_out)

        # noisy_data_standardised = (noisy_data - torch.mean(noisy_data)) / torch.std(noisy_data)
        noisy_data_scaled = torch.view_as_complex((2 * ((torch.view_as_real(noisy_data) - self.config.data_minC) /
                    (self.config.data_maxC - self.config.data_minC))) - 1)
        predict_noise_mask_out = self(noisy_data_scaled)
        predict_noise_mask = bound_cRM(predict_noise_mask_out)

        predict_noise_data = complex_mat_mult(noisy_data, predict_noise_mask)
        predict_clean_data = noisy_data - predict_noise_data
        predict_clean_audio = mag_phase_2_wave(torch.abs(predict_clean_data), \
                                torch.angle(predict_clean_data), self.config)
        predict_noise_audio = mag_phase_2_wave(torch.abs(predict_noise_data), \
                                torch.angle(predict_noise_data), self.config)

    noise_audio = mag_phase_2_wave(noise_mag, noise_phase, self.config)
    noisy_audio = mag_phase_2_wave(noisy_mag, noisy_phase, self.config)

    if platform == "linux":
        pesq_av = calc_metric(clean_audio, predict_clean_audio, self.config, pesq)
    else:
        pesq_av = 1
    stoi_av = calc_metric(clean_audio, predict_clean_audio, self.config, stoi)

    noise_loss, speech_loss, test_loss = calc_loss(self,
                                                    target_noise_mask=target_noise_mask,
                                                    predict_noise_mask=predict_noise_mask,
                                                    predict_noise_audio=predict_noise_audio,
                                                    predict_clean_audio=predict_clean_audio,
                                                    noise_audio=noise_audio,
                                                    noisy_audio=noisy_audio,
                                                    clean_audio=clean_audio)

    return noise_loss, speech_loss, test_loss, pesq_av, stoi_av, \
                    predict_noise_audio, predict_clean_audio, \
                    noise_audio, noisy_audio, clean_audio, id, start_point

def epoch_end(self, outputs, type):

    no_of_batches = len(outputs)
    random_batches = random.choice(no_of_batches, size=min(self.config.val_log_sample_size, no_of_batches), replace=False)

    no_of_samples = min(self.config.data_params['batch_size'],
                    outputs[-1]['clean'].shape[0],
                    outputs[-1]['predict_clean'].shape[0],
                    outputs[-1]['noise'].shape[0],
                    outputs[-1]['predict_noise'].shape[0],
                    outputs[-1]['noisy'].shape[0])
    random_samples = random.choice(no_of_samples, size=min(self.config.val_log_sample_size, no_of_samples), replace=False)

    for i, ridx in enumerate(range(min(self.config.val_log_sample_size, no_of_samples))):
        clean_sample = outputs[random_batches[ridx]]['clean'][random_samples[ridx],:]
        predict_clean_sample = outputs[random_batches[ridx]]['predict_clean'][random_samples[ridx],:]
        noise_sample = outputs[random_batches[ridx]]['noise'][random_samples[ridx],:]
        predict_noise_sample = outputs[random_batches[ridx]]['predict_noise'][random_samples[ridx],:]
        noisy_sample = outputs[random_batches[ridx]]['noisy'][random_samples[ridx],:]

        self.logger.experiment.add_audio("clean({})/{}".format(type, i),
                                        clean_sample,
                                        self.global_step,
                                        sample_rate=self.config.sr)
        self.logger.experiment.add_audio("predict_clean({})/{}".format(type, i),
                                        predict_clean_sample,
                                        self.global_step,
                                        sample_rate=self.config.sr)
        self.logger.experiment.add_audio("noise({})/{}".format(type, i),
                                        noise_sample,
                                        self.global_step,
                                        sample_rate=self.config.sr)
        self.logger.experiment.add_audio("predict_noise({})/{}".format(type, i),
                                        predict_noise_sample,
                                        self.global_step,
                                        sample_rate=self.config.sr)
        self.logger.experiment.add_audio("noisy({})/{}".format(type, i),
                                        noisy_sample,
                                        self.global_step,
                                        sample_rate=self.config.sr)

class InputMonitor(pl.Callback):

    def on_train_batch_start(self, trainer, pl_module, batch, batch_idx, dataloader_idx):
        if (batch_idx + 1) % trainer.log_every_n_steps == 0:
            noise_real = batch[0].real
            noise_imag = batch[0].imag
            noisy_real = batch[1].real
            noisy_imag = batch[1].imag
            clean_real = batch[2].real
            clean_imag = batch[2].imag
            logger = trainer.logger
            logger.experiment.add_histogram("noise data real", noise_real, global_step=trainer.global_step)
            logger.experiment.add_histogram("noise data imag", noise_imag, global_step=trainer.global_step)
            logger.experiment.add_histogram("noisy data real", noisy_real, global_step=trainer.global_step)
            logger.experiment.add_histogram("noisy data imag", noisy_imag, global_step=trainer.global_step)
            logger.experiment.add_histogram("clean data real", clean_real, global_step=trainer.global_step)
            logger.experiment.add_histogram("clean data imag", clean_imag, global_step=trainer.global_step)

class CheckBatchGradient(pl.Callback):
    def on_train_start(self, trainer, model):
        n = 0

        example_input = model.example_input_array.to(model.device)
        example_input.requires_grad = True

        model.zero_grad()
        output = model(example_input)
        output[n].abs().sum().backward()

        zero_grad_inds = list(range(example_input.size(0)))
        zero_grad_inds.pop(n)

        if example_input.grad[zero_grad_inds].abs().sum().item() > 0:
            raise RuntimeError("Your model mixes data across the batch dimension!")


import pandas as pd
import numpy as np
import random
from sklearn.datasets import load_iris
import matplotlib.pyplot as plt

x= ""

def calc_color_indxs(centroids):
    #function assigns centroid indexes to each training example i.e. it assigns the
    # nearest cluster centroid to each training example
    # It uses Eucledian Distance to measure the distance between cluster centroids and training example
    global x
    centroid_indx = np.zeros(((x.shape[0]),1))
    for i in range(0,x.shape[0]):
        dist = x[i,:]-centroids
        dist = np.sum(np.power(dist,2),axis = 1)
        centroid_indx[i] = np.argmin(dist)
    return centroid_indx.astype(int)

def calc_cost(centroids,sample_color_indx):
    #calculates the cost value of the calculated centroid.
    #cost = average of the distances between the centroids and the assigned training examples
    sample_centroids = centroids[sample_color_indx.reshape((sample_color_indx.shape[0]))]
    dist = x - sample_centroids
    dist = np.sum(np.power(np.sum(np.power(dist,2),axis = 1),0.5),axis = 0)
    return dist/sample_centroids.shape[0]

def update_centroids(centroids,sample_color_indx,k):
    #updates the centroid for each assigned cluster
    #calculates the centroid by taking mean of all the example assigned to the cluster
    for i in range(0,k):
        indxs = np.where(sample_color_indx == i)
        x_centroid = x[indxs[0]]
        if x_centroid.shape[0] == 0:
            continue
        centroids[i] = np.mean(x_centroid,axis = 0)
    return centroids

if __name__ == '__main__':
    data = load_iris(as_frame = True)
    df = data.data
    num_of_features = df.shape[1]
    x = np.array(df.iloc[1:,0:num_of_features])
    k = int(input("Enter Number of Clusters: "))
    random_init_indx = random.sample(range(0,df.shape[0]),k)
    centroids = np.array(df.iloc[random_init_indx,0:num_of_features])
    plt.subplot(1,2,1)
    i = 0
    #------------------------------------------------------------------
    sample_color_indx = calc_color_indxs(centroids) #step1
    cost0 = calc_cost(centroids,sample_color_indx)
    prev_centroids = centroids
    centroids = update_centroids(centroids,sample_color_indx,k) #step2\
    plt.scatter(i,cost0)
    i = i + 1
    #----------------------------------------------------------------
    sample_color_indx = calc_color_indxs(centroids) #step1
    cost1 = calc_cost(centroids,sample_color_indx) #step2
    #--------------------------------------------------------------------
    while cost0-cost1>=pow(10,-9):
        i = i + 1
        plt.scatter(i,cost1)
        prev_centroids = centroids
        centroids = update_centroids(centroids,sample_color_indx,k)
        cost0 = cost1
        sample_color_indx = calc_color_indxs(centroids)
        cost1 = calc_cost(centroids,sample_color_indx)
    print(cost0)
    #plots two subplots in a figure,
    #1.) Cost funcn vs. no. of iterations
    #2.) Plot Training examples of same clusters with same color.
    plt.subplot(1,2,2)
    sample_color_indx = calc_color_indxs(prev_centroids)
    colors = plt.cm.Spectral(np.linspace(0,1,k))
    for i,col in zip(range(k),colors):
        indxs = np.where(sample_color_indx == i)
        x_centroid = x[indxs[0]]
        plt.scatter(x_centroid[:,0],x_centroid[:,1],color = col)
    plt.show()


import bpy
import re

from ..helpers import sentence_join

default_lock = False
default_lock_array = [default_lock] * 3
component_names = ('X', 'Y', 'Z', 'W')

def is_prop_locked(pb, name, component_index):
    if name == 'location':
        return getattr(pb, 'lock_location', default_lock_array)[component_index]
    elif name in {'rotation_euler', 'rotation_quaternion', 'rotation_axis_angle'}:
        if component_index < 3:
            return getattr(pb, 'lock_rotation', default_lock_array)[component_index]
        else:
            return getattr(pb, 'lock_rotation_w', default_lock)
    elif name == 'scale':
        return getattr(pb, 'lock_scale', default_lock_array)[component_index]

class GRET_OT_channels_delete_unavailable(bpy.types.Operator):
    """Delete location/rotation/scale channels that are locked in the transform panel"""

    bl_idname = 'gret.channels_delete_unavailable'
    bl_label = "Delete Unavailable Channels"
    bl_options = {'REGISTER', 'UNDO'}

    @classmethod
    def poll(cls, context):
        return context.space_data and context.space_data.type in {'DOPESHEET_EDITOR', 'GRAPH_EDITOR'}

    def execute(self, context):
        obj = context.active_object
        action = obj.animation_data.action if (obj and obj.animation_data) else None
        if not action:
            return {'CANCELLED'}

        remove_fcurves = []
        delete_invalid = False
        num_invalid = num_locked = 0

        for fc in action.fcurves:
            try:
                obj.path_resolve(fc.data_path)
            except ValueError:
                if delete_invalid:
                    print(f"Removing curve, can't resolve {fc.data_path}")
                    remove_fcurves.append(fc)
                    num_invalid += 1
                continue

            pb_match = re.match(r'^pose\.bones\[\"([^\"]+)"\]\.(\w+)$', fc.data_path)
            if pb_match:
                pb = obj.pose.bones.get(pb_match[1])
                prop_name = pb_match[2]
                if pb and is_prop_locked(pb, prop_name, fc.array_index):
                    print(f"Removing curve, bone {pb.name} {component_names[fc.array_index]} "
                        f"{prop_name} is locked")
                    remove_fcurves.append(fc)
                    num_locked += 1
                    continue

        for fc in remove_fcurves:
            action.fcurves.remove(fc)

        num_removed_str = sentence_join([
            f"{num_invalid} invalid" if num_invalid else "",
            f"{num_locked} locked transform" if num_locked else "",
        ])
        if num_removed_str:
            self.report({'INFO'}, f"Removed {num_removed_str} curves.")

        return {'FINISHED'}

def draw_menu(self, context):
    self.layout.operator(GRET_OT_channels_delete_unavailable.bl_idname)

def register(settings, prefs):
    if not prefs.animation__enable_channels_delete_unavailable:
        return False

    bpy.utils.register_class(GRET_OT_channels_delete_unavailable)
    bpy.types.GRAPH_MT_channel.append(draw_menu)
    bpy.types.DOPESHEET_MT_channel.append(draw_menu)

def unregister():
    bpy.types.GRAPH_MT_channel.remove(draw_menu)
    bpy.types.DOPESHEET_MT_channel.remove(draw_menu)
    bpy.utils.unregister_class(GRET_OT_channels_delete_unavailable)


import threading

import traitlets

import pyrosetta
import pyrosetta.rosetta.basic.options
import pyrosetta.rosetta.protocols.rosetta_scripts as rosetta_scripts
import pyrosetta.rosetta.protocols.moves as moves

import pyrosetta.distributed
import pyrosetta.distributed.tasks.taskbase as taskbase
import pyrosetta.distributed.packed_pose as packed_pose

def validate(protocol_xml):
    """Perform schema and parse validation for the given protocol xml."""
    try:
        test_task = BaseRosettaScriptsTask(protocol_xml)
        test_task.maybe_setup()
    except RuntimeError as error:
        raise error

class BaseRosettaScriptsTask(taskbase.TaskBase):
    @property
    @pyrosetta.distributed.requires_init
    @pyrosetta.distributed.with_lock
    def parser(self):
        if not getattr(self, "_parser", None):
            BaseRosettaScriptsTask._parser = \
                    rosetta_scripts.RosettaScriptsParser()

        return self._parser

    protocol_xml = traitlets.CUnicode()

    def __init__(self, protocol_xml):
        super().__init__(protocol_xml=protocol_xml)

    @pyrosetta.distributed.requires_init
    @pyrosetta.distributed.with_lock
    def setup(self):
        self.default_options = pyrosetta.rosetta.basic.options.process()
        self.tag = self.parser.create_tag_from_xml_string(
                self.protocol_xml, self.default_options)

        # Validate by parsing
        self.parser.parse_protocol_tag(self.tag, self.default_options)
        self.protocol_lock = threading.Lock()

    @property
    @pyrosetta.distributed.requires_init
    @pyrosetta.distributed.with_lock
    def parsed_protocol(self):
        return self.parser.parse_protocol_tag(self.tag, self.default_options)

    def execute(self, pack_or_pose):
        return packed_pose.to_packed(self.apply(pack_or_pose))

class MultioutputRosettaScriptsTask(BaseRosettaScriptsTask):
    @pyrosetta.distributed.requires_init
    def apply(self, pack_or_pose):
        """Apply task generating pose objects."""
        protocol = self.parsed_protocol

        wpose = packed_pose.to_pose(pack_or_pose)

        with self.protocol_lock:
            protocol.apply(wpose)

            if protocol.get_last_move_status() != moves.MoverStatus.MS_SUCCESS:
                return

            while wpose:
                yield wpose
                wpose = protocol.get_additional_output()

class SingleoutputRosettaScriptsTask(BaseRosettaScriptsTask):
    @pyrosetta.distributed.requires_init
    def apply(self, pack_or_pose):
        """Apply task returning a pose object."""
        protocol = self.parsed_protocol

        wpose = packed_pose.to_pose(pack_or_pose)

        with self.protocol_lock:
            protocol.apply(wpose)

            if protocol.get_last_move_status() != moves.MoverStatus.MS_SUCCESS:
                return
            else:
                return wpose


from Sentence import Sentence
import nltk

class Text:

    def __init__(self, rawText, name):
        self.rawText = rawText#self.formatText(rawText)
        self.name = name

        splitAtNewlines = [s.strip() for s in rawText.splitlines()]
        rawSentences = []
        for line in splitAtNewlines:
            sentencesInLine = nltk.sent_tokenize(line)
            rawSentences.extend(sentencesInLine)

        self.sentences = []
        for rawSentence in rawSentences:
            sentence = Sentence(self, rawSentence)
            self.sentences.append(sentence)

    def formatText(self, rawText):
        return  rawText.replace(u"\u2018", "'").replace(u"\u2019", "'").replace(u"\xa9", "e").replace(u"\u2014","-").decode("utf8")


import requests
import collections
import secrets
import json
import sqlite3
import scrape

from bs4 import BeautifulSoup

API_KEY = secrets.API_KEY

headers = {
	"Authorization": "Bearer %s" % API_KEY
}

BASEURL = 'https://api.yelp.com/v3/businesses/search'

CACHE_DICT = {}
CACHE_FILENAME = 'search_cache.json'

DB_NAME = 'yelp.sqlite'

class Filter:

	def __init__(self):
		self.cities = []
		self.terms = []

	def add_city(self, city):
		if city not in self.cities:
			self.cities.append(city)

	def add_term(self, t):
		if t not in self.terms:
			self.terms.append(t)

	def show_city_list(self):
		return self.cities

	def show_term_list(self):
		return self.terms

class Business:

	def __init__(self, business):
		self.business_name = business.get('name', '')
		self.yelp_id = business.get('id', '')
		self.city = business.get('location', {}).get('city', '')
		self.phone_number = business.get('phone', '')
		self.review_count = business.get('review_count', -1)
		self.rating = business.get('rating', -1)
		self.price = business.get('price', '').count('$')
		self.url = business.get('url', '')
		self.address = business.get('location', {}).get('address1', '')

		if self.business_name == None: self.business_name = ''
		if self.yelp_id == None: self.yelp_id = ''
		if self.city == None: self.city = ''
		if self.phone_number == None: self.phone_number = ''
		if self.review_count == None: self.review_count = -1
		if self.rating == None: self.rating = -1
		if self.price == None: self.price = 0
		if self.url == None: self.url = ''
		if self.address == None: self.address = ''

		self.category = ['NULL'] * 3
		if 'categories' in business:
			for i in range(min(3, len(business['categories']))):
				self.category[i] = business['categories'][i]['title']

		self.pic, self.review = scrape.get_info_from_url(self.url)

	def get_business_info(self):
		return [self.yelp_id, self.business_name, self.city, self.phone_number,
				self.review_count, self.rating, self.price, self.address, self.url]

	def get_category_info(self):
		return [self.yelp_id] + self.category

def open_cache():
    ''' Opens the cache file if it exists and loads the JSON into
    the CACHE_DICT dictionary.
    if the cache file doesn't exist, creates a new cache dictionary

    Args:
    	None

    Returns:
    	cache_dict (dict): The opened cache.
    '''
    try:
    	cache_file = open(CACHE_FILENAME, 'r')
    	cache_contents = cache_file.read()
    	cache_dict = json.loads(cache_contents)
    	cache_file.close()
    except:
    	cache_dict = {}

    return cache_dict

def save_cache(cache_dict):
	''' Saves the current state of the cache to disk

	Args:
		cache_dict (dict): The dictionary to save.

	Returns:
		None
	'''
	dumped_json_cache = json.dumps(cache_dict)
	fw = open(CACHE_FILENAME, "w")
	fw.write(dumped_json_cache)
	fw.close()

def construct_unique_key(baseurl, params):
    ''' constructs a key that is guaranteed to uniquely and
    repeatably identify an API request by its baseurl and params

    Args:
    	baseurl (str): The URL for the API endpoint.
    	params (dict): A dictionary of param:value pairs.

    Returns:
    	unique_key (str): The unique key as a string.
    '''
    param_string = []
    connector = "_"

    for k in params.keys():
        param_string.append(f"{k}_{params[k]}")

    param_string.sort()
    unique_key = baseurl + connector + connector.join(param_string)

    return unique_key

def make_request(baseurl, params):
    '''Make a request to the Web API using the baseurl and params

    Args;
    	baseurl (str): The URL for the API endpoint.
    	params (dict): A dictionary of param:value pairs.

    Returns:
    	results (dict): The JSON response from the request.
    '''
    response = requests.get(baseurl, params=params, headers=headers)
    results = response.json()
    return results

def make_request_with_cache(baseurl, term='', location='', count=50):
	''' Check the cache for a saved result for this baseurl+params:values
    combo. If the result is found, return it. Otherwise send a new
    request, save it, then return it.

    Args:
    	baseurl (str): The URL for the API endpoint
    	term (str): The search term passes to the API.
    	location (str): The search location passes to the API.
    	count (int): The number of business results to return.

    Return:
    	results (dict): The JSON response from the request.
	'''
	params = {
		'term': term.lower().replace(" ", "+"),
		'location': location.lower().replace(" ", "+"),
		'limit': count
	}
	request_key = construct_unique_key(baseurl=baseurl, params=params)

	if request_key in CACHE_DICT:
		# The data has been fetched before and stored in the cache
		return CACHE_DICT[request_key]
	else:
		results = make_request(baseurl=baseurl, params=params)
		CACHE_DICT[request_key] = results
		save_cache(cache_dict=CACHE_DICT)
		return results

def write_to_business_single(info):
	''' Write a row into business_info table

	Args:
		info (list): A list of business information.

	Returns:
		None
	'''
	insert_instructors = '''
		INSERT OR REPLACE INTO business_info
		VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
	'''
	connection = sqlite3.connect(DB_NAME)
	cursor = connection.cursor()
	cursor.execute(insert_instructors, info)
	connection.commit()
	connection.close()

def write_to_category_single(info):
	''' Write a row into category_info table.

	Args:
		info (list): A list of category info of one business.

	Returns:
		None
	'''
	insert_instructors = '''
		INSERT OR REPLACE INTO category_info
		VALUES (?, ?, ?, ?)
	'''
	connection = sqlite3.connect(DB_NAME)
	cursor = connection.cursor()
	cursor.execute(insert_instructors, info)
	connection.commit()
	connection.close()

def write_to_business(list):
	''' Write multiple rows into business_info table.

	Args:
		list (list): A list of business objects.

	Returns:
		None
	'''
	for busi_obj in list:
		write_to_business_single(busi_obj.get_business_info())

def write_to_category(list):
	''' Write multiple rows into category_info table.

	Args:
		list (list): A list of business objects.

	Returns:
		None
	'''
	for busi_obj in list:
		write_to_category_single(busi_obj.get_category_info())

def get_business_list(term='', location='', count=50):
	''' Fetch the data throught API and process the JSON
	response into two lists.

	Args:
		term (str): The search term passed into API.
		location (str): The search location passed into API.
		count (int): The number of business results to return.

	Returns:
		business_list (list): A list of business objects.
	'''
	results = make_request_with_cache(baseurl=BASEURL,
									term=term, location=location, count=count)
	business_info = results['businesses']

	business_list = []
	for business in business_info:
		business_list.append(
			Business(business)
			)

	return business_list

if __name__ == '__main__':
	# term = 'barbecue'
	# city = 'New York'
	# busi_list = get_business_list(term=term, location=city, count=50)
	# write_to_business_single(busi_list[31].get_business_info())

	f = Filter()

	f.add_term('Chinese restaurants')
	f.add_term('Japanese restaurants')
	f.add_term('Indian restaurants')
	f.add_term('Mediterranean restaurants')
	f.add_term('breakfast')
	f.add_term('barbecue')
	f.add_term('coffee')
	f.add_term('noodles')
	f.add_term('food')
	f.add_term('hamburger')
	f.add_term('sandwich')
	f.add_term('bubble tea')
	f.add_term('taco')
	f.add_term('dumplings')
	f.add_term('Korean')
	f.add_term('sushi')
	f.add_term('ramen')
	f.add_term('curry')
	f.add_term('cocktail')
	f.add_term('bar')
	f.add_term('seafood')
	f.add_term('hot pot')
	f.add_term('steak')
	f.add_term('Vegetarian')

	f.add_city('San Francisco')
	f.add_city('Seattle')
	f.add_city('New York')
	f.add_city('Ann Arbor')
	f.add_city('San Jose')
	f.add_city('Boston')
	f.add_city('Los Angeles')
	f.add_city('Las Vegas')
	f.add_city('Chicago')
	f.add_city('Washington')
	f.add_city('Detroit')

	for term in f.show_term_list():
		for city in f.show_city_list():
			print(term, city)
			busi_list = get_business_list(term=term, location=city, count=50)
			write_to_business(busi_list)
			write_to_category(busi_list)


'''
- Change tree from octree to R-tree. or study other balanced trees
- If octree pool overflows it should create a second pool
'''

from Framework.Segmentation.SegmentationHandler import *
from Framework.Segmentation.ROI import ROI
from Framework.Tools.shunting_yard import shuntingYard

from Framework.Tools.DataStructures import OctreePointBased

class ROISegmentation(SegmentationHandler):
	# @averageTimeit
	def __init__(self, bundle, shaderDict):
		super().__init__(bundle, shaderDict)

		self.segmentationIdentifier = SegmentationTypes.ROIs

		self.tree = None
		self.roiValidator = []
		self.rois = []
		# self.fiberSizes = bundle.fiberSizes

		for sibling in self.parent.children:
			if isinstance(sibling, ROISegmentation):
				self.tree = sibling.tree

		if self.tree == None:
			self.tree = OctreePointBased(self.points, self.fiberSizes)

		self.fileName = 'ROI Segmentation' # temporal

		self.alpha = 0.8
		self.validLogic = False

		self.configFiberValidator()

		self._loadBuffers()
		self.buildVertex2Fiber()
		self.vboAndLinkVertex2Fiber()

		self.boundingbox = BoundingBox(shaderDict, self, bundle.boundingbox.dims, bundle.boundingbox.center)

	# @timeit
	def segmentMethod(self):
		rois2beQuery = None
		roisResults = None

		if self.validLogic:
			rois2beQuery = [self.rois[i] for i in self.logicRois]
		else:
			rois2beQuery = [self.rois[i] for i in [i for i, e in enumerate(self.roiValidator) if e]]

		n = len(rois2beQuery)

		if n == 0:
			self.fiberValidator[:self.curvescount] = 1

		else:
			roisResults = np.zeros((n, self.curvescount), dtype=np.int8)

			dt = np.dtype([	('center', np.float32, 3),
							('radius', np.float32, 3),
							('roiType', np.int32, (1,))])

			dataPacked = np.empty(len(rois2beQuery), dtype=dt)

			for i in range(len(rois2beQuery)):
				dataPacked[i]['center'] = rois2beQuery[i].getCenter(self.inverseModel)
				dataPacked[i]['radius'] = rois2beQuery[i].getRadius(self.inverseModel)
				dataPacked[i]['roiType'] = rois2beQuery[i].getROIValue()

			self.tree.queryCollision(dataPacked, roisResults)

			if self.validLogic:
				infix = [roisResults[self.logicRois.index(i)] if isinstance(i, int) else i for i in self.logicInfix]
				self.fiberValidator[:self.curvescount] = shuntingYard(infix)

			else:
				self.fiberValidator[:self.curvescount] = roisResults.sum(axis=0, dtype=np.int8) #could overflow with 256 rois or more

	def addROI(self, roi):
		'''
		'''

		if isinstance(roi, ROI) and not roi in self.rois:
			self.children.append(roi)
			self.rois.append(roi)
			self.roiValidator.append(True)

	def removeROIFromIndex(self, index):
		roi = self.rois.pop(index)
		self.roiValidator.pop(index)
		self.children.remove(roi)

	def setValidatorAtIndex(self, index, validate):
		self.roiValidator[index] = validate

	def updateLogic(self, logicStr):
		self.validLogic = False

		if logicStr == '':
			raise ValueError('ROISegmentation: Empty logic string.')

		parsed = self.parseLogicString(logicStr)

		if not parsed:
			raise ValueError('ROISegmentation: Not a valid string for logic operations.')

		self.logicInfix = parsed

		self.logicRois = list(set([i for i in parsed if isinstance(i, int)]))

		if max(self.logicRois) >= len(self.rois):
			raise ValueError('ROISegmentation: Not a valid ID for ROI selection. ID: {}.'.format(max(self.logicRois)))

		self.validLogic = True

	def parseLogicString(self, logicStr):
		''' Could get a list of valid ids '''
		numberStack = ''
		infix = []

		for i in logicStr:
			if i.isdigit():
				numberStack += i

			elif i == '|' or i == '&' or i == '^' or i == '(' or i == ')' or i == '!':

				if numberStack != '':
					infix.append(int(numberStack))
					if infix[-1] >= len(self.rois):
						return False
					numberStack = ''

				infix.append(i)

			elif i == '+':
				if numberStack != '':
					infix.append(int(numberStack))
					if infix[-1] >= len(self.rois):
						return False
					numberStack = ''

				infix.append('|')

			else:
				return False

		if numberStack != '':
			infix.append(int(numberStack))

		return infix


# -*- coding: utf-8 -*-
# (C) 2013 Smile (<http://www.smile.fr>)
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).

from odoo import api, fields, models, _
from odoo.tools import format_date

class AccountInvoice(models.Model):
    _inherit = 'account.invoice'

    @api.multi
    def action_invoice_open(self):
        if not self._context.get('force_invoice_open'):
            invoices_in_error, errors = self._check_unvalid_taxes()
            if invoices_in_error:
                return {
                    'type': 'ir.actions.act_window',
                    'name': _('Unvalid taxes'),
                    'res_model': 'account.invoice.tax.wizard',
                    'view_mode': 'form',
                    'view_id': False,
                    'res_id': False,
                    'context': {
                        'default_invoices_in_error':
                            repr(invoices_in_error.ids),
                        'default_errors': '\n'.join(errors),
                    },
                    'target': 'new',
                }
        return super(AccountInvoice, self).action_invoice_open()

    @api.multi
    def _check_unvalid_taxes(self):
        invoices_in_error, errors = self.browse(), []
        for invoice in self:
            date_invoice = invoice.date_invoice or fields.Date.today()
            for tax in invoice.mapped('invoice_line_ids.invoice_line_tax_ids'):
                if tax.date_start and date_invoice < tax.date_start:
                    invoices_in_error |= invoice
                    errors.append(
                        _('The tax %s shall apply from %s') %
                        (tax.name, format_date(self.env, tax.date_start)))
                if tax.date_stop and date_invoice > tax.date_stop:
                    invoices_in_error |= invoice
                    errors.append(
                        _('The tax %s shall apply to %s') %
                        (tax.name, format_date(self.env, tax.date_stop)))
        return invoices_in_error, errors


from django.test import TestCase
from car import models

class ModelTest(TestCase):

    def test_create_user_with_email_successful(self):
        """Test creating a new car is successful"""
        category = 'CO'
        model = "TT RS 2020"
        name = 'Audi TT RS TURBO'
        number_of_doors = 3
        description = 'This car is a beast'
        car = models.Car.objects.create(
            category=category,
            model=model,
            name=name,
            number_of_doors=number_of_doors,
            description=description
        )

        self.assertEqual(car.category, category)
        self.assertEqual(car.model, model)
        self.assertEqual(car.name, name)
        self.assertEqual(car.number_of_doors, number_of_doors)
        self.assertEqual(car.description, description)


import time
from selenium.webdriver.support.ui import Select
from selenium import webdriver

class InventoryPage():
    def __init__(self,driver) :
        self.driver = driver

    def navigate(self, urlLogin):
        self.driver.get(urlLogin)

    def changeSorting(self, locatorClass, option):
        self.sel = Select (self.driver.find_element_by_class_name (locatorClass))
        self.sel.select_by_value (option)

    def check_A_to_Z_sort(self):
        items_names = self.driver.find_elements_by_class_name("inventory_item_name")
        for name in items_names:
            name_text=name.text
            print(name_text)
            names_list=[]
            names_list.append(name_text)
        sorted_names = sorted(names_list)
        if(names_list == sorted_names):
            print("'A_to_Z' sorting working ")
        else:
            print("'A_to_Z' sorting not working")

    def check_Z_to_A_sort(self):
        items_names = self.driver.find_elements_by_class_name("inventory_item_name")
        for name in items_names:
            name_text=name.text
            print(name_text)
            names_list=[]
            names_list.append(name_text)
        sorted_names = sorted(names_list)
        reversed_names = sorted_names.reverse()
        if(names_list == reversed_names):
            print("'Z_to_A' sorting working ")
        else:
            print("'Z_to_A' sorting not working")

    def check_low_to_high_sort(self):
        items_prices = self.driver.find_elements_by_class_name ("inventory_item_price")
        for price in items_prices:
            price_text=price.text
            price_text = price_text.replace('$','')
            value = float(price_text)
            prices_values=[]
            prices_values.append(value)
        sorted_prices = sorted(prices_values)
        if(prices_values == sorted_prices):
            print("'low_to_high' sorting working ")
        else:
            print("'low_to_high' sorting not working")

    def check_high_to_low_sort(self):
        items_prices = self.driver.find_elements_by_class_name ("inventory_item_price")
        for price in items_prices:
            price_text=price.text
            price_text = price_text.replace('$','')
            value = float(price_text)
            prices_values=[]
            prices_values.append(value)
        sorted_prices = sorted(prices_values)
        reversed_prices = sorted_prices.reverse()
        if(prices_values == reversed_prices):
            print("'high_to_low' sorting working ")
        else:
            print("'high_to_low' sorting not working")

    def click_item_page_and_verify(self,item_full_id):
        self.driver.find_element_by_id(item_full_id).click()
        item_id = item_full_id[5]
        currentURL = self.driver.current_url
        assert currentURL == "https://www.saucedemo.com/inventory-item.html?id=" + str(item_id)
        print("item page " + str(item_id)+" opened")

    def click_item_to_cart_and_verify(self,item_id):
        self.driver.find_element_by_id(item_id).click()
        item_shopped = self.driver.find_element_by_class_name("shopping_cart_badge")
        assert int(item_shopped.text) == 1
        self.driver.find_element_by_class_name("shopping_cart_badge").click()
        time.sleep(2)
        self.driver.find_element_by_id("checkout").click()
        time.sleep(2)
        currentURL = self.driver.current_url
        assert currentURL == "https://www.saucedemo.com/checkout-step-one.html"
        print("check out page opened")


import itertools

# 소수 판별 함수
# 2보다 작으면 무조건 False
# 2나 3이면 소수다.
# 2 또는 3으로 나눠지면 소수가 아니다.
# 10 미만의 값들은 2나 3으로만 나눠지지 않으면 된다.
# 그 이상의 수들에 대해서는 5, 7, 9, 11, 13, 15... 등의 홀수로 나눠보면 된다. 하지만 이미 3의 배수에 대해서는 앞에서 검사하기 때문에 5, 7, 11, 15,... 의 패턴으로 검사할 수 있다.
# N이 소수인지를 알고 싶으면 N의 제곱근까지만 검사해보면 된다.

def is_prime(n):
    if n < 2:
        return False
    if n == 2 or n == 3:
        return True
    if n % 2 == 0 or n % 3 == 0:
        return False
    if n < 9:
        return True
    k, l = 5, n ** 0.5

    while k <= l:
        if n % k == 0 or n % (k+2) == 0:
            return False
        k += 6
    return True

def solution(nums):
    answer = 0
    nums = list(itertools.combinations(nums,3))
    for i in nums:
        n = sum(i)
        if is_prime(n):
            answer += 1

    return answer


import unittest
import socket

def test_server_connection():
    # Cria um socket e envia uma mensagem para o servidor
    client = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    client.sendto(b"Hello, server!", ("127.0.0.1", 333))

    # Verifica se a mensagem foi recebida pelo servidor corretamente
    received_message = server.recv(1024)
    assert received_message == b"Hello, server!", "Mensagem não recebida pelo servidor corretamente"

# Adiciona a função de teste ao conjunto de testes
def suite():
    suite = unittest.TestSuite()
    suite.addTest(unittest.makeSuite(test_server_connection))
    return suite

# Executa o conjunto de testes
unittest.TextTestRunner().run(suite())


from copy import deepcopy

def courses_to_take(course_to_pre_reqs):
    if not course_to_pre_reqs:
        return []
    for course in course_to_pre_reqs:
        ret = list()
        if not course_to_pre_reqs[course]:
            print(course_to_pre_reqs)
            ret.append(course)
            next_pre_reqs = deepcopy(course_to_pre_reqs)
            del next_pre_reqs[course]
            if not next_pre_reqs:
                return ret
            for c in next_pre_reqs:
                if course in next_pre_reqs[c]:
                    next_pre_reqs[c].remove(course)
            extra = courses_to_take(next_pre_reqs)
            if extra is not None:
                return ret + extra
    return None

def main():
    courses = {
        'CSC300': ['CSC100', 'CSC200'],
        'CSC200': ['CSC100'],
        'CSC100': []
    }
    assert courses_to_take(courses) == ['CSC100', 'CSC200', 'CSC300']
    prereqs = {
        'CSC400': ['CSC200'],
        'CSC300': ['CSC100', 'CSC200'],
        'CSC200': ['CSC100'],
        'CSC100': []
    }
    assert courses_to_take(prereqs) == ['CSC100', 'CSC200', 'CSC400', 'CSC300']
    prereqs = {
        'CSC400': ['CSC300'],
        'CSC300': ['CSC100', 'CSC200'],
        'CSC200': ['CSC100'],
        'CSC100': ['CSC400']
    }
    assert not courses_to_take(prereqs)

if __name__ == '__main__':
    main()


from django.test import TestCase

from costcenter.forms import FundForm

class FundFormTest(TestCase):
    def test_empty_form(self):
        form = FundForm()
        self.assertIn("fund", form.fields)
        self.assertIn("name", form.fields)
        self.assertIn("vote", form.fields)
        self.assertIn("download", form.fields)

        # test just one rendered field
        self.assertInHTML(
            '<input type="text" name="fund" maxlength="4" required id="id_fund">',
            str(form),
        )

    def test_filled_form(self):
        data = {"fund": "C119", "name": "National Procurement", "vote": 1, "download": True}
        f = FundForm(data=data)
        self.assertTrue(f.is_valid())

    def test_vote_not_1_or_5(self):
        data = {"fund": "C113", "name": "NP", "vote": "6", "download": 1}
        form = FundForm(data=data)

        self.assertEqual(form.errors["vote"], ["Vote must be 1 or 5"])

    def test_fund_starts_with_non_letter(self):
        data = {"fund": "3113"}
        form = FundForm(data=data)

        self.assertEqual(form.errors["fund"], ["Fund must begin with a letter"])

    def test_fund_is_not_4_characters_long(self):
        data = {"fund": "c3456"}
        form = FundForm(data=data)
        msg = f"Ensure this value has at most 4 characters (it has {len(data['fund'])})."
        self.assertEqual(form.errors["fund"], [msg])


from traceback import print_stack

from allure_commons.types import AttachmentType
from selenium.webdriver import ActionChains
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait
from selenium.common.exceptions import NoSuchElementException, ElementNotVisibleException, ElementNotSelectableException
import allure
import SeleniumFrameWork.utilities.CustomLogger as cl

class BaseClass:
    log = cl.customLogger()

    def __init__(self, driver):
        self.driver = driver

    def launchWebPage(self, url, title):
        try:
            self.driver.get(url)
            assert title in self.driver.title
            self.log.info("Web Page Launch with " + url)
        except:
            self.log.info("Web Page Not Launch with " + url)

    def getLocatorType(self, locatorType):
        locatorType = locatorType.lower()
        if locatorType == "id":
            return By.ID
        elif locatorType == "name":
            return By.NAME
        elif locatorType == "class":
            return By.CLASS_NAME
        elif locatorType == "link":
            return By.LINK_TEXT
        elif locatorType == "xpath":
            return By.XPATH
        elif locatorType == "css":
            return By.CSS_SELECTOR
        elif locatorType == "tag":
            return By.TAG_NAME
        elif locatorType == "plink":
            return By.PARTIAL_LINK_TEXT
        else:
            self.log.error(f"Locator Type {locatorType} entered not found")
            print_stack()

        return False

    def getWebElement(self, locatorValue, locatorType="id"):
        webElement = None
        try:
            locatorType = locatorType.lower()
            locatorByType = self.getLocatorType(locatorType)
            webElement = self.driver.find_element(locatorByType, locatorValue)
            self.log.info(f"Web Element found with locator value {locatorValue} using locator type {locatorByType}")
        except:
            self.log.error(
                f"Web Element Not found with locator value {locatorValue} using locator type {locatorByType}")
            print_stack()

        return webElement

    def waitForElement(self, locatorValue, locatorType="id"):
        webElement = None
        try:
            locatorType = locatorType.lower()
            locatorByType = self.getLocatorType(locatorType)
            wait = WebDriverWait(self.driver, 25, poll_frequency=1,
                                 ignored_exceptions=[NoSuchElementException, ElementNotVisibleException,
                                                     ElementNotSelectableException])
            # webElement = self.driver.find_element(locatorByType, locatorValue)
            webElement = wait.until(lambda x: x.find_element(locatorByType, locatorValue))
            self.log.info(f"Web Element found with locator value {locatorValue} using locator type {locatorByType}")
        except:
            self.log.error(
                f"Web Element Not found with locator value {locatorValue} using locator type {locatorByType}")
            print_stack()
            self.takeScreenshot(locatorType)
            assert False
        return webElement

    def clickOnElement(self, locatorValue, locatorType="id"):
        try:
            locatorType = locatorType.lower()
            webElement = self.waitForElement(locatorValue, locatorType)
            webElement.click()
            self.log.info(f"Click On Web Element with locator value {locatorValue} using locator type {locatorType}")
        except:
            self.log.error(
                f"Unable to Click On Element with locator value {locatorValue} using locator type {locatorType}")
            print_stack()
            assert False

    def sendText(self, text, locatorValue, locatorType="id"):
        try:
            locatorType = locatorType.lower()
            webElement = self.waitForElement(locatorValue, locatorType)
            webElement.send_keys(text)
            self.log.info(
                f"Send the text {text} in Web Element with locator value {locatorValue} using locator type {locatorType}")
        except:
            self.log.info(
                f"Unable to Send the text {text} in Web Element with locator value {locatorValue} using locator type {locatorType}")
            print_stack()
            self.takeScreenshot(locatorType)
            assert False

    def getText(self, locatorValue, locatorType="id"):
        elementText = None
        try:
            locatorType = locatorType.lower()
            webElement = self.waitForElement(locatorValue, locatorType)
            elementText = webElement.text
            self.log.info(
                f"Got the text {elementText} in Web Element with locator value {locatorValue} using locator type {locatorType}")
        except:
            self.log.info(
                f"Unable to get the text {elementText} in Web Element with locator value {locatorValue} using locator type {locatorType}")
            print_stack()

        return elementText

    def isElementDisplayed(self, locatorValue, locatorType="id"):
        elementDisplayed = None
        try:
            locatorType = locatorType.lower()
            webElement = self.waitForElement(locatorValue, locatorType)
            elementDisplayed = webElement.is_displayed()
            self.log.info(
                f" Web Element is Displayed web page with locator value {locatorValue} using locator type {locatorType}")
        except:
            self.log.info(
                f" Web Element is Not Displayed web page with locator value {locatorValue} using locator type {locatorType}")
            print_stack()

        return elementDisplayed

    def scrollTo(self, locatorValue, locatorType="id"):
        actions = ActionChains(self.driver)
        try:
            locatorType = locatorType.lower()
            webElement = self.waitForElement(locatorValue, locatorType)
            actions.move_to_element(webElement).perform()
            self.log.info(
                f"Scrolled to WebElement with locator value {locatorValue} using locator type {locatorType}")
        except:
            self.log.info(
                f"Unable to Scroll to WebElement with locator value {locatorValue} using locator type {locatorType}")
            print_stack()

    def takeScreenshot(self, text):
        allure.attach(self.driver.get_screenshot_as_png(), name=text, attachment_type=AttachmentType.PNG)


from django.urls import path

from Zoo import views
import templates

urlpatterns = [
    path('login/', views.user_login, name='login'),
    path('logout/',views.logout, name='logout'),
    path('user_create/', views.user_create, name='user_create'),
    path('index/', views.index, name='index'),
    path('detail/<int:id>', views.animal_detail, name='animal_detail'),
    path('animal_delete/<int:id>/', views.animal_delete, name='animal_delete'),
    path('check/<int:id>', views.check, name='check'),
    path('search/', views.search, name='search'),
    path('search_filter/', views.search_filter, name='search_filter'),
    path('write_log/<int:id>/', views.write_log, name='write_log'),
    path('edit_log/<int:id>/', views.edit_log, name='edit_log'),
    path('log_delete/<int:id>/', views.log_delete, name='log_delete'),
    path('zone/<int:id>', views.zone, name='zone'),
]


import collections

from .pybeesgrid import TAG_SIZE, NUM_CONFIGS, NUM_MIDDLE_CELLS
from .pybeesgrid import GridGenerator, BadGridArtist, BlackWhiteArtist, \
    MaskGridArtist, DepthMapArtist
from .pybeesgrid import drawGrids

from .pybeesgrid import INNER_BLACK_SEMICIRCLE, CELL_0_BLACK, CELL_1_BLACK, \
    CELL_2_BLACK, CELL_3_BLACK, CELL_4_BLACK, CELL_5_BLACK, CELL_6_BLACK, \
    CELL_7_BLACK, CELL_8_BLACK, CELL_9_BLACK, CELL_10_BLACK, CELL_11_BLACK, \
    IGNORE, CELL_0_WHITE, CELL_1_WHITE, CELL_2_WHITE, CELL_3_WHITE,  \
    CELL_4_WHITE, CELL_5_WHITE, CELL_6_WHITE, CELL_7_WHITE, CELL_8_WHITE, \
    CELL_9_WHITE, CELL_10_WHITE, CELL_11_WHITE, OUTER_WHITE_RING, \
    INNER_WHITE_SEMICIRCLE

import numpy as np
import warnings

TAG_ID = ['bits']
TAG_CONFIG = ['z_rotation', 'y_rotation', 'x_rotation', 'center', 'radius']
TAG_STRUCTURE = ['inner_ring_radius', 'middle_ring_radius', 'outer_ring_radius', 'bulge_factor',
                 'focal_length']

TAG_LABEL_NAMES = TAG_ID + TAG_CONFIG + TAG_STRUCTURE

CONFIG_LABELS = ('z_rotation', 'y_rotation', 'x_rotation',
                 'center_x', 'center_y', 'radius')

CONFIG_ROTS = (
    CONFIG_LABELS.index('z_rotation'),
    CONFIG_LABELS.index('y_rotation'),
    CONFIG_LABELS.index('x_rotation'),
)

CONFIG_CENTER = (
    CONFIG_LABELS.index('center_x'),
    CONFIG_LABELS.index('center_y'),
)

CONFIG_RADIUS = CONFIG_LABELS.index('radius')

MASK = collections.OrderedDict([
    ("INNER_BLACK_SEMICIRCLE", INNER_BLACK_SEMICIRCLE),
    ("CELL_0_BLACK",           CELL_0_BLACK),
    ("CELL_1_BLACK",           CELL_1_BLACK),
    ("CELL_2_BLACK",           CELL_2_BLACK),
    ("CELL_3_BLACK",           CELL_3_BLACK),
    ("CELL_4_BLACK",           CELL_4_BLACK),
    ("CELL_5_BLACK",           CELL_5_BLACK),
    ("CELL_6_BLACK",           CELL_6_BLACK),
    ("CELL_7_BLACK",           CELL_7_BLACK),
    ("CELL_8_BLACK",           CELL_8_BLACK),
    ("CELL_9_BLACK",           CELL_9_BLACK),
    ("CELL_10_BLACK",          CELL_10_BLACK),
    ("CELL_11_BLACK",          CELL_11_BLACK),
    ("IGNORE",                 IGNORE),
    ("CELL_0_WHITE",           CELL_0_WHITE),
    ("CELL_1_WHITE",           CELL_1_WHITE),
    ("CELL_2_WHITE",           CELL_2_WHITE),
    ("CELL_3_WHITE",           CELL_3_WHITE),
    ("CELL_4_WHITE",           CELL_4_WHITE),
    ("CELL_5_WHITE",           CELL_5_WHITE),
    ("CELL_6_WHITE",           CELL_6_WHITE),
    ("CELL_7_WHITE",           CELL_7_WHITE),
    ("CELL_8_WHITE",           CELL_8_WHITE),
    ("CELL_9_WHITE",           CELL_9_WHITE),
    ("CELL_10_WHITE",          CELL_10_WHITE),
    ("CELL_11_WHITE",          CELL_11_WHITE),
    ("OUTER_WHITE_RING",       OUTER_WHITE_RING),
    ("INNER_WHITE_SEMICIRCLE", INNER_WHITE_SEMICIRCLE)
])

MASK_KEYS = list(MASK.keys())
CELLS_BLACK = MASK_KEYS[MASK_KEYS.index("CELL_0_BLACK"):MASK_KEYS.index("CELL_11_BLACK")+1]
MASK_BLACK = ["INNER_BLACK_SEMICIRCLE"] + CELLS_BLACK
CELLS_WHITE = MASK_KEYS[
              MASK_KEYS.index("CELL_0_WHITE"):
              MASK_KEYS.index("CELL_11_WHITE")+1]

MASK_WHITE = CELLS_WHITE + ["OUTER_WHITE_RING", "INNER_WHITE_SEMICIRCLE"]

def dtype_tag_params(nb_bits=12, with_structure=False):
    keys = TAG_ID + TAG_CONFIG
    if with_structure:
        keys += TAG_STRUCTURE
    reps = {key: 1 for key in keys}
    reps['bits'] = nb_bits
    reps['center'] = 2
    return [(key, "({},)float32".format(n)) for key, n in reps.items()]

def draw_grids(params, with_structure='auto', scales=[1.], artist=None):
    def get_positions(keys):
        positions = {}
        i = 0
        for name in keys:
            positions[name] = i
            i += len(params[name][0])
        return positions, i

    def array_fill_by_keys(struct_arr, keys, positions, arr):
        for name in keys:
            b = positions[name]
            e = b + len(struct_arr[name][0])
            arr[:, b:e] = struct_arr[name]

    if artist is None:
        artist = BlackWhiteArtist(0, 255, 0, 1)

    batch_size = len(params['bits'])
    positions, size = get_positions(TAG_ID + TAG_CONFIG)
    bits_and_config = np.zeros((batch_size, size), dtype=np.float32)
    array_fill_by_keys(params, TAG_ID + TAG_CONFIG, positions, bits_and_config)

    if with_structure == 'auto':
        with_structure = all([struct_key in params.dtype.names for struct_key in TAG_STRUCTURE])
    if with_structure:
        struct_positions, struct_size = get_positions(TAG_STRUCTURE)
        structure = np.zeros((batch_size, struct_size), dtype=np.float32)
        array_fill_by_keys(params, TAG_STRUCTURE, struct_positions, structure)
        structure = np.ascontiguousarray(structure)
    else:
        structure = None
    bits_and_config = np.ascontiguousarray(bits_and_config)
    if structure is not None and (structure == 0).all():
        warnings.warn(
            "draw_grids got a structure that is all zero. Did you use "
            "`dtype_tag_params(with_structure=True)`"
            " and forgot to set the structure?")

    assert bits_and_config.dtype == np.float32
    assert bits_and_config.flags['C_CONTIGUOUS']
    return drawGrids(bits_and_config, structure, artist, scales)

def _normalize_angle(x):
    x %= 2*np.pi
    x = (x + 2*np.pi) % (2*np.pi)
    x[x > np.pi] -= 2*np.pi
    assert ((-np.pi <= x) & (x <= np.pi)).all()
    return x


import time
from openerp.report import report_sxw
from openerp.osv import osv

class report_common(report_sxw.rml_parse):
    def __init__(self, cr, uid, name, context=None):
        super(report_common, self).__init__(cr, uid, name, context=context)
        self.localcontext.update({
            'time': time,
            'rmb_upper': self._rmb_upper,
        })

    def _rmb_upper(self, value):
        """
        人民币大写
        来自：http://topic.csdn.net/u/20091129/20/b778a93d-9f8f-4829-9297-d05b08a23f80.html
        传入浮点类型的值返回 unicode 字符串
        """
        rmbmap = [u"零", u"壹", u"贰", u"叁", u"肆", u"伍", u"陆", u"柒", u"捌", u"玖"]
        unit = [u"分", u"角", u"元", u"拾", u"佰", u"仟", u"万", u"拾", u"佰", u"仟", u"亿",
                u"拾", u"佰", u"仟", u"万", u"拾", u"佰", u"仟", u"兆"]

        nums = map(int, list(str('%0.2f' % value).replace('.', '')))
        words = []
        zflag = 0  # 标记连续0次数，以删除万字，或适时插入零字
        start = len(nums) - 3
        for i in range(start, -3, -1):  # 使i对应实际位数，负数为角分
            if 0 != nums[start - i] or len(words) == 0:
                if zflag:
                    words.append(rmbmap[0])
                    zflag = 0
                words.append(rmbmap[nums[start - i]])
                words.append(unit[i + 2])
            elif 0 == i or (0 == i % 4 and zflag < 3):  # 控制‘万/元’
                words.append(unit[i + 2])
                zflag = 0
            else:
                zflag += 1

        if words[-1] != unit[0]:  # 结尾非‘分’补整字
            words.append(u"整")
        return ''.join(words)

class report_vehicle_contract(osv.AbstractModel):
    _name = 'report.vehicle_sales_contract_print.report_contract'
    _inherit = 'report.abstract_report'
    _template = 'vehicle_sales_contract_print.report_contract'
    _wrapped_report_class = report_common


import json
import random

while True:
    inp = input("> ")
    ints = {}
    with open('intents.json', 'r') as f:
        json.dump(f, ints)
    try:
        if ints[inp].type() == list:
            val = random.choice(ints[inp])
        else:
            val = ints[inp]
        print(val)
    except:
        print("I don't understand.")


def solution(s):
    from collections import deque
    answer = ''
    s = deque(s)
    while s:
        a = s.popleft()
        if answer:
            if answer[-1] == ' ':
                answer += a.upper()
            else:
                answer += a.lower()
        else:
            answer += a.upper()
    return answer

프로그래머스/lv2/12951. JadenCase 문자열 만들기/JadenCase 문자열 만들기.py


import sys

def parse_text(start_state, rules_for_state, fileinput_gen, file=None):
    if file:
        f = open(file, 'w+')
        sys.stdout = f

    line_number = 1
    state = start_state
    text = ''.join(fileinput_gen)
    start_index = 0
    end_index = len(text)
    while start_index < end_index:
        best_len = 0
        best_rule = None
        rules = rules_for_state[state]
        regex = text[start_index:end_index]
        for rule in rules:
            length = rule.automate.satisfies(regex)
            if length > best_len:
                best_len = length
                best_rule = rule
        if best_rule:
            accepted_text = regex[:best_len]
            if best_rule.vrati_se is not None:
                accepted_text = accepted_text[:best_rule.vrati_se]
                start_index += best_rule.vrati_se
            else:
                start_index += len(accepted_text)
            if best_rule.uniform_sign != '-':
                print(best_rule.uniform_sign, line_number, accepted_text, sep=' ') #regex or accepted_text
            if best_rule.udji_u_stanje:
                state = best_rule.udji_u_stanje
            if best_rule.novi_redak:
                line_number += 1
        else:
            start_index += 1
    f.close()


# 10845 : 큐

import sys

n = int(sys.stdin.readline())     # n 입력받기
arr = []

for i in range(n) :               # n 번만큼 반복해서 명령어 입력받기
  command = sys.stdin.readline().split()
  func = command[0]               # func : 명령어

  if len(command) == 2 :          # push : 명령어와 숫자가 동시에 들어올 때
    arr.append(command[1])        # arr 배열에 원소 추가

  else :
    if func == 'pop' :            # 명령어가 pop 일 때
      if len(arr) != 0 :
        print(arr[0])
        arr.pop(0)
      else :
        print(-1)

    elif func == 'size' :         # 명령어가 size 일 때
      print(len(arr))

    elif func == 'empty' :        # 명령어가 empty 일 때
      print(1 if len(arr) == 0 else 0)

    elif func == 'front' :         # 명령어가 front 일 때
      print(arr[0] if len(arr) != 0 else -1)

    elif func == 'back' :          # 명령어가 back 일 때
      print(arr[-1] if len(arr) != 0 else -1)

# pop()  : 맨 마지막 원소 삭제
# pop(0) : 맨 처음 원소 삭제