import os
import sys
from functools import partial

from PyQt5.QtGui import *
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *

from toolBar import ToolBar
from Canvas.canvas import Canvas

import cv2
import numpy as np

from grab_cut import Grab_cut
from choiceDiaGen import ChoiceDiaGen
from choiceDiaStyle import ChoiceDiaStyle
from zoomWidget import ZoomWidget
from birdDialog import BirdDialog

from generator import Generator
from styleChanger import StyleChanger

__appname__ = 'grab_cut'

class ResizesQWidget(QWidget):
    def sizeHint(self):
        return QSize(100, 150)

class struct(object):
    def __init__(self, **kwargs):
        self.__dict__.update(kwargs)

# 菜单栏和工具栏
class WindowMixin(object):

    # 根据名字和action列表创建一个菜单，比如File,[new,edit]
    def menu(self, title, actions=None):
        menu = self.menuBar().addMenu(title)
        if actions:
            addActions(menu, actions)
        return menu

    def toolbar(self, title, actions=None):
        toolbar = ToolBar(title)
        toolbar.setObjectName('{}ToolBar'.format(title))
        toolbar.setToolButtonStyle(Qt.ToolButtonTextUnderIcon)
        if actions:
            addActions(toolbar, actions)
        self.addToolBar(Qt.LeftToolBarArea, toolbar)  # 加到布局左侧
        return toolbar

# 创建一个新Action
def newAction(parent, text, slot=None, shortcut=None,
              tip=None, icon=None, checkable=False,
              enable=True):
    a = QAction(text, parent)
    if icon is not None:
        a.setIcon(QIcon(icon))
    if shortcut is not None:
        a.setShortcut(shortcut)
    if tip is not None:
        a.setToolTip(tip)
        a.setStatusTip(tip)
    if slot is not None:
        a.triggered.connect(slot)
    if checkable:
        a.setChecked(True)
    a.setEnabled(enable)
    return a

# 讲actions加入到父控件
def addActions(widget, actions):
    for action in actions:
        if action is None:
            widget.addSeparator()
        widget.addAction(action)  # weidget is toolBar or menu

# 主界面
class MainWindow(QMainWindow, WindowMixin):
    FIT_WINDOW, FIT_WIDTH, MANUAL_ZOOM = list(range(3))

    def __init__(self, defaultFilename=None):
        super().__init__()

        self.dirty = True  # 文件是否已保存
        self.mImgList = []  # 图片列表
        self.dirname = None  # 文件名
        self._beginner = True  #

        self.image_out_np = None  # 提取结果
        self.default_save_dir = None  # 默认保存路径
        self.filePath = None  # 当前载入的图片路径
        self.mattingFile = None

        # 垂直布局，
        listLayout = QVBoxLayout()
        listLayout.setContentsMargins(0, 0, 0, 0)

        # ---#显示图片的label pic
        matResultShow = ResizesQWidget()  # 返回是是Qwidget
        matResultShow.resize(150, 150)

        self.pic = QLabel(matResultShow)
        self.pic.resize(150, 150)
        self.setGeometry(50, 20, 150, 150)

        matResultShow.setLayout(listLayout)

        # 建一个dockwidget放图片label
        self.resultdock = QDockWidget('输出结果', self)
        self.resultdock.setObjectName('result')

        self.resultdock.setWidget(matResultShow)
        self.resultdock.resize(150, 150)
        # self.resultdock.setFeatures(QDockWidget.DockWidgetFloatable)

        # 建一个fileDoc放文件
        self.fileListWidget = QListWidget()  # 列表布局
        self.fileListWidget.itemDoubleClicked.connect(
            self.fileItemDoubleClicked)
        fileListLayout = QVBoxLayout()
        fileListLayout.setContentsMargins(0, 0, 0, 0)
        fileListLayout.addWidget(self.fileListWidget)
        fileListContainer = QWidget()
        fileListContainer.setLayout(fileListLayout)
        self.filedock = QDockWidget('导入文件列表', self)
        self.filedock.setObjectName('Files')
        self.filedock.setWidget(fileListContainer)

        self.zoomWidget = ZoomWidget()

        self.canvas = Canvas(parent=self)
        scroll = QScrollArea()
        scroll.setWidget(self.canvas)
        scroll.setWidgetResizable(True)
        self.scrollBars = {
            Qt.Vertical: scroll.verticalScrollBar(),
            Qt.Horizontal: scroll.horizontalScrollBar()
        }
        self.scrollArea = scroll
        self.canvas.scrollRequest.connect(self.scrollRequest)

        self.setCentralWidget(scroll)
        self.addDockWidget(Qt.RightDockWidgetArea, self.resultdock)
        self.addDockWidget(Qt.RightDockWidgetArea, self.filedock)
        # self.filedock.setFeatures(QDockWidget.DockWidgetFloatable)

        self.dockFeatures = QDockWidget.DockWidgetClosable | QDockWidget.DockWidgetFloatable
        self.resultdock.setFeatures(
            self.resultdock.features() ^ self.dockFeatures)

        # Actions
        action = partial(newAction, self)

        open_file = action('导入图片', self.openFile, 'Ctrl+O', '导入图片')
        open_dir = action('导入文件夹', self.openDir,
                          'Ctrl+D', '导入文件夹中的所有图片到列表')
        change_save_dir = action('&更改预设的保存路径', self.changeSavedirDialog)
        # open_next_img = action('&Next Image', self.openNextImg,
        #                        'Ctrl+N', 'Open next image')
        # open_pre_img = action('&Previous Image', self.openPreImg,
        #                        'Ctrl+M', 'Open previous image')
        save = action('保存结果', self.saveFile, 'Crl+S', '保存输出结果图')
        create = action('指定区域', self.createShape,
                        'w', '框选ROI')
        mark = action('标记微调', self.markDown, None, '左键白色，标记前景；右键黑色，标记后景')
        matting = action('迭代一次', self.grabcutMatting,
                         'e', '用当前标记迭代一次获取前景算法')

        # 用预训练模型生成图片
        generate = action('生成图片', self.generate, None, '输入文字，生成图片素材')

        # 用预训练模型进行风格迁移
        style = action('风格转换', self.styleChange, None, '选择一个风格，进行图像风格转换')
        # 字典，对应一个放缩比
        self.scalers = {
            self.FIT_WINDOW: self.scaleFitWindow,
            self.FIT_WIDTH: self.scaleFitWidth,
            # Set to one to scale to 100% when loading files.
            self.MANUAL_ZOOM: lambda: 1,
        }

        # store actions for further handling
        self.actions = struct(save=save, open_file=open_file,
                              open_dir=open_dir, change_save_dir=change_save_dir,
                              # open_next_img=open_next_img, open_pre_img=open_pre_img,
                              create=create, mark=mark, matting=matting, generate=generate, style=style)

        # Auto saving: enable auto saving if pressing next
        # self.autoSaving = QAction('Auto Saving', self)
        # self.autoSaving.setCheckable(True)
        # self.autoSaving.setChecked()

        # set toolbar
        self.tools = self.toolbar('Tools')
        self.actions.all = (open_file, open_dir,
                            change_save_dir, create,
                            # open_pre_img, open_next_img,
                            mark, matting, generate, style, save)
        addActions(self.tools, self.actions.all)

        # set status
        self.statusBar().showMessage('{} 已就绪.'.format(__appname__))

    def okToContinue(self):
        if self.dirty:
            reply = QMessageBox.question(self, "Attention",
                                         "you have unsaved changes, proceed anyway?",
                                         QMessageBox.Yes | QMessageBox.No | QMessageBox.Cancel)
            if reply == QMessageBox.Cancel:
                return False
            elif reply == QMessageBox.Yes:
                return self.fileSave
        return True

    def resetState(self):
        self.canvas.resetState()

    def errorMessage(self, title, message):
        return QMessageBox.critical(self, title,
                                    '
%s
%s' % (title, message))

    def beginner(self):
        return self._beginner

    def advanced(self):
        return not self.beginner()

    def openFile(self, _value=False):
        path = os.path.dirname(self.filePath) if self.filePath else '.'
        formats = ['*.%s' % fmt.data().decode("ascii").lower()
                   for fmt in QImageReader.supportedImageFormats()]
        filters = "Image (%s)" % ' '.join(formats)
        filename = QFileDialog.getOpenFileName(
            self, '%s - Choose Image or Label file' % __appname__, path, filters)
        if filename:
            if isinstance(filename, (tuple, list)):
                filename = filename[0]
            self.loadFile(filename)

    def openDir(self, dirpath=None):
        defaultOpenDirPath = dirpath if dirpath else '.'
        targetDirPath = QFileDialog.getExistingDirectory(self,
                                                         '%s - Open Directory' % __appname__, defaultOpenDirPath,
                                                         QFileDialog.ShowDirsOnly | QFileDialog.DontResolveSymlinks)
        self.importDirImages(targetDirPath)

    # 将导入图片显示在列表栏
    def importDirImages(self, dirpath):
        self.fileListWidget.clear()
        self.mImgList = self.scanAllImages(dirpath)
        # self.openNextImg()
        for imgPath in self.mImgList:
            item = QListWidgetItem(imgPath)
            self.fileListWidget.addItem(item)

    # 扫描路径下的所有文件，返回图片列表
    def scanAllImages(self, folderPath):
        extensions = ['.%s' % fmt.data().decode("ascii").lower()
                      for fmt in QImageReader.supportedImageFormats()]
        imageList = []

        for root, dirs, files in os.walk(folderPath):
            for file in files:
                if file.lower().endswith(tuple(extensions)):
                    relativePath = os.path.join(root, file)
                    path = os.path.abspath(relativePath)
                    imageList.append(path)
        imageList.sort(key=lambda x: x.lower())
        return imageList

    def fileItemDoubleClicked(self, item=None):
        currIndex = self.mImgList.index(item.text())  # 获取图片列表的index
        if currIndex < len(self.mImgList):
            filename = self.mImgList[currIndex]
            if filename:
                self.loadFile(filename)  # 载入图片列表

    # 读取图片到canvas
    def loadFile(self, filePath=None):
        self.resetState()  # 清理canvas
        self.canvas.setEnabled(False)

        # 高亮选中项
        if filePath and self.fileListWidget.count() > 0:
            index = self.mImgList.index(filePath)
            fileWidgetItem = self.fileListWidget.item(index)
            fileWidgetItem.setSelected(True)

        if filePath and os.path.exists(filePath):
            # load image
            self.ImageData = read(filePath, None)
        else:
            return

        image = QImage.fromData(self.ImageData)
        # 内存中没有图片
        if image.isNull():
            self.errorMessage(u'Error opening file',
                              u'
Make sure %s is a valid image file.' % filePath)
            self.status('Error reading %s' % filePath)
            return False
        self.status('Loaded %s' % os.path.basename(filePath))
        self.image = image  # Qimage格式
        self.filePath = filePath  # 当前载入的文件路径
        self.canvas.loadPixmap(QPixmap.fromImage(image))  # canvas中放置图片
        self.canvas.setEnabled(True)
        self.adjustScale(initial=True)
        self.paintCanvas()

    # 显示当前状态
    def status(self, message, delay=5000):
        self.statusBar().showMessage(message, delay)

    def adjustScale(self, initial=False):
        value = self.scalers[self.FIT_WINDOW if initial else self.zoomMode]()
        self.zoomWidget.setValue(int(100 * value))

    def scaleFitWindow(self):
        """Figure out the size of the pixmap in order to fit the main widget."""
        e = 2.0  # So that no scrollbars are generated.
        w1 = self.centralWidget().width() - e
        h1 = self.centralWidget().height() - e
        a1 = w1 / h1
        # Calculate a new scale value based on the pixmap's aspect ratio.
        w2 = self.canvas.pixmap.width() - 0.0
        h2 = self.canvas.pixmap.height() - 0.0
        a2 = w2 / h2
        return w1 / w2 if a2 >= a1 else h1 / h2

    def scaleFitWidth(self):
        # The epsilon does not seem to work too well here.
        w = self.centralWidget().width() - 2.0
        return w / self.canvas.pixmap.width()

    def paintCanvas(self):
        assert not self.image.isNull(), "cannot paint null image"
        self.canvas.scale = 0.01 * self.zoomWidget.value()
        self.canvas.adjustSize()
        self.canvas.update()

    def createShape(self):
        assert self.beginner()
        self.canvas.setEditing(False)
        self.actions.create.setEnabled(False)

    # 开始标记,mod换成editting
    def markDown(self):
        self.canvas.setEditing(True)

    def toggleDrawMode(self, edit=True):
        self.canvas.setEditing(edit)
        self.actions.createMode.setEnabled(edit)
        self.actions.editMode.setEnabled(not edit)

    # 生成图片
    def generate(self):
        # 种类选择对话框
        choiceDia = ChoiceDiaGen()
        choiceDia.show()
        choiceDia.hide()
        # 由Generator类控制生成对话框
        # 传入类型和属性列表
        gen = Generator(choiceDia.type,choiceDia.attrList)
        gen.generate()

        # 将生成的图片取出来显示在主页
        self.loadFile("StackGAN/resultImg/latest.png")

    def styleChange(self):
        # 风格选择对话框
        choiceDia = ChoiceDiaStyle()
        choiceDia.show()
        choiceDia.hide()
        print(choiceDia.type)
        changer = StyleChanger(choiceDia.type, self.filePath)
        changer.changeStyle()
        # self.loadFile("CycleGAN/targetImg/latest.png")
        result = cv2.imread("CycleGAN/targetImg/latest.png")
        # 转换为四通道
        result = self.addAchannel(result)
        self.showResultImg(result)
        self.image_out_np = result

    # 接收opencv读入的格式
    def addAchannel(self, x):
        b_channel, g_channel, r_channel = cv2.split(x)
        alpha_channel = np.ones(b_channel.shape, dtype=b_channel.dtype) * 255
        result_BGAR = cv2.merge((b_channel, g_channel, r_channel, alpha_channel))
        # result[np.all(result==[0,0,0,255],axis=2)]=[0,0,0,0]
        result_BGAR[np.all(result_BGAR == [0, 0, 0, 255], axis=2)] = [0, 0, 0, 0]
        return result_BGAR

    # 提取前景操作
    def grabcutMatting(self):

        if self.mattingFile is None:
            self.mattingFile = Grab_cut()

        def format_shape(s):
            return dict(line_color=s.line_color.getRgb(),
                        fill_color=s.fill_color.getRgb(),
                        points=[(p.x(), p.y()) for p in s.points],
                        backMark=self.canvas.getBackMark(),
                        whiteMark=self.canvas.getForMark())

        # 有四个点（矩形的话）+填充线颜色和边缘线颜色
        shape = format_shape(self.canvas.shapes[-1])
        self.image_out_np = self.mattingFile.image_matting(self.filePath,
                                                           shape, iteration=10)
        self.showResultImg(self.image_out_np)
        self.actions.save.setEnabled(True)

    # 接收opencv矩阵格式
    def showResultImg(self, image_np):
        # resize to pic
        # factor = min(self.pic.width() /
        #              image_np.shape[1], self.pic.height() / image_np.shape[0])
        # image_np = cv2.resize(image_np, None, fx=factor,
        #                       fy=factor, interpolation=cv2.INTER_AREA)
        # image_np = cv2.resize((self.pic.height(), self.pic.width()))
        image = QImage(image_np, image_np.shape[1],
                       image_np.shape[0], QImage.Format_ARGB32)
        matImg = QPixmap(image)
        self.pic.setFixedSize(matImg.size())
        self.pic.setPixmap(matImg)

    def saveFile(self):
        self._saveFile(self.saveFileDialog())

    def _saveFile(self, saved_path):
        print(saved_path)
        if saved_path:
            Grab_cut.resultSave(saved_path, self.image_out_np)
            self.setClean()
            self.statusBar().showMessage('Saved to  %s' % saved_path)
            self.statusBar().show()

    def saveFileDialog(self):
        caption = '%s - Choose File' % __appname__
        filters = 'File (*%s)' % 'png'
        if self.default_save_dir is not None and len(self.default_save_dir):
            openDialogPath = self.default_save_dir
        else:
            openDialogPath = self.currentPath()

        print(openDialogPath)
        dlg = QFileDialog(self, caption, openDialogPath, filters)
        dlg.setDefaultSuffix('png')
        dlg.setAcceptMode(QFileDialog.AcceptSave)
        filenameWithoutExtension = os.path.splitext(self.filePath)[0]
        dlg.selectFile(filenameWithoutExtension)
        dlg.setOption(QFileDialog.DontUseNativeDialog, False)
        if dlg.exec_():
            return dlg.selectedFiles()[0]
        return ''

    def currentPath(self):
        return os.path.dirname(self.filePath) if self.filePath else '.'

    def changeSavedirDialog(self, _value=False):
        if self.default_save_dir is not None:
            path = self.default_save_dir
        else:
            path = '.'

        dirpath = QFileDialog.getExistingDirectory(self,
                                                   '%s - Save annotations to the directory' % __appname__, path,
                                                   QFileDialog.ShowDirsOnly
                                                   | QFileDialog.DontResolveSymlinks)

        if dirpath is not None and len(dirpath) > 1:
            self.default_save_dir = dirpath

        self.statusBar().showMessage('%s . Annotation will be saved to %s' %
                                     ('Change saved folder', self.default_save_dir))
        self.statusBar().show()

    def setClean(self):
        self.dirty = False
        self.actions.save.setEnabled(False)

        self.actions.create.setEnabled(True)

    def openNextImg(self):
        pass

    def openPreImg(self):
        pass

    def scrollRequest(self, delta, orientation):
        units = - delta / (8 * 15)
        bar = self.scrollBars[orientation]
        bar.setValue(bar.value() + bar.singleStep() * units)

# 读取二进制图片 返回
def read(filename, default=None):
    try:
        with open(filename, 'rb') as f:
            return f.read()
    except Exception:
        return default

    def resetState(self):
        self.canvas.resetState()

if __name__ == "__main__":
    app = QApplication(sys.argv)
    ex = MainWindow()
    ex.show()

    sys.exit(app.exec_())


from collections import defaultdict
d = defaultdict(int)
n = int(input())
for _ in range(n):
    d[input()] += 1
allwords = list(d)

allwords_str = d.values()
listofx = []
for x in allwords_str:
    listofx.append(str(x))
print(len(allwords))
print(" ".join(listofx))

# This line is the same as the above block > print(*d.values()) except print(len(allwords))


from django.urls import path
from card import views

urlpatterns = [
    path('create/', views.CreateFlashCardView.as_view(), name="create-flash-card"),
    path('update/<id>/', views.UpdateFlashCardView.as_view(), name="update-flash-card"),
    path('dalete/<id>/', views.DeleteFlashCardView.as_view(), name="delete-flash-card"),
    path('list/<user_id>/', views.ListFlashCardView.as_view(), name="list-user-flash-card"),
]


"""utilities for generation of CTRMs
Author: Keisuke Okumura
Affiliation: TokyoTech & OSX
"""

from __future__ import annotations

import numpy as np
from numba import f8, jit

from ..environment import Instance
from ..roadmap import TimedNode, TimedRoadmap
from ..roadmap.utils import valid_move

@jit(f8[:](f8[:, :], f8[:]), nopython=True)
def get_dist_arr(cands_pos: np.ndarray, loc: np.ndarray) -> np.ndarray:
    return np.sum((cands_pos - loc) ** 2, axis=1)

def merge_samples(
    loc: np.ndarray,
    t: int,
    agent: int,
    trm: TimedRoadmap,
    ins: Instance,
    merge_distance: float = 0.01,
) -> np.ndarray:
    """find compatible sample, otherwise return loc

    Args:
        loc (np.ndarray): location
        t (int): timestep
        agent (int): target agent
        trm (TimedRoadmap): target timed roadmap
        ins (Instance): instance
        merge_distance (:obj:`float`, optional):
            distance regarding as spatially close enough

    Returns:
        np.ndarray: location of compatible sample if found, otherwise loc

    Todo:
        use efficient set operation
    """
    rad = ins.rads[agent]
    max_speed = ins.max_speeds[agent]
    goal = ins.goals[agent]

    # get necessary distance
    cands_pos_arr = [u.pos for u in trm.V[t - 1]]  # parents
    if t + 1 <= len(trm.V) - 1:
        cands_pos_arr += [u.pos for u in trm.V[t + 1]]  # children
    if len(trm.V) > t:
        cands_pos_arr += [u.pos for u in trm.V[t]]  # merge
    dist_arr = get_dist_arr(np.array(cands_pos_arr), loc)

    # compute parents
    offset = len(trm.V[t - 1])
    parents_cands_index = np.where(dist_arr[:offset] <= max_speed ** 2)[0]
    parents = [
        i
        for i in parents_cands_index
        if not ins.objs.collide_continuous_sphere(
            trm.V[t - 1][i].pos, loc, rad
        )
    ]
    set_loc_parents = set(parents)

    # compute children
    if t + 1 <= len(trm.V) - 1:
        children_cands_index = np.where(
            dist_arr[offset : offset + len(trm.V[t + 1])] <= max_speed ** 2
        )[0]
        children = [
            i
            for i in children_cands_index
            if not ins.objs.collide_continuous_sphere(
                trm.V[t + 1][i].pos, loc, rad
            )
        ]
    else:
        children = []
    set_loc_children = set(children)

    if len(trm.V) > t:
        merge_cands_idx = np.where(
            dist_arr[-len(trm.V[t]) :] <= merge_distance ** 2
        )[0]

        # get heuristics
        h_loc = sum((loc - goal) ** 2)

        for u_ind in merge_cands_idx:
            u = trm.V[t][u_ind]
            u_parents = trm.get_parents(u)
            u_children = trm.E[t][u.index]
            set_u_parents = set(u_parents)
            set_u_children = set(u_children)

            if (
                set_u_parents == set_loc_parents
                and set_u_children == set_loc_children
            ):
                # merge to better one
                h_u = sum((u.pos - goal) ** 2)
                if h_loc < h_u:
                    # replace u by loc
                    trm.V[t][u.index] = TimedNode(t, u.index, loc)
                    return loc
                else:
                    # abandon loc
                    return u.pos

            if (
                set_u_parents >= set_loc_parents
                and set_u_children >= set_loc_children
            ):
                # abandon loc
                return u.pos

            if (
                set_u_parents <= set_loc_parents
                and set_u_children <= set_loc_children
            ):
                # replace u by loc
                trm.V[t][u.index] = TimedNode(t, u.index, loc)
                # append additional edge, children
                trm.E[t][u.index] += list(set_loc_children - set_u_children)
                # append parents
                for p in set_loc_parents - set_u_parents:
                    trm.E[t - 1][p].append(u.index)
                return loc

    # append new sample
    trm.append_sample(loc=loc, t=t, parents=parents, children=children)
    return loc

def format_trms(ins: Instance, trms: list[TimedRoadmap]) -> None:
    """align length of timed roadmaps

    Args:
        ins (Instance): instance
        trms (list[TimedRoadmap]): timed roadmaps
    """
    T = max([len(trm.V) for trm in trms]) - 1
    for i, trm in enumerate(trms):

        def valid_edge(pos1: np.ndarray, pos2: np.ndarray) -> bool:
            return valid_move(
                pos1, pos2, ins.max_speeds[i], ins.rads[i], ins.objs
            )

        # technical point, add one additional layer
        trm.extend_until(T + 1, valid_edge)

def append_goals(ins: Instance, trms: list[TimedRoadmap]) -> None:
    """append goals to timed roadmaps

    Args:
        ins (Instance): instance
        trms (list[TimedRoadmap]): timed roadmaps
    """
    for i, (trm, goal) in enumerate(zip(trms, ins.goals)):

        def valid_edge(pos1: np.ndarray, pos2: np.ndarray) -> bool:
            return valid_move(
                pos1, pos2, ins.max_speeds[i], ins.rads[i], ins.objs
            )

        for t in range(1, len(trm.V)):
            trm.append_sample(goal, t, valid_edge)


import docker

class MicroDockerClient:
    def __init__(self, micro_configuration):
       self.client = docker.from_env()
       self.config = micro_configuration

    def pull(self):
        self.client.images.pull(self.config.image_name)

    def run(self):
        self.client.containers.run(
            self.config.image_name,
            ports={F'{self.config.container_port}/tcp':str(self.config.exposed_port)},
            name=self.config.name,
            detach=True)

    def delete(self):
        try:
            ctr = self.client.containers.list(filters={'name':self.config.name})[0]
            ctr.kill()
            ctr.remove()
        except Exception :
            print("No ctr to delete")


import Accelerometer
import ButtonControl
import RollPitch

import ParserSettings

# a parser for just one wii data
class oneWii :
	def __init__(self):
		self.accelerometer = Accelerometer.Accelerometer()
		self.buttons = ButtonControl.ButtonControl()
		self.rollPitch = RollPitch.RollPitch()

	def __call__(self,ts,wid,xyz=None,buttons=None):
		if xyz is not None :
			self.accelerometer.testEvent( ts, wid, *xyz )
			self.rollPitch.testEvent( ts, wid, *xyz )
		if buttons is not None :
			self.buttons.testEvent( ts, wid, buttons )


# Please develop your ingestion service in Python. You may select the delivery format (e.g., Jupyter
# Notebook, containerized microservice). For this exercise, you may assume that a scheduling service
# to regularly invoke your ingestion is provided.
# Where and how you process the data is at your discretion.

import os
import requests
# import psycopg2
import pandas as pd
import geopandas as gpd
from zipfile import ZipFile
from shapely.geometry import Point
from urllib.request import urlretrieve
from requests.exceptions import RequestException
from zipfile import BadZipFile
from psycopg2 import OperationalError
from mappings import event_root_codes, event_base_codes, event_codes, map_fips_to_iso2

def main():
    """ Main controller function
    """
    try:
        # add folders because git won't push empty folders
        try:
            os.mkdir('files')
            os.mkdir('extracted')
        except Exception:
            print('Folders already exist, no problem! Continuing...')
        extracted_file_path, zip_file_path = retrieve_event_data()
        geo_data = retrieve_geo_data()
        cleaned_data = clean_data(extracted_file_path)
        filtered_event_data = filter_data(cleaned_data, geo_data)
        load_db(filtered_event_data, event_root_codes, event_base_codes, event_codes, map_fips_to_iso2)
        cleanup(extracted_file_path, zip_file_path)
    except RequestException as e:
        print(f"Error while retrieving data: {e}")
    except BadZipFile as e:
        print(f"Error while extracting the zip file: {e}")
    except OperationalError as e:
        print(f"Database connection error: {e}")
    except Exception as e:
        print(f"An unexpected error occurred: {e}")

def retrieve_event_data() -> str:
    """ Gets event data from external source.
        I would improve this by looking into the GDELT API.
    """
    # Retrieve data from the source site
    data_files = requests.get('http://data.gdeltproject.org/gdeltv2/lastupdate.txt').content.decode()

    # Selecting the first entry with “export” in it will
    # give you the latest 15 min worth of data
    file_download_location = data_files.replace("\n", " ").split(" ")[2]

    # get just the file name out of the url
    file_name = file_download_location.split("/")[-1]
    file_path = 'files/' + file_name

    # downloading the file to files/
    urlretrieve(file_download_location, file_path)

    # unzip and extract file to extracted/
    with ZipFile(file_path, 'r') as zip:
        zip.extractall('extracted/')

    # remove .zip suffix
    extracted_file_path = 'extracted/' + file_name[0:-4]

    print('File downloaded')
    return extracted_file_path, file_path

def clean_data(extracted_file_path):
    """ Perform some foundational data prep and quality assurance
    """
    try:
        # load event data into pandas df
        event_df = pd.read_csv(extracted_file_path, sep='\t')

        # name cols so df is easier to use
        event_df.columns = ['col_' + str(i) for i in range(61)]

        # there are many things I could do here if I had more time
        # for now I will drop duplicates and remove columns that aren't needed
        # To make this more robust, I would clean and standardize the text
        # and convert dates and floats to the appropriate formats/types
        # I would also do ifnull checks and add in logic to fill in null values as needed

        # Select cols needed in final output defined in assignment
        event_df = event_df[['col_0', 'col_1', 'col_26', 'col_27', 'col_28', 'col_52', 'col_53', 'col_56', 'col_57', 'col_59', 'col_60']]

        # name the columns according to doc
        event_df.columns = ['GLOBALEVENTID', 'SQLDATE', 'EventCode', 'EventBaseCode', 'EventRootCode', 'ActionGeo_FullName', 'ActionGeo_CountryCode', 'ActionGeo_Lat', 'ActionGeo_Long', 'DATEADDED', 'SOURCEURL']
        # Drop duplicates
        event_df = event_df.drop_duplicates()

        return event_df

    except pd.errors.EmptyDataError as e:
        raise pd.errors.EmptyDataError(f"Empty data error: {e}")
    except pd.errors.ParserError as e:
        raise pd.errors.ParserError(f"Parser error: {e}")
    except Exception as e:
        raise Exception(f"An unexpected error occurred during data cleaning: {e}")

def retrieve_geo_data():
    """ In addition to the above source data, geometric location data for US counties may be located at:
        https://raw.githubusercontent.com/plotly/datasets/master/geojson-counties-fips.json
    """
    print('Retrieving geo data')
    return requests.get('https://raw.githubusercontent.com/plotly/datasets/master/geojson-counties-fips.json').content.decode()

def filter_data(event_df, geo_data):
    """ Please filter the event data to those events located within the US
        based on their lat/lon coordinates (lat: ActionGeo_Long, long:ActionGeo_Lat)
    """
    # Load choropleth data using geopandas
    choropleth_df = gpd.read_file(geo_data)

    # Convert the event dataframe to a GeoDataFrame using "ActionGeo_Lat" and "ActionGeo_Long" columns
    event_df['geometry'] = event_df.apply(lambda row: Point(row['ActionGeo_Long'], row['ActionGeo_Lat']), axis=1)
    # Specify the CRS for the event data
    event_gdf = gpd.GeoDataFrame(event_df, geometry='geometry', crs="EPSG:4326")

    # Ensure that both datasets have the same CRS
    event_gdf = event_gdf.to_crs(choropleth_df.crs)

    # Perform the spatial join to filter events in the U.S.
    us_events = gpd.sjoin(event_gdf, choropleth_df, how='inner', predicate='intersects')

    print('Data filtered - might add in specifics using variables here')
    return us_events

def load_db(filtered_event_data, event_root_codes, event_base_codes, event_codes, map_fips_to_iso2):
    """ Please use Postgres/GIS as your target database. You should demonstrate how you might make
        and manage the database connection, as well as the execution of needed transactions. You do not
        need to configure and run the actual database except as it is helpful to you to do so.
    """
    # This is just example code

    # # Define the database connection parameters
    # database_uri = "<insert your uri connection string here>"

    # # Establish a connection to the database
    # connection = psycopg2.connect(database_uri)

    # # Create a cursor for executing SQL commands
    # cursor = connection.cursor()

    # create_table_sql = """
    # CREATE TABLE events (
    #     GLOBALEVENTID SERIAL PRIMARY KEY,
    #     SQLDATE DATE,
    #     EventCode VARCHAR,
    #     EventBaseCode VARCHAR,
    #     EventRootCode VARCHAR,
    #     ActionGeo_FullName VARCHAR,
    #     ActionGeo_CountryCode VARCHAR,
    #     ActionGeo_Lat FLOAT,
    #     ActionGeo_Long FLOAT,
    #     DATEADDED DATE,
    #     SOURCEURL TEXT
    # )
    # """

    # I would also add the JSON mappings into the database as dimension tables
    # By creating the tables and inserting the given values into them

    # # Execute the SQL command to create the table
    # cursor.execute(create_table_sql)
    # connection.commit()

    # us_events.to_sql("events", connection, if_exists="replace", index=False)
    # connection.commit()

    # cursor.close()
    # connection.close()

    print('DB fictionally loaded: fictionally variable number of rows inserted')

def cleanup(extracted_file_path, zip_file_path):
    """ Removes downloaded and extracted files at end
    """
    print('Removing files')
    os.remove(extracted_file_path)
    os.remove(zip_file_path)

if __name__ == "__main__":
    main()


import spoonacular as sp
api = sp.API("eaf1205e8c26404a8cda30c46c86f1cd")

def find_from_ingredients(ingredient_list):
#ranking = 2 means minimizing missing ingredients
 recipe_list = api.search_recipes_by_ingredients(ingredients=ingredient_list, number=1, ranking=2)
 return recipe_list

def get_recipe_nutrition(ingredient_list, serving_num):
	recipe_list = api.visualize_recipe_nutrition(ingredientList=ingredient_list, servings=serving_num)
	return recipe_list

ingredients = input("Enter ingredients you would like to cook with: ")
nutrition = get_recipe_nutrition(ingredients, 1)
for recipe in nutrition:
 print(recipe)


# Task 1  For a given integer n calculate the value which is equal to a:
# squared number, if its value is strictly positive;
# modulus of a number, if its value is strictly negative;
# zero, if the integer n is zero.
# Example: n=4 result= 16; n=-5 result= 5; n=0 result=0

n = float(input("Please, enter n for calculation:"))
if n > 0:
    print((n**2))
elif n < 0:
    print(abs(n))
else:
    print('0')
print('------------ TASK2')
# Task 2.
# Find the maximum integer, that can be obtained by permutation of numbers of an arbitrary three-digit
# positive integer n (100<=n<=999).  Example: n =165 result = 651

n = input("Please, enter n for finding the maximum:")
n = (sorted(n, reverse=True))
print([int(x) for x in n])

print('------------ TASK3')
# Task 3.
# For a positive integer n calculate the result value, which is equal to the sum of the odd numbers of n.
# Example: n = 1234 result = 4, n = 246 result = 0

n = input("Please, enter n for calculation the sum of odd numbers:")
count_odd = 0
for i in n:
    if int(i) % 2 != 0:
        count_odd+=1
print('The sum of odd numbers:', count_odd)

print('------------ TASK4')
# Task 4. For a positive integer n calculate the result value, which is equal to the sum of the “1” in the
# binary representation of n.  Example: n = 1410 = 11102 result = 3, n = 12810 = 1000 00002 result = 1

n = input("Please, enter n for calculation of '1s': ")
n = int(n)
n = (bin(n) [2:])
print(n)
count_1_in_bin_format = 0
for i in n:
    if int(i) == 1:
        count_1_in_bin_format+=1
print('The count of "1" on binary format is:', count_1_in_bin_format)

print('------------ TASK5')
# Task 5. Create function Fibonacci for a positive integer n, calculate the result value, which is equal to the sum
# of the first n Fibonacci numbers.  Note. Fibonacci numbers are a series of numbers in which each next number is equal
# to the sum of the two preceding ones: 0, 1, 1, 2, 3, 5, 8, 13... (F0=0, F1=F2=1, then F(n)=F(n-1)+F(n-2) for n>2)
#  Example: n=8 result=33,  n = 11 result = 143

def fibinocci(n):
    if n == 1 or n == 2:
        return 1
    return fibinocci(n - 1) + fibinocci(n - 2)

x = fibinocci(8)
print('sum_of_n_Fibonacci', x)

print('------------ TASK6')


import numpy as np
import matplotlib.pyplot as plt
from scipy.constants import degree
from FallingCat import FallingCat

JI = 0.25
alpha = 30*degree

plt.figure(figsize=(5,7))

c = FallingCat(JI, alpha)
t = c.theta/degree
psi = c.lean()/degree
gamma = c.bend()/degree
phi = c.twist()/degree
print(phi[-1])
print((c.alpha + c.beta)/degree)
print((c.beta - c.alpha)/degree)

plt.subplot(3,1,1)
plt.plot(t, psi)
plt.ylabel(r'$\psi$  / deg')

plt.subplot(3,1,2)
plt.plot(t, gamma)
plt.ylabel(r'$\gamma$  / deg')

plt.subplot(3,1,3)
plt.plot(t, phi)
plt.ylabel(r'$\phi$  / deg')

plt.xlabel(r'$\theta$  / deg')
plt.tight_layout()
plt.savefig('fig2.eps')
plt.show()


# 给你一个字符串 s ，仅反转字符串中的所有元音字母，并返回结果字符串。

# 元音字母包括 'a'、'e'、'i'、'o'、'u'，且可能以大小写两种形式出现。

class Solution(object):
    def reverseVowels(self, s):
        """
        :type s: str
        :rtype: str
        """
        Vowels = ['a', 'e', 'i', 'o', 'u', 'A', 'E', 'I', 'O', 'U']
        s = list(s)
        i = 0
        j = len(s) - 1

        while(i < j):
            while(i < len(s) and s[i] not in Vowels):
                i += 1

            while(j >= 0 and s[j] not in Vowels):
                j -= 1
            if i >= j:
                break
            s[i], s[j] = s[j], s[i]
            i += 1
            j -= 1

        return ''.join(s)

s = ",."
a = Solution()
print(a.reverseVowels(s))


import json
import logging
import os
from http.client import HTTPConnection
from pathlib import Path
from typing import Dict, Any

from mmcc_framework import DictCallback, Framework
from mmcc_framework.nlu_adapters import NluAdapter

from tuning.mmcc_config.callbacks import my_callbacks
from tuning.types import Pipeline, PipelineCallback

# Load the process description and kb from file.
with open(Path(__file__).parent / 'mmcc_config' / 'process_desc.json', "r") as process_file:
    proc = json.loads(process_file.read())
    logging.getLogger(__name__).info('Reading process_desc file')
with open(Path(__file__).parent / 'mmcc_config' / 'process_kb.json', "r") as process_file:
    kb = json.loads(process_file.read())
    logging.getLogger(__name__).info('Reading process_kb file')

def get_framework(pipeline: Pipeline, result: str, start_work: PipelineCallback) -> Framework:
    """Creates a new framework object, remember to call `handle_data_input({})` to get the first sentence.

    The framework will have no NLU and the kb will not be saved at the end of execution.
    The context will contain the dataset and the pipeline.

    :param pipeline: the pipeline used in the last analysis
    :param result: base64 string representation of the previous analysis result
    :param start_work: callback that takes the pipeline and starts the execution in another thread
    """
    return Framework(process=proc,
                     kb=kb,
                     initial_context={'pipeline': pipeline, 'result': result, 'start_work': start_work},
                     callback_getter=DictCallback(callbacks=my_callbacks),
                     nlu=MyRasaNlu(),
                     on_save=lambda *args: None)

class MyRasaNlu(NluAdapter):
    """ This adapter uses Rasa, to use this adapter it is necessary to first setup and train the interpreter.

    The instructions on how to use Rasa are available on Rasa's website, and consist basically in the following steps:

    - Install Rasa and its dependencies;
    - Run `rasa init` in your folder of choice;
    - Edit the `data/nlu` file with the utterances used for training;
    - Run `rasa train nlu` to produce a model;
    - Start rasa on port 5005 and pass the location of the model:
      for example `rasa run --enable-api -m models/nlu-20201228-183937.tar.gz`

    Example:
        Suppose that the nlu is trained with, among the others, the intent "insert_name" with a entity "name".
        Initialize the adapter: `my_adapter = RasaNlu()`

        Suppose that it is time to insert the name. If it is necessary to insert it as text use:
        `my_framework.handle_text_input("Mark")`. The callback corresponding to the current activity will receive
        (if the intent is recognized): `{"intent": "insert_name", "name": "Mark"}`.

        If it is necessary to insert the name as data use:
        `my_framework.handle_data_input(RasaNlu.dict("insert_name", {"name": "Mark"}))`, which will pass to the callback
        the same structure as above.

    :ivar interpreter: the instance of the rasa interpreter used by this adapter
    """

    def __init__(self):
        self.host = os.getenv("RASA_IP", "localhost")  # TODO(giubots): fix here (host.docker.internal)
        self.port = int(os.getenv("RASA_PORT", "5005"))

    def parse(self, utterance: str) -> Dict[str, Any]:
        """ Runs the interpreter to parse the given utterance and returns a dictionary containing the parsed data.

        If no intent can be extracted from the provided utterance, this returns an empty dictionary.

        :param utterance: the text input from the user
        :return: a dictionary containing the detected intent and corresponding entities if any exists.
        """
        connection = HTTPConnection(host=self.host, port=self.port)
        connection.request("POST", "/model/parse", json.dumps({"text": utterance}))
        response = json.loads(connection.getresponse().read())
        if response["intent"]["name"] is None:
            return {"intent": ""}
        res = self.dict(response["intent"]["name"], {item['entity']: item["value"] for item in response["entities"]})
        logging.getLogger(__name__).info('Detected intent: %s', res)
        return res

    @staticmethod
    def dict(intent: str, values: Dict[str, Any] = None) -> Dict[str, Any]:
        """ Helper method that can be used to produce a dictionary equivalent to the one of the parse method.
        Use this method with framework.handle_data_input.

        :param intent: the intent corresponding to this input
        :param values: an optional dictionary containing pairs of entity-value
        :return: a dictionary equivalent to the one produced by the parse method
        """
        if values is None:
            values = {}
        return {"intent": intent, **values}


import sys

if __name__ == '__main__':
    if len(sys.argv) == 1:
        print("Usage: python {} [rom.ch8] >> [output.csv]".format(sys.argv[0]))
        exit()

    rom = sys.argv[-1]

    bytes = bytearray()
    with open(rom, 'rb') as r:
        byte = r.read(1)
        while byte != "":
            bytes.append(byte)
            byte = r.read(1)

    disassemble = []
    byteindex = 0
    while byteindex < len(bytes):
        disassemble.append(bytes[byteindex] << 8 | bytes[byteindex + 1])
        byteindex += 2

    pc = 0x200
    print("address,instruction,opcode,x,y,n,kk,nnn,description")
    for ip in range(0x00, len(disassemble)):
        mem_addr = '0x{0:0{1}X}'.format(pc, 4)
        instr = '0x{0:0{1}X}'.format(disassemble[ip], 4)
        opcode = '0x{0:0{1}X}'.format(disassemble[ip] & 0xF000, 4)
        x = '0x{0:0{1}X}'.format((disassemble[ip] >> 8) & 0x000F, 4)
        y =  '0x{0:0{1}X}'.format((disassemble[ip] >> 4) & 0x000F, 4)
        n =  '0x{0:0{1}X}'.format(disassemble[ip] & 0x000F, 4)
        kk =  '0x{0:0{1}X}'.format(disassemble[ip] & 0x0FF, 4)
        nnn =  '0x{0:0{1}X}'.format(disassemble[ip] & 0x0FFF, 4)
        desc = ""
        kk
        if int(opcode, 16) == 0x0000:
            if int(kk, 16) == 0x00E0:
                desc = "CLEAR_SCREEN"
            elif int(kk, 16) == 0x00EE:
                desc = "SUBROUTINE_RETURN"
            else:
                desc = "UNKNOWN_0x00_INSTRUCTION"
        elif int(opcode, 16) == 0x1000:
            desc = "JUMP_{}".format(nnn)
        elif int(opcode, 16) == 0x2000:
            desc = "SUBROUTINE_CALL_{}".format(nnn)
        elif int(opcode, 16) == 0x3000:
            desc = "SKIP_NEXT_INSTRUCTION_IF_V[{}]_EQUALS_{}".format(x, kk)
        elif int(opcode, 16) == 0x4000:
            desc = "SKIP_NEXT_INSTRUCTION_IF_V[{}]_NOT_EQUALS_{}".format(x, kk)
        elif int(opcode, 16) == 0x5000:
            desc = "SKIP_NEXT_INSTRUCTION_IF_V[{}]_EQUALS_V[{}]".format(x, y)
        elif int(opcode, 16) == 0x6000:
            desc = "SET_V[{}]_EQUALSTO_{}".format(x, kk)
        elif int(opcode, 16) == 0x7000:
            desc = "SET_V[{}]_EQUALSTO_V[{}]+{}".format(x, x, kk)
        elif int(opcode, 16) == 0x8000:
            if int(n, 16) == 0x0000:
                desc = "SET_V[{}]_EQUALSTO_V[{}]".format(x, y)
            elif int(n, 16) == 0x0001:
                desc = "SET_V[{}]_EQUALSTO_V[{}]_OR_V[{}]".format(x, x, y)
            elif int(n, 16) == 0x0002:
                desc = "SET_V[{}]_EQUALSTO_V[{}]_AND_V[{}]".format(x, x, y)
            elif int(n, 16) == 0x0003:
                desc = "SET_V[{}]_EQUALSTO_V[{}]_XOR_V[{}]".format(x, x, y)
            elif int(n, 16) == 0x0004:
                desc = "SET_V[{}]_EQUALSTO_V[{}]_PLUS_V[{}]".format(x, x, y)
            elif int(n, 16) == 0x0005:
                desc = "SET_V[{}]_EQUALSTO_V[{}]_MINUS_V[{}]".format(x, x, y)
            elif int(n, 16) == 0x0006:
                desc = "SET_V[{}]_EQUALSTO_V[{}] >> 1".format(x, x)
            elif int(n, 16) == 0x0007:
                desc = "SET_V[{}]_EQUALSTO_V[{}]_MINUS_V[{}]".format(x, y, x)
            elif int(n, 16) == 0x000E:
                desc = "SET_V[{}]_EQUALSTO_V[{}] << 1".format(x, x)
            else:
                desc = "UNKNOWN_0x8000_INSTRUCTION"
        elif int(opcode, 16) == 0x9000:
            desc = "SKIP_NEXT_INSTRUCTION_IF_V[{}]_NOT_EQUALS_V[{}]".format(x, y)
        elif int(opcode, 16) == 0xA000:
            desc = "SET_I_EQUALSTO_{}".format(nnn)
        elif int(opcode, 16) == 0xB000:
            desc = "JUMP_V0_PLUS_{}".format(nnn)
        elif int(opcode, 16) == 0xC000:
            desc = "SET_V[{}]_EQUALSTO_RANDOM".format(x)
        elif int(opcode, 16) == 0xD000:
            desc = "DRAW_SPRITE_AT_COORDINATES_V[{}]V[{}]_WIDTH_8_HEIGHT_{}".format(x, y, n)
        elif int(opcode, 16) == 0xE000:
            if int(kk, 16) == 0x009E:
                desc = "SKIP_NEXT_INSTRUCTION_IF_V[{}]_PRESSED".format(x)
            elif int(kk, 16) == 0x00A1:
                desc = "SKIP_NEXT_INSTRUTION_IF_V[{}]_NOTPRESSED".format(x)
            else:
                desc = "UNKNOWN_0xE000_INSTRUCTION"
        elif int(opcode, 16) == 0xF000:
            if int(kk, 16) == 0x0007:
                desc = "SET_V[{}]_EQUALSTO_DELAYTIMER".format(x)
            elif int(kk, 16) == 0x00A:
                desc = "KEYPRESS_WAIT_AND_STOREKEY_IN_V[{}]".format(x)
            elif int(kk, 16) == 0x0015:
                desc = "SET_DELAYTIMER_EQUALSTO_V[{}]".format(x)
            elif int(kk, 16) == 0x0018:
                desc = "SET_SOUNDTIMER_EQUALSTO_V[{}]".format(x)
            elif int(kk, 16) == 0x001E:
                desc = "SET_I_EQUALSTO_I_PLUS_V[{}]".format(x)
            elif int(kk, 16) == 0x0029:
                desc = "SET_I_EQUALSTO_SPRITE_ADDRESS_OF_CHAR_IN_V[{}]".format(x)
            elif int(kk, 16) == 0x0033:
                desc = "SET_BCD_V[{}]".format(x)
            elif int(kk, 16) == 0x0055:
                desc = "STORE_V[0-{}]_STARTINGAT_MEM[I]".format(x)
            elif int(kk, 16) == 0x0065:
                desc = "LOAD_MEM[I - I+{}]_IN_V[0-{}]".format(x, x)
            else:
                desc = "UNKNOWN_0xF000_INSTRUCTION"
        else:
            desc = "UNKNOWN_{}_OPCODE".format(opcode)
        pc += 2

        print("{},{},{},{},{},{},{},{},{}".format(mem_addr, instr, opcode, x, y, n, kk, nnn, desc))


# 영역 구하기

import sys

sys.setrecursionlimit(100000000)

input = sys.stdin.readline

m, n, k = map(int, input().split())

# 종이
paper = [[0 for _ in range(n)] for _ in range(m)]

# 방문 처리
visited = [[False for _ in range(n)] for _ in range(m)]
res = []

# 종이에 색칠하기
for _ in range(k):
    x1, y1, x2, y2 = map(int, input().split())
    for y in range(y1, y2):
        for x in range(x1, x2):
            paper[y][x] = 1

def dfs(y, x):
    res = 0

    def _dfs(y, x):
        nonlocal res
        res += 1
        visited[y][x] = True
        direction = [(1, 0), (0, -1), (-1, 0), (0, 1)]
        for d in direction:
            next_step = (y + d[0], x + d[1])
            if (
                0 <= next_step[0] < m
                and 0 <= next_step[1] < n
                and paper[next_step[0]][next_step[1]] == 0
                and not visited[next_step[0]][next_step[1]]
            ):
                _dfs(next_step[0], next_step[1])

    _dfs(y, x)
    return res

# 모든 종이를 숞회하면서 방문처리 되어있지 않은 곳이면 dfs 호출
for y in range(m):
    for x in range(n):
        if paper[y][x] == 0 and not visited[y][x]:
            cnt = dfs(y, x)
            res.append(cnt)

print(len(res))
for num in sorted(res):
    print(num, end=" ")


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

plt.style.use("bmh")

def exact(r1, r2, w):
    return 2 * np.sqrt(w/np.pi) * np.exp(- w * (r1 * r1 + r2 * r2))

def fmt(x, pos):
    a, b = '{:.1e}'.format(x).split('e')
    b = int(b)
    return r'${} \times 10^{{{}}}$'.format(a, b)

if __name__ == "__main__":
    N = 1000
    radius = 3
    r = np.linspace(-radius, radius, N)

    data = np.zeros((N, N))
    for i in range(N):
        for j in range(N):
            data[i, j] = exact(r[i], r[j], 1)

    #data /= np.sum(data)

    size = 28
    size_ticks = 20
    label_size = {"size":str(size)}
    plt.rcParams["font.family"] = "Serif"
    plt.rcParams.update({'figure.autolayout': True})

    fig, ax = plt.subplots(figsize=(8,6))

    img = ax.imshow(data, cmap=plt.cm.jet, extent=[-radius,radius,-radius,radius])
    cbar = fig.colorbar(img, fraction=0.046, pad=0.04) #, format=ticker.FuncFormatter(fmt))
    cbar.set_label(r'$\rho(r_i,r_j)$', rotation=90, labelpad=10, y=0.5, **label_size)
    cbar.ax.tick_params(labelsize=size_ticks)

    plt.tight_layout()

    ax.set_xlabel("$r_j$", **label_size)
    ax.set_ylabel("$r_i$", **label_size)
    ax.tick_params(labelsize=size_ticks)

    tick = [-3, -2, -1, 0, 1, 2, 3]
    ax.set_xticks(tick)
    ax.set_yticks(tick)

    plt.grid()
    plt.show()


from fastapi import FastAPI, HTTPException
from fastapi.middleware.cors import CORSMiddleware
import json, os

app = FastAPI()

app.add_middleware(
    CORSMiddleware,
    allow_origins=['*'],
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

@app.get('/contents/{page_id}/{content_id}')
async def content(
    page_id: str,
    content_id: str):
    json_path = f"./data/json/{page_id}/{content_id}.json"
    if not os.path.exists(json_path):
        raise HTTPException(status_code=404, detail="Page not found")
    with open(json_path, 'r', encoding='utf-8') as j:
        json_load = json.load(j)
        return json_load

@app.get('/contents/{page_id}')
async def contentslist(
    page_id: str,):
    json_path = f"./data/pagelist/{page_id}.json"
    if not os.path.exists(json_path):
        raise HTTPException(status_code=404, detail="Page not found")
    with open(json_path, 'r', encoding='utf-8') as j:
        json_load = json.load(j)
        return json_load

@app.get('/pagelist')
async def pagelist():
    json_path = "./data/pagelist/all.json"
    with open(json_path, 'r', encoding='utf-8') as j:
        json_load = json.load(j)
        return json_load


from django.contrib import admin
from django.contrib.staticfiles.urls import staticfiles_urlpatterns
from django.urls import path,  include
from django.contrib.auth import views as auth_views
from polls.views import (
    RegistrationView,
    CreateBoardView,
    BoardDetailView,
    BoardDeleteView,
    CreateListView,
    # ListDetailView,
    ListEditView,
    ListDeleteView,
    CreateCardView,
    CardEditView,
    CardDeleteView,
    CardMoveView,
)

urlpatterns = [
    path('admin/', admin.site.urls),
    path("accounts/", include("django.contrib.auth.urls")),
    path("accounts/register/", RegistrationView.as_view()),
    path("", CreateBoardView.as_view(), name="board"),
    path("board/detail/<id>/", BoardDetailView.as_view(), name="board_detail"),
    path("board/delete<id>/", BoardDeleteView.as_view(), name="board_delete"),
    path("list/<id>", CreateListView.as_view(), name="list_create"),
    # path("list/detail/<id>/", ListDetailView.as_view(), name="list_detail"),
    path("list/edit/<id>/", ListEditView.as_view(), name="list_edit"),
    path("list/delete/<id>/", ListDeleteView.as_view(), name="list_delete"),
    path("card/<id>/", CreateCardView.as_view(), name="card_create"),
    path("card/edit/<id>/", CardEditView.as_view(), name="card_edit"),
    path("card/delete/<id>/", CardDeleteView.as_view(), name="card_delete"),
    path("card/<id>/move/", CardMoveView.as_view(), name="card_move"),
]

urlpatterns += staticfiles_urlpatterns()


from heatSink import HeatSink
from waterPipes import WaterPipes
from solarPanel import SolarPanel
from system import System
import matplotlib.pyplot as plt

flow_rates = [0.00025, 0.0005, 0.001, 0.002, 0.003, 0.005]
panel_temp = []
no_pipes = []

inlet_temp = 30

for f in flow_rates:
    temps = []
    pipes = []
    for p in [1, 2, 3, 4, 5]:
        heat_sink = HeatSink()
        solar_panel = SolarPanel()
        water_pipes = WaterPipes(no_pipes=p)
        final_temp = 0
        for i in range(0, 40):
            system = System(heat_sink=heat_sink,
                            solar_panel=solar_panel,
                            water_pipes=water_pipes,
                            ambient_temp=30,
                            flow_rate=f,
                            flow_temp=inlet_temp)
            system.update()
            inlet_temp = system.outletTemp
            final_temp = system.T_2

        temps.append(final_temp)
        pipes.append(p)

    panel_temp.append(temps)
    no_pipes.append(pipes)

for i in range(0, len(flow_rates)):
    plt.plot(no_pipes[i], panel_temp[i], 'o-', label='Flow rate: ' + str(flow_rates[i]) + ' m3/s')

plt.legend()
plt.xlabel('Number of Pipes')
plt.ylabel('Panel Surface Temperature (°C)')
plt.show()


# Configuration file for the Sphinx documentation builder.
#
# For the full list of built-in configuration values, see the documentation:
# https://www.sphinx-doc.org/en/master/usage/configuration.html

# -- Project information -----------------------------------------------------
# https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information

project = "Polaris' NoteBook"
copyright = '2023, PolarisXQ'
author = 'PolarisXQ'
release = '0.0'

# -- General configuration ---------------------------------------------------
# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration

extensions = [
    'sphinx_markdown_tables',
    # 'sphinxemoji.sphinxemoji',
    'sphinx.ext.githubpages',
    'sphinx_copybutton',
    'sphinx.ext.mathjax',
    # 'pallets_sphinx_themes'
    'myst_parser'
]

myst_enable_extensions = [
    "amsmath",
    "attrs_inline",
    "colon_fence",
    "deflist",
    "dollarmath",
    "fieldlist",
    "html_admonition",
    "html_image",
    "linkify",
    "replacements",
    "smartquotes",
    "strikethrough",
    "substitution",
    "tasklist",
]

templates_path = ['_templates']
exclude_patterns = []

language = 'zh_CN'

# -- Options for HTML output -------------------------------------------------
# https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output

html_theme = 'press'
html_static_path = ['_static']
html_sidebars = {
    '***': ['util/searchbox.html', 'util/sidetoc.html'],
}

from recommonmark.parser import CommonMarkParser
source_parsers = {
'.md': CommonMarkParser,
}
source_suffix = ['.rst', '.md']

html_logo = '_static/madcat_mini.png'

html_favicon='_static/madcat_mini.png'

html_theme_options = {
  "external_links": [
      ("Github", "https://github.com/PolarisXQ"),
    #   ("Other", "https://bla.com")
  ]
}


import boto3
import json
from tqdm import tqdm
dynamodb = boto3.resource('dynamodb',region_name='us-east-2')
table = dynamodb.Table('FSBP_tree')

print(table.creation_date_time)
'''
with open('/hdd/c3s/data/aws_data/breach_compilation-pw_tree_1000000.json') as f:
    data = json.load(f)
with table.batch_writer() as batch:
    for item in data:
        batch.put_item(
            Item={
                'NodeId': item,
                'Info': data[item]
            }
        )
'''
f = open('/hdd/c3s/data/aws_data/splits/intr_tree_lucy_0.txt','r')
t = 0
bar= tqdm(f)
with table.batch_writer() as batch:
    for line in bar:
        item = line.split('\t')
        batch.put_item(
            Item={
                'NodeId': item[0],
                'Info': item[1]
            }
        )


import errno

from flask import current_app, request, render_template
from flask.views import MethodView
from werkzeug.exceptions import Forbidden, NotFound

from ..constants import COMPLETE, FILENAME, LOCKED, TYPE
from ..utils.date_funcs import delete_if_lifetime_over
from ..utils.http import redirect_next_referrer
from ..utils.permissions import ADMIN, CREATE, may
from ..utils.upload import Upload

class ModifyView(MethodView):
    def error(self, item, error):
        return render_template('error.html', heading=item.meta[FILENAME], body=error), 409

    def response(self, name):
        return redirect_next_referrer('bepasty.display', name=name)

    def get_params(self):
        return {
            FILENAME: request.form.get('filename'),
            TYPE: request.form.get('contenttype'),
        }

    def post(self, name):
        if not may(CREATE):
            raise Forbidden()

        try:
            with current_app.storage.openwrite(name) as item:
                if not item.meta[COMPLETE] and not may(ADMIN):
                    error = 'Upload incomplete. Try again later.'
                    return self.error(item, error)

                if item.meta[LOCKED] and not may(ADMIN):
                    raise Forbidden()

                if delete_if_lifetime_over(item, name):
                    raise NotFound()

                params = self.get_params()
                if params[FILENAME]:
                    item.meta[FILENAME] = Upload.filter_filename(
                        params[FILENAME], name, params[TYPE], item.meta[TYPE]
                    )
                if params[TYPE]:
                    item.meta[TYPE], _ = Upload.filter_type(
                        params[TYPE], item.meta[TYPE]
                    )

                return self.response(name)

        except OSError as e:
            if e.errno == errno.ENOENT:
                raise NotFound()
            raise


from flask_restful import Resource, reqparse
from flask_jwt import jwt_required, current_identity
from models.player import PlayerModel
from models.team import TeamModel

class Player(Resource):
    parser = reqparse.RequestParser()
    parser.add_argument(
        'back_number',
        type=int,
        required=True,
        help="This field must be integer"
    )

    parser.add_argument(
        'team_name',
        type=str,
        required=True,
        help="This field must be integer"
    )

    parser.add_argument(
        'new_back_number',
        type=str,
        required=False,
        help="This field must be integer"
    )

    def get(self, name, division=None, team_name=None):
        if team_name is None and division is None:
            players = PlayerModel.find_by_name(name)
            if players.count() > 0:
                return {"players": [player.json() for player in players]}
        elif team_name is None:
            print (division)
        else:
            team = TeamModel.find_by_name_division(team_name, division)
            if team:
                players = PlayerModel.find_by_team_id(team.id)
                if players.count() > 0:
                    return {"players": [player.json() for player in players]}
        return {"message": "Player does not exists"}

    def post(self, name):
        data = Player.parser.parse_args()
        team = TeamModel.find_by_name(data['team_name'])
        if team is None:
            return {"message" : "Team does not exist"}

        if PlayerModel.find_by_back_number_in_team(data['back_number'], team.id):
            return {"message" : "Back number is already taken."}

        player = PlayerModel(name, data['back_number'], team.id)
        player.save_to_db()
        return player.json()

    @jwt_required()
    def delete(self, name):
        data = Player.parser.parse_args()
        team = TeamModel.find_by_name(data['team_name'])
        if team is None:
            return {"message" : "Team does not exist"}

        player = PlayerModel.find_player_in_team(name, team.id, data['back_number'])
        if player:
            player.delete_from_db()
        return {"message":"Player deleted"}

    def put(self, name):
        data = Player.parser.parse_args()

        team = TeamModel.find_by_name(data['team_name'])
        if team is None:
            return {"message" : "Team does not exist"}

        if PlayerModel.find_by_back_number_in_team(data['new_back_number'], team.id):
            return {"message" : "Back number is already taken."}

        player = PlayerModel.find_player_in_team(name, team.id, data['back_number'])

        if player is None:
            return {"message" : "Player doesn not exist"}
        else:
            if data['new_back_number'] is None:
                return {"message" : "New Back Number is missing"}
            player.back_number = data['new_back_number']

        player.save_to_db()

        return player.json()

class PlayerList(Resource):
    def get(self, team_name=None, division=None):
        if team_name is None and division is None:
            players = PlayerModel.query.all()
        else:
            team = TeamModel.find_by_name(team_name)
            if team:
                players = PlayerModel.find_by_team_id(team.id)
            else:
                players = PlayerModel.find_by_division(division)

        return {"players" : [player.json() for player in players]}


import numpy
import multiprocessing as mp
import scipy.fftpack as fft
import scipy.signal as signal

import h5py
from .utilities import working_dir
from .stationbandpass import lofar_station_subband_bandpass

def fir_filter_coefficients(num_chan, num_taps, cal_factor=1./50.0):
    '''
    Compute FIR filter coefficients for channel separation.

    **Parameters**

    num_chan : int
        Required number of channels in PPF output.

    num_taps : int
        Number of PPF taps.

    **Returns**

    A num_taps x num_chan numpy.array of float32.

    **Example**

    >>> fir_filter_coefficients(num_chan=4, num_taps=8)
    array([[-0.00337621,  0.01111862, -0.01466139,  0.00781696],
           [ 0.00988741, -0.02981976,  0.03694931, -0.01888615],
           [-0.0233096 ,  0.06982564, -0.08770566,  0.0466728 ],
           [ 0.06241577, -0.21720791,  0.36907339, -0.46305624],
           [ 0.46305624, -0.36907339,  0.21720791, -0.06241577],
           [-0.0466728 ,  0.08770566, -0.06982564,  0.0233096 ],
           [ 0.01888615, -0.03694931,  0.02981976, -0.00988741],
           [-0.00781696,  0.01466139, -0.01111862,  0.00337621]], dtype=float32)

    '''
    raw_coefficients = signal.firwin((num_taps)*num_chan, 1/(num_chan),
                                     width=0.5/(num_chan))
    auto_fftshift = raw_coefficients*(-1)**numpy.arange(num_taps*num_chan)
    coefficients = numpy.array(auto_fftshift*(num_chan**0.5),
                               dtype=numpy.float32)
    coefficients *= cal_factor
    return coefficients.reshape((num_taps, num_chan))

def channelize_ppf(timeseries_taps, fir_coefficients):
    '''
    Make a polyphase-filtered spectrum of a timeseries.

    **Parameters**

    timeseries_taps : 2D numpy.array of complex64
        A `num_taps x num_chan` array containing the timeseries data,
        where `timeseries_taps.ravel()` should yield the input (single
        channel) timeseries data.

    fir_coefficients : 2D numpy.array of float32
        A `num_taps x num_chan` array containing the FIR coefficients,
        where `fir_coefficients.ravel()` should yield the FIR filter to
        multiply with the original (single channel) timeseries data.

    **Returns**

    A 1D numpy.array of complex64 with length num_chan containing the
    PPF output.

    **Example**

    >>> fir = fir_filter_coefficients(num_chan=4, num_taps=2, cal_factor=1)
    >>> fir.dtype
    dtype('float32')
    >>> timeseries = numpy.array(numpy.exp(2j*numpy.pi*2.8*numpy.arange(8)),
    ...                          dtype=numpy.complex64)
    >>> timeseries
    array([ 1.000000 +0.00000000e+00j,  0.309017 -9.51056540e-01j,
           -0.809017 -5.87785244e-01j, -0.809017 +5.87785244e-01j,
            0.309017 +9.51056540e-01j,  1.000000 -3.42901108e-15j,
            0.309017 -9.51056540e-01j, -0.809017 -5.87785244e-01j], dtype=complex64)
    >>> spectrum = channelize_ppf(timeseries.reshape(fir.shape), fir)
    >>> spectrum
    array([-0.03263591-0.01060404j, -0.00383157+0.00195229j,
           -0.00848089+0.02610143j,  0.78864020+1.54779351j], dtype=complex64)
    '''
    return (fft.fft((timeseries_taps*fir_coefficients).sum(axis=0)))

def channelize_ppf_multi_ts(timeseries_taps, fir_coefficients):
    '''FIR coefficients are num_taps x num_chan, blocks are num_timeslots x num_taps x num_chan arrays'''
    return (fft.fft((timeseries_taps*fir_coefficients[numpy.newaxis,:,:]).sum(axis=1),
                    axis=1))

def channelize_ppf_contiguous_block(timeseries_taps, fir_coefficients):
    num_taps, num_chan = fir_coefficients.shape
    num_ts_blocks = timeseries_taps.shape[0]
    num_spectra = num_ts_blocks -(num_taps-1)
    output_spectra = numpy.zeros((num_spectra, num_chan),
                                 dtype=numpy.complex64)
    for sp in range(num_spectra):
        output_spectra[sp,:] += channelize_ppf(timeseries_taps[sp:sp+num_taps,:],
                                               fir_coefficients)
    return output_spectra

def samples_per_block(block_length_s, sample_duration_s, num_chan, num_taps):
    r'''
    Calculate the number of samples per correlator intergration time,
    as well as the number of samples that must be read. The latter is
    larger because a certain number of samples before and after the
    actual interval must be read to properly fill the PPF.

    **Parameters**

    block_length_s : float
        Number of seconds per correlator interval.

    sample_duration_s : float
        Number of seconds per sample in the time series data.

    num_chan : int
        Number of channels for the PPF.

    num_taps : int
        Number of taps in the PPF

    **Returns**

    Tuple (block_length samples, samples_to_read_per_block). Both
    integers.

    **Examples**

    >>> block_length_samples, samples_to_read = samples_per_block(0.1, 1024/200e6, num_chan=256, num_taps=16)
    >>> block_length_samples, block_length_samples/256, samples_to_read/256
    (19456, 76.0, 91.0)
    >>> print(block_length_samples*1024/200e6, ' seconds')
    0.09961472  seconds

    '''
    num_spectra = int(round(block_length_s/sample_duration_s/num_chan))
    block_length_samples = num_spectra*num_chan
    samples_to_read_per_block = (num_spectra+(num_taps-1))*num_chan
    return block_length_samples, samples_to_read_per_block

def read_and_process_antenna_worker(h5_names, sap_id,
                                    num_sb, fir_coefficients,
                                    connection):
    r'''
    Read a complex time series from a sequence of four HDF5 groups
    containing, X_re, X_im , Y_re, Y_im, respectively. Read
    num_timeslots starting at first_timeslot. If apply_fn is not None,
    apply it to the resulting time series per sub band and return its
    result.

    **Parameters**

    h5_names : sequence strings
        The HDF5 file names of X_re, X_im, Y_re, and Y_im.

    first_timeslot : int
        The first timeslot to read.

    num_timeslots : int
        The number of timeslots to read.

    num_sb : int
        The number of sub bands expected in the data.

    fir_coefficients : 2D numpy.array of float32
        A `num_taps x num_chan` array containing the FIR coefficients,
        where `fir_coefficients.ravel()` should yield the FIR filter to
        multiply with the original (single channel) timeseries data.

    **Returns**

    Tuple of x and y numpy arrays(time, sb, channel).

    **Example**

    >>> None
    None
    '''
    sap_fmt = 'SUB_ARRAY_POINTING_%03d/BEAM_000/STOKES_%d'
    num_pol = len(h5_names)
    num_taps, num_chan = fir_coefficients.shape

    bandpass = lofar_station_subband_bandpass(num_chan)

#    with working_dir(dir_name):
    h5_files = [h5py.File(file_name, mode='r') for file_name in h5_names]
    h5_groups = [h5_file[sap_fmt % (sap_id, pol)]
                 for pol, h5_file in enumerate(h5_files)]
    while True:
        message = connection.recv()
        if message == 'done':
            connection.close()
            [h5_file.close() for h5_file in h5_files]
            break
        first_timeslot, num_timeslots = message
        time_series_real = numpy.zeros((4, num_timeslots, num_sb), dtype=numpy.float32)
        [h5_groups[pol].read_direct(time_series_real,
                                    numpy.s_[first_timeslot:first_timeslot+num_timeslots,:],
                                    numpy.s_[pol, :, :])
         for pol in range(num_pol)]
        time_series_complex_x = time_series_real[0,:,:] + 1j*time_series_real[1,:,:]
        time_series_complex_y = time_series_real[2,:,:] + 1j*time_series_real[3,:,:]

        result_x = numpy.array([channelize_ppf_contiguous_block(
            time_series_complex_x[:, sb].reshape((-1, num_chan)),
            fir_coefficients)/bandpass[numpy.newaxis,:]
                                for sb in range(num_sb)],
                               dtype=numpy.complex64)

        result_y = numpy.array([channelize_ppf_contiguous_block(
            time_series_complex_y[:, sb].reshape((-1, num_chan)),
            fir_coefficients)/bandpass[numpy.newaxis,:]
                                for sb in range(num_sb)],
                               dtype=numpy.complex64)
        connection.send(['x', result_x.shape, result_x.dtype])
        connection.send_bytes(result_x.tobytes())
        connection.send(['y', result_y.shape, result_y.dtype])
        connection.send_bytes(result_y.tobytes())

def time_and_freq_axes(h5_filename, sap_id=0):
    r'''
    '''
    coordinate_fmt = 'SUB_ARRAY_POINTING_%03d/BEAM_000/COORDINATES/COORDINATE_%d'
    h5_file = h5py.File(h5_filename, mode='r')
    time_axis, freq_axis = [
        dict([item
              for item in h5_file[coordinate_fmt %
                                     (sap_id, axis_id)].attrs.items()])
        for axis_id in [0, 1]]
    h5_file.close()
    return time_axis, freq_axis

def read_and_process_antenna_block_mp(dir_name, sas_id_string, sap_ids,
                                      fir_coefficients, interval_s=None,
                                      interval_samples=None, num_samples=256*16,
                                      max_duration_s=None):
    sap_fmt = 'SUB_ARRAY_POINTING_%03d/BEAM_000/STOKES_%d'
    with working_dir(dir_name):
        sap_names = [[('%s_SAP%03d_B000_S%d_P000_bf.h5' % (sas_id_string, sap_id, pol))
                      for pol in [0, 1, 2, 3]]
                     for sap_id in sap_ids]

        first_file = h5py.File(sap_names[0][0], mode='r')
        timeslots_per_file = first_file[sap_fmt % (0, 0)].shape[0]
        first_file.close()
        time_axis, freq_axis = time_and_freq_axes(sap_names[0][0], sap_id=0)
        num_sb = len(freq_axis['AXIS_VALUES_WORLD'])

        sample_duration_s = time_axis['INCREMENT']
        if interval_samples is None:
            samples_per_interval = int(numpy.floor(interval_s/sample_duration_s))
        else:
            samples_per_interval = interval_samples
        first_timeslot = 0

        pipes = [mp.Pipe() for sap_id in sap_ids]
        manager_ends = [pipe[0] for pipe in pipes]
        worker_ends = [pipe[1] for pipe in pipes]
        processes = [mp.Process(target=read_and_process_antenna_worker,
                                args=(h5_names, sap_id, num_sb, fir_coefficients, connection))
                     for h5_names, sap_id, connection in zip(sap_names, sap_ids, worker_ends)]
        [process.start() for process in processes]
        while first_timeslot < timeslots_per_file - samples_per_interval - num_samples:
            time_axis['REFERENCE_VALUE'] = (first_timeslot + num_samples/2)*sample_duration_s
            if max_duration_s is not None and (first_timeslot +num_samples)*sample_duration_s > max_duration_s:
                break

            [pipe.send([first_timeslot, num_samples]) for pipe in manager_ends]
            x_metadata = [pipe.recv() for pipe in manager_ends]
            x_data     = [numpy.frombuffer(pipe.recv_bytes(), dtype=x_meta[2]).reshape(x_meta[1])
                          for x_meta, pipe in zip(x_metadata, manager_ends)]
            y_metadata = [pipe.recv() for pipe in manager_ends]
            y_data     = [numpy.frombuffer(pipe.recv_bytes(), dtype=y_meta[2]).reshape(y_meta[1])
                          for y_meta, pipe in zip(y_metadata, manager_ends)]
            first_timeslot += samples_per_interval
            # Return X[sap, sb, time, chan], Y[sap, sb, time, chan], time, freq
            yield (numpy.array(x_data, dtype=numpy.complex64),
                   numpy.array(y_data, dtype=numpy.complex64), time_axis, freq_axis)
        [pipe.send('done') for pipe in manager_ends]
        [pipe.close() for pipe in manager_ends]
        [process.join() for process in processes]
        return None


# Write a program to convert decimal number to equivalent binary, octal, and hexadecimal numbers.

def binary(num):
    b=''
    while num:
        r=num%2
        b+=str(r)
        num=num// 2
    return b[::-1]

def octal(num):
    x=''
    while num:
        r=num%8
        x=x+str(r)
        num=num//8
    return x[::-1]

def hexdec(num):
    x=''
    while num:
        r=num%16
        if r>10:
            x+=chr(r+55)
        else:
            x=x+str(r)
        num=num//16
    return x[::-1]

num=int(input("Enter any decimal number : "))
print("The binary of the ",num," are : ",binary(num))
print("The octal of the ",num," are : ",octal(num))
print("The hexadecimal of the ",num," are : ",hexdec(num))


#!/usr/bin/env python
'''
  summarise slurm job details
  Usage: summarise.py --files slurm-*.log > summary.tsv
  Time is in hours.
  Memory is in GB.
'''

#(venv_somatic_2) spartan-login1 18:48:20 msi-evaluation$ sacct -j 18860471  --format="JobName,CPUTime,MaxRSS,Elapsed,MaxVMSize,Timelimit"
#   JobName    CPUTime     MaxRSS    Elapsed  MaxVMSize  Timelimit
#---------- ---------- ---------- ---------- ---------- ----------
#    mantis   17:37:48              02:56:18              08:00:00
#     batch   17:37:48    733264K   02:56:18  47907692K
#    extern   17:37:48      1212K   02:56:18    144788K

import argparse
import logging
import subprocess
import sys

def to_hours(v):
  # d-hh:mm:ss or hh:mm:ss
  if '-' in v:
    d = float(v.split('-')[0])
    return 24 * d + to_hours(v.split('-')[1])
  else:
    h, m, s = [int(x) for x in v.split(':')]
    return h + m / 60 + s / 3600

def to_g(v):
  if v.endswith('K'):
    return float(v[:-1]) / 1024 / 1024
  elif v.endswith('M'):
    return float(v[:-1]) / 1024
  elif v.endswith('Mn'):
    return float(v[:-2]) / 1024
  elif v.endswith('Gn'):
    return float(v[:-2])
  else:
    logging.warn('tricky memory value: %s', v)
    return float(v)

def main(files, filter_name):
  logging.info('starting...')

  sys.stdout.write('ID,Name,TimeRequested,TimeUsed,MemoryRequested,MemoryUsed,TimeDiff,MemoryDiff\n')
  for f in files:
    logging.info('%s...', f)
    i = f.split('/')[-1].split('.')[0].split('-')[-1]
    output = subprocess.check_output("sacct -j {} -p --format JobName,Elapsed,MaxRSS,ReqMem,TimeLimit".format(i), shell=True).decode()
    lines = output.split('\n')
    jobname = lines[1].split('|')[0]
    time_requested = to_hours(lines[1].split('|')[4])
    time_used = to_hours(lines[2].split('|')[1])
    memory_used = to_g(lines[2].split('|')[2])
    memory_requested = to_g(lines[2].split('|')[3])

    if filter_name == 'snakemake':
      jobname = '-'.join(jobname.split('-')[-2:-1])
      logging.debug('new jobname is %s', jobname)

    sys.stdout.write('{},{},{:.1f},{:.1f},{:.1f},{:.1f},{:.1f},{:.1f}\n'.format(i, jobname, time_requested, time_used, memory_requested, memory_used, time_requested - time_used, memory_requested - memory_used))

  logging.info('done')

if __name__ == '__main__':
  parser = argparse.ArgumentParser(description='Slurm summariser')
  parser.add_argument('--files', required=True, nargs='+', help='files containing slurm ids')
  parser.add_argument('--filter_name', required=False, help='filter names in snakemake format *-name-*')
  parser.add_argument('--verbose', action='store_true', help='more logging')
  args = parser.parse_args()
  if args.verbose:
    logging.basicConfig(format='%(asctime)s %(levelname)s %(message)s', level=logging.DEBUG)
  else:
    logging.basicConfig(format='%(asctime)s %(levelname)s %(message)s', level=logging.INFO)

  main(args.files, args.filter_name)


# -*- coding: utf-8 -*-
"""
Created on Wed May 12 04:34:12 2021

@author: Zakaria
"""

import pandas as pd

data = pd.read_csv('prediction_de_fraud_2.csv')

caracteristiques = data.drop('isFraud', axis=1).values

cible = data['isFraud'].values

from sklearn.preprocessing import LabelEncoder

LabEncdr_X = LabelEncoder()
caracteristiques[:, 1] = LabEncdr_X.fit_transform(caracteristiques[:, 1])
caracteristiques[:, 3] = LabEncdr_X.fit_transform(caracteristiques[:, 3])
caracteristiques[:, 6] = LabEncdr_X.fit_transform(caracteristiques[:, 6])

from sklearn.model_selection import train_test_split

x_train, x_test, y_train, y_test = train_test_split(caracteristiques, cible, test_size=.3, random_state=50)

from sklearn.ensemble import RandomForestClassifier

Random_frst_cls = RandomForestClassifier(random_state=50)

Random_frst_cls.fit(x_train, y_train)

Random_frst_cls.score(x_test, y_test) ## ==> 0.9550561797752809


### This file has been adopted from
### https://github.com/openlawlibrary/pygls/blob/master/examples/json-extension/server/server.py

import asyncio
from bisect import bisect

from cromwell_tools import api as cromwell_api
from cromwell_tools.cromwell_auth import CromwellAuth
from cromwell_tools.utilities import download

from functools import wraps

from pygls.features import (
    CODE_ACTION,
    DEFINITION,
    REFERENCES,
    TEXT_DOCUMENT_DID_OPEN,
    TEXT_DOCUMENT_DID_CHANGE,
    TEXT_DOCUMENT_DID_SAVE,
    TEXT_DOCUMENT_WILL_SAVE,
    WORKSPACE_DID_CHANGE_CONFIGURATION,
    WORKSPACE_DID_CHANGE_WATCHED_FILES,
)
from pygls.server import LanguageServer
from pygls.types import (
    CodeActionParams,
    ConfigurationItem,
    ConfigurationParams,
    Diagnostic,
    DiagnosticSeverity,
    DidChangeConfigurationParams,
    DidOpenTextDocumentParams,
    DidChangeTextDocumentParams,
    DidSaveTextDocumentParams,
    WillSaveTextDocumentParams,
    TextDocumentPositionParams,
    DidChangeWatchedFiles,
    FileChangeType,
    MessageType,
    Location,
    Position,
    Range,
)

from os import environ, name as platform, pathsep
from pathlib import Path
import re, sys
from requests import HTTPError
from threading import Timer
from time import sleep
from typing import Callable, Dict, Iterable, List, Set, Tuple, Union
from urllib.parse import urlparse

import WDL
from WDL import SourceNode, SourcePosition, Lint

PARSE_DELAY_SEC = 0.5 # delay parsing of WDL until no more keystrokes are sent

class Server(LanguageServer):
    SERVER_NAME = 'wdl'
    CONFIG_SECTION = SERVER_NAME

    CMD_RUN_WDL = SERVER_NAME + '.run'

    def __init__(self):
        super().__init__()
        self.wdl_paths: Dict[str, Set[str]] = dict()
        self.wdl_types: Dict[str, Dict[str, SourcePosition]] = dict()
        self.wdl_defs: Dict[str, Dict[SourcePosition, SourcePosition]] = dict()
        self.wdl_refs: Dict[str, Dict[SourcePosition, List[SourcePosition]]] = dict()
        self.wdl_symbols: Dict[str, List[SourcePosition]] = dict()
        self.aborting_workflows: Set[str] = set()

    def catch_error(self, log = False):
        def decorator(func: Callable):
            @wraps(func)
            def wrapper(*args, **kwargs):
                try:
                    return func(*args, **kwargs)
                except Exception as e:
                    if log:
                        self.show_message_log(str(e), MessageType.Error)
                    else:
                        self.show_message(str(e), MessageType.Error)
            return wrapper
        return decorator

server = Server()

def _get_client_config(ls: Server):
    config = ls.get_configuration(ConfigurationParams([
        ConfigurationItem(section=Server.CONFIG_SECTION)
    ])).result()
    return config[0]

# https://gist.github.com/walkermatt/2871026
def debounce(delay_sec: float, id_arg: Union[int, str]):
    """ Decorator that will postpone a functions
        execution until after wait seconds
        have elapsed since the last time it was invoked. """
    def decorator(func: Callable):
        @wraps(func)
        def debounced(*args, **kwargs):
            if not hasattr(debounced, 'timers'):
                debounced.timers: Dict[str, Timer] = dict()
            id = args[id_arg] if isinstance(id_arg, int) else kwargs[id_arg]
            if id in debounced.timers:
                debounced.timers[id].cancel()
            timer = Timer(delay_sec, lambda: func(*args, **kwargs))
            debounced.timers[id] = timer
            timer.start()
        return debounced
    return decorator

@debounce(PARSE_DELAY_SEC, 1)
def parse_wdl(ls: Server, uri: str):
    ls.show_message_log('Validating ' + uri, MessageType.Info)
    diagnostics, wdl = _parse_wdl(ls, uri)
    ls.publish_diagnostics(uri, diagnostics)
    ls.show_message_log(
        '{} {}'.format('Valid' if wdl else 'Invalid', uri),
        MessageType.Info if wdl else MessageType.Warning
    )

def _parse_wdl(ls: Server, uri: str):
    try:
        paths = _get_wdl_paths(ls, uri)
        doc = asyncio.run(
            WDL.load_async(uri, path=paths, read_source=_read_source(ls))
        )

        types = _get_types(doc.children, dict())
        ls.wdl_types[uri] = types
        ls.wdl_defs[uri], ls.wdl_refs[uri] = _get_links(doc.children, types, dict(), dict())
        ls.wdl_symbols[uri] = sorted(_get_symbols(doc.children, []))

        return list(_lint_wdl(ls, doc)), doc

    except WDL.Error.MultipleValidationErrors as errs:
        return [_diagnostic_err(e) for e in errs.exceptions], None

    except WDLError as e:
        return [_diagnostic_err(e)], None

    except Exception as e:
        ls.show_message_log(str(e), MessageType.Error)
        return [], None

def _read_source(ls: Server):
    async def read_source(uri: str, path, importer):
        uri = await WDL.resolve_file_import(uri, path, importer)
        if uri.startswith('/'):
            uri = 'file://' + uri
        source = ls.workspace.get_document(uri).source
        return WDL.ReadSourceResult(source_text=source, abspath=uri)
    return read_source

def _get_symbols(nodes: Iterable[SourceNode], symbols: List[SourcePosition]):
    for node in nodes:
        symbols.append(node.pos)
        _get_symbols(node.children, symbols)
    return symbols

# find SourcePosition as the minimum bounding box for cursor Position
def _find_symbol(ls: Server, uri: str, p: Position):
    if uri not in ls.wdl_symbols:
        return
    symbols = ls.wdl_symbols[uri]

    best_score = (sys.maxsize, sys.maxsize)
    best_sym: SourcePosition = None

    line = p.line + 1
    col = p.character + 1

    min_pos = SourcePosition(uri, uri, line, 0, line, 0)
    i = bisect(symbols, min_pos)

    while i < len(symbols):
        sym = symbols[i]
        if sym.line > line or (sym.line == line and sym.column > col):
            break
        elif sym.end_line > line or (sym.end_line == line and sym.end_column >= col):
            score = (sym.end_line - sym.line, sym.end_column - sym.column)
            if score <= best_score:
                best_score = score
                best_sym = sym
        i += 1
    return best_sym

def _get_types(nodes: Iterable[SourceNode], types: Dict[str, SourcePosition]):
    for node in nodes:
        if isinstance(node, WDL.StructTypeDef):
            types[node.type_id] = node.pos
        _get_types(node.children, types)
    return types

def _get_links(
    nodes: Iterable[SourceNode],
    types: Dict[str, SourcePosition],
    defs: Dict[SourcePosition, SourcePosition],
    refs: Dict[SourcePosition, List[SourcePosition]],
):
    for node in nodes:
        source: SourcePosition = None
        if isinstance(node, WDL.Call):
            source = node.callee.pos
        elif isinstance(node, WDL.Decl) and isinstance(node.type, WDL.Type.StructInstance):
            source = types[node.type.type_id]
        elif isinstance(node, WDL.Expr.Ident):
            ref = node.referee
            if isinstance(ref, WDL.Tree.Gather):
                source = ref.final_referee.pos
            else:
                source = ref.pos
        if source is not None:
            defs[node.pos] = source
            refs.setdefault(source, []).append(node.pos)
        _get_links(node.children, types, defs, refs)
    return defs, refs

SourceLinks = Union[SourcePosition, List[SourcePosition]]

def _find_links(ls: Server, uri: str, pos: Position, links: Dict[str, Dict[SourcePosition, SourceLinks]]):
    symbol = _find_symbol(ls, uri, pos)
    if (symbol is None) or (uri not in links):
        return
    symbols = links[uri]
    if symbol in symbols:
        return symbols[symbol]

def _find_def(ls: Server, uri: str, pos: Position):
    link = _find_links(ls, uri, pos, ls.wdl_defs)
    if link is not None:
        return Location(link.abspath, _get_range(link))

def _find_refs(ls: Server, uri: str, pos: Position):
    links = _find_links(ls, uri, pos, ls.wdl_refs)
    if links is not None:
        return [Location(link.abspath, _get_range(link)) for link in links]

def _lint_wdl(ls: Server, doc: WDL.Document):
    _check_linter_path()
    warnings = Lint.collect(Lint.lint(doc, descend_imports=False))
    _check_linter_available(ls)
    for pos, _, msg, _ in warnings:
        yield _diagnostic(msg, pos, DiagnosticSeverity.Warning)

def _check_linter_path():
    if getattr(_check_linter_path, 'skip', False):
        return

    LOCAL_BIN = '/usr/local/bin'
    PATH = environ['PATH'].split(pathsep)

    if platform == 'posix' and LOCAL_BIN not in PATH:
        environ['PATH'] = pathsep.join([LOCAL_BIN] + PATH)
    _check_linter_path.skip = True

def _check_linter_available(ls: Server):
    if getattr(_check_linter_available, 'skip', False):
         return

    if not Lint._shellcheck_available:
        ls.show_message('''
            WDL task command linter is not available on the system PATH.
            Please install ShellCheck and/or add it to the PATH:
            https://github.com/koalaman/shellcheck#installing
        ''', MessageType.Warning)
    _check_linter_available.skip = True

def _get_wdl_paths(ls: Server, wdl_uri: str, reuse_paths = True) -> List[str]:
    ws = ls.workspace
    if ws.folders:
        ws_uris = [f for f in ws.folders if wdl_uri.startswith(f)]
    elif ws.root_uri:
        ws_uris = [ws.root_uri]
    else:
        ws_uris = []
    wdl_paths: Set[str] = set()
    for ws_uri in ws_uris:
        if reuse_paths and (ws_uri in ls.wdl_paths):
            ws_paths = ls.wdl_paths[ws_uri]
        else:
            ws_paths: Set[str] = set()
            ws_root = Path(urlparse(ws_uri).path)
            for p in ws_root.rglob('*.wdl'):
                ws_paths.add(str(p.parent))
            ls.wdl_paths[ws_uri] = ws_paths
        wdl_paths.update(ws_paths)
    return list(wdl_paths)

WDLError = (WDL.Error.ImportError, WDL.Error.SyntaxError, WDL.Error.ValidationError)

def _diagnostic(msg: str, pos: SourcePosition = None, severity = DiagnosticSeverity.Error):
    return Diagnostic(_get_range(pos), msg, severity=severity)

def _get_range(p: SourcePosition = None):
    if p is None:
        return Range(
            Position(),
            Position(0, sys.maxsize),
        )
    else:
        return Range(
            Position(p.line - 1, p.column - 1),
            Position(p.end_line - 1, p.end_column - 1),
        )

def _diagnostic_err(e: WDLError):
    cause = ': {}'.format(e.__cause__) if e.__cause__ else ''
    msg = str(e) + cause
    return _diagnostic(msg, e.pos)

@server.thread()
@server.feature(TEXT_DOCUMENT_DID_OPEN)
@server.catch_error()
def did_open(ls: Server, params: DidOpenTextDocumentParams):
    parse_wdl(ls, params.textDocument.uri)

@server.thread()
@server.feature(TEXT_DOCUMENT_DID_CHANGE)
@server.catch_error()
def did_change(ls: Server, params: DidChangeTextDocumentParams):
    parse_wdl(ls, params.textDocument.uri)

@server.thread()
@server.feature(TEXT_DOCUMENT_DID_SAVE)
@server.catch_error()
def did_save(ls: Server, params: DidSaveTextDocumentParams):
    pass

@server.thread()
@server.feature(TEXT_DOCUMENT_WILL_SAVE)
@server.catch_error()
def will_save(ls: Server, params: WillSaveTextDocumentParams):
    pass

@server.feature(WORKSPACE_DID_CHANGE_CONFIGURATION)
def did_change_configuration(ls: Server, params: DidChangeConfigurationParams):
    pass

@server.thread()
@server.feature(WORKSPACE_DID_CHANGE_WATCHED_FILES)
@server.catch_error()
def did_change_watched_files(ls: Server, params: DidChangeWatchedFiles):
    for change in params.changes:
        if  change.type in [FileChangeType.Created, FileChangeType.Deleted] and \
            change.uri.endswith('.wdl'):
            _get_wdl_paths(ls, change.uri, reuse_paths=False)

@server.thread()
@server.feature(DEFINITION)
@server.catch_error()
def goto_definition(ls: Server, params: TextDocumentPositionParams):
    return _find_def(ls, params.textDocument.uri, params.position)

@server.thread()
@server.feature(REFERENCES)
@server.catch_error()
def find_references(ls: Server, params: TextDocumentPositionParams):
    return _find_refs(ls, params.textDocument.uri, params.position)

class RunWDLParams:
    def __init__(self, wdl_uri: str):
        self.wdl_uri = wdl_uri

@server.feature(CODE_ACTION)
@server.catch_error()
def code_action(ls: Server, params: CodeActionParams):
    return [{
        'title': 'Run WDL',
        'kind': Server.CMD_RUN_WDL,
        'command': {
            'command': Server.CMD_RUN_WDL,
            'arguments': [RunWDLParams(params.textDocument.uri)],
        },
    }]

@server.thread()
@server.command(Server.CMD_RUN_WDL)
@server.catch_error()
def run_wdl(ls: Server, params: Tuple[RunWDLParams]):
    wdl_uri = params[0].wdl_uri
    wdl_path = urlparse(wdl_uri).path

    _, wdl = _parse_wdl(ls, wdl_uri)
    if not wdl:
        return ls.show_message('Unable to submit: WDL contains error(s)', MessageType.Error)

    config = _get_client_config(ls)
    auth = CromwellAuth.from_no_authentication(config.cromwell.url)
    workflow = cromwell_api.submit(
        auth, wdl_path, raise_for_status=True,
    ).json()
    id = workflow['id']

    title = 'Workflow {} for {}'.format(id, wdl_path)
    _progress(ls, 'start', {
        'id': id,
        'title': title,
        'cancellable': True,
        'message': workflow['status'],
    })

    status: str = ''
    while True:
        if status != workflow['status']:
            status = workflow['status']
            if status == 'Succeeded':
                message_type = MessageType.Info
            elif status in ('Aborting', 'Aborted'):
                message_type = MessageType.Warning
            elif status == 'Failed':
                message_type = MessageType.Error
            else:
                _progress(ls, 'report', {
                    'id': id,
                    'message': status,
                })
                continue

            _progress(ls, 'done', {
                'id': id,
            })
            message = '{}: {}'.format(title, status)
            ls.show_message(message, message_type)

            diagnostics = _parse_failures(wdl, id, auth)
            return ls.publish_diagnostics(wdl_uri, diagnostics)

        sleep(config.cromwell.pollSec)

        if id in ls.aborting_workflows:
            workflow = cromwell_api.abort(
                id, auth, raise_for_status=True,
            ).json()
            ls.aborting_workflows.remove(id)
            continue

        try:
            workflow = cromwell_api.status(
                id, auth, raise_for_status=True,
            ).json()
        except HTTPError as e:
            ls.show_message_log(str(e), MessageType.Error)

def _progress(ls: Server, action: str, params):
    ls.send_notification('window/progress/' + action, params)

@server.feature('window/progress/cancel')
def abort_workflow(ls: Server, params):
    ls.aborting_workflows.add(params.id)

def _parse_failures(wdl: WDL.Document, id: str, auth: CromwellAuth):
    workflow = cromwell_api.metadata(
        id, auth,
        includeKey=['status', 'executionStatus', 'failures', 'stderr'],
        expandSubWorkflows=True,
        raise_for_status=True,
    ).json()
    if workflow['status'] != 'Failed':
        return

    calls = workflow['calls']
    if calls:
        diagnostics: List[Diagnostic] = []
        elements = wdl.workflow.elements

        for call, attempts in calls.items():
            for attempt in attempts:
                if attempt['executionStatus'] == 'Failed':
                    pos = _find_call(wdl.workflow.elements, wdl.workflow.name, call)
                    failures = _collect_failures(attempt['failures'], [])

                    stderr = _download(attempt['stderr'])
                    if stderr is not None:
                        failures.append(stderr)

                    msg = '\n\n'.join(failures)
                    diagnostics.append(_diagnostic(msg, pos))
        return diagnostics
    else:
        failures = _collect_failures(workflow['failures'], [])
        msg = '\n\n'.join(failures)
        return [_diagnostic(msg)]

class CausedBy:
    def __init__(self, causedBy: List['CausedBy'], message: str):
        self.causedBy = causedBy
        self.message = message

def _collect_failures(causedBy: List[CausedBy], failures: List[str]):
    for failure in causedBy:
        if failure['causedBy']:
            _collect_failures(failure['causedBy'], failures)
        failures.append(failure['message'])
    return failures

WorkflowElements = List[Union[WDL.Decl, WDL.Call, WDL.Scatter, WDL.Conditional]]

def _find_call(elements: WorkflowElements, wf_name: str, call_name: str):
    found: SourcePosition = None
    for el in elements:
        if found:
            break
        elif isinstance(el, WDL.Call) and '{}.{}'.format(wf_name, el.name) == call_name:
            found = el.pos
        elif isinstance(el, WDL.Conditional) or isinstance(el, WDL.Scatter):
            found = _find_call(el.elements, wf_name, call_name)
    return found

@server.catch_error(log=True)
def _download(url: str):
    return str(download(url), 'utf-8')


import xml.dom.minidom
import string;
import logging;

def LoadSession(system, FileName):
    Logger = logging.getLogger("PPLT");
    Logger.debug("Try to load Session from %s"%FileName);
    doc = xml.dom.minidom.parse(FileName);

    dev_tag = doc.getElementsByTagName("Devices")[0];
    sym_tag = doc.getElementsByTagName("SymbolTree")[0];
    srv_tag = doc.getElementsByTagName("Servers")[0];

    LoadDevices(system, dev_tag);
    LoadSymTree(system, sym_tag.firstChild);
    LoadServers(system, srv_tag);

def LoadDevices(system, Tag):
    devlst = Tag.getElementsByTagName("Device");
    for dev in devlst:
        Para    = xmlFetchParameters(dev);
        Alias   = dev.getAttribute("alias");
        FQDN    = dev.getAttribute("fqdn");
        system.LoadDevice(FQDN, Alias, Para);

def LoadServers(system, Tag):
    srvlst = Tag.getElementsByTagName("Server");
    for srv in srvlst:
        Para    = xmlFetchParameters(srv);
        Alias   = srv.getAttribute("alias");
        FQSN    = srv.getAttribute("fqsn");
        DefUser = srv.getAttribute("user");
        Root    = srv.getAttribute("root");
        if not Root:
            Root = "/";
        system.LoadServer(FQSN, Alias, DefUser, Para,Root);

def LoadSymTree(system, Tag, PathList=[]):
    if not Tag:
        return(None);
    if Tag.nodeType != Tag.ELEMENT_NODE:
        return(LoadSymTree(system, Tag.nextSibling, PathList));
    if Tag.localName == "Symbol":
        Name    = Tag.getAttribute("name");
        Slot    = Tag.getAttribute("slot");
        Refresh = Tag.getAttribute("refresh");
        Group   = Tag.getAttribute("group");
        Owner   = Tag.getAttribute("owner");
        Modus   = str(Tag.getAttribute("modus"));
        Path    = PathList2Str(PathList+[Name]);
        system.CreateSymbol(Path, Slot, Refresh, Modus, Owner, Group);
    if Tag.localName == "Folder":
        Name    = Tag.getAttribute("name");
        Group   = Tag.getAttribute("group");
        Owner   = Tag.getAttribute("owner");
        Modus   = Tag.getAttribute("modus");
        Path    = PathList2Str(PathList+[Name]);
        system.CreateFolder(Path, Modus, Owner, Group);
        if Tag.hasChildNodes():
            LoadSymTree(system,Tag.firstChild,PathList+[Name]);
    return(LoadSymTree(system,Tag.nextSibling,PathList));

def xmlFetchParameters(Node):
    parameter = {};
    parlst = Node.getElementsByTagName("Parameter");
    for par in parlst:
        name = par.getAttribute("name");
        value = xmlFetchText(par.firstChild);

        parameter.update( {name:value} );
    return(parameter);

def xmlFetchText(Node,txt=""):
    if not Node:
        return(txt);
    if Node.nodeType == Node.TEXT_NODE:
        txt += string.strip(Node.data);
    return(xmlFetchText(Node.nextSibling,txt));

def PathList2Str(PathLst):
    p = "";
    if len(PathLst) == 0:
        return("/");
    for item in PathLst:
        p += "/"+item;
    return(p);


from aio_proxy.response.formatters.elus import format_elus
from aio_proxy.response.unite_legale_model import CollectiviteTerritoriale

def format_collectivite_territoriale(
    colter_code=None,
    colter_code_insee=None,
    colter_elus=None,
    colter_niveau=None,
):
    if colter_code is None:
        return None
    else:
        return CollectiviteTerritoriale(
            code=colter_code,
            code_insee=colter_code_insee,
            elus=format_elus(colter_elus),  # Format elus if provided
            niveau=colter_niveau,
        ).dict()