#! /usr/bin/env python

import sys
import os
import re
import math
import numpy
import array
import pyDRC
import matplotlib.pyplot as plt

def PCA(DataFileList, PCA_dir, analysis_dir):
    PreWindowGap = 192
    PreWindowLen = 256
    dataLength = 2**16
    SampleRate = pyDRC.GetSampleRate(DataFileList[0])
    Size = len(DataFileList)

    Mean = numpy.zeros((Size), numpy.double)
    DataArray = numpy.zeros((Size,dataLength), numpy.double)
    TrArray = numpy.zeros((Size,dataLength), numpy.double)
    ResultArray = numpy.zeros((Size, dataLength), numpy.double)
    #SpectrumArray = numpy.zeros((Size, dataLength), float)

    length = 0
    for i in range(Size):
        print("---------------------------------------------------------------------------------")
        print("\tProcessing impulse file:%s"%DataFileList[i])
        l = pyDRC.FSize(DataFileList[i])
        length = max(length, l)
        peakPos =  pyDRC.FindMaxPcm(DataFileList[i])
        DataArray[i]  = numpy.asarray(pyDRC.ReadSignal(DataFileList[i], 2*dataLength, peakPos)[0])[dataLength-PreWindowLen:-PreWindowLen]
        for j in range(PreWindowLen - PreWindowGap):
            DataArray[i][j] = 0.
        DataArray[i][PreWindowLen - PreWindowGap: PreWindowLen] *= numpy.blackman(2*PreWindowGap)[:PreWindowGap]
        DataArray[i][-PreWindowGap:] *= numpy.blackman(2*PreWindowGap)[PreWindowGap:]
        print("\t\tLenght:%i samples. Sample peak at:%i"%(l, peakPos))

    for k in range(0, int(2*numpy.ceil(Size/2)), 2):
        fig, (ax) = plt.subplots(2,2)
        for l in range(2):
            i = k + l
            spectrum = 20*numpy.log10(numpy.abs(numpy.fft.fft(DataArray[i])))
            mn = spectrum.mean()
            smax = int(10*numpy.ceil((spectrum-mn).max()/10))
            ax[l,1].semilogx(numpy.linspace(0, SampleRate, len(spectrum)),spectrum - mn, linewidth=0.4)
            ax[l,1].set_xlim(xmin=20.,xmax=20000.)
            ax[l,1].set_ylim(ymin=smax-50.,ymax=smax)
            ax[l,1].tick_params(axis='x', labelsize=9)
            ax[l,1].tick_params(axis='y', labelsize=9)
            ax[l,1].set_xlabel("Frequency Hz", fontsize = 9)
            ax[l,1].set_ylabel("dB", fontsize = 9)
            ax[l,1].set_title("%s spectrum"%DataFileList[i].split("/")[-1].replace('.wav',''),fontsize = 9)
            ax[l,1].grid(True)
            if DataArray[i].max() == numpy.abs(DataArray[i]).max():
                ax[l,0].plot(numpy.linspace(0, len(DataArray[i]), len(DataArray[i])),DataArray[i]/numpy.abs(DataArray[i]).max(),linewidth=0.4)
            else:
                ax[l,0].plot(numpy.linspace(0, len(DataArray[i]), len(DataArray[i])),-1.0*DataArray[i]/numpy.abs(DataArray[i]).max(),linewidth=0.4)
            ax[l,0].set_xlim(xmin=0,xmax=1000)
            ax[l,0].set_ylim(ymin=-1.2,ymax=1.2)
            ax[l,0].tick_params(axis='x', labelsize=9)
            ax[l,0].tick_params(axis='y', labelsize=9)
            ax[l,0].set_xlabel("Time (samples)",fontsize = 9)
            ax[l,0].set_ylabel("Amplitude (normalized)", fontsize = 9)
            ax[l,0].set_title("%s"%DataFileList[i].split("/")[-1].replace('.wav',''),fontsize = 9)
            ax[l,0].grid(True)
            plt.tight_layout()
            pyDRC.WriteSignal('%s/filtered_data__%s.wav'%(analysis_dir,DataFileList[i].split("/")[-1].replace('.wav','')),DataArray[i]/(2*numpy.abs(DataArray[i]).max()),0,dataLength,SampleRate,'F')
        plt.savefig("%s/impulse_spectrum_%i.png"%(analysis_dir,k/2))
    print("Data File max length:%d"%length)

    for i in range(Size):
        Mean[i] = numpy.mean(DataArray[i])
        TrArray[i] = DataArray[i] - Mean[i]

    ER = numpy.cov(TrArray)
    print("Covariance matrix:\n",ER)
    eigvalues, eigvectors = numpy.linalg.eig(ER)
    print("Eigenvalues:\n",eigvalues)
    print("Eigenvectors:\n",eigvectors)
    ResultArray = numpy.dot(numpy.transpose(eigvectors),TrArray)
    ER2 = numpy.cov(ResultArray)
    print("Final Covariance matrix:\n",ER2)

    maxvalue = 0
    for i in range(Size):
        maxvalue = max(maxvalue,max(ResultArray[i]))
        if ResultArray[0].max() == numpy.abs(ResultArray[0]).max():
            pyDRC.WriteSignal('%s/PCA_%d.wav'%(PCA_dir, i+1),numpy.concatenate((numpy.zeros(len(ResultArray[i])),ResultArray[i]/(2*numpy.abs(ResultArray[i]).max()))),0,2*len(ResultArray[i]), SampleRate,'F')
        else:
            pyDRC.WriteSignal('%s/PCA_%d.wav'%(PCA_dir, i+1),numpy.concatenate((numpy.zeros(len(ResultArray[i])),-1.0*ResultArray[i]/(2*numpy.abs(ResultArray[i]).max()))),0,2*len(ResultArray[i]), SampleRate,'F')
    for k in range(0, int(2*numpy.ceil(Size)/2), 2):
        fig, (ax) = plt.subplots(2,2)
        for l in range(2):
            i = k + l
            spectrum = 20*numpy.log10(numpy.abs(numpy.fft.fft(ResultArray[i])))
            smax = int(10*numpy.ceil(spectrum.max()/10))
            ax[l,1].semilogx(numpy.linspace(0, SampleRate, len(spectrum)),spectrum, linewidth=0.4)
            ax[l,1].set_xlim(xmin=20.,xmax=20000.)
            ax[l,1].set_ylim(ymin=smax-50.,ymax=smax)
            ax[l,1].tick_params(axis='x', labelsize=9)
            ax[l,1].tick_params(axis='y', labelsize=9)
            ax[l,1].set_xlabel("Frequency Hz", fontsize = 9)
            ax[l,1].set_ylabel("dB", fontsize = 9)
            ax[l,1].set_title("PCA-%d sprectrum"%i, fontsize = 9)
            ax[l,1].grid(True)
            if ResultArray[0].max() == numpy.abs(ResultArray[0]).max():
                ax[l,0].plot(numpy.linspace(0, len(ResultArray[i]), len(ResultArray[i])),ResultArray[i]/numpy.abs(ResultArray[i]).max(),linewidth=0.4)
            else:
                ax[l,0].plot(numpy.linspace(0, len(ResultArray[i]), len(ResultArray[i])),-1.*ResultArray[i]/numpy.abs(ResultArray[i]).max(),linewidth=0.4)
            ax[l,0].set_xlim(xmin=0,xmax=1000)
            ax[l,0].set_ylim(ymin=-1.2,ymax=1.2)
            ax[l,0].tick_params(axis='x', labelsize=9)
            ax[l,0].tick_params(axis='y', labelsize=9)
            ax[l,0].set_xlabel("Time (samples)",fontsize = 9)
            ax[l,0].set_ylabel("Amplitude (normalized)", fontsize = 9)
            ax[l,0].set_title("PCA-%d "%i, fontsize = 9)
            ax[l,0].grid(True)
            plt.tight_layout()
        plt.savefig("%s/PCA_spectrum_%i.png"%(analysis_dir,k/2))

    fig, (ax1, ax2) = plt.subplots(2)
    spectrum = 20*numpy.log10(numpy.abs(numpy.fft.fft(ResultArray[0])))
    ax2.semilogx(numpy.linspace(0, SampleRate, len(spectrum)),spectrum-spectrum.max(),linewidth=0.4)
    ax2.set_xlim(xmin=20.,xmax=20000.)
    ax2.set_ylim(ymin=-50.,ymax=10.)
    ax2.tick_params(axis='x', labelsize=9)
    ax2.tick_params(axis='y', labelsize=9)
    ax2.set_xlabel("Frequency Hz", fontsize = 9)
    ax2.set_ylabel("dB", fontsize = 9)
    ax2.grid(True)
    if ResultArray[0].max() == numpy.abs(ResultArray[0]).max():
        ax1.plot(numpy.linspace(0, len(ResultArray[0]), len(ResultArray[0])),ResultArray[0]/numpy.abs(ResultArray[0]).max(),linewidth=0.4)
    else:
        ax1.plot(numpy.linspace(0, len(ResultArray[0]), len(ResultArray[0])),-1.*ResultArray[0]/numpy.abs(ResultArray[0]).max(),linewidth=0.4)
    ax1.set_xlim(xmin=0,xmax=1000)
    ax1.set_ylim(ymin=-1.2,ymax=1.2)
    ax1.tick_params(axis='x', labelsize=9)
    ax1.tick_params(axis='y', labelsize=9)
    ax1.set_xlabel("Time (samples)",fontsize = 9)
    ax1.set_ylabel("Amplitude (normalized)", fontsize = 9)
    ax1.grid(True)
    plt.savefig("%s/Spectrum_PCA_principal.png"%(analysis_dir))

def main():
    impulse_dir ="."
    PCA_dir = "."
    analysis_dir = "."
    if len(sys.argv) < 7:
        print("Usage:")
        print("python pca_analysis.py -i impulses_dir -p PCA_dir -a analysis_dir")
        sys.exit()
    for i in range(1,len(sys.argv)):
        if sys.argv[i] == "-i":
            impulse_dir = sys.argv[i+1]
        elif sys.argv[i] == "-p":
            PCA_dir = sys.argv[i+1]
            if not os.path.isdir(PCA_dir):
                os.mkdir(PCA_dir)
        elif sys.argv[i] == "-a":
            analysis_dir = sys.argv[i+1]
            if not os.path.isdir(analysis_dir):
                os.mkdir(analysis_dir)

    DataFileList = []
    for fileName in os.listdir(impulse_dir):
        if fileName.find("wav") > 0:
            print("Found impulse file %s"%fileName)
            DataFileList.append("%s/%s"%(impulse_dir,fileName))
    DataFileList.sort()
    PCA(DataFileList, PCA_dir, analysis_dir)

if __name__ == '__main__':
    main()


from __future__ import absolute_import, unicode_literals

from celery import Celery,task
from time import sleep

app = Celery('tasks')
app.config_from_object('celeryconfig')

@app.task()
def hello_world():
    return 'Hello world.........'

@app.task()
def UploadTask():

    # Update the state. The meta data is available in task.info dicttionary
    # The meta data is useful to store relevant information to the task
    # Here we are storing the upload progress in the meta.

    UploadTask.update_state(state='PROGRESS', meta={'progress': 0})
    sleep(30)
    UploadTask.update_state(state='PROGRESS', meta={'progress': 30})
    sleep(30)
    UploadTask.update_state(state='SUCCESS', meta={'progress': 100})


import os
import uuid

from django.conf import settings
from django.core.files import File
from django.db.models import Q
from django.http import HttpResponse, Http404
from knox.auth import TokenAuthentication
from rest_framework import generics
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response

from application.models import Challenges, TruthFile, Dataset, Submission
from application.serializers import ChallengeSerializer, ChallengePrintSerializer, DatasetSerializer
from authentification.permissions import IsAdmin, IsStaff

# Fonction de DUPLICATION D'UN CHALLENGE
def duplicate_challenge_func(destination_course_id, challenge_id):
    challenge_source = Challenges.objects.get(challenge_id=challenge_id)
    # Copie du fichier script
    file = File(challenge_source.scriptFile)
    filename = os.path.basename(file.name)
    file.name = filename
    try:
        Challenges.objects.get(course_id=destination_course_id, title=challenge_source.title)
        challenge_name = challenge_source.title + str(uuid.uuid1())[0:8]
    except Challenges.DoesNotExist:
        challenge_name = challenge_source.title

    challenge = Challenges.objects.create(course_id=destination_course_id, title=challenge_name,
                                          description=challenge_source.description,
                                          limitDate=challenge_source.limitDate, nbSubmit=challenge_source.nbSubmit,
                                          nbStudent=challenge_source.nbStudent, inputExt=challenge_source.inputExt,
                                          inputParam=challenge_source.inputParam,
                                          command=challenge_source.command,
                                          scriptFile=File(file),
                                          args=challenge_source.args, outputs=challenge_source.outputs,
                                          scoreKeys=challenge_source.scoreKeys)
    truths = TruthFile.objects.filter(challenge_id=challenge_id)
    dataset = Dataset.objects.filter(challenge_id=challenge_id)
    # Copie des fichiers truths

    for item in truths:
        file = File(item.file)
        filename = os.path.basename(file.name)
        file.name = filename
        TruthFile.objects.create(param=item.param, file=file, course=challenge.course,
                                 challenge=challenge)
    # Copie des fichiers datasets

    for item in dataset:
        file = File(item.file)
        filename = os.path.basename(file.name)
        file.name = filename
        Dataset.objects.create(file=file, course=challenge.course, challenge=challenge)
    return challenge

# DataParam parser
def dataToArray(data, datakey):
    array = []
    i = 0
    while True:
        itemFile = data.get(datakey + "[" + str(i) + "]")

        if None == itemFile:
            break
        array.append(itemFile)
        i += 1
    return array

# TurthParam parser
def combinateTruth(data):
    array = []
    i = 0
    while True:
        itemParam = data.get("truthFilesParam" + "[" + str(i) + "]")
        itemFile = data.get("truthFiles" + "[" + str(i) + "]")

        if None == itemFile or None == itemParam:
            break
        item = {}
        item["param"] = itemParam
        item["file"] = itemFile
        array.append(item)
        i += 1
    return array

# ArgsParam parser
def combinateArgs(data):
    array = []
    i = 0
    while True:
        itemValue = data.get("argsValue" + "[" + str(i) + "]")
        itemParam = data.get("argsParam" + "[" + str(i) + "]")

        if None == itemValue or None == itemParam:
            break
        item = {}
        item["param"] = itemParam
        item["value"] = itemValue
        array.append(item)
        i += 1
    return array

# OutputsParam parser

def combinateOutputs(data):
    array = []
    i = 0
    while True:
        itemParam = data.get("outputsParam" + "[" + str(i) + "]")
        itemExt = data.get("outputsExt" + "[" + str(i) + "]")

        if None == itemExt or None == itemParam:
            break
        item = {}
        item["param"] = itemParam
        item["ext"] = itemExt
        array.append(item)
        i += 1
    return array

class CreateChallenge(generics.GenericAPIView):
    permission_classes = [IsAuthenticated, IsAdmin]
    authentication_classes = (TokenAuthentication,)
    serializer_class = ChallengeSerializer

    def post(self, request, *args, **kwargs):
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        challenge = serializer.save(args=combinateArgs(self.request.data), outputs=combinateOutputs(self.request.data),
                                    scoreKeys=dataToArray(self.request.data, "scoreKeys"))
        truths = combinateTruth(self.request.data)
        dataset = dataToArray(self.request.data, "dataset")
        # Creation des truths
        for item in truths:
            TruthFile.objects.create(param=item['param'], file=item['file'], course=challenge.course,
                                     challenge=challenge)
        # Creations des datasets
        for item in dataset:
            Dataset.objects.create(file=item, course=challenge.course, challenge=challenge)

        return Response(
            {
                "challenge": ChallengeSerializer(challenge, context=self.get_serializer_context()).data
            }
        )

class DuplicateChallenge(generics.GenericAPIView):
    permission_classes = [IsAuthenticated, IsAdmin]
    authentication_classes = (TokenAuthentication,)

    def post(self, request, *args, **kwargs):
        challenge_id = self.request.data.get("challenge_id")
        destination_course_id = self.request.data.get("course_id")
        challenge = duplicate_challenge_func(destination_course_id, challenge_id)
        return Response(
            {
                "challenge": ChallengeSerializer(challenge, context=self.get_serializer_context()).data
            }
        )

class EditChallenge(generics.UpdateAPIView):
    permission_classes = [IsAuthenticated, IsAdmin]
    authentication_classes = (TokenAuthentication,)
    serializer_class = ChallengeSerializer

    def get_object(self, queryset=None):
        return Challenges.objects.get(challenge_id=self.request.data.get("challenge_id"))

    def update(self, request, *args, **kwargs):
        instance = self.get_object()
        serializer = self.get_serializer(instance, data=self.request.data)
        serializer.is_valid(raise_exception=True)
        challenge = serializer.save(args=combinateArgs(self.request.data), outputs=combinateOutputs(self.request.data),
                                    scoreKeys=dataToArray(self.request.data, "scoreKeys"))
        # Supression des anciens Truths et datasets
        TruthFile.objects.filter(challenge=challenge).delete()
        Dataset.objects.filter(challenge=challenge).delete()

        truths = combinateTruth(self.request.data)
        dataset = dataToArray(self.request.data, "dataset")
        # Creation des nouveaux Truths et datasets

        for item in truths:
            TruthFile.objects.create(param=item['param'], file=item['file'], course=challenge.course,
                                     challenge=challenge)

        for item in dataset:
            Dataset.objects.create(file=item, course=challenge.course, challenge=challenge)

        return Response(
            {
                "challenge": ChallengeSerializer(challenge, context=self.get_serializer_context()).data
            }
        )

class ChallengeFetch(generics.ListAPIView):
    permission_classes = (IsAuthenticated,)
    authentication_classes = (TokenAuthentication,)
    serializer_class = ChallengePrintSerializer

    def get_queryset(self):
        # Pour staff
        if self.request.user.is_staff:
            criterion1 = Q(course__owner_id=self.request.user)
            criterion2 = Q(course__management__user_id=self.request.user)
            qs = Challenges.objects.filter(criterion1 | criterion2)
        # Pour users
        else:
            criterion1 = Q(course__enrollment__user_id=self.request.user)
            criterion2 = Q(is_visible=True)
            qs = Challenges.objects.filter(criterion1 & criterion2)

        for item in qs:
            query_dataset = Dataset.objects.filter(challenge=item)
            item.dataset = DatasetSerializer(query_dataset, many=True).data
        return qs

class RemoveChallenge(generics.DestroyAPIView):
    permission_classes = [IsAuthenticated, IsStaff]
    authentication_classes = (TokenAuthentication,)
    serializer_class = ChallengeSerializer
    lookup_field = 'challenge_id'

    def get_queryset(self):
        challenge_id = self.kwargs['challenge_id']
        queryset_challenges = Challenges.objects.filter(course__owner_id=self.request.user, challenge_id=challenge_id)
        return queryset_challenges

    def destroy(self, request, *args, **kwargs):
        instance = self.get_object()
        TruthFile.objects.filter(challenge=instance).delete()
        Dataset.objects.filter(challenge=instance).delete()
        Submission.objects.filter(challenge=instance).delete()

        self.perform_destroy(instance)

        return Response(
            {
                "detail": "ok"
            })

# Rendre un challenge visible ou non par les étudiants
class SwitchVisibility(generics.UpdateAPIView):
    permission_classes = [IsAuthenticated, IsStaff]
    authentication_classes = (TokenAuthentication,)
    serializer_class = ChallengeSerializer
    lookup_field = 'challenge_id'

    def get_queryset(self):
        challenge_id = self.kwargs['challenge_id']
        queryset_challenges = Challenges.objects.filter(course__owner_id=self.request.user, challenge_id=challenge_id)
        return queryset_challenges

    def update(self, request, *args, **kwargs):
        instance = self.get_object()
        instance.is_visible = not instance.is_visible
        instance.save()
        self.perform_update(instance)

        return Response({
            "challenge": ChallengeSerializer(instance, context=self.get_serializer_context()).data

        })

# Autoriser ou non la supression des soumissions

class SwitchDeleteSubmission(generics.UpdateAPIView):
    permission_classes = [IsAuthenticated, IsStaff]
    authentication_classes = (TokenAuthentication,)
    serializer_class = ChallengeSerializer
    lookup_field = 'challenge_id'

    def get_queryset(self):
        challenge_id = self.kwargs['challenge_id']
        queryset_challenges = Challenges.objects.filter(course__owner_id=self.request.user, challenge_id=challenge_id)
        return queryset_challenges

    def update(self, request, *args, **kwargs):
        instance = self.get_object()
        instance.enable_delete_submission = not instance.enable_delete_submission
        instance.save()
        self.perform_update(instance)

        return Response({
            "challenge": ChallengeSerializer(instance, context=self.get_serializer_context()).data

        })

# Autoriser ou non la modification des membre d'un groupe

class SwitchEditGroup(generics.UpdateAPIView):
    permission_classes = [IsAuthenticated, IsStaff]
    authentication_classes = (TokenAuthentication,)
    serializer_class = ChallengeSerializer
    lookup_field = 'challenge_id'

    def get_queryset(self):
        challenge_id = self.kwargs['challenge_id']
        queryset_challenges = Challenges.objects.filter(course__owner_id=self.request.user, challenge_id=challenge_id)
        return queryset_challenges

    def update(self, request, *args, **kwargs):
        instance = self.get_object()
        instance.enable_edit_group = not instance.enable_edit_group
        instance.save()
        self.perform_update(instance)

        return Response({
            "challenge": ChallengeSerializer(instance, context=self.get_serializer_context()).data

        })

# Demande de telechargement des datasets
class getDataset(generics.RetrieveAPIView):
    permission_classes = (IsAuthenticated,)
    authentication_classes = (TokenAuthentication,)

    def get(self, request, *args, **kwargs):
        dataset = Dataset.objects.get(file_id=request.GET['file_id'])
        file_path = os.path.join(settings.MEDIA_ROOT, str(dataset.file))
        if os.path.exists(file_path):
            with open(file_path, 'rb') as fh:
                response = HttpResponse(fh.read(), content_type="application/force-download")
                response['Content-Disposition'] = 'inline; filename=' + os.path.basename(file_path)
                return response
        raise Http404


# Runge Kutta 4th order to edo system of two equations.

"""
INPUT:  dy/dx = f1(x,y,z)  : differential equation 1
        dz/dx = f2(x,y,z)  : differential equation 2
        y(x(0)) = y0 : initial condition 1
        z(x(0)) = z0 : initial condition 2
        xf           : variable final which define range
        n            : number of points
OUTPUT: Aproximation solution of differential equations system whit its graph
"""

import numpy as np
import matplotlib.pyplot as plt

def solveSystem(x0,y0,z0,xf,n):

    h = (xf-x0)/(n-1)
    x = np.linspace(x0,xf,n)
    y = np.zeros([n,1])
    z = np.zeros([n,1])

    y[0] = y0
    z[0] = z0

    for i in range(1,n):
        k1 = h*f1(x[i-1],y[i-1],z[i-1])
        l1 = h*f2(x[i-1],y[i-1],z[i-1])
        k2 = h*f1(x[i-1]+h/2,y[i-1]+k1/2,z[i-1]+l1/2)
        l2 = h*f2(x[i-1]+h/2,y[i-1]+k1/2,z[i-1]+l1/2)
        k3 = h*f1(x[i-1]+h/2,y[i-1]+k2/2,z[i-1]+l2/2)
        l3 = h*f2(x[i-1]+h/2,y[i-1]+k2/2,z[i-1]+l2/2)
        k4 = h*f1(x[i-1]+h, y[i-1]+k3,z[i-1]+l3)
        l4 = h*f2(x[i-1]+h, y[i-1]+k3,z[i-1]+l3)

        y[i] = y[i-1] + (k1 + 2*k2 + 2*k3 + k4)/6
        z[i] = z[i-1] + (l1 + 2*l2 + 2*l3 + l4)/6

    plt.plot(x,y,label='Y aprox')
    plt.plot(x,z,label='Z aprox')
    plt.xlabel("X values")
    plt.ylabel("Y,Z values")
    plt.legend()
    plt.title("Sytem of First Order Differential Equations")
    plt.show()

def f1(x,y,z):
    return z

def f2(x,y,z):
    return 0.05*z-0.15*y

def main():

    x0 = 0.0
    y0 = 1.0
    z0 = 0.0
    xf = 5.0
    n  = 21  # 21 points -> 20 spaces between points.
    solveSystem(x0,y0,z0,xf,n,)

main()


#import library
import pathlib
import numpy as np
from tensorflow import keras
from keras import Sequential
from keras.layers import Dense
import  csv
import  tensorflow as tf

#Train Data to make a prediction about total sold based on price
def predictionmodel():
    # Preprocessing Data
    filename = 'Dataset.csv'
    reader = csv.reader(open(filename, "rt"), delimiter=",")
    header = next(reader)
    sold = []
    price = []
    for row in reader:
        price.append(row[1])
        sold.append(row[2])
    price = np.array(price, dtype=float)
    sold = np.array(sold, dtype=float)
    PRICE = price / 1000000
    SOLD = sold / 100

    # Split Data
    train_ratio = 0.8
    Y_TRAIN_SIZE = int(len(SOLD) * train_ratio)
    X_TRAIN_SIZE = int(len(PRICE) * train_ratio)
    xtrain_data = PRICE[:X_TRAIN_SIZE]
    xtest_data = PRICE[X_TRAIN_SIZE:]
    ytrain_data = SOLD[:Y_TRAIN_SIZE]
    ytest_data = SOLD[Y_TRAIN_SIZE:]
    X_train = [item for item in xtrain_data]
    X_test = [item for item in xtest_data]
    y_train = [item for item in ytrain_data]
    y_test = [item for item in ytest_data]

    # build model
    model = Sequential([Dense(10,input_shape=[1],input_dim=1),
                        Dense(10),
                        Dense(1)])

    # compile the model
    model.compile(optimizer=keras.optimizers.SGD(learning_rate=1e-4), loss='mean_squared_error',metrics=['mae'])

    # train the model
    model.fit(X_train, y_train, epochs=100,validation_data=(X_test,y_test))
    return model

#make a simple case
model = predictionmodel()
inpt = int(input('Masukkan Harga Untuk Prediksi jumlah yang akan terjual(jt) : '))
new_x = inpt
prediction = model.predict([new_x])[0][0]
print('Prediksi Jumlah Rata-Rata yang akan Terjual :',int(prediction * 100) ,'unit' )
model.save("model.h5")

#save the model
# export_dir ='model/1'
# if '__main__':
#     tf.saved_model.save(model,export_dir=export_dir)
#     mode = 'Speed'
#     if mode =='Storage':
#         optimization=tf.lite.Optimize.OPTIMIZE_FOR_SIZE
#     elif mode =='Speed':
#         optimization =tf.lite.Optimize.OPTIMIZE_FOR_LATENCY
#     else:
#         optimization = tf.lite.Optimize.DEFAULT
#     converter = tf.lite.TFLiteConverter.from_keras_model(export_dir)
#     converter.optimizations=[optimization]
#     tflite_model = converter.convert();
#     tflite_model_file = pathlib.Path('./model.tflite')
#     tflite_model_file.write_bytes(tflite_model)


"""
PublicIP related functions.

PublicIPs object variables:

	public_ips.public_ips - list of PublicIP objects

PublicIP object variables:

	public_ip.id - alias of public
	public_ip.public
	public_ip.internal
	public_ip.ports - list of port/protocol dicts

Port object variables:

	port.protocol
	port.port
	port.port_to

Source Restriction object variables:

	source_restriction.cidr

"""
from __future__ import print_function, absolute_import, unicode_literals

# vCur:

# vNext:
# TODO - PublicIPs search by port and source restriction
# TODO - Access PublicIPs by index - map directly to public_ips.public_ipds list
# TODO - wait on request and ID/store assigned public IP
# TODO - optional param to not call PublicIP.Update() with port/src changes so they can be batched

import re
import json
import clc

class PublicIPs(object):

	def __init__(self,server,public_ips_lst,session=None):
		self.server = server
		self.public_ips = []
		self.session = session

		for public_ip in public_ips_lst:
			if 'public' in public_ip:
				self.public_ips.append(PublicIP(id=public_ip['public'],parent=self,public_ip_obj=public_ip,session=self.session))

	def Get(self,key):
		"""Get public_ip by providing either the public or the internal IP address."""

		for public_ip in self.public_ips:
			if public_ip.id == key:  return(public_ip)
			elif key == public_ip.internal:  return(public_ip)

	def Add(self,ports,source_restrictions=None,private_ip=None):
		"""Add new public_ip.

		Specify one or more ports using a list of dicts with the following keys:

			protocol - TCP, UDP, or ICMP
			port - int 0-65534
			port_to - (optional) if specifying a range of ports then the rqange end.  int 0-65534

		Optionally specify one or more source restrictions using a list of dicts with the following keys:

			cidr - string with CIDR notation for the subnet (e.g. "132.200.20.0/24")

		private_ip is the existing private IP address to NAT to (optional)

		# New public IP with single port
		>>> p = clc.v2.Server(alias='BTDI',id='WA1BTDIX03').PublicIPs()
		>>> p.Add(ports=[{"protocol": "TCP","port":5}]).WaitUntilComplete()
		0

		# New public IP with port range
		>>> p.Add([{"protocol": "UDP","port":10,"port_to":50}]).WaitUntilComplete()
		0

		# Map existing private IP to single port
		>>> p.Add(ports=[{"protocol": "TCP","port":22}],k
		          source_restrictions=[{'cidr': "132.200.20.0/24"}],
				  private_ip="10.80.148.13").WaitUntilComplete()
		0

		* Note this API is subject to revision to make ports and source restrictions access to parallel
		  that used for accessors.

		* public_ips.public_ips will not be updated to reflect this addition. Recreate object after request completes
		  to access new info including getting the IP itself

		"""

		payload = {'ports': []}
		for port in ports:
			if 'port_to' in port:  payload['ports'].append({'protocol':port['protocol'], 'port':port['port'], 'portTo':port['port_to']})
			else:  payload['ports'].append({'protocol':port['protocol'], 'port':port['port']})
		if source_restrictions:  payload['sourceRestrictions'] = source_restrictions
		if private_ip:  payload['internalIPAddress'] = private_ip

		return(clc.v2.Requests(clc.v2.API.Call('POST','servers/%s/%s/publicIPAddresses' % (self.server.alias,self.server.id),
		                                       json.dumps(payload),session=self.session),
		                       alias=self.server.alias,session=self.session))

class PublicIP(object):

	def __init__(self,id,parent,public_ip_obj=None,session=None):
		"""Create PublicIP object."""

		self.id = id
		self.internal = public_ip_obj['internal']
		self.parent = parent
		self.data = None
		self.session = session

	def _Load(self,cached=True):
		"""Performs a full load of all PublicIP metadata."""

		if not self.data or not cached:
			self.data = clc.v2.API.Call('GET','servers/%s/%s/publicIPAddresses/%s' % (self.parent.server.alias,self.parent.server.id,self.id),
										session=self.session)

			# build ports
			self.data['_ports'] = self.data['ports']
			self.data['ports'] = []
			for port in self.data['_ports']:
				if 'portTo' in port:  self.ports.append(Port(self,port['protocol'],port['port'],port['portTo']))
				else:  self.ports.append(Port(self,port['protocol'],port['port']))

			# build source restriction
			self.data['_source_restrictions'] = self.data['sourceRestrictions']
			self.data['source_restrictions'] = []
			for source_restriction in self.data['_source_restrictions']:
				self.source_restrictions.append(SourceRestriction(self,source_restriction['cidr']))

		return(self.data)

	def Delete(self):
		"""Delete public IP.

		>>> clc.v2.Server("WA1BTDIX01").PublicIPs().public_ips[0].Delete().WaitUntilComplete()
		0

		"""

		self.parent.public_ips = [o for o in self.parent.public_ips if o!=self]
		return(clc.v2.Requests(clc.v2.API.Call('DELETE','servers/%s/%s/publicIPAddresses/%s' % (self.parent.server.alias,self.parent.server.id,self.id),
											   session=self.session),
		                       alias=self.parent.server.alias,
							   session=self.session))

	def Update(self):
		"""Commit  current PublicIP definition to cloud.

		Usually called by the class to commit changes to port and source restriction policies.

		>>> clc.v2.Server("WA1BTDIX01").PublicIPs().public_ips[0].Update().WaitUntilComplete()
		0

		"""

		return(clc.v2.Requests(clc.v2.API.Call('PUT','servers/%s/%s/publicIPAddresses/%s' % (self.parent.server.alias,self.parent.server.id,self.id),
						                       json.dumps({'ports': [o.ToDict() for o in self.ports],
											               'sourceRestrictions': [o.ToDict() for o in self.source_restrictions] }),
											   session=self.session),
							   alias=self.parent.server.alias,
							   session=self.session))

	def AddPort(self,protocol,port,port_to=None):
		"""Add and commit a single port.

		# Add single port
		>>> clc.v2.Server("WA1BTDIX01").PublicIPs().public_ips[0].AddPort(protocol='TCP',port='22').WaitUntilComplete()
		0

		# Add port range
		>>> clc.v2.Server("WA1BTDIX01").PublicIPs().public_ips[0].AddPort(protocol='UDP',port='10000',port_to='15000').WaitUntilComplete()
		0

		"""

		self.ports.append(Port(self,protocol,port,port_to))

		return(self.Update())

	def AddPorts(self,ports):
		"""Create one or more port access policies.

		Include a list of dicts with protocol, port, and port_to (optional - for range) keys.

		>>> clc.v2.Server("WA1BTDIX01").PublicIPs().public_ips[0]
				.AddPorts([{'protocol': 'TCP', 'port': '80' },
				           {'protocol': 'UDP', 'port': '10000', 'port_to': '15000'}]).WaitUntilComplete()
		0

		"""

		for port in ports:
			if 'port_to' in port:  self.ports.append(Port(self,port['protocol'],port['port'],port['port_to']))
			else:  self.ports.append(Port(self,port['protocol'],port['port']))

		return(self.Update())

	def AddSourceRestriction(self,cidr):
		"""Add and commit a single source IP restriction policy.

		>>> clc.v2.Server("WA1BTDIX01").PublicIPs().public_ips[0]
				.AddSourceRestriction(cidr="132.200.20.1/32").WaitUntilComplete()
		0

		"""

		self.source_restrictions.append(SourceRestriction(self,cidr))

		return(self.Update())

	def AddSourceRestrictions(self,cidrs):
		"""Create one or more CIDR source restriction policies.

		Include a list of CIDR strings.

		>>> clc.v2.Server("WA1BTDIX01").PublicIPs().public_ips[0]
				.AddSourceRestrictions(cidrs=["132.200.20.1/32","132.200.20.100/32"]).WaitUntilComplete()
		0

		"""

		for cidr in cidrs:  self.source_restrictions.append(SourceRestriction(self,cidr))

		return(self.Update())

	def __getattr__(self,var):
		if var in ('source_restrictions',):  key = var
		elif var[0] != "_": key = re.sub("_(.)",lambda pat: pat.group(1).upper(),var)
		else:  key = var

		if not self.data: self._Load()

		if key in self.data:  return(self.data[key])
		else:  raise(AttributeError("'%s' instance has no attribute '%s'" % (self.__class__.__name__,key)))

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

class Port(object):

	def __init__(self,public_ip,protocol,port,port_to=None):
		self.public_ip = public_ip
		self.protocol = protocol
		self.port = port
		self.port_to = port_to

	def Delete(self):
		"""Delete this port and commit change to cloud.

		>>> clc.v2.Server("WA1BTDIX01").PublicIPs().public_ips[0].ports[0].Delete().WaitUntilComplete()
		0

		"""

		self.public_ip.ports = [o for o in self.public_ip.ports if o!=self]

		return(self.public_ip.Update())

	def ToDict(self):
		d = {'protocol': self.protocol,'port': self.port}
		if self.port_to:  d['portTo'] = self.port_to

		return(d)

	def __str__(self):
		if self.port_to:  return("%s-%s/%s" % (self.port,self.port_to,self.protocol))
		else:  return("%s/%s" % (self.port,self.protocol))

class SourceRestriction(object):

	def __init__(self,public_ip,cidr):
		self.public_ip = public_ip
		self.cidr = cidr

	def Delete(self):
		"""Delete this source restriction and commit change to cloud.

		>>> clc.v2.Server("WA1BTDIX01").PublicIPs().public_ips[0].source_restrictions[0].Delete().WaitUntilComplete()
		0

		"""

		self.public_ip.source_restrictions = [o for o in self.public_ip.source_restrictions if o!=self]

		return(self.public_ip.Update())

	def ToDict(self):
		d = {'cidr': self.cidr}

		return(d)

	def __str__(self):
		return("%s" % (self.cidr))


import hudmodule
from matplotlib.backends.backend_tkagg import (
    FigureCanvasTkAgg, NavigationToolbar2Tk)
from matplotlib.figure import Figure
import tkinter as tk
from tkinter import *
import networkx as nx

class interface_analysis:
    def __init__(self):
        self.root = tk.Tk()
        self.fig = Figure(figsize=(7, 7), dpi=72)
        self.canvas = FigureCanvasTkAgg(self.fig, master=self.root)
        self.toolbar = NavigationToolbar2Tk(self.canvas, self.root)
        self.root.wm_title("Анализ репозиторий Github")
        self.canvas.draw()
        self.canvas.get_tk_widget().pack(side=tk.TOP, fill=tk.BOTH, expand=1)
        self.toolbar.update()
        self.canvas.get_tk_widget().pack(side=tk.TOP, fill=tk.BOTH, expand=1)
        self.ax = self.fig.add_subplot(111)
        self.githubGraph = hudmodule.githubStars()

    def example(self):
        self.ax.clear()
        self.githubGraph.setToken('2cb6efd6c6628ecd7e5e359d191feb5a2ea1e495')
        self.githubGraph.setUser('MNYudina')
        self.githubGraph.setRepo('Seminars')
        g = self.githubGraph.getGraph()
        g = self.githubGraph.getMoreGraph(g)
        nx.draw(g, node_color=self.githubGraph.color_map, with_labels=True, ax=self.ax)
        self.canvas.draw()

    def enter(self):
        self.ax.clear()
        self.githubGraph.setToken(self.e1.get())
        self.githubGraph.setUser(self.e2.get())
        self.githubGraph.setRepo(self.e3.get())
        g = self.githubGraph.getGraph()
        g = self.githubGraph.getMoreGraph(g)
        nx.draw(g, node_color=self.githubGraph.color_map, with_labels=True, ax=self.ax)
        self.canvas.draw()

    def start(self):
        self.button = tk.Button(master=self.root, text="Пример", command=self.example)
        self.button.pack(side=tk.BOTTOM)
        self.button = tk.Button(master=self.root, text="Расчитать", command=self.enter)
        self.button.pack(side=tk.BOTTOM)
        self.labl = Label(text="Токен", fg="#eee", bg="#333")
        self.labl.pack()
        self.e1 = Entry(width=50)
        self.e1.pack()
        self.labl2 = Label(text="Пользователь", fg="#eee", bg="#333")
        self.labl2.pack()
        self.e2 = Entry(width=50)
        self.e2.pack()
        self.labl3 = Label(text="Названия репозитория", fg="#eee", bg="#333")
        self.labl3.pack()
        self.e3 = Entry(width=50)
        self.e3.pack()
        tk.mainloop()

if __name__ == '__main__':
    prog = interface_analysis()
    prog.start()


from parse_bt_payload import ParseBTPayload
from datetime import datetime

class NormalizedWebhookData(object):

  def __init__(self, webhook):

    self.raw_webhook = webhook
    self.provider = None
    self.id = None
    self.date = None
    self.user_id = None
    self.user_name = None
    self.type = None
    self.raw_type = None

    # parse data for filtering (bt)
    if hasattr(webhook, 'data') and 'bt_payload' in webhook.data and bool(len(webhook.data['bt_payload'])):
      parsed_data = ParseBTPayload(webhook.data['bt_payload'][0]).to_dict()
      webhook = parsed_data['notification']
      self.provider = 'braintree'
      self.id = webhook['subject']['subscription']['id']
      self.date = self.convert_bt_timestamp(webhook['timestamp']['value'])
      self.raw_type = webhook['kind']
    # stripe
    else:
      self.provider = 'stripe'
      self.id = webhook.data['data']['object']['customer']
      self.date = datetime.fromtimestamp(webhook.data['created'])
      self.raw_type = webhook.data['type']
      self.user_name = webhook.data['data']['object']['source']['name'] if 'source' in webhook.data['data']['object'] else webhook.data['data']['object']['customer_email']

  def meets_criteria(self, criteria):
    conditions = criteria.split('&')

    # stage 1, transform data into iterables/other types if needed for comparators
    comparatorTransform = {
      ':in->': lambda actual, given: [actual, list(map(lambda x: x.strip(), given.split(',')))]
    }

    # stage 2, primitives / iterable of primitives each transformed by their attribute type
    typeTransform = {
      'date': [
        lambda actual: actual,
        lambda given: datetime.strptime(given.replace(':', '').replace('-',''), "%Y%m%d")
      ]
    }

    # stag 3, comparison is done
    dic = {
      ':in->': lambda actual, given: actual in given,
      '=' : lambda actual, given: actual == given,
      '<' : lambda actual, given: actual < given,
      '>' : lambda actual, given: actual > given,
    }

    meets_criteria = True
    for condition in conditions:
      activeComparator = None
      comparatorPossiblities = dic.keys()
      for possibleComparator in comparatorPossiblities:
        if possibleComparator in condition:
          activeComparator = possibleComparator
          break
      if activeComparator is not None and activeComparator in dic:
        [actualKey, givenValue] = condition.split(activeComparator)
        actualValue = getattr(self, actualKey)
        if actualValue is not None:
          if activeComparator in comparatorTransform:

            [actualValue, givenValue] = comparatorTransform[activeComparator](actualValue, givenValue)
          if actualKey in typeTransform:
            modifierFnActual = typeTransform[actualKey][0]
            modifierFnGiven = typeTransform[actualKey][1]
            actualValue = list(map(lambda x: modifierFnActual(x), actualValue)) if isinstance(actualValue, list) else modifierFnActual(actualValue)
            givenValue = list(map(lambda x: modifierFnGiven(x), givenValue)) if isinstance(givenValue, list) else modifierFnGiven(givenValue)
          meets_criteria = dic[activeComparator](actualValue, givenValue)
          if not meets_criteria:
            break

    return meets_criteria

  def max_text(self, text, _max=None):
    text = str(text)
    buffer = 3
    ellipsis = '...'
    extra = buffer + len(ellipsis)
    if _max is None:
      return text
    elif len(text) <= _max - extra:
      return text + ''.join(map(lambda x: ' ', range(0, _max - len(text))))
    else:
      return text[0: _max - extra] + ''.join(map(lambda x: ' ', range(0, len(text[0: _max - extra]) - _max))) + ellipsis + ' '.join(map(lambda x: '', range(0, buffer + 1)))

  def to_str_row(self):
    return f'{self.max_text(self.provider, 15)}{self.max_text(self.id, 24)}{self.max_text(self.raw_type, 42)}{self.max_text(self.date, 25)}{(self.user_name if self.user_name is not None else "Unknown User")} {f"({self.user_id})" if self.user_id is not None else ""}'

  def convert_bt_timestamp(self, ts):
    return datetime.strptime(ts.replace(':', '').replace('-',''), "%Y%m%dT%H%M%SZ")


import cPickle
import numpy as np
import os
import scipy.stats as spstats

class Workspace(object):

    def __init__(self, movies, ratings, users, k=1, cwd='dat/pkl'):
        self.cwd = cwd
        self.k = k

        self.movies = movies
        self.ratings = ratings
        self.users = users
        self.tags = {}
        self.decades = {}
        self.age_groups = {}
        self.genders = {}
        self.occupations = {}

    def summarize_movies(self):
        def compute():
            movie_ratings = self.ratings.for_movie(m.ID)
            return Workspace.summary_stats(movie_ratings)

        for m in self.movies.movies:
            pickle_fn = os.path.join(self.cwd, 'movies', str(m.ID))
            self.movies[m.ID].summarize(*Workspace.load_or_compute(pickle_fn, compute))

    def summarize_users(self):
        def compute():
            movie_ratings = self.ratings.for_user(u.ID)
            return Workspace.summary_stats(movie_ratings)

        for u in self.users.users:
            pickle_fn = os.path.join(self.cwd, 'users', str(u.ID))
            self.users[u.ID].summarize(*Workspace.load_or_compute(pickle_fn, compute))

    def summarize_tags(self):
        def compute():
            movie_ratings = self.ratings.for_tag(t, movies=self.movies)
            return Workspace.summary_stats(movie_ratings)

        for t in self.movies.tags:
            pickle_fn = os.path.join(self.cwd, 'tags', str(t))
            self.tags[t] = Workspace.load_or_compute(pickle_fn, compute)

    def summarize_decades(self):
        def compute():
            movie_ratings = self.ratings.for_decade(d, movies=self.movies)
            return Workspace.summary_stats(movie_ratings)

        for d in self.movies.decades:
            pickle_fn = os.path.join(self.cwd, 'decades', str(d))
            self.decades[d] = Workspace.load_or_compute(pickle_fn, compute)

    def summarize_age_groups(self):
        def compute():
            movie_ratings = self.ratings.for_age_group(a, users=self.users)
            return Workspace.summary_stats(movie_ratings)

        for a in self.users.age_groups:
            pickle_fn = os.path.join(self.cwd, 'age_groups', str(a))
            self.age_groups[a] = Workspace.load_or_compute(pickle_fn, compute)

    def summarize_genders(self):
        def compute():
            movie_ratings = self.ratings.for_gender(g, users=self.users)
            return Workspace.summary_stats(movie_ratings)

        for g in self.users.genders:
            pickle_fn = os.path.join(self.cwd, 'genders', str(g))
            self.genders[g] = Workspace.load_or_compute(pickle_fn, compute)

    def summarize_occupations(self):
        def compute():
            movie_ratings = self.ratings.for_occupation(o, users=self.users)
            return Workspace.summary_stats(movie_ratings)

        for o in self.users.occupations:
            pickle_fn = os.path.join(self.cwd, 'occupations', str(o))
            self.occupations[o] = Workspace.load_or_compute(pickle_fn, compute)

    def extract_components(self):
        def compute():
            raise Exception('run features.py to extract components')

        for m in self.movies.movies:
            if m.count > 0:
                pickle_fn = os.path.join(self.cwd, 'components', '%02d' % self.k, str(m.ID))
                components = Workspace.load_or_compute(pickle_fn, compute)
                self.movies[m.ID].components = np.ones(components.size + 1)
                self.movies[m.ID].components[1:] = components  # components[0] === scale factor

    @staticmethod
    def load_or_compute(pickle_fn, compute):
        if os.path.isfile(pickle_fn):
            result = cPickle.load(open(pickle_fn))
        else:
            result = compute()
            cPickle.dump(result, open(pickle_fn, 'wb'))
        return result

    @staticmethod
    def summary_stats(movie_ratings):
        r_ids = [r.ID for r in movie_ratings]
        count = len(movie_ratings)
        if count > 0:
            amean = np.mean([r.rating for r in movie_ratings])
            hmean = spstats.hmean([r.rating for r in movie_ratings])
            var = np.var([r.rating for r in movie_ratings])
        else:
            amean = np.NaN
            hmean = np.NaN
            var = np.NaN
        return r_ids, count, amean, hmean, var


"""
Model
-----
This module defines AI-dependent functions.
"""
import json
from pathlib import Path
import random
import numpy as np
import torch
from transformers import AutoTokenizer

from src.models.contriever import Contriever

SEED = 42
random.seed(SEED)
np.random.seed(SEED)
torch.manual_seed(SEED)
torch.cuda.manual_seed_all(SEED)

contriever = Contriever.from_pretrained("facebook/contriever")
tokenizer = AutoTokenizer.from_pretrained("facebook/contriever")

with open(Path(__file__).parents[1] / "dataset\qa_df.json", "r", encoding="utf-8") as file:
    faq = json.load(file)

questions = [item["question"] for item in faq]

def get_answer(question: str):
    """Return an aswer and a context to the question from the datanase."""
    answer_and_context = [(item["text"], item["context"]) for item in faq if item["question"] == question]
    return answer_and_context

def find_similar_questions(question: str):
    """Return a list of similar questions from the database."""
    query = tokenizer(question, padding=True, truncation=True, return_tensors="pt")
    embeddings_query = contriever(**query)
    questions_toks = tokenizer(questions, padding=True, truncation=True, return_tensors="pt")
    embeddings_question = contriever(**questions_toks)
    dot_product = []
    for idx, _ in enumerate(embeddings_question):
        dot_product.append((embeddings_query @ embeddings_question[idx]).item())
    ids_max_score = sorted(range(len(dot_product)), key=lambda x: dot_product[x], reverse=True)[:3]
    result = []
    for i in ids_max_score:
        result.append(questions[i])
    return result


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

"""
@Author  : pixelock
@File    : manager.py
@Date    : 2022/10/17 22:00
"""

import os
import cv2
import json
import shutil
import numpy as np
import collections
from tqdm import tqdm

from utils.text import dbc2sbc
from utils.image import get_rotate_crop_image, rotate_image
from utils.bbox import minimal_rectangle, trans_xywh2corners, trans_integer

class DataManager(object):
    def __init__(self, name, is_detection, is_recognition, is_scatter):
        self.dataset_name = name
        self.is_detection = is_detection
        self.is_recognition = is_recognition
        self.is_scatter = is_scatter

        self.det_gts = None
        self.rec_gts = None

    def initialize(self):
        if self.is_detection:
            self.det_gts = self.get_detection_gts()
        if self.is_recognition:
            self.rec_gts = self.get_recognition_gts()

    def get_detection_gts(self):
        raise NotImplementedError

    def detection_output_paddle(self, output_dir):
        gts = self.det_gts or self.get_detection_gts()
        lines = []
        for path, gt in tqdm(gts.items()):
            line = '{}\t{}'.format(
                path,
                json.dumps(gt, ensure_ascii=False),
            )
            lines.append(line)

        with open(output_dir, 'w', encoding='utf-8') as f:
            f.write('\n'.join(lines))

    def save_cropped_image(self, output_dir, v2h=True, v2h_threshold=1.5):
        if not os.path.exists(output_dir):
            os.makedirs(output_dir)

        gts = self.rec_gts

        for path, boxes in tqdm(gts.items()):
            img_data = cv2.imread(path, cv2.IMREAD_COLOR)

            for name, box in boxes.items():
                points = box['points']
                cropped_image = get_rotate_crop_image(
                    img_data,
                    np.array(points).astype('float32'),
                    v2h=v2h,
                    v2h_threshold=v2h_threshold,
                )
                cropped_path = os.path.join(output_dir, name)
                cv2.imwrite(cropped_path, cropped_image, [int(cv2.IMWRITE_JPEG_QUALITY), 100])

    def get_recognition_gts(self):
        ground_truths = dict()

        for image_path, gt in tqdm(self.det_gts.items()):
            image_name = os.path.splitext(os.path.split(image_path)[1])[0]
            available_boxes = dict()

            for index, box in enumerate(gt):
                text = box['transcription']
                points = box['points']
                if '###' in text:
                    continue
                if not text.replace('#', '').strip():
                    continue
                if 'invalid' in box and box['invalid']:
                    continue
                cropped_name = self.generate_cropped_image_name(self.dataset_name, index, image_name)
                available_boxes[cropped_name] = {
                    'transcription': text,
                    'points': points
                }

            ground_truths[image_path] = available_boxes

        return ground_truths

    def generate_cropped_image_name(self, prefix, index, image_name=None, box_info=None):
        if index is None:
            return '{}_{}.jpg'.format(prefix, image_name)
        else:
            return '{}_{}_{}.jpg'.format(prefix, image_name, index)

    def recognition_output_paddle(self, output_dir, image_dir):
        gts = self.rec_gts or self.get_recognition_gts()
        lines = []
        for path, boxes in tqdm(gts.items()):
            for name, box in boxes.items():
                text = box['transcription']
                cropped_path = os.path.join(image_dir, name)
                line = '{}\t{}'.format(cropped_path, text)
                lines.append(line)

        with open(output_dir, 'w', encoding='utf-8') as f:
            f.write('\n'.join(lines))

    @staticmethod
    def convert_points_format(p):
        return [[p[0], p[1]], [p[2], p[3]], [p[4], p[5]], [p[6], p[7]]]

class ReCTSManager(DataManager):
    NUM_SAMPLES = 20000
    P_IMAGE = 'train_ReCTS_{:0>6d}.jpg'
    P_GT = 'train_ReCTS_{:0>6d}.json'

    def __init__(self, path, level='lines'):
        super(ReCTSManager, self).__init__(
            name='rects',
            is_detection=True,
            is_recognition=True,
            is_scatter=True,
        )

        self.root_path = path
        self.img_path = os.path.join(self.root_path, 'img')
        self.gt_path = os.path.join(self.root_path, 'gt')
        self.level = level

        self.initialize()

    def get_detection_gts(self):
        ground_truths = dict()
        for i in tqdm(range(1, self.NUM_SAMPLES + 1)):
            image_path = os.path.abspath(os.path.join(self.img_path, self.P_IMAGE.format(i)))
            gt_path = os.path.join(self.gt_path, self.P_GT.format(i))

            with open(gt_path, 'r', encoding='utf-8') as f:
                raw_gt = json.load(f)
            boxes = raw_gt[self.level]

            available_boxes = []
            for index, box in enumerate(boxes):
                text = box['transcription'] if box['ignore'] == 0 else '###'
                points = self.convert_points_format(box['points'])
                available_boxes.append({
                    'transcription': text,
                    'points': points
                })
            ground_truths[image_path] = available_boxes
        return ground_truths

class LSVTManager(DataManager):
    def __init__(self, path):
        super(LSVTManager, self).__init__(
            name='lsvt',
            is_detection=True,
            is_recognition=True,
            is_scatter=False,
        )
        self.root_path = path
        self.image_dir = os.path.join(path, 'train_images')
        self.gt_path = os.path.join(path, 'train_full_labels.json')

        with open(self.gt_path, 'r', encoding='utf-8') as f:
            self.raw_gt = json.load(f)

        self.initialize()

    def get_detection_gts(self):
        ground_truths = dict()
        for name, gt in tqdm(self.raw_gt.items()):
            image_path = os.path.abspath(os.path.join(self.image_dir, '{}.jpg'.format(name)))

            available_boxes = []
            for box in gt:
                text = box['transcription'].replace('＃', '#') if not box['illegibility'] else '###'
                points = box['points']
                if len(points) > 4:
                    new_points = minimal_rectangle(points, ordered=True)
                    points = new_points.tolist()
                available_boxes.append({
                    'transcription': text,
                    'points': points
                })

            ground_truths[image_path] = available_boxes

        return ground_truths

class ShopSignManager(DataManager):
    def __init__(self, path, exclude_unrecognizable=False):
        self.exclude_unrecog = exclude_unrecognizable
        name = 'shopsign' if not self.exclude_unrecog else 'shopsign_ex_unrecog'

        super(ShopSignManager, self).__init__(
            name=name,
            is_detection=True,
            is_recognition=True,
            is_scatter=True,
        )

        self.root_path = path
        self.anno_path = os.path.join(self.root_path, 'annotation')

        self.initialize()

    def get_detection_gts(self):
        ground_truths = dict()

        name_list = [name for name in os.listdir(self.root_path) if name.lower().endswith('.jpg')]
        for name in tqdm(name_list):
            image_path = os.path.abspath(os.path.join(self.root_path, name))

            index = os.path.splitext(name)[0].replace('image_', '')
            if int(index) >= 21000:
                gt_name = os.path.join(self.anno_path, 'gt_img_{}.txt'.format(index))
                with open(gt_name, 'r', encoding='gbk') as f:
                    lines = [t.strip()for t in f.read().split('\n') if t.strip()]
            else:
                gt_name = os.path.join(self.anno_path, 'image_{}.txt'.format(index))
                with open(gt_name, 'r', encoding='utf-8') as f:
                    lines = [t.strip()for t in f.read().split('\n') if t.strip()]

            available_boxes = []
            for line in lines:
                segs = line.split(',')
                assert len(segs) == 9, "error format sample: {}".format(line)

                text = segs[-1]
                invalid = False
                if self.exclude_unrecog:
                    if text == '###':
                        continue
                    if '###' in text:
                        invalid = True
                        text = text.replace('###', '').strip()

                points = self.convert_points_format([int(p) for p in segs[:8]])
                available_boxes.append({
                    'transcription': text,
                    'points': points,
                    'invalid': invalid,
                })

            ground_truths[image_path] = available_boxes

        return ground_truths

class BDCIPOIManager(DataManager):
    def __init__(self, path):
        super(BDCIPOIManager, self).__init__(
            name='bdci_poi',
            is_detection=True,
            is_recognition=True,
            is_scatter=False,
        )

        self.root_path = path
        self.image_path_train = os.path.join(self.root_path, 'train_images')
        self.image_path_test_a = os.path.join(self.root_path, 'testA_images')
        self.image_path_test_b = os.path.join(self.root_path, 'testB_images')

        with open(os.path.join(self.root_path, 'public_train_label.json'), 'r', encoding='utf-8') as f:
            self.train_gts = json.load(f)['data']
        with open(os.path.join(self.root_path, 'public_test_A.json'), 'r', encoding='utf-8') as f:
            self.test_a_gts = json.load(f)['data']
        with open(os.path.join(self.root_path, 'public_test_B.json'), 'r', encoding='utf-8') as f:
            self.test_b_gts = json.load(f)['data']

        self.initialize()

    def get_detection_gts(self):
        ground_truths = dict()

        all_gts = dict()
        for _, value in self.train_gts.items():
            image_id = value['image_id']
            image_name = '{}.jpg'.format(image_id)
            image_path = os.path.join(self.image_path_train, image_name)
            all_gts[image_path] = value['texts']
        for _, value in self.test_a_gts.items():
            image_id = value['image_id']
            image_name = '{}.jpg'.format(image_id)
            image_path = os.path.join(self.image_path_test_a, image_name)
            all_gts[image_path] = value['texts']
        for _, value in self.test_b_gts.items():
            image_id = value['image_id']
            image_name = '{}.jpg'.format(image_id)
            image_path = os.path.join(self.image_path_test_b, image_name)
            all_gts[image_path] = value['texts']

        for path, gts in tqdm(all_gts.items()):
            image_path = os.path.abspath(path)
            available_boxes = []
            for box in gts:
                text = box['text']
                contour = box['contour']
                points = minimal_rectangle(contour, ordered=True).tolist()
                available_boxes.append({
                    'transcription': text,
                    'points': points,
                })

            ground_truths[image_path] = available_boxes

        return ground_truths

class CTWManager(DataManager):
    def __init__(self, path, direction='all'):
        """
        :param path: folder path of CTW dataset
        :param direction: filter images by camera angle. must be one of (`all`, `side`). default: all
        """
        super(CTWManager, self).__init__(
            name='ctw',
            is_detection=True,
            is_recognition=True,
            is_scatter=False,
        )

        self.root_path = os.path.abspath(path)
        self.image_train_path = os.path.join(self.root_path, 'images-train')
        self.image_test_path = os.path.join(self.root_path, 'images-test')
        self.label_train_path = os.path.join(self.root_path, 'train.jsonl')
        self.label_val_path = os.path.join(self.root_path, 'val.jsonl')
        self.label_test_path = os.path.join(self.root_path, 'test_cls.jsonl')

        self.direction = direction

        self.train_gts = []
        self.val_gts = []
        self.test_gts = []

        with open(self.label_train_path, 'r', encoding='utf-8') as f:
            for line in f:
                sample = json.loads(line)
                if self.filter_direction(sample):
                    self.train_gts.append(sample)
        with open(self.label_val_path, 'r', encoding='utf-8') as f:
            for line in f:
                sample = json.loads(line)
                if self.filter_direction(sample):
                    self.val_gts.append(sample)
        with open(self.label_test_path, 'r', encoding='utf-8') as f:
            for line in f:
                sample = json.loads(line)
                if self.filter_direction(sample):
                    self.test_gts.append(sample)

        self.initialize()

    def filter_direction(self, sample):
        if self.direction == 'side':
            file_name = sample['file_name']
            return True if file_name.startswith('1') or file_name.startswith('3') else False
        return True

    @staticmethod
    def poly2bbox(poly):
        key_points = list()
        rotated = collections.deque(poly)
        rotated.rotate(1)
        for (x0, y0), (x1, y1) in zip(poly, rotated):
            for ratio in (1 / 3, 2 / 3):
                key_points.append((x0 * ratio + x1 * (1 - ratio), y0 * ratio + y1 * (1 - ratio)))
        x, y = zip(*key_points)
        adjusted_bbox = (min(x), min(y), max(x) - min(x), max(y) - min(y))
        return key_points, adjusted_bbox

    def get_detection_gts(self):
        ground_truths = dict()

        total_train_gts = self.train_gts + self.val_gts
        for gt in tqdm(total_train_gts):
            width, height = gt['width'], gt['height']
            image_id = gt['image_id']
            image_name = gt['file_name']
            image_path = os.path.join(self.image_train_path, image_name)

            available_boxes = []

            annotations = gt['annotations']
            for sentence in annotations:
                sentence_chars = []
                polygons = []
                for char in sentence:
                    text = char['text']
                    polygon = char['polygon']
                    sentence_chars.append(text)
                    polygons.extend(polygon)

                points = minimal_rectangle(polygons, ordered=True).tolist()
                # key_points, adjusted_bbox = self.poly2bbox(polygons)
                # points = trans_xywh2corners(adjusted_bbox)
                available_boxes.append({
                    'points': points,
                    'transcription': ''.join(sentence_chars),
                })

            ignores = gt['ignore']
            for box in ignores:
                points = trans_integer(box['polygon'], width=width, height=height)
                available_boxes.append({
                    'points': points,
                    'transcription': '###',
                })

            ground_truths[image_path] = available_boxes

        return ground_truths

class BaiduCHSTRManager(DataManager):
    def __init__(self, path, tidy):
        super(BaiduCHSTRManager, self).__init__(
            name='baidu_ch_str',
            is_detection=False,
            is_recognition=True,
            is_scatter=False,
        )

        self.root_path = path
        self.image_train_path = os.path.join(self.root_path, 'train_images')

        with open(os.path.join(self.root_path, 'train.list'), 'r', encoding='utf-8') as f:
            self.lines = f.read().split('\n')

        self.tidy = tidy

        self.initialize()

    def get_recognition_gts(self):
        ground_truths = dict()

        for line in tqdm(self.lines):
            if not line.strip():
                continue

            width, height, image_name, text = line.split('\t')
            width, height = int(width), int(height)

            image_path = os.path.abspath(os.path.join(self.image_train_path, image_name))

            text = dbc2sbc(text).strip()
            if not text:
                print('image {} contains no text'.format(image_path))
                continue
            if self.tidy and len(text) <= 1:
                # print('exclude image {} with text [{}]'.format(image_path, text))
                continue

            new_image_name = self.generate_cropped_image_name(self.dataset_name, index=None, image_name=os.path.splitext(image_name)[0])
            ground_truths[image_path] = {
                'text': text,
                'width': width,
                'height': height,
                'image_name': new_image_name,
            }

        return ground_truths

    def recognition_output_paddle(self, output_dir, image_dir):
        gts = self.rec_gts or self.get_recognition_gts()
        lines = []
        for path, box in tqdm(gts.items()):
            image_name = box['image_name']
            new_image_path = os.path.join(image_dir, image_name)
            text = box['text']
            line = '{}\t{}'.format(new_image_path, text)
            lines.append(line)

        with open(output_dir, 'w', encoding='utf-8') as f:
            f.write('\n'.join(lines))

    def save_cropped_image(self, output_dir, v2h=True, v2h_threshold=1.5):
        if not os.path.exists(output_dir):
            os.makedirs(output_dir)

        gts = self.rec_gts

        for raw_path, box in tqdm(gts.items()):
            new_name = box['image_name']
            new_path = os.path.join(output_dir, new_name)
            text = box['text']

            width, height = box['width'], box['height']
            if len(text) > 1 and v2h and height / (width + 1e-12) > v2h_threshold:
                # read and rotate raw image
                img_data = cv2.imread(raw_path, cv2.IMREAD_COLOR)
                new_data = rotate_image(img_data)
                cv2.imwrite(new_path, new_data, [int(cv2.IMWRITE_JPEG_QUALITY), 100])
            else:
                # copy raw image
                shutil.copyfile(src=raw_path, dst=new_path)


"""
    This module provides an AzureTranslator class for translating text using the Azure Cognitive Services Translator Text API.

    Classes:
    - AzureTranslator: A translator class that uses the Azure Cognitive Services Translator Text API for text translation.

        Methods:
        - __init__(): Initializes the AzureTranslator class by setting up the necessary credentials and endpoint.
        - preprocess(text): Preprocesses the text for translation, including language detection and language pair selection.
        - postprocess(response): Postprocesses the translation response and returns the translated text.
        - translate(text): Translates the given text and returns the translated text.

"""

import requests
import uuid
from langdetect import detect
import os
from src.translation.base import Translator

class AzureTranslator(Translator):
    def __init__(self):
        self.key = os.environ["azure_trans_key"]
        self.location = "eastus"
        self.endpoint = "https://api.cognitive.microsofttranslator.com"
        self.path = "/translate"
        self.constructed_url = self.endpoint + self.path
        self.headers = {
            "Ocp-Apim-Subscription-Key": self.key,
            "Ocp-Apim-Subscription-Region": self.location,
            "Content-type": "application/json",
            "X-ClientTraceId": str(uuid.uuid4()),
        }

    def preprocess(self, text):
        language = detect(text)
        if language == "ar":
            self.from_lang, self.to_lang = "ar", "en"
        else:
            self.from_lang, self.to_lang = "en", "ar"

        params = {"api-version": "3.0", "from": self.from_lang, "to": self.to_lang}

        body = [{"text": text}]

        response = requests.post(
            self.constructed_url, params=params, headers=self.headers, json=body
        )
        response = response.json()
        return response

    def postprocess(self, response):
        translated_text = response[0]["translations"][0]["text"]
        return translated_text

    def translate(self, text):
        response = self.preprocess(text)
        translation = self.postprocess(response)
        return translation

if __name__ == "__main__":
    # text_to_translate = "Hello, how are you?"

    with open("src/rasa/data/english-questions.txt", "r") as f:
        text_to_translate = f.read()

    translator = AzureTranslator()
    translation = translator.translate(text_to_translate)

    with open("src/rasa/data/azure-arabic-questions.txt", "w") as f:
        f.write(translation)

    # with open('src/rasa/data/example-arabic.txt', 'r') as f:
    #     text_to_translate = f.read()

    # translator = AzureTranslator()
    # translation = translator.translate(text_to_translate)

    # with open('src/rasa/data/azure-example-english-after-arabic.txt', 'w') as f:
    #     f.write(translation)

    # translation = translator.translate(text_to_translate)

    # print("Translation: {}".format(translation))


import os
from PyQt6.QtWidgets import (QApplication, QMainWindow, QVBoxLayout,
                               QPushButton, QWidget, QStackedLayout,QLineEdit,
                               QGridLayout, QLabel,QTableWidget, QCheckBox,
                               QTableWidgetItem,QGroupBox)
from PyQt6.QtGui import QAction, QColor , QPainter, QPixmap
from PyQt6.QtCore import Qt
from matplotlib.figure import Figure
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from mpl_toolkits.mplot3d import Axes3D
from matplotlib import cm
from matplotlib.colors import Normalize

import time
import networkx as nx
import math as m
from math import cos,sin, pi, sqrt
import numpy as np
from numpy.linalg import eig
from sympy import Symbol, expand

#==========================================================================

def cartesian_to_qrectf(x, y, height,width):
    y_qrectf = height - y
    x_1231 = width + x
    return x_1231, y_qrectf

def my_eval(str1):
    str2 = f"lambda x, y: {str1}"
    return eval(str2)

def my_eval_with_t(str1):
    x = Symbol("x")
    y = Symbol("y")
    t = Symbol("t")
    sssstr = expand(str1)
    print(str(sssstr))
    str2 = f"lambda x, y, t: {str(sssstr)}"
    #str2 = f"lambda x, y, t: {str1}"
    return eval(str2)

def enc(str1):
    if type(str1)!=type("a"):        str1 = str(str1)
    return "(" + str1 + ")"

def cell_dribling(item, leng):
    lengnew = leng*2
    new1 = 2*item-1+(item-1)//leng*lengnew
    new2 = new1+1
    new3 = new1+lengnew
    new4 = new2+lengnew
    return [new1, new2, new3, new4]

#==========================================================================

class MainWindow(QMainWindow):

    def __init__(self,name11):
        super(MainWindow, self).__init__()
        self.name = name11
        self.setWindowTitle("Построение меры максимальной энтропии")
        self.layout_stack = QStackedLayout()

#--------------------------------------------------------------------------
        self.layout_input = QGridLayout()

        self.group1 = QGroupBox("Система уравнений")
        self.group1.setMaximumSize(300, 200)
        layout1 = QGridLayout()
        self.funlabel1 = QLabel("f = ")
        self.funlabel2 = QLabel("g = ")
        self.fun1 = QLineEdit( "  x*x-y*y+a " )
        self.fun2 = QLineEdit( " - 2*x*y+b " )
        layout1.addWidget(self.funlabel1,0,0)
        layout1.addWidget(self.funlabel2,1,0)
        layout1.addWidget(self.fun1,0,1)
        layout1.addWidget(self.fun2,1,1)
        self.group1.setLayout(layout1)
        self.layout_input.addWidget( self.group1 ,1 , 0)

        self.group1 = QGroupBox("Параметры")
        self.group1.setMaximumSize(300, 200)
        layout1 = QGridLayout()
        self.labelparam = QLabel("Параметры уравнения ")
        self.listparam = QLineEdit( " a=0.3,b=0.2 " )
        layout1.addWidget(self.labelparam,0,0)
        layout1.addWidget(self.listparam,0,1)
        self.labelobl = QLabel("Область ")
        self.txtobl = QLineEdit( " [-2,-2]x[2,2] " )
        layout1.addWidget(self.labelobl,1,0)
        layout1.addWidget(self.txtobl,1,1)
        self.group1.setLayout(layout1)
        self.layout_input.addWidget( self.group1 ,1 , 1)

        self.group1.setLayout(layout1)
        self.layout_input.addWidget( self.group1 ,1 , 0)

        self.group1 = QGroupBox("Построить итераций и Достроить итераций")
        self.group1.setMaximumSize(300, 200)
        layout1 = QGridLayout()
        self.button1 = QPushButton("Построить график для итераций:")
        self.globiterc1 = QLineEdit( " 7 ")
        self.button1.clicked.connect(self.iterate_from_start)
        #self.button3 = QPushButton("[x]Проитерировать существующий:")
        #self.globiterc2 = QLineEdit( " 1 ")
        #self.button3.clicked.connect(self.iterate_from_current)
        layout1.addWidget(self.button1 , 0, 0)
        layout1.addWidget(self.globiterc1 , 0, 1)
        #layout1.addWidget(self.button3 , 1 , 0 )
        #layout1.addWidget(self.globiterc2 , 1, 1)
        self.button44 = QPushButton("Построить изображение")
        self.button44.clicked.connect(self.mymainpainter)
        layout1.addWidget(self.button44 , 2, 0)
        self.group1.setLayout(layout1)
        self.layout_input.addWidget( self.group1 ,2 ,0 )

        self.group1 = QGroupBox("Функция оснащения")
        self.group1.setMaximumSize(300, 200)
        layout1 = QGridLayout()
        self.labelextra= QLabel("φ(x,y) = ")
        layout1.addWidget(self.labelextra,0,0)
        self.txtfunnn = QLineEdit( "x*x+y*y" )
        layout1.addWidget(self.txtfunnn,0,1)
        self.extradefault = False
        self.group1.setLayout(layout1)
        self.layout_input.addWidget( self.group1 ,2 , 1)

        self.widget_input = QWidget()
        self.widget_input.setLayout(self.layout_input)
        self.layout_stack.addWidget(self.widget_input)

#--------------------------------------------------------------------------
        self.layout_graph = QVBoxLayout()

        self.W_HIGHT = 700
        self.W_WIDTH = 700

        self.picture_out1 = QLabel()
        self.picture_out1.setMinimumSize(self.W_WIDTH, self.W_HIGHT)
        self.layout_graph.addWidget( self.picture_out1)

        pixmap = QPixmap(self.W_HIGHT, self.W_WIDTH)
        pixmap.fill(QColor(255, 255, 255))
        self.picture_out1.setPixmap(pixmap)

        self.widget_graph = QWidget()
        self.widget_graph.setLayout(self.layout_graph)
        self.layout_stack.addWidget(self.widget_graph)

#--------------------------------------------------------------------------
        self.layout_out = QGridLayout()

        self.res_out1 = QLabel()
        self.res_neout1 = ""
        self.res_out1.setText(f"Количество ячеек,\n Время итерации")
        self.layout_out.addWidget( self.res_out1)

        self.widget_out = QWidget()
        self.widget_out.setLayout(self.layout_out)
        self.layout_stack.addWidget(self.widget_out)

#-------------------------------------------------------------------------
        self.central_widget = QWidget()
        self.central_widget.setLayout(self.layout_stack)
        self.setCentralWidget(self.central_widget)

#-------------------------------------------------------------------------
        self.menu = self.menuBar()
        self.viewMenu = self.menu.addMenu("Меню")

        self.switchAction1 = QAction("Ввод", self)
        self.switchAction1.triggered.connect(self.switch_layout_input)
        self.viewMenu.addAction(self.switchAction1)

        self.switchAction2 = QAction("Графики", self)
        self.switchAction2.triggered.connect(self.switch_layout_graph)
        self.viewMenu.addAction(self.switchAction2)

        self.switchAction3 = QAction("Результат", self)
        self.switchAction3.triggered.connect(self.switch_layout_out)
        self.viewMenu.addAction(self.switchAction3)

    def switch_layout_input(self):
        self.layout_stack.setCurrentIndex(0)

    def switch_layout_graph(self):
        self.layout_stack.setCurrentIndex(1)

    def switch_layout_out(self):
        self.layout_stack.setCurrentIndex(2)
    #==========================================================
    def extraaction(self):
        print("--")
        if self.extradefault:
            self.extradefault = False
            print("tofalse")
        else:
            print("totrue")
            self.extradefault = True

    def iterate_from_start(self):
        self.iternum = int(self.globiterc1.text())
        self.res_neout1 = ""
        self.mainiteration()

    def iterate_from_current(self):
        self.iternum += int(self.globiterc2.text())
        self.mainiteration()

    def draw_3d_bar(self):
        _x = np.arange(4)
        _y = np.arange(3)
        _xx, _yy = np.meshgrid(_x, _y)
        _x, _y = _xx.ravel(), _yy.ravel()

        _z = np.zeros_like(_x)
        _dx = _dy = np.ones_like(_z)
        _dz = [1, 2, 3, 4, 2, 3, 4, 2, 5, 7, 2, 1]

        self.axis.bar3d(_x, _y, _z, _dx, _dy, _dz)
        self.canvas.draw()

    def mainiteration(self):
        somelist1, somelist2 = (self.txtobl.text()).split("x")
        somelist1 = eval(str(somelist1))
        somelist2 = eval(str(somelist2))
        x0 = somelist1[0]
        y0 = somelist2[1]
        L = somelist2[0] - somelist1[0]
        H = somelist2[1] - somelist1[1]
        print(x0,y0,L,H)
        somelist1, somelist2 = (self.listparam.text()).split(",")
        a = str(somelist1).split("=")[1]
        b = str(somelist2).split("=")[1]
        print(a,b)
        iterations = self.globiterc1.text()
        #if self.iternum == int(self.globiterc1.text()):
            #self.res_neout1 = f"{matr}\nСобственные значения: {eig(matr)[0][0]} {eig(matr)[0][1]} {eig(matr)[0][2]}\n"
        self.start = time.time()
        os.system(f".\main.exe {x0} {y0} {L} {H} {a} {b} {iterations}") # {a32} {a33} {self.iternum}")
        #os.system(f".\main.exe {a11} {a12} {a13} {a21} {a22} {a23} {a31} {a32} {a33} {self.iternum}")

    def mymainpainter(self):
        with open('res.txt') as f:
            lines = f.readlines()

        print(lines[-1])
        print(lines[-2])
        print(lines[-3])
        toprintdiam = lines[-3]
        toprintcoms = lines[-2]
        toprintnumc = lines[-1]
        #toprintcomsnum = lines[-1].rstrip()
        #toprintcellamount = lines[-2].split(" ")[1].rstrip()
        #toprintentropy = lines[-3].rstrip()
        #toprintloglambda = lines[-4].rstrip()
        #self.res_neout1 = f"{self.res_neout1}Время подсчета { self.iternum } итераций: {restime}\nРазмер ячейки: {d}\n"
        lines = lines[:-3]
        celllist = lines

        pixmap = QPixmap(self.W_HIGHT, self.W_WIDTH)
        pixmap.fill(QColor(255, 255, 255))

        painter = QPainter(pixmap)
        painter.setPen(QColor(255, 0, 0))#
        painter.setBrush(QColor(255, 0, 0))

        painter.drawRect(int(self.W_WIDTH/2), 0, 0, self.W_HIGHT) #VERTICAL
        painter.drawRect(0, int(self.W_HIGHT/2), self.W_WIDTH, 0) #HORISONTAL

        painter.setPen(QColor(0, 0, 0))#
        painter.setBrush(QColor(0, 0, 0))

        self.x0 = -2
        self.x1 = 2
        self.y0 = -2
        self.y1 = 2
        self.h = float(toprintdiam)
        self.mashtab = self.W_HIGHT/abs(self.y0-self.y1)
        print(self.mashtab)
        self.xposition = lambda cell, leng: self.x0+self.h*(cell-(cell-1)//leng*leng-1)
        self.yposition = lambda cell, leng: self.y1-self.h*((cell-1)//leng+1)
        self.lengx = abs(self.x1 - self.x0) / self.h

        for e in celllist:
            e = eval(e)
            #print(e,self.lengx)
            x,y = cartesian_to_qrectf(self.xposition(e, self.lengx), self.yposition(e, self.lengx),  max([self.y1,self.y0]), max([self.x1,self.x0]))
            #print(x,y)
            painter.drawRect( int(x*self.mashtab), int(y*self.mashtab) ,int(self.h*self.mashtab), int(self.h*self.mashtab))
        painter.end()
        self.picture_out1.setPixmap(pixmap)

        try:
            restime = time.time() - self.start
        except AttributeError:
            restime = 0
            self.iternum = 0
        print(restime)
        self.res_neout1 = f"{self.res_neout1}Время подсчета { self.iternum } итераций: {restime}\nРазмер ячейки: {toprintdiam}\n"
        self.res_neout1 = f"{self.res_neout1}Количество ячеек { toprintnumc }\n Компонент сильной связности: {toprintcoms}\n"
        #self.res_neout1 = f"{self.res_neout1}Энтропия: { toprintentropy }\n ln(lambda): { toprintloglambda }\n"

        with open('res1.txt') as f:
            lines = f.readlines()

        for i,line in enumerate(lines):
            eee = line.split(" ; ")
            self.res_neout1 = f"{self.res_neout1}Для компоненты {i+1}\nЛучшее нижнее значение { eee[0] } Лучшее верхнее значение {eee[1]}\n"

        self.res_out1.setText(self.res_neout1)

#==========================================================
app = QApplication([])
window = MainWindow("window")
window.show()
app.exec()


import datetime
import re

# 3.3
def remove_text_garbage(
        text, remove_apos=True, remove_parens=True, remove_punct=True):
    if remove_parens:
        text = re.sub(r"\(([^)]*)\)", r"\1", text)
    if remove_apos:
        text = re.sub(r"([^\s']+)'[\S]+", r"\1", text)
    if remove_punct:
        text = text.replace(",", "")
        text = text.replace(".", "")
        text = text.replace("?", "")
    if text.startswith('"') and text.endswith('"'):
        text = text[1:-1]
    return text

# 4.1
# When I originally wrote my word search functions, I made them split the
# question sentence into each word, and then turned the set of words into a set.
# Then, I turned the list of words to search for into a set, and checked whether
# the words to search for were a subset of the words in the question sentence
# resser = df_word_search(jeopardy, "way", "hell", exact=False)
# print(jeopardy[resser].question.count())
# resser = df_word_search(jeopardy, "blue"] exact=False)
# print(jeopardy[resser].question.count())
# resser = df_word_search(jeopardy, "poo", "pool", exact=False)
# print(jeopardy[resser].question.count())
# resser = df_word_search(jeopardy, "they", "there", exact=False)
# print(jeopardy[resser].question.count())
# resser = df_word_search(jeopardy, "'s", exact=False)
# print(jeopardy[resser].question.count())
# resser = df_word_search(jeopardy, "'re", exact=False)
# print(jeopardy[resser].question.count())
# resser = df_word_search(jeopardy, "'ve", exact=False)
# print(jeopardy[resser].question.count())

# 5.1
def money_to_float(money):
    if money is None or money == "None":
        return 0.0
    if money.startswith("$"):
        money = money[1:]
    if money.find(",") >= 0:
        monies = money.split(",")
        money = "".join(monies)
    return float(money)

# 7.1
def to_date(date):
    date_things = date.split("-")
    #if len(date_things) < 3:
        #print("Date:", date)
    #date_things += ["1"] * (3 - len(date_things))
    return datetime.date(*map(int, date_things))

# Helper - set up Jeopardy DataFrame for analysis
def preprocess(jeopardy):
    jeopardy.rename(columns={
    "Show Number": "show_number",
    " Air Date": "air_date",
    " Round": "round",
    " Category": "category",
    " Value": "value",
    " Question": "question",
    " Answer": "answer"
    }, inplace=True)
    jeopardy["value_float"] = jeopardy.value.apply(money_to_float)
    jeopardy.air_date = jeopardy.air_date.apply(to_date)
    jeopardy["air_year"] = jeopardy.air_date.apply(lambda d: d.year)


import os
import torch
import json
import pandas as pd
import matplotlib.pyplot as plt
import sys
import cv2
import numpy as np
import glob
from skimage import io, transform

from utils.utils import json_load
from utils.constants import IMG_EXT

import torch
import torchvision
from torch.utils.data import Dataset
import torchvision.transforms as transforms

sample_input = 'input/iwildcam-2020-fgvc7'
train_data_path = f'{sample_input}/train'
json_path = f'{train_data_path}/sample_train.json'
train_annotations = json_load(json_path=f'{sample_input}/iwildcam2020_train_annotations.json')
num_class = len(train_annotations['categories'])
labels = [cls['id'] for cls in train_annotations['categories']]

transform = transforms.Compose(
    [
        transforms.ToTensor(),
        transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5)),
        transforms.Resize((224, 224))
    ]
)

class ClassificationDataset(Dataset):
    """Face Landmarks dataset."""

    def __init__(self, json_path, root_dir, transform=None):
        """
        Arguments:
            csv_file (string): Path to the csv file with annotations.
            root_dir (string): Directory with all the images.
            transform (callable, optional): Optional transform to be applied
                on a sample.
        """
        self.root_dir = root_dir
        self.transform = transform

        image_dict = json_load(json_path=json_path)
        self.data = pd.DataFrame(image_dict.items(),
                       columns=['image_path', 'label'])

    def __len__(self):
        return len(self.data)

    def __getitem__(self, idx):
        if torch.is_tensor(idx):
            idx = idx.tolist()

        img_path = os.path.join(self.root_dir,
                                self.data.iloc[idx, 0])
        img = io.imread(img_path)
        label = self.data.iloc[idx, 1]
        label = torch.tensor(labels.index(label))
        # label =  torch.nn.functional.one_hot(torch.tensor(labels.index(label)), num_classes=self.num_classes)

        if self.transform:
            img = self.transform(img)

        return img, label

class InferenceDataset(Dataset):
    def __init__(self, root_dir, transform=None):
        """
        Inference dataset without labels
        Arguments:
            root_dir (string): Directory with all the images.
            transform (callable, optional): Optional transform to be applied
                on a sample.
        """
        self.root_dir = root_dir
        self.transform = transform

        image_paths = [path for path in glob.glob(f'{root_dir}/*') if path.split('.')[-1].lower() in IMG_EXT]
        image_paths = [os.path.basename(path) for path in image_paths]
        image_dict = {'image_path': image_paths}
        self.data = pd.DataFrame(data=image_dict)

    def __len__(self):
        return len(self.data)

    def __getitem__(self, idx):
        if torch.is_tensor(idx):
            idx = idx.tolist()

        img_path = os.path.join(self.root_dir,
                                self.data.iloc[idx, 0])

        img = io.imread(img_path)

        if self.transform:
            img = self.transform(img)

        return img, img_path

def main():
    # img_dataset = ClassificationDataset(
    #     json_path=json_path,
    #     root_dir=train_data_path,
    #     transform=transform
    #     )

    img_dataset = InferenceDataset(
        root_dir=train_data_path,
        transform=transform
        )

    for i in range(len(img_dataset)):
        img, label  = img_dataset[i]

        # print(i, img.shape, label)
        # img = sample['image']
        # img = cv2.imread(sample['image'])
        # print(img.shape)
        showImg = np.rollaxis(np.array(img), 0, 3)
        plt.imshow(showImg)
        plt.show()

if __name__ == '__main__':
    main()


"""This script finds the correlation between ratemaps for each cell for each task type."""

from ripple_heterogeneity.utils import (
    functions,
    loading,
    add_new_deep_sup,
)
import nelpy as nel
from ripple_heterogeneity.place_cells import maps
import pandas as pd
import numpy as np
from itertools import combinations
from typing import Union

def find_repeated_strings(lst: list) -> dict:
    """
    Find all repeated strings in a list.
    Parameters
    ----------
    lst : list or list-like object
        List of strings to search for repeated strings.
    Returns
    -------
    repeated_strings : dict
        Dictionary with repeated strings as keys and list of indices where
        the string is found as values.
    """
    if not isinstance(lst, list):
        try:
            lst = list(lst)
        except:
            raise TypeError("lst must be a list or a list-like object")
    repeated_strings = {}
    for i in range(len(lst)):
        if lst[i] in repeated_strings:
            repeated_strings[lst[i]].append(i)
        elif lst.count(lst[i]) > 1:
            repeated_strings[lst[i]] = [i]
    return repeated_strings

def ratemap_cor(A: np.ndarray, B: np.ndarray) -> float:
    # for given ratemaps A & B, find their correlation
    x1 = A.flatten()
    x2 = B.flatten()
    bad_idx = np.isnan(x1) | np.isnan(x2)
    return np.corrcoef(x1[~bad_idx], x2[~bad_idx])[0, 1]

def run(
    basepath: str, n_shuff: int = 500, parallel_shuff: bool = True
) -> Union[pd.DataFrame, None]:

    position_df = loading.load_animal_behavior(basepath)
    position_df_no_nan = position_df.query("not x.isnull() & not y.isnull()")

    if position_df_no_nan.shape[0] == 0:
        return pd.DataFrame()

    st, cm = loading.load_spikes(basepath, putativeCellType="Pyr", brainRegion="CA1")

    if st.isempty:
        return pd.DataFrame()

    cm = add_new_deep_sup.deep_sup_from_distance(cm)

    pos = nel.PositionArray(
        data=position_df_no_nan[["x", "y"]].values.T,
        timestamps=position_df_no_nan.timestamps.values,
    )
    beh_df = loading.load_epoch(basepath)
    beh_df = beh_df.query("environment != 'sleep'")

    beh_epochs = nel.EpochArray(np.array([beh_df.startTime, beh_df.stopTime]).T)

    # find all repeated strings in beh_df.environment
    tasks = find_repeated_strings(list(beh_df.environment.values))

    results_df = pd.DataFrame()
    for task in tasks:

        results_df_temp = pd.DataFrame()
        # linearize position if necessary
        if "linear" in task:
            for i in tasks[task]:
                idx = functions.in_intervals(pos.abscissa_vals, beh_epochs[i].data)
                x, y = pos.data[:, idx]
                if len(x) == 0:
                    continue
                pos._data[:, idx] = functions.linearize_position(x, y)

        # pull out coordinates for for this task type to get spatial extent
        current_pos = pos[beh_epochs[tasks[task]]]
        if current_pos.isempty:
            continue
        xminmax = [np.nanmin(current_pos.data[0, :]), np.nanmax(current_pos.data[0, :])]
        yminmax = [np.nanmin(current_pos.data[1, :]), np.nanmax(current_pos.data[1, :])]

        # find ratemaps for each cell
        # for reduced complexity, using 2d spatial maps and not splitting by direction (linear track)
        ratemaps = []
        spatial_pval = []
        n_spikes = []
        peak_firing_rate = []
        epoch = []
        for i in tasks[task]:
            current_pos = pos[beh_epochs[i]]
            current_st = st[beh_epochs[i]]

            if current_pos.isempty | current_st.isempty:
                continue

            spatial_maps = maps.SpatialMap(
                current_pos,
                current_st,
                dim=2,
                s_binsize=3,
                x_minmax=xminmax,
                y_minmax=yminmax,
                tuning_curve_sigma=3,
                n_shuff=n_shuff,
                parallel_shuff=parallel_shuff,
            )
            # store ratemaps
            ratemaps.append(spatial_maps.ratemap)
            # store p-values for spatial information shuffle
            spatial_pval.append(spatial_maps.shuffle_spatial_information())
            # store n spikes per cell
            n_spikes.append(current_st.n_events)
            # store peak firing rate for each cell
            peak_firing_rate.append(spatial_maps.max(axis=1))
            # store epoch n for each cell
            epoch.append(np.ones((len(current_st.data), 1)) * i)

        # find correlation between all pairs of ratemaps for each cell
        # find all pairs of ratemaps
        pairs = np.array(list(combinations(np.arange(0, len(ratemaps)), 2)))
        # set up arrays to store metadata
        metadata = {
            "spatial_pval": spatial_pval,
            "n_spikes": n_spikes,
            "peak_firing_rate": peak_firing_rate,
            "epoch": epoch,
        }
        metadata_ref_target = {}
        for key in metadata:
            metadata_ref_target["ref_" + key] = np.zeros((len(st.data), len(pairs)))
            metadata_ref_target["target_" + key] = np.zeros((len(st.data), len(pairs)))

        between_corr = np.zeros((len(st.data), len(pairs)))

        # loop through pairs
        for pair_i, s in enumerate(pairs):
            # loop through cells
            for cell_i in range(len(st.data)):
                # find correlation between ratemaps
                between_corr[cell_i, pair_i] = ratemap_cor(
                    ratemaps[s[0]][cell_i, :, :], ratemaps[s[1]][cell_i, :, :]
                )
                # store metadata for each cell for each pair
                for key in metadata:
                    metadata_ref_target["ref_" + key][cell_i, pair_i] = metadata[key][s[0]][cell_i]
                    metadata_ref_target["target_" + key][cell_i, pair_i] = metadata[key][s[1]][cell_i]

        # store results in dataframe
        results_df_temp["correlation"] = between_corr.flatten("F")

        for key in metadata_ref_target:
            results_df_temp[key] = metadata_ref_target[key].flatten("F")

        results_df_temp["UID"] = np.tile(cm.UID.values, len(pairs))
        results_df_temp["deepSuperficial"] = np.tile(
            cm.deepSuperficial.values, len(pairs)
        )
        results_df_temp["task"] = task
        results_df = pd.concat([results_df, results_df_temp], ignore_index=True)

    results_df["basepath"] = basepath
    return results_df


from jumpscale import j
import netifaces

class DHCP:
    """
Configure DHCP on a certain network (interface) by giving a range of IP addresses
 which will be issued to clients booting up on the given network interface
    """

    def __init__(self):
        self.__jslocation__ = "j.sal.dhcp_ihc"
        self.__imports__ = "netifaces"
        self.configPath = j.tools.path.get(
            '/etc').joinpath('dhcp3', 'dhcpd.conf')
        self._executor = j.tools.executorLocal

    def configure(self, ipFrom, ipTo, interface):
        interface = netifaces.ifaddresses(interface)[2]
        if self.configPath.exists():
            header = '''default-lease-time 600;
max-lease-time 7200;
'''
            self.configPath.touch()
            self.configPath.write_text(header)

        config = '''
subnet %s netmask %s {
    option subnet-mask 255.255.255.0;
    option routers 10.0.0.1;
    range %s %s;
}''' % (interface['addr'], interface['netmask'], ipFrom, ipTo)

        self.configPath.write_text(config, append=True)
        self.restart()

    def start(self):
        """
        Start DHCP server.
        """
        self._executor.execute('service isc-dhcp-server start')

    def stop(self):
        """
        Stop DHCP server.
        """
        self._executor.execute('service isc-dhcp-server stop')

    def restart(self):
        """Restarts DHCP server"""
        self._executor.execute('service isc-dhcp-server restart')