#Head Material
#leftPorts=1
#rightPorts=1
#type=inputInterface
#done

#Block Description
'''
Author: Kyle Norland
Date: 10/13/20
Description: General signal reader from CSV
'''
#---------------------------------
#-------------Imports---------
#---------------------------------
import zmq
import json
import time
import sys

#Special
import csv

#Defaults:
proxyInputPort = 8000
proxyOutputPort = 9000
subTopics = []
pubTopics = ['cats']
blockName = "source--"

logfile = open("blockLogs/readCSVLog.txt", "w")
logfile.write("Got to here")
#------------------
#--Pull arguments--
#------------------
numArgs = len(sys.argv)
print("There are " + str(numArgs) + " arguments")

if numArgs >= 3:
    proxyInputPort = int(sys.argv[1])
    proxyOutputPort = int(sys.argv[2])
    stringArchitecture = sys.argv[3]
    try:
        print(stringArchitecture)
        jsonArch = json.loads(stringArchitecture)
        subTopics = jsonArch['subTopics']
        pubTopics = jsonArch['pubTopics']
        blockName = jsonArch['blockName']
        inputFileName = jsonArch['inputFiles'][0]
        print("The csv input file is: " + inputFileName)
    except:
        print("Something in the json loading process broke")
#------------------

#---------------------------------------
#-------Connect to the sockets----------
#---------------------------------------
context = zmq.Context()

pubSocket = context.socket(zmq.PUB)
pubSocket.connect("tcp://127.0.0.1:" + str(proxyInputPort))

subSocket = context.socket(zmq.SUB)
subSocket.connect("tcp://127.0.0.1:" + str(proxyOutputPort))

for subTopic in subTopics:
    subSocket.setsockopt(zmq.SUBSCRIBE, subTopic.encode())

#-------------------------------------------------------------
#-------------------Run Loop---------------------------
#------------------------------------------------------
logfile.write("Publishing to: " + str(pubTopics[0]))

with open(inputFileName, "r") as inputFile:
    csv_reader = csv.reader(inputFile, delimiter=",")
    line_count = 0

    dataLabels = []
    sendTemplate = {}
    for row in csv_reader:
        if line_count == 0:
            # Initialize the first row as the json keys
            for i in range(0, len(row)):
                dataLabels.append(str(row[i]))
                sendTemplate[str(row[i])] = ' '
            print(dataLabels)
            print(sendTemplate)
            line_count += 1

        if line_count != 0:
            #Create a json object and publish it.
            sendData = sendTemplate
            for i in range(0, len(row)):
                sendData[dataLabels[i]] = row[i]

            print(sendData)
            #Publish it
            pubSocket.send_string(pubTopics[0], zmq.SNDMORE)
            pubSocket.send_json(sendData)
            time.sleep(0.5)

            line_count += 1


"""Contiene clases que representan los actores comunes que pueden ser presentados en los diferentes tipos de escenas.
"""

from __future__ import annotations

from functools import cached_property, partial, wraps
from typing import Optional, Union, Tuple, Sequence, TYPE_CHECKING, Callable, Any

import numpy as np
import vtkmodules.all as vtk
from vtkmodules.util import numpy_support

from zonda.enums import Unidad
from zonda.graficos.directores.utils_iter import aplicar_func_recursivamente
from zonda.unidades import convertir_unidad

if TYPE_CHECKING:
    from zonda.tipos import Punto

colores = vtk.vtkNamedColors()

def color_3d(color: Optional[str] = None) -> vtk.vtkColor3d:
    """Obtiene un color 3D desde un string.

    Args:
        color: El color a obtener. Si es None se adopta "Gainsboro".

    Returns:
        El color 3D.
    """
    color = color or "Gainsboro"
    return colores.GetColor3d(color)

def crear_poly_data(puntos: Sequence[Punto]) -> vtk.vtkPolyData:
    vtk_puntos = vtk.vtkPoints()
    polygon = vtk.vtkPolygon()
    polygon.GetPointIds().SetNumberOfIds(len(puntos))
    for i, p in enumerate(puntos):
        vtk_puntos.InsertNextPoint(*p)
        polygon.GetPointIds().SetId(i, i)
    polygons = vtk.vtkCellArray()
    polygons.InsertNextCell(polygon)

    poly_data = vtk.vtkPolyData()
    poly_data.SetPoints(vtk_puntos)
    poly_data.SetPolys(polygons)

    return poly_data

def crear_mapper(
    data: Union[vtk.vtkPolyData, vtk.vtkPolyDataAlgorithm],
    scalar_visibility: bool = False,
) -> vtk.vtkPolyDataMapper:
    """

    Args:
        data: Polydata o un Source (Cono, flecha, etc)
        scalar_visibility: Define si se se usan los escalares para definir los colores.

    Returns:
        Un mapper.
    """
    mapper = vtk.vtkPolyDataMapper()
    try:
        mapper.SetInputConnection(data.GetOutputPort())
    except (TypeError, AttributeError):
        mapper.SetInputData(data)
    if not scalar_visibility:
        mapper.ScalarVisibilityOff()
    return mapper

def clip_poly_data(
    poly_data: vtk.vtkPolyData, origen: Punto, normal: Punto
) -> Union[None, vtk.vtkPolyData]:
    plano = vtk.vtkPlane()
    plano.SetOrigin(*origen)
    plano.SetNormal(*normal)

    clip = vtk.vtkClipPolyData()
    clip.SetClipFunction(plano)
    clip.SetInputData(poly_data)
    clip.Update()

    poly_data_clip = clip.GetOutput()

    if poly_data_clip.GetNumberOfPolys() == 0:
        return

    return poly_data_clip

def crear_actor(
    data: Union[vtk.vtkPolyData, vtk.vtkPolyDataAlgorithm],
    color: Optional[str] = None,
    scalar_visibility: bool = False,
) -> vtk.vtkActor:
    """Crea un actor VTK.

    Args:
        data: Polydata o un Source (Cono, flecha, etc)
        color: El color del actor.
        scalar_visibility: Define si se se usan los escalares para definir los colores.

    Returns:
        Un actor.
    """
    mapper = crear_mapper(data, scalar_visibility)
    actor = vtk.vtkActor()
    actor.SetMapper(mapper)

    if color is not None:
        actor.GetProperty().SetColor(color_3d(color))

    return actor

class ActorMixin:
    """ActorMixin.

    Agrega funcionalidad para añadir u ocultar actores en el renderer.
    """

    def __init__(self, renderer: vtk.vtkRenderer) -> None:
        self.renderer = renderer

    def _añadir(self) -> None:
        """Añade un actor al renderer."""
        self.renderer.AddActor(self)

    def mostrar(self) -> None:
        """Muestra un actor."""
        self.VisibilityOn()

    def ocultar(self) -> None:
        """Oculta un actor."""
        self.VisibilityOff()

class ActorTexto2D(vtk.vtkTextActor, ActorMixin):
    """ActorTexto2D.

    Genera un texto 2D usado para titulo o anotaciones del grafico en VTK.
    """

    def __init__(self, renderer: vtk.vtkRenderer) -> None:
        super().__init__(renderer)

        propiedad_texto = vtk.vtkTextProperty()
        propiedad_texto.SetColor(color_3d("Black"))
        propiedad_texto.SetFontSize(15)
        propiedad_texto.SetVerticalJustificationToTop()
        propiedad_texto.SetFontFamilyAsString("Arial")

        self.SetTextProperty(propiedad_texto)
        self.GetPositionCoordinate().SetCoordinateSystemToNormalizedDisplay()
        self.SetPosition(0.025, 0.975)

        self._añadir()

    def setear_texto(self, texto: str) -> None:
        """Setea el texto en el actor.

        Args:
            texto: El texto a setear..

        """
        self.SetInput(texto)

class ActorBarraEscala(vtk.vtkScalarBarActor, ActorMixin):
    """ActorBarraEscala.

    Genera una barra de escalas de colores.
    """

    def __init__(
        self,
        renderer: vtk.vtkRenderer,
        tabla_colores: vtk.vtkLookupTable,
        unidad: Unidad,
    ) -> None:
        """
        Args:
            renderer: El renderer que añade el actor.
            tabla_colores: Tabla utilizada para genera la barra.
            unidad: La unidad en la que se muestran los valores.
        """
        super().__init__(renderer)

        propiedad_texto = vtk.vtkTextProperty()
        propiedad_texto.SetColor(color_3d("Black"))
        propiedad_texto.SetFontSize(12)
        propiedad_texto.SetVerticalJustificationToCentered()

        self.SetLabelTextProperty(propiedad_texto)
        self.SetLookupTable(tabla_colores)
        self.SetNumberOfLabels(4)
        self.SetMaximumWidthInPixels(75)
        self.SetMaximumHeightInPixels(200)
        self.SetLabelFormat(f"%.2f {unidad.value}/m\u00B2")
        self.SetPosition(0.025, 0.025)
        self.SetAnnotationTextScaling(False)
        self.SetUnconstrainedFontSize(True)
        self.SetTextPad(2)

        self._añadir()

class ActorLabel(vtk.vtkBillboardTextActor3D, ActorMixin):
    """ActorLabel.

    Representa un recuadro con texto que siempre mira a la cámara.
    """

    def __init__(
        self,
        renderer: vtk.vtkRenderer,
        tamaño_texto: int = 12,
        borde: bool = True,
        centrado: bool = False,
    ) -> None:
        """
        Args:
            renderer: El renderer que añade u oculta al actor.
            tamaño_texto: El tamaño de texto.
            borde: Indica si el borde es visible.
            centrado: Indica si se debe centrar el texto vertical y horizontalmente.
        """

        super().__init__(renderer)

        self.tamaño_texto = tamaño_texto

        rgb = 237 / 255

        self._propiedad_texto = vtk.vtkTextProperty()
        self._propiedad_texto.SetColor(color_3d("Black"))
        self._propiedad_texto.SetFrameColor(color_3d("Black"))
        self._propiedad_texto.SetFontSize(tamaño_texto)
        self._propiedad_texto.SetVerticalJustificationToBottom()
        self._propiedad_texto.SetFrame(borde)
        self._propiedad_texto.SetBackgroundColor(rgb, rgb, rgb)
        self._propiedad_texto.SetBackgroundOpacity(1)
        self._propiedad_texto.UseTightBoundingBoxOff()
        if centrado:
            self._propiedad_texto.SetJustificationToCentered()
            self._propiedad_texto.SetVerticalJustificationToCentered()

        self.SetTextProperty(self._propiedad_texto)

        self._añadir()

    def setear_texto(self, texto: str) -> None:
        """Setea texto en el actor.

        Args:
            texto: El texto a setear.
        """
        self.SetInput(texto)

    def setear_posicion(self, posicion: Tuple[float, float, float]) -> None:
        """Setar la posición para el actor.

        Args:
            posicion: En el hint indica tuple, pero puede ser cualquier secuencia de tres floats.
        """
        self.SetPosition(*posicion)

    def aumentar_tamaño(self) -> None:
        """Aumenta el tamaño del texto."""
        self._cambiar_tamaño(1.1111)

    def disminuir_tamaño(self) -> None:
        """Disminuye el tamaño del texto."""
        self._cambiar_tamaño(0.9)

    def _cambiar_tamaño(self, factor: float) -> None:
        """Cambia el tamaño del texto de acuerdo al factor ingresado.

        Args:
            factor: El factor que modifica el tamaño.
        """
        tamaño = self._propiedad_texto.GetFontSize() * factor
        tamaño = max(tamaño, self.tamaño_texto)
        self._propiedad_texto.SetFontSize(int(tamaño))

class ActorFlechaPresion(vtk.vtkActor, ActorMixin):
    """ActorFlechaPresion.

    Actor representado por una flecha que se usa para indicar las presiones sobre las superficies.
    """

    def __init__(
        self,
        renderer: vtk.vtkRenderer,
        normal_centro: vtk.vtkCellCenters,
        max_valor_presion: float,
    ) -> None:
        """

        Args:
            renderer: El renderer utilizado para añadir u ocultar el actor.
            normal_centro: La norma en el centro de un poligono.
            max_valor_presion: El mayor valor de presión. Se utiliza para escalar el actor en base a este valor.
        """
        super().__init__(renderer)
        self.normals_centro = normal_centro
        self.max_valor_presion = max_valor_presion

        self._arrow_source = vtk.vtkArrowSource()
        self._arrow_source.SetTipResolution(30)
        self._arrow_source.SetShaftResolution(30)
        self._arrow_source.InvertOn()
        self._arrow_source.SetShaftRadius(0.03)
        self._arrow_source.SetTipRadius(0.1)
        self._arrow_source.SetTipLength(0.3)

        self._escala_base = 7

        self._mapper = crear_mapper(self._glyph3d)
        self.SetMapper(self._mapper)

        self.label = ActorLabel(renderer)
        self.SetPickable(False)

        self._añadir()

    def aumentar_escala(self) -> None:
        """Aumenta la escala de la flecha."""
        self._cambiar_escala_general(1.1111)

    def disminuir_escala(self) -> None:
        """Disminuye la escala de la flecha."""
        self._cambiar_escala_general(0.9)

    def _cambiar_escala_general(self, factor: float) -> None:
        """Cambia la escala base de acuerdo al factor ingresado. Además, modifica la escala actual de la flecha tambien
        con el factor ingresado.

        Args:
            factor: El factor que modifica la escala.
        """
        self._escala_base *= factor
        escala_actual = self._glyph3d.GetScaleFactor() * factor
        self._escalar_reubicar_label(escala_actual)

    @cached_property
    def _glyph3d(self) -> vtk.vtkGlyph3D:
        """Crea un glyph 3D que sirve para orientar el actor (la flecha) según la normal al polígono.

        Returns:
            Glyph3d
        """
        glyph3d = vtk.vtkGlyph3D()
        glyph3d.SetSourceConnection(self._arrow_source.GetOutputPort())
        glyph3d.SetVectorModeToUseNormal()
        glyph3d.SetInputConnection(self.normals_centro.GetOutputPort())
        glyph3d.OrientOn()
        glyph3d.Update()

        return glyph3d

    def asignar_presion(self, valor: float) -> None:
        """Asigna una presión al actor. Con este valor de presión se escala el actor (la flecha) y se orienta la dependiendo
        del signo de la presión (Positivo entra al poligono y negativo sale del poligono)

        Args:
            valor: El valor de presión.
        """
        self._escalar_reubicar_label(
            abs(valor) / self.max_valor_presion * self._escala_base
        )
        bool_invertir_flecha = valor >= 0
        self._arrow_source.SetInvert(bool_invertir_flecha)

    def mostrar(self) -> None:
        """Añade el actor (la flecha) y el label."""
        self.VisibilityOn()
        self.label.mostrar()

    def ocultar(self) -> None:
        """Ocualta el actor (la flecha) y el label."""
        self.VisibilityOff()
        self.label.ocultar()

    def reubicar_label(self) -> None:
        """Cambia la posición del label. Se detecta la escala de la flecha y en base a esta y su posición se obtiene
        el punto extremos de la misma que es donde se ubica el label.
        """
        escala = self._glyph3d.GetScaleFactor()
        np_normal = numpy_support.vtk_to_numpy(
            self.normals_centro.GetOutput().GetCellData().GetNormals()
        )
        posicion = np.array(self.GetCenter()) + escala / 2 * 1.05 * np_normal
        self.label.setear_posicion(posicion)

    def _escalar_reubicar_label(self, escala: float) -> None:
        """Escala el actor (la flecha) en base al valor ingresado y reubica el label.

        Args:
            escala: El valor de escala.
        """
        self._glyph3d.SetScaleFactor(escala)
        self._glyph3d.Update()
        self.reubicar_label()

class ActorPresion(vtk.vtkActor, ActorMixin):
    """ActorPresion.

    Visualizar las presiones. Se representada por un poligono que representa el area sobre la que actua el viento, por
    una flecha normal a este que representa su sentido, orientación y por un label que indica el valor de presión.
    """

    def __init__(
        self,
        renderer: vtk.vtkRenderer,
        puntos_poligono: Optional[Sequence[Punto]] = None,
        poly_data: Optional[vtk.vtkPolyData] = None,
        color: Optional[str] = None,
        tabla_colores: Optional[vtk.vtkLookupTable] = None,
        presion: bool = False,
        mostrar: bool = True,
    ) -> None:
        """

        Args:
            renderer: El renderer utilizado para añadir u ocultar el actor.
            puntos_poligono: Los puntos X, Y, Z que forman el poligono.
            poly_data: La polydata a usar si esta presente en lugar de los puntos.
            color: El color del poligono.
            tabla_colores: La tabla de escalas de colores de la escena general.
            presion: Indica si se debe mostrar la flecha y el label.
            mostrar: Indica si debe ser mostrado cuando se instancia.
        """
        super().__init__(renderer)
        self.puntos_poligono = puntos_poligono
        self._poly_data = poly_data
        self.color = color
        if tabla_colores is not None:
            self.tabla_colores = tabla_colores
            valor_min_presion, valor_max_presion = tabla_colores.GetTableRange()
            self._max_valor_presion = max(
                abs(valor_min_presion), abs(valor_max_presion)
            )

        self._mapper = crear_mapper(self.poly_data)
        self.SetMapper(self._mapper)
        self.GetProperty().EdgeVisibilityOn()
        self.GetProperty().SetLineWidth(2)
        self.GetProperty().SetColor(color_3d(self.color))

        if presion and tabla_colores is not None:
            self.flecha = ActorFlechaPresion(
                self.renderer,
                self._normals_centro,
                self._max_valor_presion,
            )

        self._añadir()

        if mostrar:
            self.mostrar()
        else:
            self.ocultar()

    def asignar_presion(
        self, presion: float, unidad: Unidad, str_extra: str = ""
    ) -> None:
        """Asigna un valor de presión al actor.

        Al hacerlo obtiene un color de la tabla en base al valor de presión y se lo asigna al poligono. Además escala
        la flecha, modifica su orientación en base al signo de la presión y asigna el texto correspondiente al label.

        Args:
            presion: El valor de presión.
            unidad: La unidad en que se encuentra la presión.
            str_extra: Un string a añadir al texto del label.
        """
        presion = convertir_unidad(presion, unidad)
        color_poligono = self._obtener_color(presion)
        self.GetProperty().SetColor(color_poligono)
        self.flecha.asignar_presion(presion)
        self.flecha.label.setear_texto(
            f"{presion:.2f} {unidad.value}/m\u00B2 {str_extra}"
        )
        self.mostrar()

    def mostrar(self) -> None:
        """Añade el actor y la flecha (si existe)."""
        if not self.GetVisibility():
            self.VisibilityOn()
            if hasattr(self, "flecha"):
                self.flecha.mostrar()

    def ocultar(self) -> None:
        """Oculta el actor y la flecha (si existe)."""
        if self.GetVisibility():
            self.VisibilityOff()
            if hasattr(self, "flecha"):
                self.flecha.ocultar()

    @cached_property
    def poly_data(self) -> vtk.vtkPolyData:
        """Crea la polydata del poligono.

        Returns:
            Polydata del poligono.
        """
        if self._poly_data is not None:
            return self._poly_data
        return crear_poly_data(self.puntos_poligono)

    @cached_property
    def _normals(self) -> vtk.vtkPolyDataNormals:
        """Obtiene las normales de la polydata.

        Returns:
            Normales de la polydata.
        """
        normals = vtk.vtkPolyDataNormals()

        normals.SetInputData(self._mapper.GetInput())
        normals.ComputePointNormalsOn()
        normals.ComputeCellNormalsOn()
        normals.SplittingOff()
        normals.ConsistencyOn()
        normals.AutoOrientNormalsOff()
        normals.Update()

        return normals

    @cached_property
    def _normals_centro(self) -> vtk.vtkCellCenters:
        """Obtiene el centro de las normales.

        Returns:
            Centro de las normales.
        """
        centro = vtk.vtkCellCenters()
        centro.SetInputConnection(self._normals.GetOutputPort())
        centro.VertexCellsOn()
        centro.Update()
        return centro

    def _obtener_color(self, presion: float) -> list:
        """Obtiene un color de la tabla de colores en base al valor de presión ingresado.

        Args:
            presion: El valor de presión.

        Returns:
            El color obtenido.
        """
        dcolor = 3 * [0.0]
        self.tabla_colores.GetColor(presion, dcolor)
        return dcolor

def actores_poligonos(
    func: Optional[Callable] = None,
    *,
    crear_atributo: bool = False,
    color: Optional[str] = None,
    presion: bool = False,
    mostrar: bool = False,
) -> Any:
    """Crea un actor poligono VTK a partir de un método que retorna una secuencia de puntos que forman el poligono.

    Se debe usar como decorador de un método de clase.

    Args:
        func: La función o método decorado.
        crear_atributo: Indica si se debe crear un atributo en la clase que referencie a los actores generados. El nombre
            del atributo esta dado por "actores_" + el nombre del método.
        color: El color del actor poligono generado.
        presion: Indica si el poligono actua como poligono de presión, es decir si se le debe agregar una flecha y label.
        mostrar: Indica si debe ser mostrado al ser instanciado por el renderer.

    Notes:
        La clase que contiene al metodo debe tener creados los atributos "self._renderer" y "self._tabla_colores". Este
        último es necesario si el actor es de tipo presión.

    Returns:
        Actores generado en base los puntos retornado por el método decorado.
    """
    if func is None:
        return partial(
            actores_poligonos,
            crear_atributo=crear_atributo,
            color=color,
            presion=presion,
            mostrar=mostrar,
        )

    @wraps(func)
    def wrapped(self, *args, **kwargs):
        puntos = func(self, *args, **kwargs)
        tabla_colores = getattr(self, "tabla_colores", None)
        actores = aplicar_func_recursivamente(
            puntos,
            lambda x: ActorPresion(
                self.renderer,
                x,
                color=color,
                tabla_colores=tabla_colores,
                presion=presion,
                mostrar=mostrar,
            ),
        )
        if crear_atributo:
            setattr(self, f"actores_{func.__name__}", actores)

    return wrapped


import pygame

WallCors = []
class Character:

	StartingPositionX = 0
	StartingPositionY = 0
	Speed = 0
	size = [0,0]
	position = dict(x = StartingPositionX,y= StartingPositionY)

	def __init__(self):
		StartingPositionX = self.StartingPositionX
		StartingPositionY = self.StartingPositionY
		position = self.position

	@property
	def Position(self):
		return self.position

	@Position.setter
	def Position(self,x,y):
		self.position = [x,y]

	@property
	def Size(self):
		return self.size

	@property
	def Tile(self):
		return pygame.Rect(self.Position['x'],self.Position['y'],*self.Size)

	def DrawOn(self,surface):
		pygame.draw.rect(surface,(225, 225, 0), [self.Position['x'],self.Position['y'],*self.Size])

	def _checkObstacles(self,direction):
		if direction is 'left':
			if (self.Position['x'] - self.Speed) not in WallCors:
				return True

		if direction is 'right':
			if (self.Position['x'] +  self.Speed) not in WallCors:
				return True

		if direction is 'up':
			if (self.Position['y'] - self.Speed) not in WallCors:
				return True

		if direction is 'down':
			if (self.Position['y'] + self.Speed) not in WallCors:
				return True

	def GoLeft(self):
		if self._checkObstacles('left'):
			self.Position['x'] -=self.Speed
			self.Tile.move_ip(0-self.Speed,0)

	def GoRight(self):
		if self._checkObstacles('right'):
			self.Position['x'] +=self.Speed
			self.Tile.move_ip(0+self.Speed,0)

	def GoUp(self):
		if self._checkObstacles('up'):
			self.Position['y'] -=self.Speed
			self.Tile.move_ip(0,0-self.Speed)

	def GoDown(self):
		if self._checkObstacles('down') :
			self.Position['y'] +=self.Speed
			self.Tile.move_ip(0,0+self.Speed)


# Python 3.6 introduced a new implementation of dict.
# dict now keeps its items ordered as well.

# An OrderedDict is a dictionary subclass that remembers the order in which its contents are added.
from collections import OrderedDict

if __name__ == "__main__":
    order_dic = OrderedDict()
    order_dic['a'] = 'A'
    order_dic['b'] = 'B'
    order_dic['c'] = 'C'
    order_dic['d'] = 'D'
    order_dic['e'] = 'E'

    for k, v in order_dic.items():
        print(k, v)

    # https://docs.python.org/3/library/collections.html#collections.OrderedDict.popitem
    # last=True -> LIFO
    # last=False -> FIFO

    print(
        order_dic.popitem(last=True) # -> ('e', 'E')
    )

    print(
        order_dic.popitem(last=False) # -> ('a', 'A')
    )

    # https://docs.python.org/3/library/collections.html#collections.OrderedDict.move_to_end
    # last=True   -> The item is moved to the right end
    # last=False  -> The item is moved to the beginning

    print('origin:', order_dic) # OrderedDict([('b', 'B'), ('c', 'C'), ('d', 'D')])
    order_dic.move_to_end('b', last=True)
    print(order_dic) # OrderedDict([('c', 'C'), ('d', 'D'), ('b', 'B')])
    order_dic.move_to_end('b', last=False)
    print(order_dic) # OrderedDict([('b', 'B'), ('c', 'C'), ('d', 'D')])


import torch.nn as nn
from mmcv.cnn import build_norm_layer

from ..builder import NECKS

@NECKS.register_module()
class Feature2Pyramid(nn.Module):
    """Feature2Pyramid.

    A neck structure connect ViT backbone and decoder_heads.

    Args:
        embed_dims (int): Embedding dimension.
        rescales (list[float]): Different sampling multiples were
            used to obtain pyramid features. Default: [4, 2, 1, 0.5].
        norm_cfg (dict): Config dict for normalization layer.
            Default: dict(type='SyncBN', requires_grad=True).
    """

    def __init__(self,
                 embed_dim,
                 rescales=[4, 2, 1, 0.5],
                 norm_cfg=dict(type='SyncBN', requires_grad=True)):
        super(Feature2Pyramid, self).__init__()
        self.rescales = rescales
        self.upsample_4x = None
        for k in self.rescales:
            if k == 4:
                self.upsample_4x = nn.Sequential(
                    nn.ConvTranspose2d(
                        embed_dim, embed_dim, kernel_size=2, stride=2),
                    build_norm_layer(norm_cfg, embed_dim)[1],
                    nn.GELU(),
                    nn.ConvTranspose2d(
                        embed_dim, embed_dim, kernel_size=2, stride=2),
                )
            elif k == 2:
                self.upsample_2x = nn.Sequential(
                    nn.ConvTranspose2d(
                        embed_dim, embed_dim, kernel_size=2, stride=2))
            elif k == 1:
                self.identity = nn.Identity()
            elif k == 0.5:
                self.downsample_2x = nn.MaxPool2d(kernel_size=2, stride=2)
            elif k == 0.25:
                self.downsample_4x = nn.MaxPool2d(kernel_size=4, stride=4)
            else:
                raise KeyError(f'invalid {k} for feature2pyramid')

    def forward(self, inputs):
        assert len(inputs) == len(self.rescales)
        outputs = []
        if self.upsample_4x is not None:
            ops = [
                self.upsample_4x, self.upsample_2x, self.identity,
                self.downsample_2x
            ]
        else:
            ops = [
                self.upsample_2x, self.identity, self.downsample_2x,
                self.downsample_4x
            ]
        for i in range(len(inputs)):
            outputs.append(ops[i](inputs[i]))
        return tuple(outputs)


from django.shortcuts import render
from .models import Pilotos, Corridas, Circuitos

# Create your views here.

def index(request):
    return render(request, 'index.html')

def detalhe_pilotos(request, pk):
    pilotos = Pilotos.objects.get(pk=pk)
    pilotos_quantidade = Pilotos.objects.all()
    context = {
        'sobrenome': pilotos.ultimo_nome,
        'nome': pilotos.primeiro_nome,
        'referencia': pilotos.ref_piloto,
        'nascimento': pilotos.nascimento,
        'nacionalidade': pilotos.nacionalidade_piloto,
        'total': pilotos_quantidade.count,
    }
    return render(request, 'pilotos.html', context)

def detalhe_corridas(request, pk):
    corridas = Corridas.objects.get(pk=pk)
    corrida_fk = corridas.id_circuito;
    corridas_quantidade = Corridas.objects.all()
    context = {
        'ano': corridas.ano_corrida,
        'nome_circuito': corrida_fk.nome_circuito,
        'rodada': corridas.rodada,
        'nome': corridas.nome_corrida,
        'data': corridas.data_corrida,
        'tempo': corridas.tempo_corrida,
        'total': corridas_quantidade.count
    }
    return render(request, 'corridas.html', context)

def detalhe_piloto_por_nome(request, nome):
    pilotos = Pilotos.objects.get(primeiro_nome=nome)
    pilotos_quantidade = Pilotos.objects.all()
    context = {
        'sobrenome': pilotos.ultimo_nome,
        'nome': pilotos.primeiro_nome,
        'referencia': pilotos.ref_piloto,
        'nascimento': pilotos.nascimento,
        'nacionalidade': pilotos.nacionalidade_piloto,
        'total': pilotos_quantidade.count

    }
    return render(request, 'pilotos.html', context)

def pilotos(request):
    pilotos= Pilotos.objects.all()
    context = {
        'pilotos': pilotos
    }
    return render(request, 'pilotos.html', context)


import discord
from discord.ext import commands
from datetime import datetime

intents = discord.Intents.all()
intents.members = True
bot = commands.Bot(command_prefix='!',intents=intents)

serverID = ""
with open('serverID.txt') as f:
    serverID = f.readline()
serverID = int(serverID)

bot.newChanBitrate = 9600
bot.oldFartServer = ""
bot.twosMakerChannel = ""
bot.threesMakerChannel = ""
bot.fourssMakerChannel = ""
bot.sixesMakerChannel = ""
bot.twosCategory = ""
bot.threesCategory = ""
bot.foursCategory = ""
bot.sixesCategory = ""
bot.lfgCategory = ""
bot.customCreators = []

@bot.event
async def on_ready():
    print(bot.user.name + " is Online...")
    print(datetime.now().strftime('%H:%M:%S %m-%d-%Y'))
    print('------')

    #get guild
    for g in bot.guilds:
        if g.id == serverID:
            print("Found server")
            bot.oldFartServer = g
            oldFartServer = bot.oldFartServer
            #set the new channel bitrate to whatever the max rate is for the server
            bot.newChanBitrate = int(oldFartServer.bitrate_limit)

    #create categories
    if not guild_has_category(oldFartServer, "2-MAX VOICE CHANNELS"):
        print("making 2v2 category...")
        await oldFartServer.create_category("2-MAX VOICE CHANNELS")

        bot.twosCategory = get_category(oldFartServer, "2-MAX VOICE CHANNELS")
         #create temp vc makers
        await oldFartServer.create_voice_channel("➕ Create 2's VC",category=bot.twosCategory)

    #create 3v3 category
    if not guild_has_category(oldFartServer, "3-MAX VOICE CHANNELS"):
        print("making 3v3 category...")
        await oldFartServer.create_category("3-MAX VOICE CHANNELS")

        bot.threesCategory = get_category(oldFartServer, "3-MAX VOICE CHANNELS")
         #create temp vc makers
        await oldFartServer.create_voice_channel("➕ Create 3's VC",category=bot.threesCategory)

    #create 4v4 category
    if not guild_has_category(oldFartServer, "4-MAX VOICE CHANNELS"):
        print("making 4v4 category...")
        await oldFartServer.create_category("4-MAX VOICE CHANNELS")

        bot.foursCategory = get_category(oldFartServer, "4-MAX VOICE CHANNELS")
         #create temp vc makers
        await oldFartServer.create_voice_channel("➕ Create 4's VC",category=bot.foursCategory)

    #create 6mans category
    if not guild_has_category(oldFartServer, "6-MAX VOICE CHANNELS"):
        print("making 6mans category...")
        await oldFartServer.create_category("6-MAX VOICE CHANNELS")

        bot.sixesCategory = get_category(oldFartServer, "6-MAX VOICE CHANNELS")
         #create temp vc makers
        await oldFartServer.create_voice_channel("➕ Create 6's VC",category=bot.sixesCategory)

    #get categories
    bot.twosCategory = get_category(oldFartServer, "2-MAX VOICE CHANNELS")
    bot.threesCategory = get_category(oldFartServer, "3-MAX VOICE CHANNELS")
    bot.foursCategory = get_category(oldFartServer, "4-MAX VOICE CHANNELS")
    bot.sixesCategory = get_category(oldFartServer, "6-MAX VOICE CHANNELS")
    #get creator channels
    for c in oldFartServer.channels:
        if c.name == "➕ Create 2's VC":
            bot.twosMakerChannel = c
        if c.name == "➕ Create 3's VC":
            bot.threesMakerChannel = c
        if c.name == "➕ Create 4's VC":
            bot.foursMakerChannel = c
        if c.name == "➕ Create 6's VC":
            bot.sixesMakerChannel = c

async def update_channels():
    print("update channels")
    try:
        await rename_and_reorder("2 Max", bot.twosMakerChannel.position +1)
    except Exception as e:
        print(e)
    try:
        await rename_and_reorder("3 Max", bot.threesMakerChannel.position +1)
    except Exception as e:
        print(e)
    try:
        await rename_and_reorder("4 Max", bot.foursMakerChannel.position +1)
    except Exception as e:
        print(e)
    try:
        await rename_and_reorder("6 Max", bot.sixesMakerChannel.position +1)
    except Exception as e:
        print(e)

@bot.event
async def on_voice_state_update(member, before, after):

    #delete any empty VCs that we are making
    if before.channel != None and "Max #" in before.channel.name:
        if len(before.channel.members) == 0:
            await before.channel.delete()
            await update_channels()

    if after.channel == bot.twosMakerChannel:
        #create 2 max VC
        cpos = bot.twosMakerChannel.position + 1
        await create_custom_channel("2 Max", cpos, bot.twosCategory,2,member)

    if after.channel == bot.threesMakerChannel:
        #create 3 max VC
        cpos = bot.threesMakerChannel.position + 1
        await create_custom_channel("3 Max", cpos, bot.threesCategory,3,member)

    if after.channel == bot.foursMakerChannel:
        #create 4 max VC
        cpos = bot.foursMakerChannel.position + 1
        await create_custom_channel("4 Max", cpos, bot.foursCategory,4,member)

    if after.channel == bot.sixesMakerChannel:
        #create 6 max VC
        cpos = bot.sixesMakerChannel.position + 1
        await create_custom_channel("6 Max", cpos, bot.sixesCategory,6,member)

async def create_custom_channel(cName, position, category, userLimit, player):
    cnum = 1
    cpos = position
    guild = bot.oldFartServer
    for c in guild.channels:
        if c != None and cName in c.name:
            await c.edit(name = cName +" #" + str(cnum))
            cnum = cnum+1
            cpos = cpos +1
    await guild.create_voice_channel(cName + " #" + str(cnum), position=cpos, category=category, bitrate = bot.newChanBitrate, user_limit=userLimit)
    #pull user into new VC
    for c in guild.channels:
        if c != None and c.name == cName + " #" + str(cnum):
            await player.move_to(c)

def guild_has_category(guild, cat):
    for c in guild.categories:
        if c.name == cat:
            return True
    print("didnt find it")
    return False

def get_category(guild, cat):
    for c in guild.categories:
        if c.name == cat:
            return c
    return

async def rename_and_reorder(cName, cPos):
    cnum = 1
    #for channel in server
    for c in bot.oldFartServer.channels:
        if c != None and cName in c.name:
            await c.edit(name = cName +" #" + str(cnum), position = cPos)
            cnum = cnum +1
            cPos = cPos +1

with open('token.txt') as f:
    TOKEN = f.readline()

bot.run(TOKEN)


import math
import heapq
import numpy as np
import random
from collections import namedtuple, deque

from model import QNetwork

import torch
import torch.nn.functional as F
import torch.optim as optim

device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")

class experience:
    """Represents an experience.

    It provides the __lt__ method so that it can be added to a heapq.
    """

    def __init__(self, state, action, reward, next_state, done, error=1.0):
        self.state = state
        self.action = action
        self.reward = reward
        self.next_state = next_state
        self.done = done
        self.error = error

    def __lt__(self, other):
        return self.error < other.error

    def __eq__(self, other):
        return self.error == other.error

    def __repr__(self):
        return str(self.error)

class ReplayBuffer:
    """Fixed-size buffer to store experience tuples."""

    def __init__(self, action_size, state_size, buffer_size, batch_size, seed):
        """Initialize a ReplayBuffer object.

        Params
        ======
            action_size (int): dimension of each action
            state_size (int): dimension of each state
            buffer_size (int): maximum size of buffer
            batch_size (int): size of each training batch
            seed (int): random seed
        """
        self.action_size = action_size
        self.state_size = state_size
        self.memory = deque(maxlen=buffer_size)
        self.batch_size = batch_size
        self.seed = random.seed(seed)

    def add(self, state, action, reward, next_state, done):
        """Add a new experience to memory."""
        e = experience(state, action, reward, next_state, done)
        self.memory.append(e)

    def sample(self):
        """Randomly sample a batch of experiences from memory."""
        experiences = random.sample(self.memory, k=self.batch_size)

        states = torch.from_numpy(np.vstack([e.state for e in experiences if e is not None])).float().to(device)
        actions = torch.from_numpy(np.vstack([e.action for e in experiences if e is not None])).long().to(device)
        rewards = torch.from_numpy(np.vstack([e.reward for e in experiences if e is not None])).float().to(device)
        next_states = torch.from_numpy(np.vstack([e.next_state for e in experiences if e is not None])).float().to(device)
        dones = torch.from_numpy(np.vstack([e.done for e in experiences if e is not None]).astype(np.uint8)).float().to(device)
        weights = torch.ones(self.batch_size, 1, dtype=torch.float, device=device)

        return (states, actions, rewards, next_states, dones, weights, None)

    def update(self, entries, errors):
        pass

    def __len__(self):
        """Return the current size of internal memory."""
        return len(self.memory)

class PrioritizedReplayBuffer:
    """Fixed-size buffer to store experience tuples."""

    def __init__(self, action_size, state_size, buffer_size, batch_size, seed, update_buffer_steps, alpha, beta, beta_inc):
        """Initialize a ReplayBuffer object.

        Params
        ======
            action_size (int): dimension of each action
            state_size (int): dimension of each state
            buffer_size (int): maximum size of buffer
            batch_size (int): size of each training batch
            seed (int): random seed
            update_buffer_steps (int): How often to update the buffer
            alpha (float): The priority exponent
            beta (float): The importance sampling exponent
            beta_inc (float): The importance sampling exponent increment
        """
        self.action_size = action_size
        self.state_size = state_size
        self.buffer_size = buffer_size
        self.batch_size = batch_size
        self.memory = []
        self.step_counter = 0
        self.seed = random.seed(seed)
        self.update_buffer_steps = update_buffer_steps
        self.alpha = alpha
        self.beta = beta
        self.beta_inc = beta_inc

    def add(self, state, action, reward, next_state, done, error=1.0):
        """Add a new experience to memory."""
        e = experience(state, action, reward, next_state, done, error)
        if len(self.memory) >= self.buffer_size:
            heapq.heapreplace(self.memory, e)
        else:
            heapq.heappush(self.memory, e)

        # sort memory
        self.step_counter = (self.step_counter + 1) % self.update_buffer_steps
        if self.step_counter == 0:
            heapq.heapify(self.memory)
            self.beta = min(1.0, self.beta * self.beta_inc)

    def sample(self):
        """Randomly sample a batch of experiences from memory."""
        states = np.zeros((self.batch_size, self.state_size), dtype=np.float)
        actions = np.zeros((self.batch_size,1), dtype=np.int32)
        rewards = np.zeros((self.batch_size,1), dtype=np.float)
        next_states = np.zeros((self.batch_size, self.state_size), dtype=np.float)
        dones = np.zeros((self.batch_size,1), dtype=np.uint8)
        p_j = np.zeros((self.batch_size,1), dtype=np.float)
        entries = []

        segment_size = len(self.memory) // self.batch_size
        for i in range(self.batch_size):
            start = i * segment_size
            end = len(self.memory) if i==self.batch_size-1 else (i+1)*segment_size
            j = random.randint(start, end-1)
            e = self.memory[j]
            entries.append(e)
            states[i,:] = e.state
            actions[i] = e.action
            rewards[i] = e.reward
            next_states[i,:] = e.next_state
            dones[i] = e.done
            p_j[i] = e.error

        # place tensors in GPU for faster calculations
        states = torch.from_numpy(states).float().to(device)
        actions = torch.from_numpy(actions).long().to(device)
        rewards = torch.from_numpy(rewards).float().to(device)
        next_states = torch.from_numpy(next_states).float().to(device)
        dones = torch.from_numpy(dones).float().to(device)
        p_j = torch.from_numpy(p_j).float().to(device)
        n = torch.tensor(self.batch_size, dtype=torch.float, device=device)
        alpha = torch.tensor(self.alpha, dtype=torch.float, device=device)
        beta = torch.tensor(self.beta, dtype=torch.float, device=device)

        # the math
        p_j = p_j ** alpha
        p_j = p_j / p_j.sum()
        weights = (n * p_j) ** -beta
        weights /= weights.max()

        return (states, actions, rewards, next_states, dones, weights, entries)

    def update(self, entries, errors):
        errors = errors.cpu()
        for entry, error in zip(entries, errors):
            entry.error = abs(error[0])

    def __len__(self):
        """Return the current size of internal memory."""
        return len(self.memory)


import sys
sys.path.insert(1, '../')

import numpy as np
import pandas as pd
import os
import shutil
from datetime import datetime

metadata_dob = pd.read_csv('itmt_v2/cvs_files/metadata_bch_scan_date.csv', header=0)
def find_age_gender(id_to_find):
    for idx, row in metadata_dob.iterrows():
        if str(id_to_find).zfill(7)==str(row['BCH_MRN']).zfill(7):
            #12/20/93
            dob=datetime.strptime(row['dob'], "%m/%d/%y")
            sex=row['sex']
            mri_date=datetime.strptime(row['scan_date'], "%m/%d/%y")
    age = (mri_date-dob).days/365
    if sex == "F":
        sex=2
    else:
        sex=1
    return round(age,2), sex

path = 'data/itmt2.0_checkedBK_bch/'
path_to = 'data/itmt2.0/'
df = pd.read_csv('data/itmt2.0_checkedBK_bch/annotations.csv', header=None)
df= df[df[1]==1] # select only the good cases

save_metadata = []

for idx in range(0,len(df)):
    file_name = df.iloc[idx][0]
    new_path = path_to+file_name.split(".")[0]+"/"
    if not os.path.exists(new_path):
        os.mkdir(new_path)
        shutil.copy(path+file_name.split(".")[0]+"_mask.nii.gz", new_path+"TM.nii.gz")

    shutil.copy('data/t1_mris/bch_reg_ench/z/'+file_name.split(".")[0]+'/'+file_name.split(".")[0]+'.nii', new_path+file_name.split(".")[0]+'.nii.gz')
    age, sex = find_age_gender(file_name.split(".")[0])
    save_metadata.append([file_name,age, sex,'BCH'])
    print(file_name,age, sex)

pd.DataFrame(save_metadata).to_csv("itmt_v2/cvs_files/itmt2.0_cancer.csv", header=["Filename","AGE_M","SEX","Dataset"], index=None)
#Filename,AGE_M,SEX,Dataset,train/test,Ok registered? Y/N


from keras.models import Model
from keras.models import load_model
from keras.layers import Input, Convolution2D, MaxPooling2D, Dense, Dropout, Activation, Flatten
from keras.utils import np_utils # utilities for one-hot encoding of ground truth values
from CNNParameters import batch_size, num_epochs, kernel_size, pool_size, conv_depth_1, conv_depth_2, drop_prob_1, drop_prob_2, hidden_size
from sklearn import preprocessing
from keras.callbacks import ModelCheckpoint,EarlyStopping
import csv
import numpy as np
from resnet import ResnetBuilder

'''
	0. Make sure training and testing data are in ../data
	1. Run:
			load_x() to load training x
			load_y() to load training y
'''

#x_train_file = open('../data/sample1.csv')
#x_train_file = open('../data/train_x.csv')
#y_train_file = open('../data/train_y.csv')
#x_test_file = open('../data/test_x.csv')

#model output path : This stores the latest model
output_path = "resnet.h5"

#prediction output path : Final prediction for Kaggle submission
prediction_filepath = "resnet.prediction.csv"

#where we will save the weights
weights_filepath="resnet.weights.best.hdf5"

#This is the pipeline function from preprocessing
#returns (50000, 64, 64, 1) shape np array
def load_x():
	path = "../data/training_data.npy"
	training_data_x = np.load(path)
	training_data_x = training_data_x.reshape(50000, 64, 64, 1)

	print("Training data x: {}".format(training_data_x.shape))

	return training_data_x

def load_y():
	path = "../data/train_y.csv"
	training_data_y = np.loadtxt(path, delimiter="\n")
	#Label Encode our results.
	#[  0.   1.   2.   3.   4.   5.   6.   7.   8.   9.  10.  11.  12.  13.  14.
	#15.  16.  17.  18.  20.  21.  24.  25.  27.  28.  30.  32.  35.  36.  40.
	#42.  45.  48.  49.  54.  56.  63.  64.  72.  81.]
	#will be encoded to 0,1,2,3,...
	#this means that "81" will be [0,0,0,0,0,...,0,1] where the 40th entry is 1
	le = preprocessing.LabelEncoder()

	le.fit(training_data_y)		#fit with label encoder
	training_data_y = le.transform(training_data_y)		#encode with label encoder

	#one-hot encoding
	training_data_y = np_utils.to_categorical(training_data_y)

	print("Training data y: {}".format(training_data_y.shape))

	return training_data_y, le

def load_test():
	path = "../data/test_data.npy"
	test_data_x = np.load(path)
	test_data_x = test_data_x.reshape(10000, 64, 64, 1)

	print("Test data x: {}".format(test_data_x.shape))

	return test_data_x

def build_resnet():
	input_shape = (1, 64, 64)
	output_shape = 40

	model = ResnetBuilder.build_resnet_18(input_shape,output_shape)
	model.compile(loss='categorical_crossentropy', # using the cross-entropy loss function
				  optimizer='adam', # using the Adam optimiser
				  metrics=['accuracy']) # reporting the accuracy
	return model

def train_resnet():
	model = build_resnet()
	x_train = load_x()

	y_train,a = load_y()

	checkpoint = ModelCheckpoint(weights_filepath, monitor='acc', verbose=1, save_best_only=True, mode='max')
	stopping = EarlyStopping(monitor='acc', min_delta=0.001, patience=10, verbose=1, mode='auto')
	callbacks_list = [checkpoint]

	print("Training ResNet")
	model.fit(x_train, y_train,                # Train the model using the training set...
			  batch_size=32, epochs=10,
			  verbose=1,callbacks = callbacks_list, validation_split=0.1) # ...holding out 10% of the data for validation

#Predicts our test set and outputs results in csv format
def predict(model, label_encoder):

	labels = label_encoder.classes_

	#load our test set
	x_test = load_test()

	#use model to predict our test set
	#this contains probabilities of each class
	pred = model.predict(x_test,verbose = 1)

	#this transforms pred to hold indices of the classes
	result = []
	for i in range(pred.shape[0]):
		label = labels[np.argmax(pred[i])]
		result.append(label)

	result2 = list(map(lambda x : int(x), result))

	#save to csv
	with open(prediction_filepath, 'w') as f:
		writer = csv.writer(f)
		writer.writerow(('Id', 'Label'))
		for i in range(1,len(result2)+1):
			writer.writerow((i, result2[i-1]))

	print("\nPredictions Successfully saved in ./{}".format(prediction_filepath))

if __name__ == '__main__':
	#train_resnet()
	a,le = load_y()
	print("loading model")
	model = build_resnet()
	resnet = model.load_weights("resnet.weights.best.hdf5")

	predict(resnet, le)


# 버튼 활성화 유무에 따른 동작

import sys
from PyQt5.QtWidgets import QApplication, QWidget, QFrame, QPushButton
from PyQt5.QtGui import QColor

class Example(QWidget):
    def __init__(self):
        super().__init__()
        self.initUI()

    def initUI(self):

        # 컬러를 지정하기 위한 컬러 객체 생성 초기값 (0, 0, 0)검정
        self.col = QColor(0, 0, 0)

        # 'Red'라는 버튼생성, 위치지정 / checkable 누른상태, 땐 상태를 구분해줌 / 위치지정.
        redb = QPushButton('Red', self)
        redb.setCheckable(True)
        redb.move(10, 10)

        # 버튼을 클릭했을때 setColor 함수와 연결
        redb.clicked.connect(self.setColor)

        greenb = QPushButton('Green', self)
        greenb.setCheckable(True)
        greenb.move(10, 60)

        greenb.clicked.connect(self.setColor)

        blueb = QPushButton('Blue', self)
        blueb.setCheckable(True)
        blueb.move(10, 110)

        blueb.clicked.connect(self.setColor)

        # 사각형 Frame을 생성해서 디스플레이 / x,y좌표 가로세로길이 / setColor함수의 값이 변하면 여기 값에 인자전달하여 이벤트
        self.square = QFrame(self)
        self.square.setGeometry(150, 20, 100, 100)
        self.square.setStyleSheet("background-color: {0}".format(self.col.name()))

        self.setGeometry(300, 300, 280, 170)
        self.setWindowTitle("QcheckBox")
        self.show()

    # 버튼이 활성화 되어있을 때 함수 pressed 눌려있으면 True 아니면 False
    def setColor(self, pressed):

        source = self.sender()      # 호출했던 버튼의 객체를 불러와서 전달함.

        # 눌렸을 경우 255, 아닐경우 0
        if pressed:
            val = 255
        else:
            val = 0

        # 불러온 객체 sourse의 text가 일치할경우
        if source.text() == "Red":
            self.col.setRed(val)
        elif source.text() == "Green":
            self.col.setGreen(val)
        else:
            self.col.setBlue(val)

        self.square.setStyleSheet("background-color: {0}".format(self.col.name()))

if __name__ == '__main__':
    app = QApplication(sys.argv)
    ex = Example()
    sys.exit(app.exec_())

8_여러가지 위젯들/2_버튼활성화에 따른 이벤트, 버튼을 눌렀을 때 frame에 해당색상을 가함.py


from time import sleep
import random
import yaml
from threading import Thread
import logging
import threading

import common
import cecclient
import mqttclient

def init(config):
    logging.basicConfig(filename='stereo.log', level=logging.INFO, format='%(asctime)s %(message)s', datefmt='%m/%d/%Y %I:%M:%S %p')
    config_file = open('config.yaml', 'r')
    config = yaml.load(config_file, Loader=yaml.FullLoader)
    config_file.close()
    return config

def publish_state():
    mymqttclient.client.publish(common.power_avail_topic, payload='online')
    mycecclient.request_stereo_power()
    mycecclient.request_audio_status()
    sleep(0.5)
    power = mycecclient.get_stereo_power()
    volume = mycecclient.get_volume()
    logging.debug("power status: %s", power)
    logging.debug("volume status: %s", volume)
    if power == 0:
        mymqttclient.client.publish(common.power_state_topic, payload='OFF')
    elif power == 1:
        mymqttclient.client.publish(common.power_state_topic, payload='ON')
    else:
        logging.error("Uh oh, weird state!")
    mymqttclient.client.publish(common.volume_state_topic, payload=str(volume))
    sleep(15)

def stereo_status_worker():
    while True:
         publish_state()

def on_connect(client, userdata, flags, rc):
    if rc == 0:
        logging.info("MQTT connected to host "+mymqttclient.broker+":1883"+" rc: "+str(rc))
        mymqttclient.client.publish(common.power_avail_topic, payload='online')
        mymqttclient.client.subscribe(common.power_command_topic)
        mymqttclient.client.subscribe(common.source_command_topic)
        mymqttclient.client.subscribe(common.volume_command_topic)
        publish_state()
    else:
        logging.error("MQTT failed to connect to host "+mymqttclient.broker+":1883"+" with rc: "+str(rc))

def on_disconnect(client, userdata, rc):
    logging.warning("Power host connection lost with rc: "+str(rc))

def on_message(client, userdata, msg):
    if msg.topic == common.power_command_topic:
        if msg.payload.decode() == 'ON':
            mymqttclient.client.publish(common.power_state_topic, payload='ON')
            mycecclient.stereo_power_on()
        elif msg.payload.decode() == 'OFF':
            mymqttclient.client.publish(common.power_state_topic, payload='OFF')
            mycecclient.stereo_power_off()
    elif msg.topic == common.source_command_topic:
        if msg.payload.decode() == 'Airplay':
            mymqttclient.client.publish(common.source_state_topic, payload='Airplay')
            mycecclient.source_airplay()
        elif msg.payload.decode() == 'TV':
            mymqttclient.client.publish(common.source_state_topic, payload='TV')
            mycecclient.source_tv()
    elif msg.topic == common.volume_command_topic:
        if msg.payload.decode() == 'ON':
            mymqttclient.client.publish(common.volume_state_topic, payload=(mycecclient.get_volume())+2)
            mycecclient.stereo_volume_up()
        elif msg.payload.decode() == 'OFF':
            mymqttclient.client.publish(common.volume_state_topic, payload=(mycecclient.get_volume())-2)
            mycecclient.stereo_volume_down()
    else:
        logging.error("bad command")

# main setup
config = None
mycecclient = None
mymqttclient = None

if __name__ == '__main__':
    config = init(config)
    mycecclient = cecclient.pyCecClient()
    mymqttclient = mqttclient.mqttClient(config)
    # setup mycecclient
    mycecclient.InitLibCec()
    # setup mymqttclient
    mymqttclient.set_connect_callback(on_connect)
    mymqttclient.set_disconnect_callback(on_disconnect)
    mymqttclient.set_message_callback(on_message)
    # stereo status monitoring thread setup
    stereoStatusThread = threading.Thread(target=stereo_status_worker)
    # start mqtt client
    mymqttclient.start_mqtt()
    # start stereo status monitoring thread
    sleep(2)
    stereoStatusThread.start()

    while True:
        sleep(0.1)


from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtWidgets import ( QWidget)

class BottomToolbar(object):

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

    def Mainpage (self, Widget):
        self.tollbar1 = QtWidgets.QWidget(Widget)
        self.tollbar1.setGeometry(QtCore.QRect(31, 470, 981, 300))
        self.tollbar1.setObjectName("tollbar1")
        self.vertikaltollbar1Layout = QtWidgets.QVBoxLayout(self.tollbar1)
        self.vertikaltollbar1Layout.setObjectName("vertikaltollbar1Layout")
        self.horizontaltollbar1Layout = QtWidgets.QHBoxLayout()
        self.horizontaltollbar1Layout.setObjectName("horizontaltollbar1Layout")
        self.label1 = QtWidgets.QLabel()
        self.label1.setObjectName("label1")
        self.horizontaltollbar1Layout.addWidget(self.label1)
        self.lineEdit1 = QtWidgets.QLineEdit("80%")
        self.horizontaltollbar1Layout.addWidget(self.lineEdit1)
        spacerItem1 = QtWidgets.QSpacerItem(80, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
        self.horizontaltollbar1Layout.addItem(spacerItem1)
        self.label2 = QtWidgets.QLabel()
        self.label2.setObjectName("label2")
        self.horizontaltollbar1Layout.addWidget(self.label2)
        self.lineEdit2 = QtWidgets.QLineEdit("80%")
        self.horizontaltollbar1Layout.addWidget(self.lineEdit2)
        spacerItem2 = QtWidgets.QSpacerItem(80, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
        self.horizontaltollbar1Layout.addItem(spacerItem2)
        self.label3 = QtWidgets.QLabel()
        self.label3.setObjectName("label3")
        self.horizontaltollbar1Layout.addWidget(self.label3)
        self.lineEdit3 = QtWidgets.QLineEdit("80%")
        self.horizontaltollbar1Layout.addWidget(self.lineEdit3)
        spacerItem3 = QtWidgets.QSpacerItem(80, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
        self.horizontaltollbar1Layout.addItem(spacerItem3)
        self.vertikaltollbar1Layout.addLayout(self.horizontaltollbar1Layout)

        self.horizontaltollbar1Layout2 = QtWidgets.QHBoxLayout()
        self.horizontaltollbar1Layout2.setObjectName("horizontaltollbar1Layout2")
        spacerItem1 = QtWidgets.QSpacerItem(515, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
        self.horizontaltollbar1Layout2.addItem(spacerItem1)
        self.buttonProcess = QtWidgets.QPushButton()
        self.horizontaltollbar1Layout2.addWidget(self.buttonProcess)
        self.vertikaltollbar1Layout.addLayout(self.horizontaltollbar1Layout2)
        self.tollbar1.setLayout(self.vertikaltollbar1Layout)
        self.retranslateUi(self.parent)

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        self.label1.setText(_translate("MainWindow", "Mean (Rata - Rata)"))
        self.label2.setText(_translate("MainWindow", "Rata - rata Macro"))
        self.label3.setText(_translate("MainWindow", "Rata - rata Micro"))
        self.buttonProcess.setText(_translate("MainWindow", "Proses"))