import SimpleITK as sitk
import os
import cv2
import pydicom
import numpy as np
import tkinter as tk
from tkinter import ttk
from tkinter import messagebox
from tkinter import filedialog
import configparser
import sys

class MyApp(object):
    def __init__(self, parent):
        self.rootframe = tk.Frame(parent)
        self.rootframe.pack()
        self.setupUI()
        self.config()
    def setupUI(self):
        self.button_browse = ttk.Button(root, text='...', width=3, command=self.SlectSourceFloder)
        self.button_browse.place(x=200, y=8)

        self.button_dest = ttk.Button(root, text='...', width=3, command=self.SlectDestFloder)
        self.button_dest.place(x=200, y=48)

        self.button_convert = ttk.Button(root, text='转换', width=20, command=self.convertVideoButton)
        self.button_convert.place(x=40, y=130)

        self.scale = tk.Scale(root, from_=0, to=10, orient=tk.HORIZONTAL, label='')
        self.scale.set(3)
        self.scale.place(x=80, y=75)

        self.text_sources = tk.Text(root, width=18, height=1, font=('tahoma', 9), bd=2)
        self.text_sources.place(x=70, y=10)
        self.label_sources = tk.Label(root, text='来源目录', font=('tahoma', 10))
        self.label_sources.place(x=10, y=10)
        self.text_dest = tk.Text(root, width=18, height=1, font=('tahoma', 9), bd=2)
        self.text_dest.place(x=70, y=50)
        self.label_dest = tk.Label(root, text='目标目录', font=('tahoma', 10))
        self.label_dest.place(x=10, y=50)

        self.check_CLAHE = tk.IntVar()
        self.RB_origin = tk.Checkbutton(root, text='CLAHE', variabl=self.check_CLAHE, command='')
        self.RB_origin.place(x=10, y=90)
        self.RB_origin.select()
      # 均衡
        self.check_equalizeHist = tk.IntVar()
        self.equalizeHist_check = tk.Checkbutton(root, text='均衡', variabl=self.check_equalizeHist, command='')
        self.equalizeHist_check.place(x=180, y=90)
        self.equalizeHist_check.select()

    def get_cf(self,key):
        cf = configparser.ConfigParser()
        cur_path = os.path.dirname(os.path.realpath(__file__))
        config_path = os.path.join(cur_path, "dicom.conf")
        # print(config_path)
        cf.read(config_path)
        value = cf.get("dicom", key)
        return value

    def set_cf(self,key, value):
        cf = configparser.ConfigParser()
        cur_path = os.path.dirname(os.path.realpath(__file__))
        config_path = os.path.join(cur_path, "dicom.conf")
        cf.read(config_path)
        cf.set('dicom', key, value)
        with open(config_path, "w+") as f:
            cf.write(f)

    def loadFile(self,filename):
        ds = sitk.ReadImage(filename)
        img_array = sitk.GetArrayFromImage(ds)
        frame_num, width, height = img_array.shape
        return img_array, frame_num, width, height

    def loadFileInformation(self,filename):
        self.information = {}
        ds = pydicom.read_file(filename)
        self.information['PatientID'] = ds.PatientID
        self.information['PatientName'] = ds.PatientName
        # self.information['PatientBirthDate'] = ds.PatientBirthDate
        self.information['PatientSex'] = ds.PatientSex
        self.information['StudyID'] = ds.StudyID
        self.information['StudyDate'] = ds.StudyDate
        self.information['StudyTime'] = ds.StudyTime
        self.information['InstitutionName'] = ds.InstitutionName
        self.information['Manufacturer'] = ds.Manufacturer

        self.information['InstanceNumber'] = ds.InstanceNumber
        angle1 = ds.PositionerPrimaryAngle
        if angle1 >= 0:
            self.information['PositionerPrimaryAngle'] = 'LAO ' + str(abs(angle1))
        else:
            self.information['PositionerPrimaryAngle'] = 'RAO ' + str(abs(angle1))
        # self.information['PositionerPrimaryAngle']=ds.PositionerPrimaryAngle
        angle2 = ds.PositionerSecondaryAngle
        if angle2 >= 0:
            self.information['PositionerSecondaryAngle'] = 'CRA ' + str(abs(angle2))
        else:
            self.information['PositionerSecondaryAngle'] = 'CAU ' + str(abs(angle2))

        try:
            self.information['NumberOfFrames'] = ds.NumberOfFrames
            self.information['RecommendedDisplayFrameRate'] = ds.RecommendedDisplayFrameRate
        except:
            pass
        self.information['ImageType'] = ds.ImageType
        #return self.self.information

    def autoEqualize(self,img_array_a):
        img_array_list = []
        for img in img_array_a:
            img_array_list.append(cv2.equalizeHist(img))
        img_array_equalized = np.array(img_array_list)
        return img_array_equalized

    def writeVideo(self,img_array, directory):
        frame_num, width, height = img_array.shape
        if self.information['ImageType'].__contains__('SECONDARY'):  # 如果是静态图片
            for img in img_array:
                cv2.imwrite(self.get_jpgname(), img)
            return
        filename_output = self.get_filename(directory)
        fourcc = cv2.VideoWriter_fourcc(*'MJPG')
        video = cv2.VideoWriter(filename_output, fourcc, 15, (width, height))
        for img in img_array:
            img_rgb = cv2.cvtColor(img, cv2.COLOR_GRAY2BGR)
            video.write(img_rgb)  # Write video file frame by frame
        video.release()

    def convertVideoButton(self):
        filepath = self.source_dir
        pathDir = os.listdir(filepath)
        for allDir in pathDir:

            filename = os.path.join('%s/%s' % (filepath, allDir))
            # try:
            self.loadFileInformation(filename)
            dirs = self.get_dir()
            #self.loadFileButton(filename)
            img_array, frame_num, width, height = self.loadFile(filename)
            img_arrays = self.core(img_array)
            self.writeVideo(img_arrays, dirs)
            # except e:
            #     print(e)

        messagebox.showinfo('提示', '完事了')

    def core(self,img_array_c):
        if self.check_equalizeHist.get():
            #print("均衡")
            img_array_c = self.autoEqualize(img_array_c)
        if self.check_CLAHE.get():
            img_array_c = self.limitedEqualize(img_array_c)
        return img_array_c

    def limitedEqualize(self,img_array):
        img_array_list = []
        for img in img_array:
            clahe = cv2.createCLAHE(clipLimit=self.scale.get(),
                                    tileGridSize=(8, 8))  # CLAHE (Contrast Limited Adaptive Histogram Equalization)
            img_array_list.append(clahe.apply(img))

        img_array_limited_equalized = np.array(img_array_list)
        return img_array_limited_equalized

    def config(self):
        cur_path = os.path.dirname(os.path.realpath(__file__))
        config_path = os.path.join(cur_path, "dicom.conf")
        if os.path.exists(config_path):
            self.source_dir = self.get_cf('source_dir')
            self.dest_dir = self.get_cf('dest_dir')
        else:
            config =configparser.ConfigParser()
            config['dicom'] = {'dest_dir': sys.path[0], 'source_dir': sys.path[0]}

            with open(config_path, 'w') as configfile:
                config.write(configfile)
            self.source_dir =  self.get_cf('source_dir')
            self.dest_dir =  self.get_cf('dest_dir')
        self.text_dest.delete('1.0', tk.END)
        self.text_dest.insert('1.0', self.dest_dir)
        self.text_sources.delete('1.0', tk.END)
        self.text_sources.insert('1.0', self.source_dir)

    def SlectSourceFloder(self):

        directory = filedialog.askdirectory(initialdir=self.source_dir)
        if directory == '':
            return
        self.source_dir = directory
        self.set_cf("source_dir", self.source_dir)
        self.text_sources.delete('1.0', tk.END)
        self.text_sources.insert('1.0', self.source_dir)

    def SlectDestFloder(self):

        directory = filedialog.askdirectory(initialdir=self.dest_dir)
        if directory == '':
            return
        self.dest_dir = directory
        self.set_cf("dest_dir", self.dest_dir)
        self.text_dest.delete('1.0', tk.END)
        self.text_dest.insert('1.0', self.dest_dir)

    def check(self):
        if self.check_CLAHE.get():
            scale['state'] = 'normal'
        else:
            scale['state'] = 'disable'

    def get_origin(self):
        str = ''
        if self.check_CLAHE.get():
            str = str + '_CLAHE'
        if self.check_equalizeHist.get():
            str = str + '_HIST'
        return str

    def get_dir(self):
        dirs = self.dest_dir + "/" + str(self.information['PatientName']).replace('^', '').replace(' ', '_') + '_' + \
               self.information['StudyDate']  # 目标文件为姓名+手术日期
        if not os.path.exists(dirs):  # 判断目标文件夹是否存在
            os.makedirs(dirs)
        return dirs

    def get_filename(self,directory):
        if self.information['ImageType'].__contains__('SECONDARY'):
            filename_output = directory + '/0' + str(self.information['InstanceNumber']) + self.get_origin() + '.avi'
        else:
            filename_output = directory + '/' + str(self.information['InstanceNumber']) + self.get_origin() + '.avi'
        return filename_output

    def add_text(self,imgs):
        imgs = cv2.putText(imgs, str(self.information['StudyDate']), (10, 20), cv2.FONT_HERSHEY_COMPLEX, 0.5,
                           (255, 255, 255), 2)  # 视频添加文字
        imgs = cv2.putText(imgs, str(self.information['PositionerPrimaryAngle']), (10, 50), cv2.FONT_HERSHEY_COMPLEX, 0.5,
                           (255, 255, 255), 2)
        imgs = cv2.putText(imgs, str(self.information['PositionerSecondaryAngle']), (10, 80), cv2.FONT_HERSHEY_COMPLEX, 0.5,
                           (255, 255, 255), 2)
        return imgs

    def creat_clahe(self,imgs, limit):  # 优化对比第一道工序
        clahe = cv2.createCLAHE(clipLimit=limit,
                                tileGridSize=(8, 8))  # CLAHE (Contrast Limited Adaptive Histogram Equalization)
        imgs = clahe.apply(imgs)
        return imgs

    def get_jpgname(self):
        jpg = self.get_dir() + '/' + str(self.information['InstanceNumber']) + self.get_origin() + '.jpg'
        return jpg

if __name__ == '__main__':
  root = tk.Tk()
  w = 250
  h = 180
  ws = root.winfo_screenwidth()
  hs = root.winfo_screenheight()
  x = (ws / 2) - (w / 2)
  y = (hs / 2) - (h / 2)
  root.geometry('%dx%d+%d+%d' % (w, h, x, y))
  root.title('DICOM TO AVI')
  MyApp(root) # 注意这句
  root.mainloop()


from PyQt5 import QtWidgets, QtCore
from pyqtgraph import PlotWidget, plot
import pyqtgraph as pg
import sys  # We need sys so that we can pass argv to QApplication
import os
from random import randint

class MainWindow(QtWidgets.QMainWindow):

    def __init__(self, *args, **kwargs):
        super(MainWindow, self).__init__(*args, **kwargs)

        self.graphWidget = pg.PlotWidget()
        self.setCentralWidget(self.graphWidget)

        self.x = list(range(100))  # 100 time points
        self.y = [randint(0,100) for _ in range(100)]  # 100 data points

        # plot data: x, y values
        #color = self.palette().color(QtGui.QPalette.Window)  # Get the default window background,
        #self.graphWidget.setBackground(color)                # and make it the background color for the graph
        self.graphWidget.setBackground('w') # Background color
        self.graphWidget.setTitle("Thermocouple", color="k", size="10pt") # Graph title
        styles = {'color':'k', 'font-size':'17px'} # Labels
        self.graphWidget.setLabel('left', 'Temperature [°C]', **styles)
        self.graphWidget.setLabel('bottom', 'Hour [H]', **styles)
        self.graphWidget.showGrid(x=True, y=True) # Grid
        self.graphWidget.addLegend() # Legend. Name must be provided in .plot() in order for legend to work
        pen = pg.mkPen(color=(255, 0, 0), width=2, style=QtCore.Qt.SolidLine) # Line style
        self.data_line = self.graphWidget.plot(self.x, self.y, name = "Sensor 1", pen=pen)

        self.timer = QtCore.QTimer()
        self.timer.setInterval(100)
        self.timer.timeout.connect(self.update_plot_data)
        self.timer.start()

    def update_plot_data(self):

        self.x = self.x[1:]  # Remove the first y element.
        self.x.append(self.x[-1] + 1)  # Add a new value 1 higher than the last.

        self.y = self.y[1:]  # Remove the first
        self.y.append( randint(0,100))  # Add a new random value.

        self.data_line.setData(self.x, self.y)  # Update the data

def main():
    app = QtWidgets.QApplication(sys.argv)
    main = MainWindow()
    main.show()
    sys.exit(app.exec_())

if __name__ == '__main__':
    main()


"""
This module has an simple implementation of DDPG, which is described in
- Continuous control with deep reinforcement learning
  - https://arxiv.org/abs/1509.02971
"""
from copy import deepcopy
from typing import Optional

import numpy as np
import torch
from torch import Tensor
from torch.nn import functional as F

from ..config import Config
from ..envs import ParallelEnv
from ..prelude import Action, Array, State
from ..replay import DQNReplayFeed
from .base import DQNLikeAgent, Netout

class DDPGAgent(DQNLikeAgent):
    SAVED_MEMBERS = "net", "target_net", "actor_opt", "critic_opt", "explorer", "replay"
    SUPPORT_PARALLEL_ENV = True

    def __init__(self, config: Config) -> None:
        super().__init__(config)
        self.net = config.net("ddpg")
        self.target_net = deepcopy(self.net)
        self.actor_opt = config.optimizer(self.net.actor_params(), key="actor")
        self.critic_opt = config.optimizer(self.net.critic_params(), key="critic")
        self.explorer = config.explorer()
        self.eval_explorer = config.explorer(key="eval")
        self.replay = config.replay_buffer()
        self.batch_indices = config.device.indices(config.replay_batch_size)

    def set_mode(self, train: bool = True) -> None:
        self.net.train(mode=train)

    @torch.no_grad()
    def eval_action(self, state: Array, net_outputs: Optional[Netout] = None) -> Action:
        action = self.net.action(state)
        if net_outputs is not None:
            net_outputs["action"] = action
        return self.eval_explorer.add_noise(action).cpu().numpy()

    def action(self, state: State) -> Action:
        if self.train_started:
            with torch.no_grad():
                action = self.net.action(state)
            action = self.explorer.add_noise(action).cpu().numpy()
        else:
            action = self.env._spec.random_action()
        return self.env._spec.clip_action(action)

    def batch_actions(self, states: Array[State], penv: ParallelEnv) -> Array[Action]:
        if self.train_started:
            states = penv.extract(states)
            with torch.no_grad():
                action = self.net.action(states)
            action = self.explorer.add_noise(action).cpu().numpy()
        else:
            action = self.env._spec.random_actions(states.shape[0])
        return self.env._spec.clip_action(action)

    @torch.no_grad()
    def _q_next(self, next_states: Array) -> Tensor:
        actions = self.target_net.action(next_states)
        return self.target_net.q_value(next_states, actions)

    def train(self, replay_feed: DQNReplayFeed) -> None:
        obs = [ob.to_array(self.env.extract) for ob in replay_feed]
        states, actions, next_states, rewards, done = map(np.asarray, zip(*obs))
        q_next = self._q_next(next_states)
        q_next = self._q_next(next_states).squeeze_().mul_(self.tensor(1.0 - done))
        q_target = self.tensor(rewards).add_(q_next.mul_(self.config.discount_factor))
        action, q_current = self.net(states, actions)

        #  Backward critic loss
        critic_loss = F.mse_loss(q_current.squeeze_(), q_target)
        self._backward(critic_loss, self.critic_opt, self.net.critic_params())

        #  Backward policy loss
        policy_loss = -self.net.q_value(states, action).mean()
        self._backward(policy_loss, self.actor_opt, self.net.actor_params())

        #  Update target network
        self.target_net.soft_update(self.net, self.config.soft_update_coef)


"""Represents a feature discovery disclosure message."""

from typing import Mapping

from marshmallow import fields, Schema
from marshmallow.validate import OneOf

from ...agent_message import AgentMessage, AgentMessageSchema
from ..message_types import DISCLOSE

HANDLER_CLASS = (
    "aries_cloudagent.messaging.discovery.handlers.disclose_handler.DiscloseHandler"
)

class Disclose(AgentMessage):
    """Represents a feature discovery disclosure, the response to a query message."""

    class Meta:
        """Disclose metadata."""

        handler_class = HANDLER_CLASS
        message_type = DISCLOSE
        schema_class = "DiscloseSchema"

    def __init__(self, *, protocols: Mapping[str, Mapping] = None, **kwargs):
        """
        Initialize disclose message object.

        Args:
            protocols: A mapping of protocol names to a dictionary of properties
        """
        super(Disclose, self).__init__(**kwargs)
        self.protocols = list(protocols) if protocols else []

class ProtocolDescriptorSchema(Schema):
    """Schema for an entry in the protocols list."""

    pid = fields.Str(required=True)
    roles = fields.List(
        fields.Str(
            description="Role: requester or responder",
            example="requester",
            validate=OneOf(["requester", "responder"]),
        ),
        required=False,
        allow_none=True,
        description="List of roles",
    )

class DiscloseSchema(AgentMessageSchema):
    """Disclose message schema used in serialization/deserialization."""

    class Meta:
        """DiscloseSchema metadata."""

        model_class = Disclose

    protocols = fields.List(
        fields.Nested(ProtocolDescriptorSchema()),
        required=True,
        description="List of protocol descriptors",
    )


import unittest
from unittest import mock
from copy import deepcopy
import py.test
from coreapis.groups.adhoc_backend import query_match, format_membership, AdHocGroupBackend
from coreapis.adhocgroups.tests.data import \
    user1, user2, user3, \
    groupid1, group1, \
    groupid2, group2, \
    public_userinfo

GROUP1_VIEW = {
    "id": 'adhoc:' + str(groupid1),
    "displayName": "pre update",
    "description": "some data",
    "type": "voot:ad-hoc",
    "membership": {
        "basic": "member",
    }
}

GROUP2_VIEW = {
    "id": 'adhoc:' + str(groupid2),
    "displayName": "pre update",
    "description": "some data",
    "type": "voot:ad-hoc",
    "public": True,
    "membership": {
        "basic": "admin",
    }
}

GROUPS = {
    groupid1: group1,
    groupid2: group2
}

MEMBERSHIP1 = {
    'groupid': groupid1,
    'userid': user1,
    'status': 'normal',
    'type': 'normal',
}

class TestQueryMatch(unittest.TestCase):
    def test_no_query(self):
        assert query_match(None, {})

    def test_match_displayName(self):
        assert query_match('foo', {'displayName': 'a foo group'})

    def test_match_description(self):
        assert query_match('foo', {'displayName': 'test group', 'description': 'a foo group'})

    def test_no_description(self):
        assert not query_match('foo', {'displayName': 'test group'})

    def test_no_match(self):
        assert not query_match('foo', {'displayName': 'no match', 'description': 'no match'})

class TestFormatMembership(unittest.TestCase):
    def test_owner_admin(self):
        assert format_membership(group1, {'userid': user1, 'type': 'admin'}) == {'basic': 'owner'}

    def test_owner_member(self):
        assert format_membership(group1, {'userid': user1, 'type': 'admin'}) == {'basic': 'owner'}

    def test_member(self):
        assert format_membership(group1, {'userid': user2, 'type': 'member'}) == {'basic': 'member'}

    def test_admin(self):
        assert format_membership(group1, {'userid': user2, 'type': 'admin'}) == {'basic': 'admin'}

class TestAdHocBackendBase(unittest.TestCase):
    @mock.patch('coreapis.middleware.cassandra_client.Client')
    def setUp(self, Client):
        self.session = Client()
        self.backend = AdHocGroupBackend('adhoc', 100, mock.Mock())

class TestAdHocBackend(TestAdHocBackendBase):
    def test_get_member_groups(self):
        self.session.get_group_memberships.return_value = iter([
            {
                'groupid': groupid1,
                'status': 'normal',
                'type': 'member',
                'userid': user3
            },
            {
                'groupid': groupid2,
                'status': 'normal',
                'type': 'admin',
                'userid': user3
            },
        ])
        self.session.get_group.side_effect = GROUPS.get
        res = self.backend.get_member_groups(dict(userid=user3), False)
        assert res == [GROUP1_VIEW, GROUP2_VIEW]

# pylint: disable=protected-access
class TestAdHocBackendGet(TestAdHocBackendBase):
    def test_normal(self):
        self.session.get_group.return_value = group1
        self.session.get_membership_data.return_value = MEMBERSHIP1
        assert self.backend._get(user1, 'fc:adhoc:{}'.format(groupid1)) == (group1, MEMBERSHIP1)

    def test_not_member(self):
        group = deepcopy(group1)
        self.session.get_group.return_value = group
        self.session.get_membership_data.side_effect = KeyError
        with py.test.raises(KeyError):
            self.backend._get(user2, 'fc:adhoc:{}'.format(groupid1))

    def test_not_member_but_owner(self):
        group = deepcopy(group1)
        self.session.get_group.return_value = group
        self.session.get_membership_data.side_effect = KeyError
        assert self.backend._get(user1, 'fc:adhoc:{}'.format(groupid1)) == (group1, None)

    def test_not_member_but_public(self):
        group = deepcopy(group1)
        group['public'] = True
        self.session.get_group.return_value = group
        self.session.get_membership_data.side_effect = KeyError
        assert self.backend._get(user2, 'fc:adhoc:{}'.format(groupid1)) == (group, None)
# pylint: enable=protected-access

class TestAdHocBackendGetMembership(TestAdHocBackendBase):
    def test_normal(self):
        with mock.patch('coreapis.groups.adhoc_backend.AdHocGroupBackend._get') as _get:
            _get.return_value = group1, MEMBERSHIP1
            assert self.backend.get_membership({'userid': user1},
                                               'fc:adhoc:{}'.format(groupid1)) == {'basic': 'owner'}

    def test_not_member(self):
        with mock.patch('coreapis.groups.adhoc_backend.AdHocGroupBackend._get') as _get:
            _get.return_value = group1, None
            with py.test.raises(KeyError):
                self.backend.get_membership({'userid': user1}, 'fc:adhoc:{}'.format(groupid1))

class TestAdHocBackendGetGroup(TestAdHocBackendBase):
    def test_normal(self):
        with mock.patch('coreapis.groups.adhoc_backend.AdHocGroupBackend._get') as _get:
            _get.return_value = group1, None
            res = self.backend.get_group({'userid': user1}, 'fc:adhoc:{}'.format(groupid1))
            expected = deepcopy(GROUP1_VIEW)
            del expected['membership']
            assert res == expected

class TestAdHocBackendGetMembers(TestAdHocBackendBase):
    def test_normal(self):
        members = [{'userid': user1, 'type': 'member', 'status': 'normal'}]
        self.session.get_group_members.return_value = iter(members)
        self.session.get_user_by_id.return_value = public_userinfo
        with mock.patch('coreapis.groups.adhoc_backend.AdHocGroupBackend._get') as _get:
            _get.return_value = group1, MEMBERSHIP1
            res = self.backend.get_members({'userid': user1},
                                           'fc:adhoc:{}'.format(groupid1), False, False)
            assert res == [{'membership': {'basic': 'owner'}, 'name': 'foo'}]

    def test_bad_member(self):
        members = [{'userid': user1, 'type': 'member', 'status': 'normal'}]
        self.session.get_group_members.return_value = iter(members)
        self.session.get_user_by_id.side_effect = KeyError
        with mock.patch('coreapis.groups.adhoc_backend.AdHocGroupBackend._get') as _get:
            _get.return_value = group1, MEMBERSHIP1
            res = self.backend.get_members({'userid': user1},
                                           'fc:adhoc:{}'.format(groupid1), False, False)
            assert res == []

    def test_bad_status(self):
        members = [{'userid': user1, 'type': 'member', 'status': 'hacked'}]
        self.session.get_group_members.return_value = iter(members)
        self.session.get_user_by_id.return_value = public_userinfo
        with mock.patch('coreapis.groups.adhoc_backend.AdHocGroupBackend._get') as _get:
            _get.return_value = group1, MEMBERSHIP1
            res = self.backend.get_members({'userid': user1},
                                           'fc:adhoc:{}'.format(groupid1), False, False)
            assert res == []

    def test_not_member(self):
        members = []
        self.session.get_group_members.return_value = iter(members)
        self.session.get_user_by_id.return_value = public_userinfo
        with mock.patch('coreapis.groups.adhoc_backend.AdHocGroupBackend._get') as _get:
            _get.return_value = group1, None
            with py.test.raises(KeyError):
                self.backend.get_members({'userid': user1},
                                         'fc:adhoc:{}'.format(groupid1), False, False)


import time
import torch as th
import torchbox as tb
import torchsar as ts
from torch.nn.parameter import Parameter
from collections import OrderedDict
from dataset import saveimage
import matplotlib.pyplot as plt

class Focuser(th.nn.Module):

    def __init__(self, Na, Nr, mas, convp=[[16, 17, 1]], xa=None, ftshift=True):
        r"""Focuser

        Focuser

        Parameters
        ----------
        Na : {number}
            [description]
        Nr : {number}
            1 or the number of range cells
        mas : {list}
            [description]
        ftshift : {bool}, optional
            [description] (the default is True, which [default_description])
        """

        super(Focuser, self).__init__()

        self.Na = Na
        self.Nr = Nr
        self.mas = mas
        self.ftshift = ftshift
        self.Ma = len(mas)
        self.nconvs = len(convp)

        FD = OrderedDict()
        FD['conv1'] = th.nn.Conv2d(2, convp[0][0], convp[0][1:3], stride=convp[0][3:5], padding=convp[0][5:7], dilation=convp[0][7:9], groups=convp[0][9])
        FD['in1'] = th.nn.InstanceNorm2d(convp[0][0])
        FD['relu1'] = th.nn.LeakyReLU()
        for n in range(1, self.nconvs):
            FD['conv' + str(n + 1)] = th.nn.Conv2d(convp[n - 1][0], convp[n][0], convp[n][1:3], stride=convp[n][3:5],
                                                   padding=convp[n][5:7], dilation=convp[n][7:9], groups=convp[n][9])
            FD['in' + str(n + 1)] = th.nn.InstanceNorm2d(convp[n][0])
            FD['relu' + str(n + 1)] = th.nn.LeakyReLU()
        FD['gapool'] = th.nn.AdaptiveAvgPool2d((1, 1))  # N-1-Na-1

        self.features = th.nn.Sequential(FD)
        self.coefs = th.nn.Sequential(OrderedDict([
            ('fc1', th.nn.Linear(convp[-1][0], 128)),
            ('relu1', th.nn.LeakyReLU()),
            # ('relu1', th.nn.LeakyReLU(0.5)),
            ('drop1', th.nn.Dropout(p=0.5, inplace=True)),
            ('fc2', th.nn.Linear(128, self.Ma)),
            # ('relu2', th.nn.LeakyReLU(0.5)),
        ]))

        if xa is None:
            xa = ts.ppeaxis(Na, norm=True, shift=ftshift, mode='fftfreq')
        xa = xa.reshape(1, Na)

        xas = th.tensor([])
        for ma in mas:
            xas = th.cat((xas, xa ** ma), axis=0)
        self.xa = Parameter(xa, requires_grad=False)  # 1-Na
        self.xas = Parameter(xas, requires_grad=False)  # Ma-Na

    def forward(self, X):
        d = X.dim()

        # Y = th.stack((X.pow(2).sum(-1).sqrt(), th.atan2(X[..., 1], X[..., 0])), dim=1)
        Y = th.stack((X[..., 0], X[..., 1]), dim=1)
        Y = self.features(Y)

        Y = Y.view(Y.size(0), -1)  # N-Na
        ca = self.coefs(Y)  # N-Ma
        pa = th.matmul(ca, self.xas)  # N-Ma x Ma-Na

        sizea = [1] * d
        sizea[0], sizea[-3], sizea[-2], sizea[-1] = pa.size(0), pa.size(1), 1, 2
        epa = th.stack((th.cos(pa), -th.sin(pa)), dim=-1)
        epa = epa.reshape(sizea)

        X = tb.fft(X, n=None, cdim=-1, dim=-3, keepcdim=True, norm=None, shift=self.ftshift)
        X = tb.ematmul(X, epa, cdim=-1)
        X = tb.ifft(X, n=None, cdim=-1, dim=-3, keepcdim=True, norm=None, shift=self.ftshift)

        return X, ca

def weights_init(m):
    if isinstance(m, th.nn.Conv2d):
        th.nn.init.orthogonal_(m.weight.data, th.nn.init.calculate_gain('leaky_relu'))
        m.bias.data.zero_()
        # print(m.weight.data.shape, m.weight.data[0, 0])
    if isinstance(m, th.nn.Linear):
        th.nn.init.orthogonal_(m.weight.data, th.nn.init.calculate_gain('leaky_relu'))
        m.bias.data.zero_()
        # print(m.weight.data.shape, m.weight.data[0, 0])

class PAFnet(th.nn.Module):

    def __init__(self, Na, Nr, Mas=[[2, 3]], Mrs=None, lpaf=[[[32, 11, 1]]], lprf=None, xa=None, ftshift=True, seed=None):
        super(PAFnet, self).__init__()
        self.Na = Na
        self.Nr = Nr
        self.Mas = Mas
        self.ftshift = ftshift
        self.seed = seed
        self.focusers = []

        if self.seed is not None:
            th.manual_seed(seed)

        self.Ma = 0
        for mas, convp in zip(Mas, lpaf):
            focusern = Focuser(Na, Nr, mas, convp, xa, ftshift)
            focusern.apply(weights_init)  # init weight
            self.Ma += len(mas)
            self.focusers.append(focusern)

        self.focusers = th.nn.ModuleList(self.focusers)
        self.Nf = len(self.focusers)

    def forward(self, X, isfft=True):

        cas = th.tensor([], device=X.device)
        for n in range(self.Nf):
            X, ca = self.focusers[n](X)
            cas = th.cat((cas, ca), axis=1)  # N-Ma

        return X, cas

    def visual_features(self, X, idx, device='cpu'):

        if self.Nf != 1:
            raise ValueError("Only support 1 Focuser now!")

        d = X.dim()

        X = th.stack((X[..., 0], X[..., 1]), dim=1)
        for i, j in enumerate(idx):
            for n in range(self.Nf):
                Xi = X[[i]].to(device)
                layers = self.focusers[n].features
                for k in range(len(layers) - 1):
                    Xi = layers[k](Xi)
                C = Xi.shape[1]
                tb.imshow([tb.mapping(Xi[0, c, :, :].detach().cpu().abs()) for c in range(C)], outfile='FeaturesOfFocuser%dOfImage%d.svg' % (n, j))

    def train_epoch(self, X, sizeBatch, loss_ent_func, loss_cts_func, loss_fro_func, loss_type, epoch, optimizer, scheduler, device):
        self.train()

        tstart = time.time()
        numSamples = X.shape[0]

        numBatch = int(numSamples / sizeBatch)
        idx = tb.randperm(0, numSamples, numSamples)
        lossENTv, lossCTSv, lossFROv, lossvtrain = 0., 0., 0., 0.
        # t1, t2, t3 = 0., 0., 0.
        for b in range(numBatch):
            # tstart1 = time.time()
            i = idx[b * sizeBatch:(b + 1) * sizeBatch]
            xi = X[i]
            xi = xi.to(device)

            optimizer.zero_grad()

            fi, casi = self.forward(xi)
            # tend1 = time.time()

            # tstart2 = time.time()
            lossENT = loss_ent_func(fi)
            lossCTS = loss_cts_func(fi)
            lossFRO = loss_fro_func(fi)
            # tend2 = time.time()

            if loss_type == 'Entropy':
                loss = lossENT
            if loss_type == 'Entropy+LogFro':
                loss = lossENT + lossFRO
            if loss_type == 'Contrast':
                loss = lossCTS
            if loss_type == 'Entropy/Contrast':
                loss = lossENT / lossCTS

            loss.backward()

            # tstart3 = time.time()
            lossvtrain += loss.item()
            lossCTSv += lossCTS.item()
            lossENTv += lossENT.item()
            lossFROv += lossFRO.item()
            # tend3 = time.time()

            optimizer.step()

            if scheduler is not None:
                scheduler.step()

            # t1 += tend1 - tstart1
            # t2 += tend2 - tstart2
            # t3 += tend3 - tstart3

        tend = time.time()

        lossvtrain /= numBatch
        lossCTSv /= numBatch
        lossENTv /= numBatch
        lossFROv /= numBatch
        # print(t1, t2, t3)
        print("--->Train epoch: %d, loss: %.4f, entropy: %.4f, l1norm: %.4f, contrast: %.4f, time: %ss" %
              (epoch, lossvtrain, lossENTv, lossFROv, lossCTSv, tend - tstart))
        return lossvtrain

    def valid_epoch(self, X, sizeBatch, loss_ent_func, loss_cts_func, loss_fro_func, loss_type, epoch, device):
        self.eval()

        tstart = time.time()
        numSamples = X.shape[0]

        numBatch = int(numSamples / sizeBatch)
        idx = list(range(numSamples))
        lossENTv, lossCTSv, lossFROv, lossvvalid = 0., 0., 0., 0.
        with th.no_grad():
            for b in range(numBatch):
                i = idx[b * sizeBatch:(b + 1) * sizeBatch]
                xi = X[i]
                xi = xi.to(device)

                fi, casi = self.forward(xi)

                lossENT = loss_ent_func(fi)
                lossCTS = loss_cts_func(fi)
                lossFRO = loss_fro_func(fi)

                if loss_type == 'Entropy':
                    loss = lossENT
                if loss_type == 'Entropy+LogFro':
                    loss = lossENT + lossFRO
                if loss_type == 'Contrast':
                    loss = lossCTS
                if loss_type == 'Entropy/Contrast':
                    loss = lossENT / lossCTS

                lossvvalid += loss.item()
                lossCTSv += lossCTS.item()
                lossENTv += lossENT.item()
                lossFROv += lossFRO.item()

        tend = time.time()

        lossvvalid /= numBatch
        lossCTSv /= numBatch
        lossENTv /= numBatch
        lossFROv /= numBatch

        print("--->Valid epoch: %d, loss: %.4f, entropy: %.4f, l1norm: %.4f, contrast: %.4f, time: %ss" %
              (epoch, lossvvalid, lossENTv, lossFROv, lossCTSv, tend - tstart))

        return lossvvalid

    def test_epoch(self, X, sizeBatch, loss_ent_func, loss_cts_func, loss_fro_func, loss_type, epoch, device):
        self.eval()

        tstart = time.time()
        numSamples = X.shape[0]

        numBatch = int(numSamples / sizeBatch)
        idx = list(range(numSamples))
        lossENTv, lossCTSv, lossFROv, lossvtest = 0., 0., 0., 0.
        with th.no_grad():
            for b in range(numBatch):
                i = idx[b * sizeBatch:(b + 1) * sizeBatch]
                xi = X[i]
                xi = xi.to(device)

                fi, casi = self.forward(xi)

                lossENT = loss_ent_func(fi)
                lossCTS = loss_cts_func(fi)
                lossFRO = loss_fro_func(fi)

                if loss_type == 'Entropy':
                    loss = lossENT
                if loss_type == 'Entropy+LogFro':
                    loss = lossENT + lossFRO
                if loss_type == 'Contrast':
                    loss = lossCTS
                if loss_type == 'Entropy/Contrast':
                    loss = lossENT / lossCTS

                lossvtest += loss.item()
                lossCTSv += lossCTS.item()
                lossENTv += lossENT.item()
                lossFROv += lossFRO.item()

        tend = time.time()

        lossvtest /= numBatch
        lossCTSv /= numBatch
        lossENTv /= numBatch
        lossFROv /= numBatch

        print("--->Test epoch: %d, loss: %.4f, entropy: %.4f, l1norm: %.4f, contrast: %.4f, time: %ss" %
              (epoch, lossvtest, lossENTv, lossFROv, lossCTSv, tend - tstart))

        return lossvtest

    def visual_epoch(self, X, sizeBatch, loss_ent_func, loss_cts_func, device):
        self.eval()

        numSamples = X.shape[0]

        numBatch = int(numSamples / sizeBatch)
        idx = list(range(numSamples))
        Y = th.zeros_like(X)
        with th.no_grad():
            for n in range(self.Nf):
                tstart = time.time()
                for b in range(numBatch):
                    i = idx[b * sizeBatch:(b + 1) * sizeBatch]
                    xi = X[i]
                    xi = xi.to(device)

                    pyi, _ = self.focusers[n](xi)
                    Y[i] = pyi.detach().cpu()

                tend = time.time()
                lossentv = loss_ent_func(Y).item()
                lossctsv = loss_cts_func(Y).item()
                X = Y

                print('Focuser: %d, Entropy: %.4f, Contrast: %.4f, Time: %.2fs' % (n, lossentv, lossctsv, tend - tstart))
                saveimage(X, X, [0, 1, 2], prefixname='visual%d' % n, outfolder='snapshot/')

    def plot(self, xi, cai, cri, xa, idx, prefixname, outfolder, device):

        self.eval()
        with th.no_grad():
            xi, cai, cri = xi.to(device), cai.to(device), cri.to(device)

            fi, casi = self.forward(xi)

        saveimage(xi, fi, idx, prefixname=prefixname, outfolder=outfolder + '/images/')

        pai = ts.polype(c=cai, x=xa)
        ppai = ts.polype(c=casi, x=xa)
        pai = pai.detach().cpu().numpy()
        ppai = ppai.detach().cpu().numpy()

        for i, ii in zip(range(len(idx)), idx):
            plt.figure()
            plt.plot(pai[i], '-b')
            plt.plot(ppai[i], '-r')
            plt.legend(['Real', 'Estimated'])
            plt.grid()
            plt.xlabel('Aperture time (samples)')
            plt.ylabel('Phase (rad)')
            plt.title('Estimated phase error (polynomial degree ' + str(self.Ma) + ')')
            plt.savefig(outfolder + '/images/' + prefixname + '_phase_error_azimuth' + str(ii) + '.png')
            plt.close()

if __name__ == '__main__':

    seed = 2020
    device = 'cuda:0'
    N, Na, Nr = 4, 25, 26

    th.random.manual_seed(seed)
    X = th.randn(N, Na, Nr, 2)

    net = Focuser(Na, Nr, mas=[2, 3], convp=[[16, 11, 1, 1, 1, 0, 0, 1, 1, 1]])
    net = net.to(device)
    X = X.to(device)
    Y, ca = net.forward(X)

    print(Y.shape)
    # print(ca)

    net = PAFnet(Na, Nr, Mas=[[2, 3], [4, 5], [6, 7]], lpaf=[[[8, 11, 1, 1, 1, 0, 0, 1, 1, 1]], [[16, 7, 1, 1, 1, 0, 0, 1, 1, 1]], [[32, 5, 1, 1, 1, 0, 0, 1, 1, 1]]], seed=2020)
    net = net.to(device)

    # print(net)

    Y, cas = net.forward(X)
    print(Y.shape, cas.shape)
    print(Y[0, 0, 0])
    # print(net.cas)


from PyQt5 import QtWidgets, uic
from PyQt5.QtWidgets import QFileDialog, QMessageBox
from pyqtgraph import PlotWidget, plot
import pyqtgraph as pg
import sys
import numpy as np
import math
from pyqtgraph.Qt import QtGui, QtCore
import SR_810 as sr_810
import pyvisa
import datetime;
import random;
import time
import os

# STARTING PARAMETERS OF OSCILLOSCOPE AND PROGRAMM
i = 0;              # points iterator
array_x = [];
array_r = [];
array_freq = [];
j = 1;              # scans iterator
path = '';          # memorize path to Open/Sae file
s = 1;              # check for save data

frequency_1 = 80000; # frequency start in Hz
frequency_2 = 2;     # frequency finish in Hz
points = 20;       # points in scan
number_scans = 1;    # number od scans
mod_amplitude = 2;   # modulation amplitude in V

time_constant= 1000;   # TC in ms
set_timer = float(time_constant); # timer for updating graph; in ms

# tc_index for QComboBox handling
if set_timer == 0.01:
    tc_index = 0;
elif set_timer == 0.03:
    tc_index = 1;
elif set_timer == 0.1:
    tc_index = 2;
elif set_timer == 0.3:
    tc_index = 3;
elif set_timer == 1:
    tc_index = 4;
elif set_timer == 3:
    tc_index = 5;
elif set_timer == 10:
    tc_index = 6;
elif set_timer == 30:
    tc_index = 7;
elif set_timer == 100:
    tc_index = 8;
elif set_timer == 300:
    tc_index = 9;
elif set_timer == 1000:
    tc_index = 10;
elif set_timer == 3000:
    tc_index = 11;
elif set_timer == 10000:
    tc_index = 12;
elif set_timer == 30000:
    tc_index = 13;
elif set_timer == 100000:
    tc_index = 14;
elif set_timer == 300000:
    tc_index = 15;
else:
    tc_index = 11;

# STARTING INITIALIZATION
##sr_810.connection()

# DESCRIPTION OF GUI FUNCTIONS AND WINDOWS
class Help(QtGui.QMainWindow):

    def __init__(self, parent=None):
        super(Help, self).__init__(parent)

        uic.loadUi('help.ui', self)   # QtDesigner file with design
        self.actionQuit.triggered.connect(self.close_2)

    # Description of functions
    def close_2(self):
        self.close()
#####################################################################
class Scan_Change(QtGui.QMainWindow):

    def __init__(self, parent=None):
        super(Scan_Change, self).__init__(parent)

        uic.loadUi('scan.ui', self)   # QtDesigner file with design
        self.change_scan.setValue(number_scans)
        self.change_scan.valueChanged.connect(self.getValue)
        self.actionQuit.triggered.connect(self.close_2)
        self.butsubmit_scan.clicked.connect(self.submit)

    # Getting value from QSpinBox
    def getValue(self):
        self.value = self.change_scan.value()
        return self.value

    # Submitting parameters
    def submit(self):
        global number_scans, j

        number_scans = self.getValue()
        if number_scans < j:
            number_scans = j
            self.change_scan.setValue(number_scans)
            print("Too Low Scans")

    # Description of functions
    def close_2(self):
        self.close()
#########################################################################

class Parameters(QtGui.QMainWindow):

    def __init__(self, parent=None):
        super(Parameters, self).__init__(parent)

        uic.loadUi('parameters.ui', self)   # QtDesigner file with design

        self.modAmpl.setValue(mod_amplitude)        # for setting initial value in QSpinBox
        self.numScan.setValue(number_scans)
        self.freqstart.setValue(frequency_1)
        self.freqfinish.setValue(frequency_2)
        self.numpoints.setValue(points)
        self.timeconst.setCurrentIndex(tc_index)    # QComboBox works with indexes

        # Connection of different function to different action
        self.actionQuit.triggered.connect(self.close_2)
        self.modAmpl.valueChanged.connect(self.getValue)
        self.numScan.valueChanged.connect(self.getValue_2)
        self.freqstart.valueChanged.connect(self.getValue_3)
        self.freqfinish.valueChanged.connect(self.getValue_4)
        self.numpoints.valueChanged.connect(self.getValue_5)
        self.timeconst.currentIndexChanged.connect(self.getValue_6)
        self.butsubmit.clicked.connect(self.submit)

    # Description of functions
    def close_2(self):
        self.close()
    # Getting value from QSpinBox
    def getValue(self):
        self.value = self.modAmpl.value()    # Value of mod amplitude
        return self.value
    def getValue_2(self):
        self.value = self.numScan.value()    # Value of Number of scans
        return self.value
    def getValue_3(self):
        self.value = self.freqstart.value()    # Value of freq start
        return self.value
    def getValue_4(self):
        self.value = self.freqfinish.value()    # Value of freq finish
        return self.value
    def getValue_5(self):
        self.value = self.numpoints.value()    # Value of points
        return self.value
    def getValue_6(self):
        self.value = self.timeconst.currentText()    # Value of time constant
        return self.value
    def getValue_7(self):
        self.value = self.timeconst.currentIndex()    # Value of index of time constant
        return self.value

    # Submitting parameters to lock-in
    def submit(self):
        global frequency_1, mod_amplitude, time_constant, set_timer, number_scans, points, frequency_2, tc_index

        frequency_1 = self.getValue_3()
        mod_amplitude = self.getValue()
        number_scans = self.getValue_2()
        points = self.getValue_5()
        frequency_2 = self.getValue_4()
        time_constant = float(self.getValue_6())
        tc_index = int(self.getValue_7())
        set_timer = time_constant;

        #print(self.ampl_calibration(mod_amplitude, frequency_1))
        #self.close()
        #sr_810.lock_in_modulation_frequency(frequency_1)
        #sr_810.lock_in_amplitude(self.ampl_calibration(mod_amplitude, frequency_1))
        #sr_810.lock_in_time_constant(time_constant)

    def ampl_calibration(self, ampl_g, f):          # modulation amplitude calibration curve

        a = 0.017*math.sqrt(f)*ampl_g;
        return a

class MainWindow(QtWidgets.QMainWindow):

    def __init__(self, *args, **kwargs):
        super(MainWindow, self).__init__(*args, **kwargs)

        # Load the UI Page
        uic.loadUi('main_window.ui', self)        # Design file
        self.lineScans.setText("Scans: " + str(number_scans))    # number of scans

        # Connection of different action to different Menus and Buttons
        self.actionFile.triggered.connect(self.exit)
        self.actionOpen.triggered.connect(self.open_dialog) # open file dialog
        self.pushSave.clicked.connect(self.save_dialog)     # save file dialog
        self.actionlock_in.triggered.connect(self.parameters_window)
        self.actionAbout.triggered.connect(self.help_window)
        self.pushStart.clicked.connect(self.start)      # buttons here work better than menus
        self.pushStop.clicked.connect(self.stop)
        self.pushClear.clicked.connect(self.clear_plot)
        self.actionAdd_Scan.triggered.connect(self.change_scan_window)#########################################################################

    # Functions that are connected to Menu
    def ampl_calibration(self, ampl_g, f):

        a = 0.017*math.sqrt(f)*ampl_g;
        return a

    def new_point(self):
        global final_data_r, i, array_r, array_x, array_freq, j, start_time, end_time

        self.lineScans.setText("Scans: " + str(number_scans))    # number of scans

        if j <= number_scans:
            self.lineScans.setStyleSheet("QLabel { background-color : rgb(255, 0, 0) }");
            self.lineScans.setText("Scans: " + str(j) + "/"+ str(number_scans))    # number of scans

            if i < points and j == 1:
                # Getting data from lock-in
                #data_x, data_y, data_r = sr_810.lock_in_signal()

                data_x = random.randint(0, 1000)
                data_r = random.randint(0, 1000)

                #freq_current = lock_in_modulation_frequency(frequency_1-step)
                ####################################################################################################################### modulation_amplitude changing
                freq_current = 10**(math.log10(frequency_1 - frequency_2)/points*(points - i)) + frequency_2            # special log step
                mod_amplitude_v = self.ampl_calibration(mod_amplitude, freq_current);
                #print(mod_amplitude_v)
                #frequency_1-step*i

                array_x = np.append(array_x, np.asarray(data_x))
                #array_y = np.append(array_y, np.asarray(data_y))
                array_r = np.append(array_r, np.asarray(data_r))
                array_freq = np.append(array_freq, np.asarray(freq_current))

                final_data_r = np.column_stack((array_freq, array_r, array_x))                                                   # appropriate format for pyqtgraph

                i = i + 1;
                end_time = time.time();
                self.lineTime.setText("Time (s): " + str(round((end_time - start_time), 1)) + "/" + str(round(time_constant*points*number_scans/1000,0)))    # time update

                #print(array_r[0])
            elif i == points:
                # Getting data from lock-in
                #data_x, data_y, data_r = sr_810.lock_in_signal()
                i = 0;
                j = j + 1;
                print("scan done")
            elif i < points and j > 1:
                data_x = random.randint(0, 1000)
                data_r = random.randint(0, 1000)

                #freq_current = lock_in_modulation_frequency(frequency_1-step)
                ################################################################################################################### modulation_amplitude changing
                freq_current = 10**(math.log10(frequency_1 - frequency_2)/points*(points - i)) + frequency_2
                mod_amplitude_v = self.ampl_calibration(mod_amplitude, freq_current);
                #print(mod_amplitude_v)
                #freq_current = frequency_1-step*i

                array_x[i] = (array_x[i]*(j-1) + np.asarray(data_x))/j
                #array_y = np.append(array_y, np.asarray(data_y))
                array_r[i] = (array_r[i]*(j-1) + np.asarray(data_r))/j

                final_data_r = np.column_stack((array_freq, array_r, array_x))            # appropriate format for pyqtgraph

                i = i+1;
                end_time = time.time();
                self.lineTime.setText("Time (s): " + str(round((end_time - start_time), 1)) + "/" + str(round(time_constant*points*number_scans/1000,0)))    # time update
                #print(final_data_r)
        else:
            self.lineScans.setStyleSheet("QLabel { background-color : rgb(0, 255, 0) }");    # number of scans

            # for saving raw data
            currenttime = datetime.datetime.now();
            file = open("00_temp_data.txt",'ab')
            np.savetxt(file, np.array(['# '+ str(currenttime)  + ', \n' 'Frequency (Hz),' + 'Intensity (a. u.) R,' + 'Intensity (a. u.) X']), fmt='%s')
            np.savetxt(file, final_data_r, delimiter=',', fmt='%.5e')
            file.close()

            self.timer.stop()

        return final_data_r

    # Experimental data plotting
    def plot(self, data1, data2):
        pen = pg.mkPen(color = (255, 255, 0, 255)) # pen for plotting slightly transparent yellow line; the last argument is opacity; 255 - no transparancy; 0 - full transparancy
        pen2 = pg.mkPen(color = (0, 0, 255, 255)) # pen for plotting slightly transparent yellow line; the last argument is opacity; 255 - no transparancy; 0 - full transparancy
        self.graphicsView.setTitle(title = "Frequency Scan")
        self.graphicsView.plot(data1, pen = pen, clear = True)  # actual plotting and clear the previous one
        self.graphicsView.plot(data2, pen = pen2)  # actual plotting and clear the previous one
        self.graphicsView.showGrid(x=True, y=True) # Grid
        self.graphicsView.setLogMode(True, False)  # LogX Plot
        self.graphicsView.setXRange(math.log10(frequency_1), math.log10(frequency_2), padding=0.055) # x axis range
        self.graphicsView.setLabel('bottom', text = "Frequency (Hz)")
        self.graphicsView.setLabel('left', text = "Intensity (a. u.)")

    def exit(self):
        #sr_810.close_connection()
        sys.exit()
    # function for updating plot when a new data from lock-in arrives
    def updating(self):

        # clear our graphs
        #self.graphicsView.clear()      # changed to clear = True
        # get new data
        final_data_r = self.new_point()
        # plot new data
        self.plot(final_data_r[:,[0,1]], final_data_r[:,[0,2]])

    # function to start timer for updating
    def start(self):
        global set_timer, array_r, array_x, array_freq, i, j, start_time, s

        if s == 0:      # for checking whether the data was saved before the start button is pressed
            message = QMessageBox(self);            # Message Box fow warning of unsaved data
            message.setWindowTitle("Are you sure?")
            message.setStyleSheet("QWidget { background-color : rgb(136, 138, 133) }")  # change background color of the open file window
            message.addButton(QtGui.QPushButton('Save'), QtGui.QMessageBox.NoRole)      # adding buttons
            message.addButton(QtGui.QPushButton('Yes'), QtGui.QMessageBox.YesRole)
            message.setText("Data was not saved. Are you sure?    ");
            message.show();
            message.buttonClicked.connect(self.clicked)                         # connect function clicked to button; get the button name
            return                                                              # stop current function

        start_time = time.time()
        #recalculation of timer for real time_constant used
        #set_timer = float(lock_in_time_constant());
        array_x = [];
        array_r = [];
        array_freq = [];
        i = 0;
        j = 1;

        set_timer = float(time_constant);
        self.timer = QtCore.QTimer()
        self.timer.timeout.connect(self.updating)
        self.timer.start(set_timer)

        s = 0;      #  for checking whether the data was saved before the start button is pressed

    def clicked(self, btn):             # Message Box fow warning of unsaved data
        global s
        if btn.text() == "Save":
            self.save_dialog()
        elif btn.text() == "Yes":
            s = 1;  #  for checking whether the data was saved before the start button is pressed
            self.start()
        else:
            return

    def clicked_2(self, btn):           # Message Box fow warning of unsaved data for clear button
        global s
        if btn.text() == "Save":
            self.save_dialog()
        elif btn.text() == "Yes":
            s = 1;      #  for checking whether the data was saved before the start button is pressed
            self.graphicsView.clear()
        else:
            return

    def stop(self):
        global i, j
        i = 0;
        j = 1;
        self.timer.stop()

    def clear_plot(self):
        global s

        if s == 0:
            message = QMessageBox(self);                # Message Box fow warning of unsaved data (see above)
            message.setWindowTitle("Are you sure?")
            message.setStyleSheet("QWidget { background-color : rgb(136, 138, 133) }")  # change background color of the open file window
            message.addButton(QtGui.QPushButton('Save'), QtGui.QMessageBox.NoRole)
            message.addButton(QtGui.QPushButton('Yes'), QtGui.QMessageBox.YesRole)
            message.setText("Data was not saved. Are you sure?    ");
            message.show();
            message.buttonClicked.connect(self.clicked_2)           # connect function clicked to button; get the button name
            return
        else:
            self.graphicsView.clear()
            s = 1;          # for checking whether the data was saved before the start button is pressed

    # New windows for parameters
    def parameters_window(self):
        global frequency_1, mod_amplitude, time_constant, number_scans, points, frequency_2

        #frequency_1 = sr_810.lock_in_modulation_frequency()
        #mod_amplitude_v = sr_810.lock_in_amplitude()
        #time_constant = sr_810.lock_in_time_constant()
        frequency_1 = frequency_1;
        mod_amplitude = mod_amplitude;
        points = points;
        number_scans = number_scans;
        time_constant = time_constant;

        self.dialog = Parameters(self)
        self.dialog.show()

############################################################################
    # New windows for scan change
    def change_scan_window(self):
        global number_scans

        number_scans = number_scans;

        self.dialog = Scan_Change(self)
        self.dialog.show()
############################################################################

    # New windows for help
    def help_window(self):

        self.dialog = Help(self)
        self.dialog.show()

    # Function for Open and Show file:
    def file_open(self, filename):
        global path
        file_data = np.genfromtxt(filename, skip_header = 1, delimiter=',', usecols=(0, 1))         # read csv with some useful options
        self.graphicsView.setTitle(title = "Frequency Scan")
        self.graphicsView.plot(file_data, pen = pg.mkPen(color = (random.randint(0, 255), random.randint(0, 255), random.randint(0, 255), 255)))
        self.graphicsView.showGrid(x=True, y=True) # Grid
        self.graphicsView.setLogMode(True, False)  # LogX Plot
        self.graphicsView.setXRange(math.log10(file_data[0,0]), math.log10(file_data[-1,0]), padding=0.055) # x axis range
        self.graphicsView.setLabel('bottom', text = "Frequency (Hz)")
        self.graphicsView.setLabel('left', text = "Intensity (a. u.)")
        path = os.path.dirname(filename) # for memorizing the path to the last used folder

    def open_dialog(self):
        global path

        if path == '':
            path = "/home/anatoly/Documents"

        filedialog = QFileDialog(self, 'Open File', directory = path, filter ="text (*.txt *.csv *.dat)", options = QFileDialog.DontUseNativeDialog) # use QFileDialog.DontUseNativeDialog to change directory
        filedialog.setStyleSheet("QWidget { background-color : rgb(136, 138, 133) }")  # change background color of the open file window
        filedialog.setFileMode(QtGui.QFileDialog.AnyFile)

        filedialog.fileSelected.connect(self.file_open) # connect to action; send filename to fumction file_open
        filedialog.show()

    # Function for Save file:
    def file_save(self, filename):
        global path

        try:
            if len (final_data_r) > 1:
                open(filename, "w").close()     # remove all the data from file before saving
                file = open(filename,'ab')
                np.savetxt(file, np.array(['Frequency (Hz),' + 'Intensity R (a. u.),' + 'Intensity (a. u.) X']), fmt='%s')
                np.savetxt(file, final_data_r, delimiter=',', fmt='%.5e')
                file.close()
        except NameError:       # if there isno data to save
                message = QMessageBox(self);
                message.setWindowTitle("Warning")
                message.setStyleSheet("QWidget { background-color : rgb(136, 138, 133) }")  # change background color of the open file window
                message.setText("No data to save   ");
                message.show();

        path = os.path.dirname(filename) # for memorizing the path to the last used folder

    def save_dialog(self):
        global path, s

        s = 1;              # for checking whether the data was saved before the start button is pressed
        if path == '':
            path = "/home/anatoly/Documents"

        filedialog = QFileDialog(self, 'Enter File Name', directory = path, options = QFileDialog.DontUseNativeDialog) # use QFileDialog.DontUseNativeDialog to change directory
        filedialog.setStyleSheet("QWidget { background-color : rgb(136, 138, 133) }")  # change background color of the open file window
        filedialog.setAcceptMode(QtGui.QFileDialog.AcceptSave)

        filedialog.fileSelected.connect(self.file_save)          # connect to action; send filename to fumction file_save
        filedialog.show()

# Running of the main window
def main():
    app = QtWidgets.QApplication(sys.argv)
    main = MainWindow()
    main.show()
    sys.exit(app.exec_())
    #sys.exit(app.exec_() and sr_810.close_connection())

if __name__ == '__main__':
    main()


import gi
import requests
import os
import glob
import subprocess
import simpleaudio as sa

gi.require_version("Gtk", "3.0")
from gi.repository import Gtk, GdkPixbuf

class Janela_Main(Gtk.Window):

    def __init__(self):
        Gtk.Window.__init__(self, title="Papelinator 1.0")

        self.builder = Gtk.Builder()
        self.builder.add_from_file("menu.glade")

        self.window = self.builder.get_object("janela")
        self.image = self.builder.get_object("imagem")
        self.entry = self.builder.get_object("entrada")
        self.bt_download = self.builder.get_object("bt_dl")
        self.bt_mudar = self.builder.get_object("bt_md")

        self.bt_download.connect("clicked", self.botao_dl)
        self.bt_mudar.connect("clicked", self.botao_muda)

        self.window.connect("destroy", Gtk.main_quit)

        self.window.show_all()

        self.link_invalido = sa.WaveObject.from_wave_file("sadtrombone.wav")
        self.nova_img = sa.WaveObject.from_wave_file("yoda.wav")

    def dados(self):
        url = self.entry.get_text()

        pasta_downloads = os.path.expanduser('~/Downloads')
        local_dl = max(glob.glob(os.path.join(pasta_downloads, '*')), key=os.path.getctime)
        diretorio = os.path.dirname(local_dl)

        output_link = None
        try:
            output_link = requests.get(url)
        except requests.exceptions.InvalidSchema:
            self.trombone_triste()

        nome_img = os.path.basename(url)

        diretorio_imgs = os.path.join(diretorio, nome_img)

        return output_link, diretorio_imgs

    def botao_muda(self, button):
        _, diretorio_imgs = self.dados()
        subprocess.run(['gsettings', 'set', 'org.gnome.desktop.background', 'picture-uri', 'file://' + diretorio_imgs])

        self.yoda_img()

    def botao_dl(self, button):
        output_link, diretorio_imgs = self.dados()

        if output_link is None:
            return

        if output_link.status_code != 200:
            self.trombone_triste()
            return

        with open(diretorio_imgs, 'wb') as file:
            file.write(output_link.content)

        pixbuf = GdkPixbuf.Pixbuf.new_from_file(diretorio_imgs)
        pixbuf = pixbuf.scale_simple(500, 300, GdkPixbuf.InterpType.BILINEAR)
        self.image.set_from_pixbuf(pixbuf)

    def trombone_triste(self):
        play_obj = self.link_invalido.play()
        play_obj.wait_done()

    def yoda_img(self):
        play_obj = self.nova_img.play()
        play_obj.wait_done()

janela = Janela_Main()
Gtk.main()


from PySide2.QtWidgets import QApplication
from PySide2.QtWidgets import QDialog, QMessageBox, QVBoxLayout
from PySide2.QtWidgets import QPushButton, QLineEdit

class Dialog(QDialog):
    def __init__(self, parent = None):
        super(Dialog, self).__init__()

        self.text_field = QLineEdit()
        self.alert_button = QPushButton('Alert')
        self.quit_button = QPushButton('Quit')

        layout = QVBoxLayout()
        layout.addWidget(self.text_field)
        layout.addWidget(self.alert_button)
        layout.addWidget(self.quit_button)
        self.setLayout(layout)

        self.alert_button.clicked.connect(self.alert)
        self.quit_button.clicked.connect(quit)

    def alert(self):
        alert = QMessageBox()
        alert.setText(self.text_field.text())
        alert.exec_()

if __name__ == '__main__':
    app = QApplication([])
    dialog = Dialog()
    dialog.show()
    app.exec_()


# This gives the sentence most similar to the inputted sentence. Different from what we are trying to do but this
    # is what gave me the idea for the sentence classification convolutional neural network

import tensorflow as tf
import tensorflow_hub as hub
import numpy as np
import os, sys
from sklearn.metrics.pairwise import cosine_similarity

# get cosine similarity matrix
def cos_sim(input_vectors):
    similarity = cosine_similarity(input_vectors)
    return similarity

# get topN similar sentences
def get_top_similar(sentence, sentence_list, similarity_matrix, topN):
    # find the index of sentence in list
    index = sentence_list.index(sentence)
    # get the corresponding row in similarity matrix
    similarity_row = np.array(similarity_matrix[index, :])
    # get the indices of top similar
    indices = similarity_row.argsort()[-topN:][::-1]
    return [sentence_list[i] for i in indices]

module_url = "https://tfhub.dev/google/universal-sentence-encoder/2" #@param ["https://tfhub.dev/google/universal-sentence-encoder/2", "https://tfhub.dev/google/universal-sentence-encoder-large/3"]

# Import the Universal Sentence Encoder's TF Hub module
embed = hub.Module(module_url)

# Reduce logging output.
tf.logging.set_verbosity(tf.logging.ERROR)

sentences_list = [
    # starting an exercise
    'getting ready',
    'starting with',
    'getting right into it',
    'join me',
    "first we're",
    "start off",
    "push up first",
    "going to start",
    "first exercise",
    "start with",
    "are you ready",
    "you ready here we go",
    "you ready",

    # stopping
    'we are done',
    "we're done",
    "it's over",
    "press pause",

    # duration
    'halfway done',
    'not much left',
    'second',
    "minute",
    "more seconds",
    "seconds left",
    "second break",
    "seconds here",
    "almost done",
    "few more seconds",
    "last round",
    "almost halfway",
    "almost there",

    "Nice work nice work not much left."
]

with tf.Session() as session:
  session.run([tf.global_variables_initializer(), tf.tables_initializer()])
  sentences_embeddings = session.run(embed(sentences_list))

similarity_matrix = cos_sim(np.array(sentences_embeddings))

sentence = "Nice work nice work not much left."
top_similar = get_top_similar(sentence, sentences_list, similarity_matrix, 4)

# printing the list using loop
for x in range(len(top_similar)):
    print(top_similar[x])


import logging
from flask_restplus import Namespace, Resource
from stellar_base.utils import account_xdr_object

from app.base.base import get_coin_types
from app.utils.code_msg import create_response, CodeMsg
from app.utils.cover_resource import CoverRequestParser
from app.models import Order

order_ns = Namespace("orders", description="order查询接口")

@order_ns.route('/')
class Orders(Resource):
    @order_ns.doc(
        params={
            "stellar_account": "stellar账户",
            "coin_name": "币种类型",
            "order_type": "订单类型:1=充值 2=提现 3=归集",
            "chain_type": "链类型 1=链内 2=链外",
        },
        description=u'订单查询返回订单信息'
    )
    def get(self):
        parser_ = CoverRequestParser()
        parser_.add_argument("stellar_account", type=str, required=True)
        parser_.add_argument("coin_name", type=str, required=False)
        parser_.add_argument("order_type", type=int, required=False)
        parser_.add_argument("chain_type", type=int, required=False)
        params = parser_.parse_args()

        user_address = params.get('stellar_account')
        coin_name = params.get('coin_name')
        order_type = params.get('order_type')
        chain_type = params.get('chain_type')
        try:
            account_xdr_object(user_address)
        except Exception as e:
            return create_response(CodeMsg.CM(1031, '账户地址错误'))
        try:
            coin_types = get_coin_types()
        except Exception as e:
            logging.error('find coin_types error:{}'.format(e))
            return create_response(CodeMsg.CM(1030, '查询失败'))
        if coin_name is not None and coin_name not in coin_types:
            return create_response(CodeMsg.CM(1031, '币种名错误'))
        if order_type is not None and int(order_type) not in (1, 2, 3):
            return create_response(CodeMsg.CM(1031, '订单类型错误'))
        if chain_type is not None and int(chain_type) not in (1, 2):
            return create_response(CodeMsg.CM(1031, '链类型错误'))

        params_dict = dict(stellar_account=user_address,
                           coin_name=coin_name,
                           order_type=order_type,
                           chain_type=chain_type,
                           )
        filter = {}
        for param in params_dict:
            if params_dict[param] is not None:
                filter[param] = params_dict[param]
        # print(filter)
        ret_list = []
        try:
            query_dict = Order.query.filter_by(**filter).all()
            for query in query_dict:
                ret_dict = {}
                ret_dict["user_id"] = query.user_id
                ret_dict["order_from"] = query.order_from
                ret_dict["order_to"] = query.order_to
                ret_dict["amount"] = str(query.amount)
                ret_dict["fee"] = str(query.fee)
                ret_dict["status"] = str(query.status)
                ret_dict["add_time"] = str(query.add_time)
                ret_dict["coin_name"] = query.coin_name

                ret_list.append(ret_dict)
        except Exception as e:
            logging.error('Db query order error:{}'.format(e))
            return create_response(CodeMsg.CM(1030, '查询错误'))

        return create_response(CodeMsg.CM(200, '查询成功'), data=ret_list)


# coding: utf-8
import os
import tkinter
import tkinter.filedialog as fd
from tkinter import *
from tkinter import ttk
from tkinter import messagebox as MessageBox
from tkinter.filedialog import askopenfilenames
from tkinterdnd2 import DND_FILES, TkinterDnD
from miagepackage.testing_tabula import check_presence
from miagepackage.testing_tabula import preprocessing
from miagepackage.handw_ext import trating_text

current_dir = os.getcwd()
sep = os.path.sep

TITRE_FENETRE = 'Lecteur de feuilles d\'abscence'
TEXTE_AIDE = 'Cliquez sur \'Déposer un fichier\' pour ajouter un fichier à la liste d\'attente d\'analyse.\nPassez la ' \
             'souris sur un fichier dans la liste d\'attente.\nCliquez sur la croix pour retirer un fichier de la ' \
             'liste d\'attente.\nCliquez sur \'Analiser\' pour Commencer l\'analise des fichiers déposés dans la ' \
             'liste d\'attente.\nCliquez n\'importe ou sur le texte de l\'aide pour la cacher ou la faire apparaitre'
TAILLE_FENETRE = "700x650"
CHEMIN_ICONE_PDF = f'{current_dir}{sep}views{sep}img{sep}icone_pdf.png'
CHEMIN_ICONE_CROIX = f'{current_dir}{sep}views{sep}img{sep}croix_cercle.png'
TYPES_FICHIERS = [('pdf files', '.pdf')]
NB_LIGNES_DEPOS = 3
APP_ICON = f'{current_dir}{sep}views{sep}img{sep}logo.png'

fenetre = TkinterDnD.Tk()
lst_fichiers = []
icone_pdf = tkinter.PhotoImage(file=CHEMIN_ICONE_PDF).subsample(7, 7)
# icone random recup sur https://icon-icons.com/fr/
# TODO voir licence ; subsample a addapter si changement d'icone
icone_croix = tkinter.PhotoImage(file=CHEMIN_ICONE_CROIX)  # idem

def analyserFichiers():
    """
    Fonction qui lance l'analyse de chaque fichiers dans la liste d'attente
    """
    if(len(lst_fichiers) == 0):
        MessageBox.showinfo("Aucun fichier", "Veuillez déposer au moins un fichier")
    else:
        for fichier in lst_fichiers:
            nom_du_fichier = nom_fichier(fichier)[:-4]
            preprocessing(fichier, nom_du_fichier)
            file_info = trating_text(nom_du_fichier + '.jpg')
            nom_du_fichier_json = file_info[-1]
            path = file_info[0] + sep + file_info[1] + sep + file_info[2] + sep + file_info[3] + sep + file_info[4] + sep
            check_presence(nom_du_fichier + '.pdf', nom_du_fichier_json, path)

        MessageBox.showinfo("Analyse terminée", "L'analyse des fichiers a été terminée")

def apparaitre_aide(event):
    """
    Faire apparaitre l'aide dans la fenetre
    """
    label_aide = event.widget

    label_aide.winfo_children()[0].pack(side=LEFT)
    label_aide.configure(text="Aide")

def cacher_aide(event):
    """
    Fait disparaitre le texte d'aide de la fenetre
    """
    label_aide = event.widget.master

    event.widget.pack_forget()
    label_aide.configure(text="Cliquez pour faire apparaitre l'aide", height=25)

def sortie_souris_frame(event):
    """
    Suppression de la croix d'une frame quand la souris sort de celle-ci
    """
    event.widget.winfo_children()[1].winfo_children()[0].destroy()

def click_souris_sur_image(event, label_vide):
    """
    Supprimer un fichier de la liste d'attente et retire l'affichage du fichier de l'interface
    """
    frame_depos = event.widget.master.master.master.master
    colonne_depos = event.widget.master.master.master
    frame_fichier = event.widget.master.master

    numero_colonne = 0
    numero_fichier_dans_colonne = 0
    for colonne in frame_depos.winfo_children():
        numero_colonne += 1
        if colonne == colonne_depos:
            for fichier in colonne.winfo_children():
                numero_fichier_dans_colonne += 1
                if fichier == frame_fichier:
                    break
            break
    numero_fichier = numero_colonne * NB_LIGNES_DEPOS - (NB_LIGNES_DEPOS - numero_fichier_dans_colonne)

    # supprimer le fichier dans lst fichier
    lst_fichiers.pop(numero_fichier - 1)
    # supprimer les affichages
    for colonne in frame_depos.winfo_children():
        colonne.destroy()
    # refaire tout les affichages
    cpt = 1
    for chemin in lst_fichiers:
        ajouter_un_label(nom_fichier(chemin), cpt, label_vide, frame_depos)
        cpt += 1

def passage_souris_sur_frame(event,label_vide):
    """
    Indications au passage de la souris sur une image
    """
    # label_depos = Label(event, text="cliquer sur l'icone pour supprimer")
    # ajouter la croix de suppression
    image_label_suppression = ttk.Label(event.widget.winfo_children()[1], image=icone_croix, padding=5)
    image_label_suppression.pack(anchor=NE)

    # ajout des evenements surlabel supression
    image_label_suppression.bind("<Button-1>", lambda eff: click_souris_sur_image(eff, label_vide))

def ajouter_un_label(nom, index_nom, label_vide, frame_depos):
    # TODO si aucun fichier replacer label vide
    """
    Afficher le nom d'un fichier et l'iconne de pdf à l'écran
    -----Variables-----
        nom : str
              nom du fichier à ajouter
        ligne : int
                index du nom dans la liste des fichiers (pas tout fait mais vus que c'est le dernier elem de la liste ça passe)
    """
    # détruire l'indication 'aucun fichier déposé'
    detruire_label_vide(label_vide)

    # créer une frame la précedente est remplie sinon recup la derniere frame de frame depos
    frame = recuperer_frame_de_depos(index_nom,frame_depos)
    frame.pack(expand=True, fill=BOTH, side=LEFT, padx=5, pady=5)

    # jout dans la Frame récupérée
    frame_fichier = Frame(frame)
    label_depos = Label(frame_fichier, text=nom)
    label_depos.pack(side=BOTTOM)
    image_label = ttk.Label(frame_fichier, image=icone_pdf, padding=10)
    image_label.pack(side=BOTTOM)
    image_label.propagate(False)
    frame_fichier.pack()

    # ajout des evenements sur frame_fichier
    #frame_fichier.bind("<Enter>", passage_souris_sur_frame(label_vide))
    frame_fichier.bind("<Enter>", lambda eff: passage_souris_sur_frame(eff, label_vide))
    frame_fichier.bind("<Leave>", sortie_souris_frame)

def detruire_label_vide(label_vide):
    if len(lst_fichiers) != 0:
        label_vide.destroy()

def recuperer_frame_de_depos(index_nom,frame_depos):
    if index_nom % NB_LIGNES_DEPOS == 1 or NB_LIGNES_DEPOS == 1:
        return Frame(frame_depos, border=False)
    else:
        return frame_depos.winfo_children()[-1]  # recupère le dernier enfant

def nom_fichier(chemin):
    """
    Donne le nom d'un fichier a partir de son chemin
    :param chemin: (str) le chemin vers un fichier
    :return: (str) le nom du fichier
    """
    return chemin.split("/")[-1]

def drop(event, label_vide, frame_depos):
    file_paths = event.data.split(" ")
    print(event.data)
    for file_path in file_paths:
        if not file_path.endswith(".pdf"):
            MessageBox.showerror("Erreur", "Un ou plusieurs fichiers ne sont pas au format pdf")
            break
        else:
            lst_fichiers.append(file_path)
            ajouter_un_label(nom_fichier(file_path), len(lst_fichiers), label_vide, frame_depos)

def ajouter_fichier_a_liste_attente(canva_depos, label_vide, frame_depos):
    """
    Ouvre une fenetre de recherche de fichier pdf
    Ajoute un fichier à la liste d'attente
    Ajoute l'icone d'un pdf et le chemin du fichier ajouté
    """

    canva_depos.configure(scrollregion=canva_depos.bbox("all"))
    chemins = askopenfilenames(title="Ouvrir une image", filetypes=TYPES_FICHIERS)

    for chemin in chemins:
        if len(chemin) != 0:
            lst_fichiers.append(chemin)
            ajouter_un_label(nom_fichier(chemin), len(lst_fichiers), label_vide, frame_depos)

            # MAJ taille scrolling
            # https://openclassrooms.com/forum/sujet/taille-d-une-frame-tkinter
            canva_depos.update_idletasks()
            # Ligne à ajouter sinon thinker considere qu'on veut màj la taille avant que le dépos ne soit fait
            canva_depos.configure(scrollregion=canva_depos.bbox("all"))


import pytest
import random
from CuckooHash import CuckooHash

def test_randomInsert():
    c = CuckooHash(10)
    inserted = []
    for i in range(random.randint(0,100)):           #loop upto a 100 times
        x = random.randint(0,100)                    #get a random int upto 100
        if not (x in inserted):                      #this list is to keep track of what is supposed to be inserted (no duplicates)
            inserted.append(x)
        c.insert(str(x), str(x))                     #try to insert x in the CuckooHash(should not insert duplicates)
    assert len(inserted) == len(c)                   #the length of the list and the CuckooHash should be the same

def test_insertingAll():                             #Insert the numbers from 0 to 99, the final length should be 100
    c = CuckooHash(100)
    for i in  range(100):
        c.insert(str(i), str(i))
    assert len(c) == 100

def test_noDuplicates():                             #Insert 20 times the same key
    c = CuckooHash(20)
    for i in range(20):
        c.insert("A", str(i))
    assert c.find("A") == "0"                        #it should return the data of the first inserted
    c.delete("A")                                    #After deleting("A"), if we try to find it, we shouldn't be able to because we dont have duplicates
    assert c.find("A") == None                       #return None if it wasn't there

def test_empty():                                    #cant find or delete something on an empty CuckooHash
    c = CuckooHash(20)
    assert c.find("A") == None
    assert c.delete("A") == False
    assert len(c) ==  0

def test_delete():                                   #Insert numbers from 0 to 19
    c = CuckooHash(1000)
    for i in range(20):
        c.insert(str(i), str(i))
    assert len(c) == 20                              #the length should be 20
    for i in range(10):
        c.delete(str(i))                             #Delete the numbers upto 9.
    assert len(c) == 10                              #the final length should be 10

def test_allThere():                                 #after inserting elements we should be able to find them all.
    c = CuckooHash(10)                               #Since the initial size is 10 and we are inserting 50 elements, if it pass this test, __growHash works
    lost = 0
    for i in range(50):
        c.insert(str(i), str(i))
    for i in range(50):
        if c.find(str(i)) == None:
            lost +=1
    assert lost == 0

def test_grow():                                     #After inserting 3 elements the array should grow because the numOfRecords>=numOfBuckets
    c = CuckooHash(6)
    c.insert("A", "a")
    c.insert("B", "b")
    c.insert("C", "c")
    assert c.numOfBuckets() == 12

pytest.main(["-v", "-s"])


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

# User-defined generic types

# You can include a Generic base class to define a user-defined class
# as generic.

from typing import (
    TypeVar,
    Generic
)

# A generic type can have any number of type variables, and type
# variables may be constrained. Each type variable argument to
# Generic must be distinct.

T = TypeVar('T')
S = TypeVar('S')

class Generic_Types(Generic[T, S]):

    def greeting(self, msg: str) -> None:
        print("Hello " + msg)

if __name__ == '__main__':
    gt = Generic_Types()
    gt.greeting('Python')

# https://www.python.org/dev/peps/pep-0484/#user-defined-generic-types


#!/usr/bin/env python
# -*- coding: utf8

from __future__ import division, print_function

from code import config
from code import db
from code.plot_helper import initialize_matplotlib
from code.plot_helper import three_plots

from collections import defaultdict

import numpy as np
import os
import plac

def main(table_name):

    initialize_matplotlib()

    obj_to_users = defaultdict(set)
    obj_count = defaultdict(int)
    duplicate_counts = defaultdict(int)
    audience_counts = defaultdict(int)

    for _, user, obj in db.iter_sorted(table_name):
        if user in obj_to_users[obj]:
            duplicate_counts[obj] += 1
        else:
            audience_counts[obj] += 1

        obj_to_users[obj].add(user)
        obj_count[obj] += 1

    out_folder = config.PLOTS_FOLDER
    fname = os.path.join(out_folder, '%s-pop.pdf' % table_name)
    three_plots(obj_count.values(), r'Popularity', fname)

    fname = os.path.join(out_folder, '%s-audi.pdf' % table_name)
    three_plots(audience_counts.values(), r'Audience', fname)

    revisits_over_audience = np.zeros(len(obj_count))
    for obj in obj_count:
        revisits_over_audience[obj] = \
                duplicate_counts[obj] / audience_counts[obj]

    fname = os.path.join(out_folder, '%s-rev-over-audi.pdf' % table_name)
    three_plots(revisits_over_audience, r'Returning/Audience (binned)', \
            fname, False)

if __name__ == '__main__':
    plac.call(main)


from typing import List
class Solution:
    def merge(self, nums1: List[int], m: int, nums2: List[int], n: int) -> None:
        len1 = m - 1
        len2 = n - 1
        lenA = m + n - 1

        while len1 >= 0 and len2 >= 0:
            if nums1[len1] >= nums2[len2]:
                nums1[lenA] = nums1[len1]
                len1 -= 1
            else:
                nums1[lenA] = nums2[len2]
                len2 -= 1
            lenA -= 1
        nums1[:len2 + 1] = nums2[:len2 + 1]

if __name__ == '__main__':
    solution = Solution()
    solution.merge([1,2,3,0,0,0],3,[2,5,6],3)


from trytond.pool import Pool
from . import prospect
from . import prospect_trace
from . import call
from . import pending_call
from . import user
from .locations import city
from .locations import department

__all__ = ['register']

def register():
    Pool.register(
        user.User,
        pending_call.PendingCall,
        call.Call,
        call.PendingTask,
        department.Department,
        city.City,
        prospect.ContactMethod,
        prospect.Prospect,
        prospect_trace.ProspectTrace,
        prospect.AssignOperatorStart,
        prospect_trace.ScheduleCallStart,
        prospect_trace.MakeCallStart,
        prospect_trace.MakeCallAsk,
        prospect_trace.MakeCallAskTask,
        prospect.ReassignProspectByOperatorStart,
        prospect.ReassignProspectByProspectStart,
        module='sale_opportunity_management', type_='model')
    Pool.register(
        prospect_trace.ScheduleCall,
        prospect.AssignOperator,
        prospect_trace.MakeCall,
        prospect.ReassignProspectByOperator,
        prospect.ReasignProspectByProspect,
        module='sale_opportunity_management', type_='wizard')
    Pool.register(
        module='sale_opportunity_management', type_='report')


# importing required modules

import pygame
import time
import random

# initializing pygame
pygame.init()

# inserting window color
white = (255, 255, 255)
yellow = (255, 255, 102)
black = (0, 0, 0)
red = (213, 50, 80)
green = (0, 255, 0)
blue = (50, 153, 213)
blue2 = (0, 0, 139, 255)

# creating a boundary
bound = 50

# constants that store our screen width and height :
# they are in pixels
dis_width = 500
dis_height = 500

# setting up our game window in pygame with our screen width and height constants as tuple
dis = pygame.display.set_mode((dis_width+bound, dis_height+bound))

# setting the caption of our game and displaying it in a gaming window
pygame.display.set_caption('Snake Game')

'''initializing pygame.time.Clock() which controls
The FPS or frame per second or more explicitly
For how many times per second our game loop below should run'''
clock = pygame.time.Clock()

# initializing snake length and snake speed
snake_block = 10
snake_speed = 15

# creating a pygame font from the system font resources
font_style = pygame.font.SysFont("Helvetica", 25)
score_font = pygame.font.SysFont("Times", 35)

# creating a function which displayes the score of the game

def Score(score):
    value = score_font.render("Your Score: " + str(score), True, yellow)
    dis.blit(value, [0, 0])

# creating a function which draws the snake head

def Snake(snake_block, snake_list):
    for x in snake_list:
        pygame.draw.rect(dis, black, [x[0], x[1], snake_block, snake_block])

# creating a function which displays the text on the gaming window

def message(msg, color):
    mesg = font_style.render(msg, True, color)
    dis.blit(mesg, [bound, dis_height/2])

# main function

def gameLoop():
    game_over = False
    game_close = False

    x1 = dis_width / 2
    y1 = dis_height / 2

    x1_change = 0
    y1_change = 0

    snake_List = []
    Length_of_snake = 1

    # function which displays multiple dots
    dotx1 = round(random.randrange(
        bound, dis_width - snake_block) / 10.0) * 10.0
    doty1 = round(random.randrange(
        bound, dis_height - snake_block) / 10.0) * 10.0

    dotx2 = round(random.randrange(
        bound, dis_width - snake_block) / 10.0) * 10.0
    doty2 = round(random.randrange(
        bound, dis_height - snake_block) / 10.0) * 10.0

    while not game_over:

        while game_close == True:
            '''function which displays
            final message,which gives the option for a user to quit or play again
            and score after the game is over'''
            dis.fill(blue2)
            message("You Lost! Press C-Play Again or Q-Quit", red)
            Score(Length_of_snake - 1)
            pygame.display.update()

            for event in pygame.event.get():
                if event.type == pygame.KEYDOWN:
                    if event.key == pygame.K_q:
                        game_over = True
                        game_close = False
                    if event.key == pygame.K_c:
                        gameLoop()

        # function which makes the snake to move up,down ,left and right
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                game_over = True
            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_LEFT:
                    x1_change = -snake_block
                    y1_change = 0
                elif event.key == pygame.K_RIGHT:
                    x1_change = snake_block
                    y1_change = 0
                elif event.key == pygame.K_UP:
                    y1_change = -snake_block
                    x1_change = 0
                elif event.key == pygame.K_DOWN:
                    y1_change = snake_block
                    x1_change = 0

        if x1 >= dis_width or x1 < bound or y1 >= dis_height or y1 < bound:
            game_close = True
        x1 += x1_change
        y1 += y1_change
        dis.fill(blue2)
        pygame.draw.rect(
            dis, blue, (bound, bound, dis_width-bound, dis_height-bound))
        pygame.draw.rect(dis, green, [dotx1, doty1, snake_block, snake_block])
        pygame.draw.rect(dis, green, [dotx2, doty2, snake_block, snake_block])
        snake_Head = []
        snake_Head.append(x1)
        snake_Head.append(y1)
        snake_List.append(snake_Head)
        if len(snake_List) > Length_of_snake:
            del snake_List[0]

        for x in snake_List[:-1]:
            if x == snake_Head:
                game_close = True

        Snake(snake_block, snake_List)
        Score(Length_of_snake - 1)

        pygame.display.update()

        # function which updates the score when the snake touches the dot
        if x1 == dotx1 and y1 == doty1:
            dotx1 = round(random.randrange(
                bound, dis_width - snake_block) / 10.0) * 10.0
            doty1 = round(random.randrange(
                bound, dis_height - snake_block) / 10.0) * 10.0
            Length_of_snake += 1
        elif x1 == dotx2 and y1 == doty2:
            dotx2 = round(random.randrange(
                bound, dis_width - snake_block) / 10.0) * 10.0
            doty2 = round(random.randrange(
                bound, dis_height - snake_block) / 10.0) * 10.0
            Length_of_snake += 1

        clock.tick(snake_speed)

    pygame.quit()
    quit()

gameLoop()