# Configuraciones / Tokens
from config import *
# TeleBot
import telebot
from telebot.types import ReplyKeyboardMarkup
from telebot.types import ForceReply
# Utils
import os
from pathlib import Path
from datetime import datetime, timezone
import pandas as pd
from dbhelper import *
from email.mime.multipart import MIMEMultipart
from email.mime.base import MIMEBase
from smtplib import SMTP

# Instanciando bot
bot = telebot.TeleBot(ALERTB_TOKEN)

# Variable para almacenar las respuestas:
respuestas = {}

# Comandos para el bot
# /start - comando inicial.
@bot.message_handler(commands=['start'])
def cmd_start(message):
    bot.send_message(message.chat.id, "Hola! Me da gusto verte aquí!\n\nTal y como pudiste leer en mi descripción, soy un bot con el que puedes contar si deseas hablar acerca de como te sientes en tu institución educativa.\nMis creadores están trabajando en mejores respuestas para cuando desees conversar, pero por ahora me gustaría que respondas algunas preguntas😊\n\nPodemos empezar cuando gustes, solo da clic en el comando /conversar y estaré a tu servicio^^")

# /help - comando de ayuda
@bot.message_handler(commands=['help'])
def cmd_help(message):
    bot.send_message(message.chat.id, 'Veo que necesitas algo de ayuda. No te preocupes! Aquí están todos los comandos que puedes ejecutar conmigo:\n\n/conversar - Con este comando puedes informarme sobre como te sientes en tu institución educativa, es decir, relaciones con tus compañeros de clase o profesores.',parse_mode='html')

# /conversar - inicia la conversación preguntando el nombre de usuario del estudiante.
@bot.message_handler(commands=['conversar'])
def cmd_conversar(message):
    markup = ForceReply()
    msg = bot.send_message(
        message.chat.id, "Primero que nada me gustaría saber tu DNI con el que te encuentras registrado en nuestro sitio web", parse_mode='html', reply_markup=markup)
    bot.register_next_step_handler(msg, act_pregunta1)

def act_pregunta1(message):
    # comprobar si el usuario realmente ingresó un dato válido
    if not message.text.isdigit():
        markup = ForceReply()
        msg = bot.send_message(message.chat.id, "Hey, yo no creo que eso sea tu DNI 🤨\nIngresa tu DNI por favor:")
        bot.register_next_step_handler(msg, act_pregunta1)
    else:
        # verificar si el dni ingresado existe en la bd
        input = str(message.text)
        datos = auth_estudiante(dni=input)

        if datos is None:
            markup = ForceReply()
            msg = bot.send_message(message.chat.id, "Este DNI no corresponde a ningún usuario, verifica que esté correctamente escrito 😓")
            bot.register_next_step_handler(msg, act_pregunta1)
        else:
            # agregar nombre de usuario al diccionario
            idEstudiante = datos[0]
            nombres = datos[1]
            apellidos = datos[2]
            correo = datos[3]

            respuestas['idEstudiante'] = idEstudiante
            respuestas['nombres'] = nombres
            respuestas['apellidos'] = apellidos
            respuestas['correo'] = correo
            respuestas['telegram_user'] = "@"+str(message.chat.username)
            markup = ForceReply()
            msg = bot.send_message(
                message.chat.id, f"Bien {nombres} un gusto tenerte aquí! Ahora me gustaría que me cuentes algo\n\n¿Cómo te has sentido últimamente en tu institución educativa?", parse_mode='html', reply_markup=markup)
            bot.register_next_step_handler(msg, act_pregunta2)

def act_pregunta2(message):
    # resultado de pregunta 1
    res_preg1 = message.text
    # guardar resultado
    respuestas['pregunta1'] = res_preg1

    markup = ForceReply()
    msg = bot.send_message(
        message.chat.id, "¿Y qué me puedes contar acerca de tus compañeros de clase o de otros salones?", parse_mode='html', reply_markup=markup)
    bot.register_next_step_handler(msg, act_pregunta3)

def act_pregunta3(message):
    # resultado pregunta 2
    res_preg2 = message.text
    # guardar resultado
    respuestas['pregunta2'] = res_preg2

    markup = ForceReply()
    msg = bot.send_message(message.chat.id, "Ahora podemos pasar a los profesores ¿Son ellos buenos contigo? Si alguna vez observaste o sufriste un caso de acoso escolar ¿ellos actuaron adecuadamente? déjame saber que piensas respecto a eso.", parse_mode='html', reply_markup=markup)
    bot.register_next_step_handler(msg, act_pregunta4)

def act_pregunta4(message):
    # resultado pregunta 3
    res_preg3 = message.text
    # guardar resultado
    respuestas['pregunta3'] = res_preg3

    markup = ForceReply()
    msg = bot.send_message(
        message.chat.id, "¿Qué hay del resto del personal de tu institución? por ejemplo los directores, personal de seguridad o limpieza ¿cómo te sientes con ellos?", parse_mode='html', reply_markup=markup)
    bot.register_next_step_handler(msg, act_pregunta5)

def act_pregunta5(message):
    # resultado pregunta 4
    res_preg4 = message.text
    # guardar resultado
    respuestas['pregunta4'] = res_preg4

    markup = ForceReply()
    msg = bot.send_message(message.chat.id, "Anotado, ahora me gustaría preguntarte acerca de algo muy importante: ¿Cómo te sientes contigo mismo/a? olvídate de tus compañeros, profesores y el resto del personal. Solo quisiera saber acerca de ti y cómo te sientes", parse_mode='html', reply_markup=markup)
    bot.register_next_step_handler(msg, act_pregunta6)

def act_pregunta6(message):
    # resultado pregunta 5
    res_preg5 = message.text
    # guardar resultado
    respuestas['pregunta5'] = res_preg5

    markup = ForceReply()
    msg = bot.send_message(message.chat.id, "Bien, ya estamos por terminar!\n\nDado que ya respondiste todas las preguntas, lo último que queda es si deseas comentarme algo. Puede ser respecto a esta pequeña sesión o algo que quizás no pudo ser respondido con las preguntas anteriores.\nClaro, si no deseas comentar nada, puedes escribir NO", parse_mode='html', reply_markup=markup)

    if msg.text.lower() == 'no':
        bot.register_next_step_handler(msg, act_final)
    else:
        bot.register_next_step_handler(msg, act_final)

def act_final(message):
    # resultado pregunta 6
    res_preg6 = message.text
    # guardar resultado
    respuestas['pregunta6'] = res_preg6

    bot.send_message(message.chat.id, "Listo! Hemos acabado. Muchas gracias por tu tiempo 🌸 registraré y enviaré tus respuestas al tutor de tu institución, si lo ve conveniente se estará contactando contigo pronto.")

    # data
    idEstudiante = respuestas['idEstudiante']
    estudiante = (str(respuestas['nombres'])).replace(' ','')
    dt = datetime.now(timezone.utc)
    now_bot = dt.strftime('%y-%m-%d %H:%M:%S.%f%z')
    time = (str(dt.strftime('%m%d%Y%H%M%S')))
    filename = estudiante + "_" + time + '.csv'
    correo = respuestas['correo']

    # imprime en consola las respuestas obtenidos como diccionario
    print("Diccionario: \n\n",respuestas,"\n")

    # transforma el diccionario a csv
    df = pd.DataFrame([respuestas])

    ## exporta el csv
    dirname = os.path.dirname(__file__)
    path = Path(dirname+'/outputreports/'+estudiante+'/')
    path.mkdir(parents=True, exist_ok=True)

    save_routh=dirname+'/outputreports/'+estudiante+'/'+filename

    df.to_csv(dirname+'/outputreports/'+estudiante+'/'+filename, index=False, sep=',', encoding='utf-8')

    # inserta el csv a la base de datos
    insert_report(filename, now_bot , 'En atención', idEstudiante)

    # envía el csv al usuario por correo
    mensaje = MIMEMultipart("plain")
    mensaje["From"]=bot_email
    mensaje["To"]=correo
    mensaje["Subject"]="Constancia de las respuestas"

    adjunto = MIMEBase("text", "csv")
    adjunto.set_payload(open(save_routh, "rb").read())
    adjunto.add_header("content-Disposition", 'attachment; filename="{}"'.format(filename))

    mensaje.attach(adjunto)

    smtp = SMTP("smtp.live.com")
    smtp.starttls()
    smtp.login(bot_email, bot_password)
    smtp.sendmail(bot_email, correo, mensaje.as_string())
    smtp.quit()

    respuestas.clear()

# Filtro de comandos que no existen.
@bot.message_handler(content_types=['text'])
def bot_unknown_commands(message):
    if message.text.startswith('/'):
        bot.send_message(message.chat.id, 'Lo siento no te entendí 😔\nEjecuta /help si quieres saber que comandos puedo ejecutar.')

# incialización del bot
if __name__ == '__main__':
    print("Alert-B está en ejecución! 🍀")
    bot.infinity_polling()


#!/usr/bin/env python3
import cv2

# Conecta com a webcam:
capture = cv2.VideoCapture(0)

# Retorno da leitura da camera:
success = True

# Contagem de fotos tiradas
count = 1

while success:
    # Le a imagem da camera
    success, image = capture.read()

    if success:
        # Mostra a imagem
        cv2.imshow("Window", image)
        # Recebe o input dado
        key=cv2.waitKey(5) & 0xFF

        if chr(key) == 's':
            # Salva a imagem
            cv2.imwrite("pictures/chessboard{}.png".format(count), image)
            count += 1


from PyQt5.QtWidgets import QGraphicsView, QApplication, QMessageBox
from PyQt5.QtCore import Qt, QEvent, pyqtSignal, QPoint
from PyQt5.QtGui import QPainter, QMouseEvent, QCursor, QPixmap, QWheelEvent

from editor.graphic.node_item import KMBNodeGraphicItem
from editor.graphic.node_edge import KMBGraphicEdge
from editor.graphic.node_note import KMBNote
from editor.wrapper.wrap_item import KMBNodeItem
from editor.wrapper.wrap_edge import KMBEdge
from editor.component.edge_type import KMBGraphicEdgeBezier, KMBGraphicEdgeDirect
from editor.component.messages import PopMessageBox
from editor.widgets.sidebar import KMBViewSideBar
from editor.threads import OrganizingThread, SearchBarThread

from cfg import icon, EDGE_CURVES, EDGE_DIRECT
from lib import debug

MOUSE_SELECT = 0
MOUSE_MOVE = 1
MOUSE_EDIT = 2
MOUSE_NOTE = 3

NODE_SELECTED = 4
NODE_DELETE = 5
NODE_CONNECT = 6

EDGE_DRAG = 7

class KMBNodeGraphicView(QGraphicsView):

    # ------------------SIGNALS--------------------

    # show the changing position in status bar.
    SCENE_POS_CHANGED = pyqtSignal(int, int)            # x, y coord

    # send to node args for creating a new args model for this node.
    # name, type, id, count, pin_args ('None' means empty)
    ADD_NEW_NODE_ITEM = pyqtSignal(str, str, str, int, str)

    # pass the id of selected node item to node args for editing.
    SELECTED_NODE_ITEM = pyqtSignal(str)                # id or state

    # send to node args for deleting its args model.
    SELECTED_DELETE_NODE = pyqtSignal(str)              # id

    # pop up the right menu of clicked node,
    # also emit the src node id along with.
    POP_UP_RIGHT_MENU = pyqtSignal(str)                 # dst id

    # del ref related items if one ref edge got deleted.
    DEL_REF_RELATED_ITEMS = pyqtSignal(str, str)        # referenced src id, dst id
    DEL_IO_EDGE_ITEM = pyqtSignal(str, str)             # io src id, dst id

    # whether current project has been modified.
    IS_MODIFIED = pyqtSignal(bool)

    # ------------------INIT--------------------

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

        self.gr_scene = graphic_scene
        self.status_bar_msg = status_bar_msg
        self.sidebar = KMBViewSideBar(self)
        self.search_bar = SearchBarThread(self)
        self.parent = parent
        self.del_items_msg = PopMessageBox('Delete items', self)

        self.mode = MOUSE_SELECT
        self.edge_type = None
        # signals from sidebar.
        self.disable_wheel = False
        self.has_pressed_zoom_btn = False
        # signals from right menu.
        self.has_chosen_from_rm = False
        self.has_chosen_to_del_from_rm = False
        # signals from note.
        self.has_finished_editing = True

        # current dynamic variables.
        self.last_scene_mouse_pos = None
        self.current_node_item_name = None
        self.current_node_item_type = None
        self.current_node_item_sort = None
        # optional
        self.current_node_pin_args = None
        self.current_node_pin_id = None
        # record group selected items.
        self.rubber_select = []

        self.zoom_in_factor = 1.25
        self.zoom = 10
        self.zoom_step = 1
        self.zoom_range = (0, 8)
        self.zoom_clamp = True

        self.init_ui()
        self.init_slots()

    def init_ui(self):
        self.setScene(self.gr_scene)
        self.setRenderHints(QPainter.Antialiasing |
                            QPainter.HighQualityAntialiasing |
                            QPainter.TextAntialiasing |
                            QPainter.SmoothPixmapTransform |
                            QPainter.LosslessImageRendering)
        self.setViewportUpdateMode(QGraphicsView.FullViewportUpdate)
        self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        self.setTransformationAnchor(self.AnchorUnderMouse)
        # default drag mode
        self.setDragMode(self.RubberBandDrag)
        # custom right menu
        self.setContextMenuPolicy(Qt.DefaultContextMenu)

    def init_slots(self):
        # init slots from sidebar.
        self.sidebar.LOCK_WHEEL.connect(self.set_wheel_disable)
        self.sidebar.ZOOM_IN.connect(self.set_one_zoom_in)
        self.sidebar.ZOOM_OUT.connect(self.set_one_zoom_out)
        self.sidebar.NODE_ORGANIZE.connect(self.organize_nodes)
        self.sidebar.NODE_LOCATE.connect(self.locating_center)

    # ------------------MODE--------------------

    def set_select_mode(self):
        self.mode = MOUSE_SELECT
        self.setDragMode(QGraphicsView.RubberBandDrag)
        self.setCursor(Qt.ArrowCursor)
        debug("Now is <select> mode")

    def set_movable_mode(self):
        self.mode = MOUSE_MOVE
        self.setDragMode(QGraphicsView.ScrollHandDrag)
        debug("Now is <move> mode")

    def set_editing_mode(self, *args):
        self.mode = MOUSE_EDIT
        if len(args) == 3:  # ... normal case
            node_name, node_type, node_sort = args
            self.status_bar_msg(f'Select: {node_name} item in '
                                f'{node_type}:{node_sort}.')
        else:  # ...from pin box
            (node_name, node_type, node_sort,
             pin_args, pin_id) = args
            self.current_node_pin_args = pin_args
            self.current_node_pin_id = pin_id
            self.status_bar_msg(f'Select: {node_name} item in Pins.')
        self.current_node_item_name = node_name
        self.current_node_item_type = node_type
        self.current_node_item_sort = node_sort
        self.set_edit_node_cursor()
        debug("Now is <edit> mode")

    def set_delete_mode(self):
        self.mode = NODE_DELETE
        del_icon = QPixmap(icon['TRASH']).scaled(32, 32)
        self.setCursor(QCursor(del_icon))
        debug("Now is <delete> mode")

    def set_edge_direct_mode(self):
        self.mode = NODE_CONNECT
        self.edge_type = EDGE_DIRECT
        self.setCursor(Qt.CrossCursor)
        debug("Now is <connect-direct> mode")

    def set_edge_curve_mode(self):
        self.mode = NODE_CONNECT
        self.edge_type = EDGE_CURVES
        self.setCursor(Qt.CrossCursor)
        debug("Now is <connect-curve> mode")

    def set_note_mode(self):
        self.mode = MOUSE_NOTE
        self.has_finished_editing = False
        self.setCursor(Qt.IBeamCursor)
        debug("Now is <note> mode")

    # ------------------OVERRIDES--------------------

    def mousePressEvent(self, event):
        if event.button() == Qt.MiddleButton or self.mode == MOUSE_MOVE:
            self.middle_mouse_button_pressed(event)
        elif event.button() == Qt.LeftButton:
            self.left_mouse_button_pressed(event)
        elif event.button() == Qt.RightButton:
            self.right_mouse_button_pressed(event)
        else:
            super().mousePressEvent(event)

    def mouseReleaseEvent(self, event):
        if event.button() == Qt.MiddleButton or self.mode == MOUSE_MOVE:
            self.middle_mouse_button_released(event)
        elif event.button() == Qt.LeftButton:
            self.left_mouse_button_released(event)
        elif event.button() == Qt.RightButton:
            self.right_mouse_button_released(event)
        else:
            super().mouseMoveEvent(event)

    def mouseMoveEvent(self, event):
        pos = event.pos()
        if self.mode == EDGE_DRAG:
            sc_pos = self.mapToScene(pos)
            self.drag_edge.gr_edge.set_dst(sc_pos.x(), sc_pos.y())
            self.drag_edge.gr_edge.update()

        # emit pos changed signal
        self.last_scene_mouse_pos = self.mapToScene(pos)
        self.SCENE_POS_CHANGED.emit(
            int(self.last_scene_mouse_pos.x()),
            int(self.last_scene_mouse_pos.y())
        )
        # enter the hot area of sidebar.
        if (
            self.sidebar.x + self.sidebar.w >= pos.x() >= self.sidebar.x and
            self.sidebar.y + self.sidebar.h >= pos.y() >= self.sidebar.y + self.sidebar.margin_bottom
        ):
            if not self.sidebar.on_display:
                self.sidebar.slide_in_animation()
        else:
            if self.sidebar.on_display:
                self.sidebar.slide_out_animation()

        super().mouseMoveEvent(event)

    def wheelEvent(self, event):
        # check whether should be end.
        if self.disable_wheel:
            if self.has_pressed_zoom_btn:
                self.has_pressed_zoom_btn = False
            else:
                return

        zoom_out_factor = 1 / self.zoom_in_factor

        if event.angleDelta().y() > 0:
            zoom_factor = self.zoom_in_factor
            self.zoom += self.zoom_step
        else:
            zoom_factor = zoom_out_factor
            self.zoom -= self.zoom_step

        clamped = False
        if self.zoom < self.zoom_range[0]:
            self.zoom, clamped = self.zoom_range[0], True
        if self.zoom > self.zoom_range[1]:
            self.zoom, clamped = self.zoom_range[1], True

        # set the gr_scene scale
        if not clamped or self.zoom_clamp is False:
            self.scale(zoom_factor, zoom_factor)

    def keyPressEvent(self, event):
        """ Shortcut: available only view is focused.
        key V - select
        key H - move
        key D - direct edge
        key R - curve edge
        key T - note
        """
        if self.mode == MOUSE_NOTE or not self.has_finished_editing:
            if event.key() == Qt.Key_Escape:
                self.set_select_mode()
        else:
            if event.key() == Qt.Key_V:
                self.set_select_mode()
            elif event.key() == Qt.Key_H:
                self.set_movable_mode()
            elif event.key() == Qt.Key_D:
                self.set_edge_direct_mode()
            elif event.key() == Qt.Key_R:
                self.set_edge_curve_mode()
            elif event.key() == Qt.Key_T:
                self.set_note_mode()
            elif event.key() == Qt.Key_Escape:
                # it can bring back the search bar.
                if self.search_bar.is_display():
                    self.search_bar(self.search_bar.cb_slide_out)
        super().keyPressEvent(event)

    def contextMenuEvent(self, event):
        # get the item that right clicked on
        item = self.get_item_at_click(event)
        if isinstance(item, KMBNodeGraphicItem):
            self.POP_UP_RIGHT_MENU.emit(item.id_str)
            # get item self right menu to display
            item.contextMenuEvent(event)

    def resizeEvent(self, event):
        w = event.size().width()
        h = event.size().height()
        self.sidebar.update_pos(w, h)
        self.search_bar((self.search_bar.cb_set_size, w, h))

    # ------------------EVENT--------------------

    def middle_mouse_button_pressed(self, event):
        release_event = QMouseEvent(QEvent.MouseButtonRelease, event.localPos(), event.screenPos(),
                                    Qt.LeftButton, Qt.NoButton, event.modifiers())
        super().mouseReleaseEvent(release_event)
        self.setDragMode(QGraphicsView.ScrollHandDrag)
        fake_event = QMouseEvent(event.type(), event.localPos(), event.screenPos(),
                                 Qt.LeftButton, event.buttons() | Qt.LeftButton, event.modifiers())

        # if it's under move mode then continue this.
        if self.mode == MOUSE_MOVE:
            self.set_movable_mode()

        super().mousePressEvent(fake_event)

    def middle_mouse_button_released(self, event):
        fake_event = QMouseEvent(event.type(), event.localPos(), event.screenPos(),
                                 Qt.LeftButton, event.buttons() & ~Qt.LeftButton, event.modifiers())
        super().mouseReleaseEvent(fake_event)
        self.setDragMode(QGraphicsView.RubberBandDrag)

        if self.mode == MOUSE_MOVE:
            self.set_movable_mode()

    def left_mouse_button_pressed(self, event):
        item = self.get_item_at_click(event)
        if self.mode == MOUSE_EDIT:
            self.add_node()

        elif self.mode == MOUSE_NOTE:
            if isinstance(item, KMBNote):
                # edit the existing note item.
                item.into_editor()
            else:
                self.add_note()

        elif self.mode == NODE_DELETE:
            # delete group
            if self.rubber_select:
                self.del_items_msg.make('Sure to delete all selected items?',
                                        PopMessageBox.TYPE_YES_OR_NO)
                res = self.del_items_msg.exec()
                if res == QMessageBox.Yes:
                    self.del_selected_items()
            # delete single
            else:
                self.del_selected_item(item)

        elif self.mode == NODE_CONNECT:
            if item is not None and isinstance(item, KMBNodeGraphicItem):
                self.mode = EDGE_DRAG
                self.edge_drag_start(item)

        else:
            self.set_node(item)

            if hasattr(item, 'node') or item is None or issubclass(item.__class__, KMBGraphicEdge):
                if event.modifiers() & Qt.ShiftModifier:
                    event.ignore()
                    fake_event = QMouseEvent(QEvent.MouseButtonPress, event.localPos(), event.screenPos(),
                                             Qt.LeftButton, event.buttons() | Qt.LeftButton,
                                             event.modifiers() | Qt.ControlModifier)
                    super().mousePressEvent(fake_event)
                    return

            if item is None:
                if event.modifiers() & Qt.ControlModifier:
                    fake_event = QMouseEvent(QEvent.MouseButtonRelease, event.localPos(), event.screenPos(),
                                             Qt.LeftButton, Qt.NoButton, event.modifiers())
                    super().mouseReleaseEvent(fake_event)
                    QApplication.setOverrideCursor(Qt.CrossCursor)
                    return

            super().mousePressEvent(event)

    def left_mouse_button_released(self, event):
        item = self.get_item_at_click(event)
        if self.mode == EDGE_DRAG:
            self.mode = NODE_CONNECT
            if (
                isinstance(item, KMBNodeGraphicItem) and
                item is not self.drag_start_item
            ):
                self.edge_drag_end(item, event)
            else:
                # if it's nothing then drop this edge
                debug(f"[dropped] => {self.drag_edge} cause nothing happened.")
                self.drag_edge.remove()
                self.drag_edge = None

        elif self.mode == MOUSE_SELECT:
            # record the group selected result,
            # if it's None, then will get a empty list.
            self.get_items_at_rubber()
            super().mouseReleaseEvent(event)

        else:
            if hasattr(item, "node") or item is None or issubclass(item.__class__, KMBGraphicEdge):
                if event.modifiers() & Qt.ShiftModifier:
                    event.ignore()
                    fake_event = QMouseEvent(event.type(), event.localPos(), event.screenPos(),
                                             Qt.LeftButton, Qt.NoButton,
                                             event.modifiers() | Qt.ControlModifier)
                    super().mouseReleaseEvent(fake_event)
                    return
            super().mouseReleaseEvent(event)

    def right_mouse_button_pressed(self, event):
        # it will cancel all the mode and back to select mode.
        if self.mode == EDGE_DRAG:
            self.drag_edge.remove()
            self.drag_edge = None
        self.set_select_mode()

    def right_mouse_button_released(self, event):
        # self.set_select_mode()
        pass

    # ------------------OPERATIONS--------------------

    def add_node(self, *args):
        # add new node, args is feeding from search bar.
        self.is_modified()
        if args:
            self.current_node_item_name = args[0]
            self.current_node_item_sort = args[1]
            self.current_node_item_type = args[2]
            self.current_node_pin_id = None
            self.current_node_pin_args = args[3]
            x, y = args[4]
        else:
            x, y = self.get_last_xy()
        node = KMBNodeItem(self.gr_scene,
                           self.current_node_item_name,
                           self.current_node_item_type,
                           self.current_node_item_sort,
                           self.current_node_pin_id,
                           self.parent)
        node.set_pos(x, y)
        # add into scene and get count of nodes.
        self.gr_scene.scene.add_node(node)
        count = self.gr_scene.scene.get_node_count(node.gr_name)
        self.ADD_NEW_NODE_ITEM.emit(self.current_node_item_name,
                                    self.current_node_item_type,
                                    node.gr_node.id_str,
                                    count, str(self.current_node_pin_args))
        self.status_bar_msg(f'Add: {self.current_node_item_name} node.')
        self.drop_received_pin()

    def add_note(self):
        # add note in scene.
        x, y = self.get_last_xy()
        note = KMBNote(self.gr_scene, x, y)
        note.FINISHED_EDITING.connect(self.set_finished_editing)
        self.set_select_mode()

    def set_node(self, item):
        # get args of node and edit it
        if item is not None and isinstance(item, KMBNodeGraphicItem):
            # if select obj, send its name.
            self.SELECTED_NODE_ITEM.emit(item.id_str)
            self.status_bar_msg(f'Select: {item.name} node.')
        else:
            # if select no obj, send empty signal to clear arg panel.
            self.SELECTED_NODE_ITEM.emit('null')

    def del_selected_item(self, item):
        # del selected node or edge
        if item is not None:
            self.is_modified()
            if isinstance(item, KMBNodeGraphicItem):
                self._del_node_item(item)
            elif issubclass(item.__class__, KMBGraphicEdge):
                self._del_edge_item(item)
            elif isinstance(item, KMBNote):
                self._del_note_item(item)

    def del_selected_items(self):
        self.is_modified()
        # del the selected items
        for item in self.rubber_select:
            self.del_selected_item(item)
        self.rubber_select.clear()

    def _del_node_item(self, node):
        self.SELECTED_DELETE_NODE.emit(node.id_str)
        # del the stored model.
        self.status_bar_msg(f'Delete: {node.name} node.')
        self.gr_scene.scene.remove_node(node.node)
        # del the node in view.
        self.gr_scene.removeItem(node)

    def _del_edge_item(self, edge):
        # del direct edge directly.
        self.status_bar_msg('Delete: One edge.')
        if isinstance(edge, KMBGraphicEdgeBezier):
            self.has_chosen_to_del_from_rm = False
            # curve edge need to del the ref.
            src_item_id = str(id(edge.edge.start_item.gr_node))
            dst_item_id = str(id(edge.edge.end_item.gr_node))
            self.DEL_REF_RELATED_ITEMS.emit(src_item_id, dst_item_id)

            if not self.has_chosen_to_del_from_rm:
                return

        elif isinstance(edge, KMBGraphicEdgeDirect):
            # only works if edge's end is Model.
            if edge.edge.end_item.gr_name == 'Model':
                src_item_id = str(id(edge.edge.start_item.gr_node))
                dst_item_id = str(id(edge.edge.end_item.gr_node))
                self.DEL_IO_EDGE_ITEM.emit(src_item_id, dst_item_id)
            self.gr_scene.removeItem(edge)
        # remove edge from view and history.
        self.gr_scene.scene.remove_edge(edge.edge)
        self.gr_scene.removeItem(edge)

    def _del_note_item(self, note):
        self.gr_scene.scene.remove_note(note)
        self.gr_scene.removeItem(note)

    def edge_drag_start(self, item):
        # pass the wrapper of gr_scene and gr_node
        self.drag_start_item = item
        self.has_chosen_from_rm = False
        self.drag_edge = KMBEdge(self.gr_scene.scene,
                                 item.node,
                                 None, self.edge_type)
        debug(f"[start dragging edge] => {self.drag_edge} at {item}")

    def edge_drag_end(self, item, event):
        debug(f"[stop dragging edge] => {self.drag_edge} at {item}")
        new_edge = KMBEdge(self.gr_scene.scene,
                           self.drag_start_item.node,
                           item.node,
                           self.edge_type)
        # remove the dragging dash edge.
        self.drag_edge.remove()
        self.drag_edge = None
        # saving for the new edge.
        saving_state = new_edge.store()
        # -1 (Invalid), 1 (Valid and display)
        if saving_state == -1:  # fail to add new edge.
            self.gr_scene.removeItem(new_edge.gr_edge)
            debug("[dropped] invalid connection.")
        else:  # add new edge successfully.
            debug(f"[connect] {self.drag_start_item} ~ {item} => {new_edge}")
            # only ref edge is able to pop up right menu of the end item,
            # so now you're able to pick up which arg it ref to.
            if self.edge_type == EDGE_CURVES:
                self._curve_edge_drag_end(event, new_edge)
            # for Model, show its input and output in right menu.
            if self.edge_type == EDGE_DIRECT:
                self._direct_edge_drag_end(event, item, new_edge)

    def _curve_edge_drag_end(self, event, new_edge):
        """ Event while end up dragging curve edge. """
        self.contextMenuEvent(event)
        # if hadn't chosen a item in right menu,
        # then give up this edge.
        if not self.has_chosen_from_rm:
            self.gr_scene.removeItem(new_edge.gr_edge)
            self.has_chosen_from_rm = False
            self.gr_scene.scene.history.destroy_edge(new_edge)
            debug("[dropped] triggered no item in right menu.")
        else:
            self.is_modified()

    def _direct_edge_drag_end(self, event, item, new_edge):
        """ Event while end up dragging direct edge.
        This method is specially for <Model> node. """
        # display its inputs and outputs in right menu.
        if item.name == 'Model':
            self.contextMenuEvent(event)
            if not self.has_chosen_from_rm:
                self.gr_scene.removeItem(new_edge.gr_edge)
                self.gr_scene.scene.history.destroy_edge(new_edge)
                debug("[dropped] triggered no item in right menu.")
            else:
                self.is_modified()
        else:
            self.is_modified()

    # ------------------UTILS--------------------

    def drop_received_pin(self):
        """ Drop all the received pin value after using. """
        self.current_node_pin_id = None
        self.current_node_pin_args = None

    def bring_search_bar(self):
        if self.search_bar.is_display():
            self.search_bar(self.search_bar.cb_slide_out)
        else:
            self.search_bar(self.search_bar.cb_slide_in)

    def get_item_at_click(self, event):
        """ Return the object that clicked on. """
        pos = event.pos()
        obj = self.itemAt(pos)
        return obj

    def get_items_at_rubber(self):
        """ Get group select items. """
        area = self.rubberBandRect()
        self.rubber_select = self.items(area)

    def get_last_xy(self):
        # return the last position of mouse in scene.
        return int(self.last_scene_mouse_pos.x()), int(self.last_scene_mouse_pos.y())

    def set_edit_node_cursor(self):
        pix = QPixmap(icon['CROSS']).scaled(30, 30)
        self.setCursor(QCursor(pix))

    def is_modified(self):
        # if current project has any changes,
        # including args then will trigger this.
        self.IS_MODIFIED.emit(True)

    def set_chosen_item_from_rm(self, _):
        # if not choose one arg item from menu to ref/io,
        # then del this edge, and this is sign.
        self.has_chosen_from_rm = True

    def set_chosen_to_del_from_rm(self, _):
        # if not choose one arg item from menu to del,
        # then give up this operation.
        self.has_chosen_to_del_from_rm = True

    def set_wheel_disable(self, state: bool):
        # on Mac: touch pad may have bad exp if wheel is enable.
        self.disable_wheel = state

    def set_finished_editing(self, state: bool):
        # note has finished editing.
        self.has_finished_editing = state

    def set_one_zoom_in(self):
        # zoom in once.
        fake_wheel_event = QWheelEvent(
            QPoint(0, 0),      # pos(fake)
            QPoint(0, 0),      # global-pos(fake)
            QPoint(0, 2),      # pixel-delta(fake)
            QPoint(0, 120),    # angle-delta(fake)
            0,                 # phase
            Qt.Vertical,       # orientation
            Qt.LeftButton,     # button
            Qt.KeyboardModifierMask  # keyboard
        )
        # enable wheel, disable it after using.
        self.has_pressed_zoom_btn = True
        # feed it to wheel.
        self.wheelEvent(fake_wheel_event)

    def set_one_zoom_out(self):
        # zoom out once.
        fake_wheel_event = QWheelEvent(
            QPoint(0, 0),
            QPoint(0, 0),
            QPoint(0, -2),
            QPoint(0, -120),
            0,
            Qt.Vertical,
            Qt.LeftButton,
            Qt.KeyboardModifierMask
        )
        self.has_pressed_zoom_btn = True
        self.wheelEvent(fake_wheel_event)

    def organize_nodes(self):
        # start organizing nodes in another thread.
        OrganizingThread(self.gr_scene.scene.history.nodes)()

    def locating_center(self):
        # locating to view center.
        self.centerOn(0, 0)


import matplotlib
matplotlib.use('Agg')

import matplotlib.pyplot as plt
import pathlib
from matplotlib import cm
from matplotlib.patches import RegularPolygon
from brabant_puzzle.make_puzzle import puzzle, category_cells
import numpy as np
import pandas as pd
import datetime
import json
import random
import os

class Plotter:
    def __init__(self, size=30, template=False):
        self.size = size
        self.template = template

        with open("/home/rob/Documents/puzzleDjango/brabant_puzzle/settings.txt", "r") as f:
            settings = json.load(f)

        if not template:
            self.filepath = "/home/rob/Documents/puzzleDjango/puzzle/static/puzzle/images/latest_solution.png"
            self.old_solutions_path = "/home/rob/Documents/puzzleDjango/puzzle/static/puzzle/images/old_solutions"
        else:
            self.filepath = "/home/rob/Documents/puzzleDjango/puzzle/static/puzzle/images/template.png"

        prefilled_filename = "/home/rob/Documents/puzzleDjango/brabant_puzzle/puzzle_filled.csv"
        with open(prefilled_filename, "r") as f:
            df = pd.read_csv(f)
            self.filled = list(df.Answer)

        if settings["use_self_filled"] == "True" or template:
            selffilled_filename = "/home/rob/Documents/puzzleDjango/brabant_puzzle/self_filled.csv"
            with open(selffilled_filename, "r") as f:
                df = pd.read_csv(f)
                self.self_filled = list(df.Answer)
        else:
            self.self_filled = []

        fig, ax = plt.subplots(figsize=(self.size, self.size))
        ax.set_aspect('equal')
        self.fig = fig
        self.ax = ax

        size = 1

        coord = []
        colors = []
        labels = []

        for i, row in enumerate(puzzle):
            for j, cell in enumerate(row):
                if i <= 7:
                    x = -i + j
                    y = -j
                else:
                    x = -7 + j
                    y = -i - j + 7

                z = i

                coord.append([x, y, z])
                if cell in category_cells:
                    colors.append(["White"])
                else:
                    colors.append(["Green"])

                labels.append([""])

        # Horizontal cartesian coords
        self.hcoord = [c[0] * size for c in coord]

        # Vertical cartersian coords
        self.vcoord = [size * 2. * np.sin(np.radians(60)) * (c[1] - c[2]) / 3. for c in coord]

        # Add some coloured hexagons
        self.labels = []
        self.hexagons = []

        for i, (x, y, c, l) in enumerate(zip(self.hcoord, self.vcoord, colors, labels)):
            if i in category_cells:
                linewidth = 5
            else:
                linewidth = 1

            color = c[0].lower()  # matplotlib understands lower case words for colours
            hex = RegularPolygon((x, y), numVertices=6, radius=2. / 3. * size,
                                 orientation=np.radians(30),
                                 facecolor=color, alpha=0.5, edgecolor='black', linewidth=linewidth)

            self.hexagons.append(hex)

            text = self.ax.text(x, y, l, ha='center', va='center', size=2, fontsize=10)
            self.ax.text(x, y - 0.2, i, ha='center', va='center', size=2, fontsize=10)
            self.labels.append(text)
            self.ax.add_patch(hex)

        # Also add scatter points in hexagon centres
        self.ax.scatter(self.hcoord, self.vcoord, c=[c[0].lower() for c in colors], alpha=0.0)

        # Show outside categories
        rotations = [30, -30, -90, 30, -30, 90]
        positions = [[-4, -1], [4, -1], [8, -8], [4, -15], [-4, -15], [-8, -8]]
        for i, category in enumerate(self.filled[-6:]):
            self.ax.text(positions[i][0], positions[i][1], category, size=50, fontsize=50, ha='center', va='center', rotation=rotations[i], rotation_mode='anchor', color='red', weight='bold')

        self.best_time = self.ax.text(-8, 0.9, datetime.datetime.now().strftime("%H:%M:%S"), size=30, fontsize=30)
        self.last_saved = self.ax.text(-8, 0.6, datetime.datetime.now().strftime("%H:%M:%S"), size=30, fontsize=30)
        self.stats = self.ax.text(-8, 0.3, "", size=30, fontsize=30)
        self.avg_time = self.ax.text(-8, 0, "", size=30, fontsize=30)
        self.qsize = self.ax.text(-8, -0.3, "", size=30, fontsize=30)

        ax.axes.get_xaxis().set_visible(False)
        ax.axes.get_yaxis().set_visible(False)

    def plot(self, S, all_options, heatmap=None, best_time="", avg_time=-1, stuck=False, qsize=-1, final=False):
        remove_filenames = []

        if not self.template:
            DIR = "/home/rob/Documents/puzzleDjango/puzzle/static/puzzle/images"
            files = os.listdir(DIR)
            remove_filenames = [f for f in files if "latest_solution" in f]

            self.filepath = "/home/rob/Documents/puzzleDjango/puzzle/static/puzzle/images/latest_solution" + str(int(random.uniform(1000, 9999))) + ".png"

        labels = []
        for c in S:
            if c is None:
                labels.append("")
            else:
                labels.append(all_options[c])

        # Define heatmap range
        norm = None
        cat_norm = None
        heats = []

        if heatmap is not None:
            heats = [len(v) for k, v in heatmap.items()]
            category_heats = [len(v) for k, v in heatmap.items() if k in category_cells]

            norm = matplotlib.colors.Normalize(vmin=min(heats), vmax=max(heats))
            cat_norm = matplotlib.colors.Normalize(vmin=min(category_heats), vmax=max(category_heats))

        # Add some coloured hexagons
        for i, (x, y, l) in enumerate(zip(self.hcoord, self.vcoord, labels)):

            if heatmap is not None:
                if i in category_cells:
                    cmap =cm.get_cmap("Oranges_r")
                    color = cmap(cat_norm(heats[i]))
                else:
                    cmap = cm.get_cmap("Greens_r")
                    color = cmap(norm(heats[i]))

            # Also add a text label
            # self.labels[i].set_text(l)
            self.labels[i].set_text(l)
            self.labels[i].set_ha('center')
            self.labels[i].set_x(x)
            self.labels[i].set_y(y)
            self.labels[i].set_size(2)
            self.labels[i].set_fontsize(10)

            if heatmap is not None:
                self.hexagons[i].set_facecolor(color)

            if l in self.filled:
                self.labels[i].set_weight('bold')
                # self.ax.text(x, y, l, ha='center', va='center', size=2, fontsize=10, weight='bold')

            elif l in self.self_filled:
                self.labels[i].set_weight('bold')
                self.labels[i].set_color('red')
                # self.ax.text(x, y, l, ha='center', va='center', size=2, fontsize=10, weight='light', color="red")

        # Plot timestamp
        self.best_time.set_text("Best time: " + best_time)
        self.last_saved.set_text("Last saved time: " + datetime.datetime.now().strftime("%H:%M:%S"))
        self.qsize.set_text("Queue size: " + str(qsize))

        string = "Filled: " + str(len([j for j in S if j is not None]) - len(self.self_filled) - len(self.filled)) + " / " + str(len(S) - len(self.self_filled) - len(self.filled))
        self.stats.set_text(string)

        self.avg_time.set_text("Avg improvement time: " + str(round(float(avg_time), 1)) + " seconds.")

        self.fig.tight_layout()

        if stuck:
            self.ax.text(-8, -0.9, "STUCK :(", size=60, fontsize=60, weight='bold')

        if not final:
            self.fig.savefig(self.filepath)

            for f in remove_filenames:
                if f != self.filepath:
                    os.remove(os.path.join(DIR, f))

            if not self.template:
                filled = len([s for s in S if s is not None])
                filename = os.path.join(self.old_solutions_path, str(filled) + "_solution.png")
                self.fig.savefig(filename)

            plt.close(self.fig)
        else:
            filepath = "/home/rob/Documents/puzzleDjango/puzzle/static/puzzle/images/finished_solutions/" + datetime.datetime.now().strftime("%d_%H:%M:%S") + "_final_solution.png"
            self.fig.savefig(filepath)

if __name__ == "__main__":
    plotter = Plotter(10)
    S = {i: i for i in range(175)}
    all_options = [v for k, v in S.items()]
    plotter.plot(S, all_options)


import argparse
import os
from unittest import TestCase

from doccli import DocCliParser, ConfigUtil

class CliTool:
    command_name = "cli"

    def __init__(self, _non_cli_param: str, param_a: str, param_b, param_c: int = 5):
        """This is the command description

        Args:
            _non_cli_param (str): Underscore leading params aren't included in the
                                  CLI specs
            param_a: A required parameter
            param_b: Note that the type needs to come from the annotation
            param_c: This one has a default
        """

        self.param_a = param_a
        self.param_b = param_b

        self._non_cli_param = _non_cli_param

class SuperTool:
    """Main CLI class to route to subcommands
    """

    command_name = "main-tool"

class TestCliParse(TestCase):
    def test_basic_cli_tool(self):
        parser_spec = DocCliParser.create_decli_spec(CliTool)

        self.assertDictEqual(
            parser_spec,
            {
                "prog": "cli",
                "description": "This is the command description",
                "arguments": [
                    {
                        "name": "--param-a",
                        "required": True,
                        "type": str,
                        "help": "A required parameter",
                    },
                    {
                        "name": "--param-b",
                        "required": True,
                        "help": "Note that the type needs to come from the annotation",
                    },
                    {
                        "name": "--param-c",
                        "type": int,
                        "default": 5,
                        "help": "This one has a default",
                    },
                ],
            },
        )

    def test_create_parser(self):
        docliparser = DocCliParser(CliTool)
        parser = docliparser.parser

        assert issubclass(parser.__class__, argparse.ArgumentParser)

    def test_subcommands(self):
        docliparser = DocCliParser(SuperTool)
        docliparser.add_subcommand(CliTool, func=lambda **kwargs: len(kwargs))
        spec = docliparser.spec
        func = spec["subcommands"]["commands"][0].pop("func")
        self.assertDictEqual(
            docliparser.spec,
            {
                "prog": "main-tool",
                "description": "Main CLI class to route to subcommands",
                "subcommands": {
                    "title": "Positional Arguments",
                    "description": "Run main-tool <arg> --help for further details",
                    "commands": [
                        {
                            "arguments": [
                                {
                                    "name": "--param-a",
                                    "type": str,
                                    "help": "A required parameter",
                                    "required": True,
                                },
                                {
                                    "name": "--param-b",
                                    "help": "Note that the type needs to come from the annotation",
                                    "required": True,
                                },
                                {
                                    "name": "--param-c",
                                    "type": int,
                                    "default": 5,
                                    "help": "This one has a default",
                                },
                            ],
                            "name": "cli",
                            "help": "This is the command description",
                        }
                    ],
                },
            },
        )

        spec["subcommands"]["commands"][0]["func"] = func

        parser = docliparser.parser
        assert issubclass(parser.__class__, argparse.ArgumentParser)

        res = parser.parse_args(
            ["cli", "--param-a", "hey", "--param-b", "you", "--param-c", "2"]
        )

        assert res.param_a == "hey"
        assert res.param_b == "you"
        assert res.param_c == 2

        assert res.func(**vars(res)) == 4  # params + func

test_file = "testfile.yml"

class ConfigCmd(ConfigUtil):
    command_name = "cfg"
    config_key = "config-cmd.options"

    def __init__(self, param_a: str, param_b: str):
        """This is the command description

        Args:
            param_a: A required parameter
            param_b: Note that the type needs to come from the annotation
        """

        self.param_a = param_a
        self.param_b = param_b

class MainFunc(ConfigUtil):
    """Main CLI class to route to subcommands
    """

    sub_config_list = [ConfigCmd]
    config_key = "main"
    flatten_sub_commands = True

class TestParseWithFile(TestCase):
    def tearDown(self):
        try:
            os.remove(test_file)
        except FileNotFoundError:
            pass
        return super().tearDown()

    def test_parse_with_file(self):
        parser = DocCliParser(MainFunc)
        parser.add_subcommand(ConfigCmd)

        parser.parse_args(["cfg", "--param-a", "hey", "--param-b", "there"])

        # If we have a missing param then it will fail (loudly)
        with self.assertRaises(SystemExit):
            parser.parse_args(["cfg", "--param-a", "hey"])

        # We can solve this by including a missing variable in a config file
        cfg = MainFunc.with_config_dict(
            {"config-cmd.options": {"param_a": "new values", "param_b": "see"}}
        )
        cfg.to_config_file(test_file)

        args = parser._parse_args_with_config_file(
            ["cfg", "--param-a", "hey"], test_file
        )
        # Note that CLI takes precedence over config file with param a
        assert args == ["cfg", "--param-b", "see", "--param-a", "hey"]


import pywhatkit as kit

def send_message(msg_list, phone_number):
    if msg_list:
        concantenate_msg = ""
        for msg in msg_list:
            concantenate_msg += f"Date: {msg['date']} | Bank: {msg['url']} | Country: {msg['country']} | Value: {msg['value']}\n\n"
        try:
            kit.sendwhatmsg_instantly(
                phone_no=phone_number,
                message=concantenate_msg,
                wait_time=15,
                tab_close=True,
                close_time=1
            )
            print("All messages sent successfully!")
        except Exception as e:
            print(e)
            return
    else:
        print("No messages to send.")


import tkinter as tk
from sympy import symbols, diff, integrate, limit, Eq, solve
# Tạo cửa sổ ứng dụng
app = tk.Tk()
app.title("Phần mềm hỗ trợ học tập Giải tích")

# Tạo biến ký tự
x, y = symbols('x y')

# Hàm tính đạo hàm
def calculate_derivative():
    expression = expression_entry.get()
    try:
        derivative = diff(expression, x)
        result_label.config(text=f"Đạo hàm: {derivative}")
    except:
        result_label.config(text="Lỗi! Kiểm tra biểu thức đầu vào.")

# Hàm tính tích phân
def calculate_integral():
    expression = expression_entry.get()
    start= start_entry.get()
    stop= stop_entry.get()
    try:
        integral = integrate(expression, (x,start,stop))
        result_label.config(text=f"Tích phân: {integral}")
    except:
        result_label.config(text="Lỗi! Kiểm tra biểu thức đầu vào.")

# Hàm tính giới hạn
def calculate_limit():
    limit_point = limit_point_entry.get()
    expression = expression_entry.get()
    try:
        value = limit(expression, x, limit_point)
        result_label.config(text=f"Giới hạn tại x = {limit_point}: {value}")
    except:
        result_label.config(text="Lỗi! Kiểm tra giới hạn hoặc biểu thức đầu vào.")

# Hàm giải phương trình
def solve_equation():
    equation = equation_entry.get()
    try:
        equation = Eq(eval(equation))
        solution = solve(equation, (x, y))
        result_label.config(text=f"Giải phương trình: {solution}")
    except:
        result_label.config(text="Lỗi! Kiểm tra phương trình đầu vào.")

# Tạo giao diện
expression_label = tk.Label(app, text="Nhập biểu thức (dùng x):")
expression_label.pack()

expression_entry = tk.Entry(app)
expression_entry.pack()

calculate_derivative_button = tk.Button(app, text="Tính Đạo hàm", command=calculate_derivative)
calculate_derivative_button.pack()

start_label = tk.Label(app, text="điểm đầu:")
start_label.pack()

start_entry = tk.Entry(app)
start_entry.pack()

stop_label = tk.Label(app, text="điểm cuối:")
stop_label.pack()

stop_entry = tk.Entry(app)
stop_entry.pack()

calculate_integral_button = tk.Button(app, text="Tính Tích phân", command=calculate_integral)
calculate_integral_button.pack()

limit_point_label = tk.Label(app, text="Nhập điểm giới hạn (x):")
limit_point_label.pack()

limit_point_entry = tk.Entry(app)
limit_point_entry.pack()

calculate_limit_button = tk.Button(app, text="Tính Giới hạn", command=calculate_limit)
calculate_limit_button.pack()

equation_label = tk.Label(app, text="Nhập phương trình (ví dụ: x**2 + x - 1):")
equation_label.pack()

equation_entry = tk.Entry(app)
equation_entry.pack()

solve_button = tk.Button(app, text="Giải phương trình", command=solve_equation)
solve_button.pack()

result_label = tk.Label(app, text="")
result_label.pack()

app.mainloop()


import ccxt
import time

def start_check_xrp():
    """Не используются функции, try except и прочие вещи для ускорения кода, чтобы лишний раз
       не замедляться, не создавать новые объекты, вызовы и пр.(хотя тут для читебальности
       и целостности они бы не помешали"""
    binance = ccxt.binance()
    symbol = 'XRP/USDT'  # пару которую ищем
    check_interval = 60

    while True:
        ticker = binance.fetch_ticker(symbol)  # получаем словарь нашей пары
        price = ticker['last']  # последняя цена
        max_price = ticker['high']  # максимальная

        # Проверка, упала ли цена на 1% от максимальной цены за последний час
        if price < max_price * 0.99:
            print(f"Цена {symbol} упала на 1% от максимальной цены за последний час: {price}")

        time.sleep(check_interval)

if __name__ == "__main__":
    start_check_xrp()


import csv
import matplotlib.pyplot as plt

#----- Define variables -----
model_letters = [ "B", "D", "R" ] # [ "B", "D", "R", "RD" ]

species_list = [ "li7", "he4" ]
title = r"$M/M_\odot=0.8$, $Z=0.001$"

custom_labels = [ "Standard", "Diffusion", "Rotation", "Rotation and diffusion" ]
line_colours = [ "k", "b", "orange", "red", "green", "grey" ]
line_styles = [ "-", "--", ":", "-.", "-", "-" ]

#----- Preferences -----
abundance_is_log_list = [ True, False ]
use_custom_xlim = False
use_custom_ylim = False
append_to_filename = False
move_title_up = True
show_legend = True

custom_xlim = [ 3.68, 3.70 ]
custom_ylim = [ -17, -9 ]
append_to_filename_text = "age"
title_y = 1.06

Teff_or_age = "Teff" # "Teff" or "age"

#----- Function to plot surface abundance vs Teff -----
def plot_surface_abundance( species, abundance_is_log ):

	#----- Definitions -----
	x_vals = [ [] for m in model_letters ]
	log_abundances = [ [] for m in model_letters ]
	graph_filename = "Models/a_Comparisons/Abundance-" + species
	graph_title = title + ", species: " + species

	if append_to_filename:
		graph_filename += "-" + append_to_filename_text

	#----- Read csv files -----
	for i in range(len( model_letters )):
		with open( "Models/" + model_letters[i] + "/CSV/history.csv", "r" ) as model_csv:
			model_data = csv.reader( model_csv )
			headers = next( model_data )

			if Teff_or_age == "Teff":
				x_col_name = "log_Teff"
				fig_xlabel = r"$\log(T_{\rm{eff}})$"
			elif Teff_or_age == "age":
				x_col_name = "star_age"
				fig_xlabel = "Star age (yr)"
			else:
				raise ValueError( "X-column %s not understood. Please choose 'Teff' or 'age'." %Teff_or_age )

			x_col = headers.index( x_col_name )
			species_col = headers.index( "log_surface_" + species )

			for j, row in enumerate( model_data ):
				x_vals[i].append( float( row[ x_col ] ) )

				if abundance_is_log:
					log_abundances[i].append( float( row[ species_col ] ) )
				else:
					log_abundances[i].append( 10**float( row[ species_col ] ) )

	#----- Plot graph -----
	plt.rcParams.update({ "font.size": 14 })
	plt.rc( "text", usetex=True )

	fig = plt.figure( figsize=(7,5) )
	ax = fig.add_subplot( 111 )

	for i in range(len( model_letters )):
		ax.plot( x_vals[i], log_abundances[i], label=custom_labels[i], color=line_colours[i], ls=line_styles[i], zorder=len(model_letters)-i )
		ax.scatter( x_vals[i][-1], log_abundances[i][-1], s=20, color=line_colours[i], zorder=len(model_letters)-i )

	ax.set_xlabel( fig_xlabel )

	if abundance_is_log:
		ax.set_ylabel( "Log surface abundance" )
	else:
		ax.set_ylabel( "Surface abundance" )
	if use_custom_xlim:
		ax.set_xlim( custom_xlim[0], custom_xlim[1] )
	if use_custom_ylim:
		ax.set_ylim( custom_ylim[0], custom_ylim[1] )
	if move_title_up:
		ax.set_title( graph_title, y=title_y )
	else:
		ax.set_title( graph_title )

	#--- Put legend outside the plot and save ---
	if show_legend:
		box = ax.get_position()
		ax.set_position( [box.x0, box.y0, box.width*0.8, box.height] )
		ax.legend( bbox_to_anchor=(1.0,1.0) )
	plt.savefig( graph_filename, bbox_inches="tight" )
	plt.close()

#----- Call the function -----
for sp, ail in zip( species_list, abundance_is_log_list ):
	plot_surface_abundance( sp, ail )


import numpy as np
import pandas as pd

import matplotlib.pyplot as plt

if __name__ == "__main__":
    k = 30
    data_df = pd.read_csv(rf"C:\Users\liori\Downloads\wandb_export_stoch_{k}.csv", sep=',')
    possible_n_shots = sorted(data_df["n_shots"].unique())
    possible_n_epochs = sorted(data_df["n_test_epochs"].unique())
    possible_adapt_steps = sorted(data_df["test_adapt_steps"].unique())
    means_df = data_df.groupby(["n_shots", "n_test_epochs", "test_adapt_steps"]).mean()["test_accuracy"].reset_index()
    stderr_df = data_df.groupby(["n_shots", "n_test_epochs", "test_adapt_steps"]).sem()["test_accuracy"].reset_index()
    stderr_df.rename(columns={'test_accuracy': 'test_accuracy_stderr'}, inplace=True)

    full_df = means_df.join(stderr_df.set_index(["n_shots", "n_test_epochs", "test_adapt_steps"]),
                                           on=["n_shots", "n_test_epochs", "test_adapt_steps"])
    full_df.to_csv(rf"C:\Users\liori\Downloads\accs_stoch_{k}.csv", index=False)

    # full_df = pd.read_csv(rf"C:\Users\liori\Downloads\accs_stoch_{k}.csv", sep=',')
    # possible_n_shots = sorted(full_df["n_shots"].unique())
    # possible_n_epochs = sorted(full_df["n_test_epochs"].unique())
    # possible_adapt_steps = sorted(full_df["test_adapt_steps"].unique())

    plt.figure()
    for n_steps in possible_n_epochs:
        df_filtered = full_df[full_df["n_test_epochs"]==n_steps]
        if n_steps == 0:
            for n_epochs in possible_adapt_steps:
                # if n_epochs == 50:
                #      continue
                df_filtered2 = df_filtered[df_filtered["test_adapt_steps"]==n_epochs]
                plt.errorbar(df_filtered2["n_shots"], df_filtered2["test_accuracy"],
                             yerr=df_filtered2["test_accuracy_stderr"], label=f"Meta-testing, {n_epochs} epochs")
        else:
            if n_steps not in [5,40]:
                continue
            plt.errorbar(df_filtered["n_shots"], df_filtered["test_accuracy"],
                         yerr=df_filtered["test_accuracy_stderr"], label=f"{n_steps} adapt steps")
    plt.title(f"Test accuracies vs n_shots")
    #plt.legend(loc="lower right")
    lgd = plt.legend(loc='upper right', bbox_to_anchor=(1.5, 1.05))
    plt.savefig(f"test_accuracies_stoch{k}.png", bbox_extra_artists=(lgd,), bbox_inches='tight')
    plt.close()


# -*- coding: utf-8 -*-
"""
Created on Wed Apr 11 11:26:23 2018

@author: jglasskatz
"""

import pandas as pd
import matplotlib.pyplot as plt
from matplotlib import colors as c
from mpl_toolkits.basemap import Basemap, shiftgrid
import numpy as np
import os
import scipy.stats as st
import matplotlib.animation

#Read in the data
#go to appropriate directory
os.chdir('C:\\Users\\jglasskatz\\Desktop\\CNRA_DATA')

#make csvs df
gwm = pd.read_csv('continuousgroundwatermonthly.csv')
stat = pd.read_csv('gwlstations.csv')
#merge to get relevant data set
gw = gwm.merge(stat, how ='left', on = 'STATION')
#Relevant depths
gw = gw[:][gw['GSE_WSE']>0]
#Get a bunch of different data sets with unique dates
Utime =pd.unique(gw['MSMT_DATE'])
datedata  =[]
for time in Utime:
    df = gw[:][gw['MSMT_DATE']==time]
    datedata.append(df)

#make a list of the ones with 100 samples or more
dfs = []
for df in datedata:
    #print(df.shape)
    if(df.shape[0]>100):
        dfs.append(df)
lons = []
lats = []
depths = []
dates = []
os.chdir('C:\\Users\\jglasskatz\\Desktop\\Depth_Im')
for i in range(0, len(dfs)):
#Do a tester
    test = dfs[i]
    test2 = test.reset_index()
    #They are the same so all unique)

    #Get data
    x1 = test2['LONGITUDE'][:]
    y1 = test2['LATITUDE'][:]
    depth = test2['GSE_WSE'][:]

    fig = plt.figure(figsize=[10,10])
    # specify (nrows, ncols, axnum)
    ax = fig.add_subplot(1, 1, 1)
    #Title
    ax.set_title('Groundwater Depth for ' + test2['MSMT_DATE'][0], fontsize = 14)

    map = Basemap(projection='cyl',llcrnrlat=32.5,urcrnrlat=42.5,llcrnrlon=-125,urcrnrlon=-115,resolution='c', ax=ax)
    #fill it in a bit
    map.drawcoastlines()
    map.drawmapboundary (fill_color='aqua', zorder =1)
    map.fillcontinents (color='#cc9955', zorder =2)
    map.drawstates(zorder =3)
    lon, lat = map(x1,y1)
    lons.append(lon)
    lats.append(lat)
    dates.append(test2['MSMT_DATE'][0])
    depths.append(depth)
    cs = map.scatter(lon, lat, c=depth, cmap='gnuplot', zorder=4)
    fig.colorbar(cs, orientation = 'horizontal')
    #fig.savefig(test2['MSMT_DATE'][0]+'.png')

#################################
#################################
#Make an animation
#The figure to be animated
fig = plt.figure(figsize=[8,8])
# specify (nrows, ncols, axnum)
ax = fig.add_subplot(1, 1, 1)
ax.set_title('Groundwater Depth for ' + dates[0], fontsize = 14)

map = Basemap(projection='cyl',llcrnrlat=32.5,urcrnrlat=42.5,llcrnrlon=-125,urcrnrlon=-115,resolution='c', ax=ax)
    #fill it in a bit
map.drawcoastlines()
map.drawmapboundary (fill_color='aqua', zorder =1)
map.fillcontinents (color='#cc9955', zorder =2)
map.drawstates(zorder =3)
cs = map.scatter(lons[0], lats[0], c=depths[0], cmap='gnuplot', zorder=4)
fig.colorbar(cs, orientation = 'horizontal')

def update(i):
    ax.set_title('Groundwater Depth for ' + dates[i], fontsize = 14)
    cs = map.scatter(lons[i], lats[i], c=depths[i], cmap='gnuplot', zorder=4)

ani = matplotlib.animation.FuncAnimation(fig, update, frames=len(dates), repeat=True)
ani.save('GWEbyMonth.mp4', writer=writer)

#Zoomed in version
#map = Basemap(projection='cyl',llcrnrlat=min(y1)-.2,urcrnrlat=max(y1)+.2,llcrnrlon=min(x1)-1,urcrnrlon=max(x1)+1,resolution='c', ax=ax)


import aiohttp
import asyncio
import logging
import sqlite3
import sys
import time

_COMMIT_BATCH_SIZE = 500

async def find_gaps(conn, start, queue):
    remote_high_water_mark = await find_remote_high_water_mark()
    logging.info('remote high water mark: %d', remote_high_water_mark)
    rows = conn.execute(
        'SELECT id FROM Items WHERE id >= ? ORDER BY id', (start,))
    try:
        next_id = next(rows)[0]
    except StopIteration:
        next_id = None

    for id in range(start, remote_high_water_mark):
        if next_id == id:
            try:
                next_id = next(rows)[0]
            except StopIteration:
                next_id = None
        else:
            await queue.put(id)

async def find_remote_high_water_mark():
    url = 'https://hacker-news.firebaseio.com/v0/maxitem.json'
    async with aiohttp.ClientSession() as session:
        async with session.get(url, raise_for_status=True) as response:
            return int(await response.text())

async def get_item(session, id):
    url = f'https://hacker-news.firebaseio.com/v0/item/{id}.json'
    async with session.get(url, raise_for_status=True) as response:
        return await response.json()

async def get_items(task_id, id_queue, item_queue):
    async with aiohttp.ClientSession() as session:
        while True:
            id = await id_queue.get()
            try:
                item = await get_item(session, id)
            except aiohttp.ClientError as e:
                logging.error('could not get item %d: %s', id, e)
                await id_queue.put(id)
                id_queue.task_done()
                continue

            logging.info('task %4d: fetched item %d', task_id, id)
            await item_queue.put(item)
            id_queue.task_done()

def serialize_list(items):
    if not items:
        return None
    return ','.join(str(item) for item in items)

def save_item(conn, item):
    if not item:
        return

    conn.execute("""\
                    INSERT INTO Items
                    (
                        id,
                        deleted,
                        type,
                        by,
                        time,
                        text,
                        dead,
                        parent,
                        poll,
                        kids,
                        url,
                        score,
                        title,
                        parts,
                        descendants)
                    VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)""",
                 (
                     item['id'],
                     item.get('deleted'),
                     item.get('type'),
                     item.get('by'),
                     item.get('time'),
                     item.get('text'),
                     item.get('dead', False),
                     item.get('parent'),
                     item.get('poll'),
                     serialize_list(item.get('kids')),
                     item.get('url'),
                     item.get('score'),
                     item.get('title'),
                     serialize_list(item.get('parts')),
                     item.get('descendants'),
                 ))

def save_items_in_list(conn, item_buffer):
    for item in item_buffer:
        save_item(conn, item)
    conn.commit()

async def save_items(conn, item_queue, item_buffer):
    start = time.time()
    while True:
        item_buffer.append(await item_queue.get())
        item_queue.task_done()

        if len(item_buffer) % _COMMIT_BATCH_SIZE == 0:
            try:
                save_items_in_list(conn, item_buffer)
            except sqlite3.OperationalError as e:
                logging.error('could not commit items: %s', e)
                for item in item_buffer:
                    await item_queue.put(item)
                item_buffer.clear()
                await asyncio.sleep(1)
                continue

            logging.info(
                'committed %d items; write rate: %2.3f items/s',
                _COMMIT_BATCH_SIZE, _COMMIT_BATCH_SIZE / (time.time() - start))
            item_buffer.clear()
            start = time.time()

async def run(conn, num_consumers, start):
    id_queue = asyncio.Queue(maxsize=10000)
    item_queue = asyncio.Queue(maxsize=10000)
    item_buffer = []

    id_producer = asyncio.create_task(
        find_gaps(conn, start, id_queue), name='id-producer')
    item_producers = [asyncio.create_task(
        get_items(task_id, id_queue, item_queue), name=f'item-producer-{task_id}')
        for task_id in range(num_consumers)]
    item_saver = asyncio.create_task(
        save_items(conn, item_queue, item_buffer), name='item-saver')

    await asyncio.gather(id_producer, *item_producers, item_saver)

    await id_queue.join()
    await item_queue.join()

    for task in item_producers + [item_saver]:
        task.cancel()

    # Commit any outstanding items.
    save_items_in_list(conn, item_buffer)
    logging.info('committed %d final items', len(item_buffer))

if __name__ == '__main__':
    logging.basicConfig(level=logging.INFO)
    db = sys.argv[1]
    num_consumers = int(sys.argv[2])
    start = int(sys.argv[3])

    conn = sqlite3.connect(db)
    try:
        asyncio.run(run(conn, num_consumers, start), debug=True)
    finally:
        conn.close()


import logging
import random
import re

from Legobot.Lego import Lego
import requests

logger = logging.getLogger(__name__)

class XKCD(Lego):
    def listening_for(self, message):
        text = message.get('text')

        if text and text.startswith('!xkcd'):
            return True

        return False

    def handle(self, message):
        text = message['text']
        logger.debug(f'Handling message:\n{text}')
        comic_id = self._get_comic_id(text)
        response = self._get_comic(comic_id)

        if response:
            opts = self.build_reply_opts(message)
            self.reply(message, response, opts)

    def _call_xkcd_api(self, comic_id=None):
        if comic_id:
            url = f'https://xkcd.com/{comic_id}/info.0.json'
        else:
            url = 'https://xkcd.com/info.0.json'

        call = requests.get(url)

        if call.status_code == 200:
            return call.json()
        else:
            logger.error(
                f'Error on GET {url}: {call.status_code}: {call.text}')

            return None

    def _get_comic(self, comic_id):
        response = None
        comic = self._call_xkcd_api(comic_id)

        if comic:
            response = 'xkcd #{}: {} {}'.format(
                comic['num'],
                comic['alt'],
                comic['img']
            )

        return response

    def _get_comic_id(self, text):
        comic_id = None
        params = re.split(r'\s+', text)

        if len(params) > 1:
            comic_id = params[1]

        if comic_id in ('r', 'random'):
            comic_id = self._get_random_comic_id()

        return comic_id

    def _get_random_comic_id(self):
        comic_id = 1337
        latest = self._call_xkcd_api()

        if latest:
            latest_id = latest['num']
            comic_id = random.randint(1, latest_id)  # nosec

        return comic_id

    def get_name(self):
        return 'xkcd'

    def get_help(self):
        return 'Fetch an xkcd. Usage: !xkcd [r|random|<int>]'


import matplotlib.pyplot as plt
import tensorflow as tf

# 载入并准备好 MNIST 数据集。将样本从整数转换为浮点数
mnist = tf.keras.datasets.mnist

(x_train, y_train), (x_test, y_test) = mnist.load_data()
x_train, x_test = x_train / 255.0, x_test / 255.0

# 显示一张样本图片
plt.imshow(x_train[0])
plt.show()

model = tf.keras.models.Sequential([
    tf.keras.layers.Flatten(input_shape=(28, 28)),
    tf.keras.layers.Dense(128, activation='relu'),
    tf.keras.layers.Dropout(0.2),
    # 数据集有 10 个类, Dense 层需要 10 个输出及一个 softmax 激活函数
    tf.keras.layers.Dense(10, activation='softmax')
])

tensorboard = tf.keras.callbacks.TensorBoard(log_dir='./log')

if False:
    # 顺序标记的label，使用sparse_categorical_crossentropy作为损失函数
    model.compile(
        optimizer='adam',
        loss='sparse_categorical_crossentropy',
        metrics=['accuracy']
    )

    model.fit(x_train, y_train, epochs=5, callbacks=[tensorboard])

    # 验证模型
    model.evaluate(x_test, y_test, verbose=2)
else:
    train_y_one_hot_label = tf.keras.utils.to_categorical(y_train)
    test_y_one_hot_label = tf.keras.utils.to_categorical(y_test)

    # 独热编码label，使用categorical_crossentropy作为损失函数
    model.compile(
        optimizer='adam',
        loss='categorical_crossentropy',
        metrics=['accuracy']
    )

    model.fit(x_train, train_y_one_hot_label, epochs=5, callbacks=[tensorboard])
    # 验证模型
    model.evaluate(x_test, test_y_one_hot_label, verbose=2)


"""initial listing model

Revision ID: d6c2334f4816
Revises:
Create Date: 2021-09-27 17:33:02.166128

"""
import sqlalchemy as sa
from sqlalchemy.dialects import postgresql

from alembic import op

# revision identifiers, used by Alembic.
revision = "d6c2334f4816"
down_revision = None
branch_labels = None
depends_on = None

def upgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    op.create_table(
        "catalog_listing",
        sa.Column("id", postgresql.UUID(as_uuid=True), nullable=False),
        sa.Column("data", postgresql.JSONB(astext_type=sa.Text()), nullable=True),
        sa.PrimaryKeyConstraint("id"),
    )
    # ### end Alembic commands ###

def downgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    op.drop_table("catalog_listing")
    # ### end Alembic commands ###


import sqlite3
import os
import matplotlib.pyplot as plt
import numpy as np
import json
import requests

def createRatingTable():

    path = os.path.dirname(os.path.abspath(__file__))
    conn = sqlite3.connect(path+'/'+"Movies.db")
    cur = conn.cursor()

    cur.execute("CREATE TABLE IF NOT EXISTS IMDB_Ratings (movie_id INTEGER PRIMARY KEY, MetacriticScore INTEGER, ImdbRate INTEGER, imdb_id TEXT)")

    conn.commit()

    return cur,conn

def retrieveIMDBdata():
    response = requests.get('https://imdb-api.com/API/AdvancedSearch/k_u7vte5gf?title_type=feature&release_date=2019-01-01,2022-01-01&groups=oscar_nominees&count=250&sort=alpha,asc')
    data = json.loads(response.text)
    movie_ratings = []
    for movies in data['results']:
        meta = int(movies['metacriticRating'])
        imdb = int(float(movies['imDbRating'])*10)
        title = movies['title']
        id = movies['id']
        tuple = meta,imdb,title,id
        movie_ratings.append(tuple)
    return movie_ratings

def fillRatingTable(movieratings, cur, conn):
    cur.execute("SELECT max(movie_id) FROM IMDB_Ratings")
    count = cur.fetchone()[0]
    if count ==  None:
        count = 0

    for i in range(count, count+26):
        meta = movieratings[i][0]
        imdb = movieratings[i][1]
        title = movieratings[i][2]
        id = movieratings[i][3]
        cur.execute(f"SELECT movie_id from Movies WHERE movie_title = ?", (title,))
        movieid = cur.fetchone()[0]
        cur.execute("INSERT OR IGNORE INTO IMDB_Ratings (movie_id, MetacriticScore, ImdbRate, imdb_id) VALUES (?,?,?,?)", (movieid, meta, imdb, id))

    conn.commit()

def graph_ratings_movies1to30(cur, conn):
    cur.execute("SELECT Movies.movie_title, IMDB_Ratings.ImdbRate, IMDB_Ratings.MetacriticScore FROM IMDB_Ratings JOIN Movies ON Movies.movie_id = IMDB_Ratings.movie_id")
    res = cur.fetchall()[:30]
    ngroups = len(res)

    imdb = []
    meta = []
    titles = []

    for tups in res:
        title = tups[0]
        titles.append(title)
        imdbrate = tups[1]
        imdb.append(imdbrate)
        metarate = tups[2]
        meta.append(metarate)

    fig, ax = plt.subplots()
    index = np.arange(ngroups)
    bar_width = 0.25
    opacity = 0.8

    rects1 = plt.bar(index, imdb, bar_width, alpha = opacity, color = 'navy', label = "Audience Ratings")
    rects2 = plt.bar(index + bar_width, meta, bar_width, alpha = opacity, color = 'salmon', label = "Critic Ratings")

    plt.xlabel('Movie')
    plt.ylabel('Ratings')
    plt.title('Ratings by Movie')
    plt.xticks(index + bar_width, titles, fontsize = 'small')
    fig.autofmt_xdate()
    plt.legend()

    plt.tight_layout()
    plt.show()

def pieChartofRatings(cur, conn):
    cur.execute("SELECT ImdbRate, MetacriticScore FROM IMDB_Ratings")
    res = cur.fetchall()

    audience_higher = 0
    critic_higher = 0
    tie = 0

    for tups in res:
        audience = tups[0]
        critic = tups[1]
        if audience > critic:
            audience_higher += 1
        if critic > audience:
            critic_higher += 1
        if audience == critic:
            tie += 1

    labels = 'Audience', 'Critic', 'Tie'
    sizes = [audience_higher, critic_higher, tie]
    explode = (0, 0.1, 0)
    colors = ('lightgreen', 'deepskyblue', 'tomato')

    fig1, ax1 = plt.subplots()
    ax1.pie(sizes, explode=explode, labels=labels, autopct='%1.1f%%',shadow=True, startangle=90, colors = colors)
    plt.title("Do Critics or Audience Rate Movies Higher?")

    ax1.axis('equal')

    plt.show()

    sizetup = (audience_higher, critic_higher, tie)
    return(sizetup)

def findAverageRatingDifference(cur, conn):
    cur.execute("SELECT ImdbRate, MetacriticScore FROM IMDB_Ratings")
    res = cur.fetchall()

    total = len(res)

    difference = 0

    for tups in res:
        audience = tups[0]
        critic = tups[1]
        dif = abs(audience - critic)
        difference += dif

    average = difference/total
    return average

def averageRatetoFile(cur, average, audience, critic, tie):

    file = open('ImdbOutfile.txt', 'w')

    cur.execute("SELECT max(movie_id) FROM IMDB_Ratings")
    totalintable = cur.fetchone()[0]

    file.write("Number of times (out of {}) the Audience score was greater than the Critic score: {}\n".format(totalintable, audience))
    file.write("Number of times (out of {}) the Critic score was greater than the Audience score: {}\n".format(totalintable, critic))
    file.write("Number of times (out of {}) the Audience score was the same as the Critic score: {}\n".format(totalintable, tie))

    file.write("Average difference between critic and audience rating scores: {}".format(average))

    file.close()

def main():
    cur,conn = createRatingTable()
    movieratings = retrieveIMDBdata()
    fillRatingTable(movieratings, cur, conn)
    # graph_ratings_movies1to30(cur, conn)
    # audience, critic, tie = pieChartofRatings(cur, conn)
    # average = findAverageRatingDifference(cur, conn)
    # averageRatetoFile(cur, average, audience, critic, tie)

if __name__ == "__main__":
    main()


import cv2
import mediapipe as mp
import time
import math

dist0 = 0
def openClose(frame, handLms, w, h):
    global dist0
    distcurr=utility(handLms, w, h)
    if(frame == 1):
        dist0 = distcurr
    if((frame%4 +1) == 1 and abs(handLms.landmark[mp.solutions.hands.HandLandmark.WRIST].x*w - w/2)<w/2 and abs(handLms.landmark[mp.solutions.hands.HandLandmark.WRIST].y*h - h/2)<h/2):
        change = dist0- distcurr
        dist = utility(handLms, w, h)
        # print(change)
        if(change>+50):
            print("Hand is closing ")
            return 1
        elif(change<-50):
            print("Hand is opening ")
            return 2
    return 0

time_left = time.time()
time_right = time.time()
left_taken = False
right_taken = False
def sliderHori(handLms, frame, w=1):
    global time_left
    global time_right
    global left_taken
    global right_taken
    for id, lm in enumerate(handLms.landmark):
        if(id==0):
            cx = int((lm.x)*w)
            if(cx < 80 and left_taken== False):
                time_left = time.time()
                left_taken = True

            if(cx > 200 and right_taken == False):
                time_right = time.time()
                right_taken = True
    if(time_left<time_right and right_taken and left_taken):
        print("Hand is moving LEFT")
        return 3
    if(time_right<time_left and right_taken and left_taken):
        print("Hand is moving RIGHT")
        return 4
    return 0

time_up = time.time()
time_down = time.time()
up_taken = False
down_taken = False
def sliderVer(handLms, frame, h=1):
    global time_up
    global time_down
    global up_taken
    global down_taken
    for id, lm in enumerate(handLms.landmark):
        if(id==0):
            cy = int((lm.y)*h)
            if(cy < 90 and up_taken== False):
                time_up = time.time()
                up_taken = True

            if(cy > 180 and down_taken == False):
                time_down = time.time()
                down_taken = True
        # print("Y pos is ", cy)
    if(time_down<time_up and down_taken and up_taken):
        print("Hand is moving UP")
        return 5
    if(time_up<time_down and down_taken and up_taken):
        print("Hand is moving DOWN")
        return 6
    return 0

def eulcidian_distance(X, Y, x_0, y_0):
    sumX = 0
    sumY = 0
    for x in X:
        sumX = sumX+(x-x_0)**2
    for y in Y:
        sumY = sumY+(y-y_0)**2
    return math.sqrt(sumX+sumY)

def utility(handLms, w, h):
    dist = 0
    X = []
    Y = []
    x_0 = 0
    y_0 = 0
    for id, lm in enumerate(handLms.landmark):
        #print(id,lm)
        # Height, width and channel of image
        h, w, c = img.shape
        # X and Y coordinate
        # their values in decimal so
        # we have to convert into pixel
        cx, cy = int((lm.x)*w),int((lm.y)*h)
        if id==0:
            x_0 = cx
            y_0 = cy
        elif (id%4)==0:
            X.append(cx)
            Y.append(cy)
    return (eulcidian_distance(X, Y, x_0, y_0))

# Create Video object
cap = cv2.VideoCapture(0)
# Formality we have to write before start
# using this model
mpHands = mp.solutions.hands
# Creating an object from class Hands
hands = mpHands.Hands(max_num_hands=1)
# creating an object to draw hand landmarks
mpDraw = mp.solutions.drawing_utils
# Previous time for frame rate
pTime = 0
# Current time for frame rate
cTime = 0
frame = 0
time_before_gesture = 0
time_vol = 0
while True:
    # Getting our Frame
    if((time.time() - time_before_gesture)>2.000):
        time_before_gesture = 0
    if((time.time() - time_vol)>0.1):
        time_vol = 0
    success, img = cap.read()
    img = cv2.resize(img,(500,500))
    # Convert image into RGB
    imgRGB = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
    # Calling the hands object to the getting results
    results = hands.process(imgRGB)
    #print(results.multi_hand_landmarks)
    # Checking something is detected or not
    if results.multi_hand_landmarks :
        # Extracting the multiple hands
        # Go through each hand
        for handLms in results.multi_hand_landmarks:
            frame = (frame+1)%31
            # Getting id(index number) and landmark of each hand
            for id, lm in enumerate(handLms.landmark):
                #print(id,lm)
                # Height, width and channel of image
                h, w, c = img.shape
                # X and Y coordinate
                # their values in decimal so
                # we have to convert into pixel
                cx, cy = int(lm.x*w),int(lm.y*h)
                #print(id, cx, cy)
                if id ==4:
                    cv2.circle(img, (cx, cy), 7, (255,0,255), cv2.FILLED)
            # Draw the landmarks and line of the each hands
            mpDraw.draw_landmarks(img, handLms, mpHands.HAND_CONNECTIONS)
            # openClose(frame, handLms)
            if(time_before_gesture == 0):
                hor = sliderHori(handLms, frame, w)
            if(time_vol == 0):
                ver = sliderVer(handLms, frame, h)
                # op = openClose(frame, handLms, w, h)
            if(hor>0):
                hor = 0
                time_before_gesture = time.time()
            if(ver>0):
                ver = 0
                time_vol = time.time()
            # if(op>0):
            #     op = 0
            #     time_before_gesture = time.time()
    else:
        left_taken = False
        right_taken = False
        up_taken = False
        down_taken = False
    # Getting the current time
    cTime = time.time()
    # Getting frame per second
    fps = 1/(cTime-pTime)
    # Previous time become current time
    pTime = cTime
    # Labeling the Frame rate
    cv2.putText(img,str(int(fps)),(10,70),cv2.FONT_HERSHEY_PLAIN,3,
                            (255,0,255),3)

    cv2.imshow("image",img) # Show the frame
    cv2.waitKey(1) # Wait for 1 millisecond


import torch
import torch.nn as nn
import torch.nn.functional as F
import torch.nn.utils.spectral_norm as spectral_norm

# This implementation directly uses SNGAN ResNet Generator and Discriminator

class ResNetBlock(nn.Module):
	def __init__(self, in_channel, out_channel, block_type = "generator", blockno=0):
		super(ResNetBlock, self).__init__()
		self.bn1 = nn.BatchNorm2d(in_channel)
		self.act1 = nn.ReLU()
		self.conv1 = nn.Conv2d(in_channel, out_channel, kernel_size=3, padding=1) if block_type == "generator" else spectral_norm(nn.Conv2d(in_channel, out_channel, kernel_size=3, padding=1))
		self.bn2 = nn.BatchNorm2d(out_channel)
		self.act2 = nn.ReLU()
		self.conv2 = nn.Conv2d(out_channel, out_channel, kernel_size=3, padding=1) if block_type == "generator" else spectral_norm(nn.Conv2d(out_channel, out_channel, kernel_size=3, padding=1))
		self.conv_residual = nn.Conv2d(in_channel, out_channel, kernel_size=1, padding=0) if block_type == "generator" else spectral_norm(nn.Conv2d(in_channel, out_channel, kernel_size=1, padding=0))
		self.block_type = block_type
		self.blockno = blockno

	def forward(self, x):
		b_size, channel, h, w = x.size()
		if self.block_type == "generator":
			x = self.bn1(x)
		out = self.act1(x)
		out = self.conv1(out)
		if self.block_type == "generator":
			out = F.interpolate(out, size=(h*2,w*2), mode="bilinear")
			out = self.bn2(out)
		out = self.act2(out)
		out = self.conv2(out)
		if (self.block_type == "discriminator") and (self.blockno == 0 or self.blockno == 1):
			out = F.avg_pool2d(out, 2)

		residual = self.conv_residual(x)
		if self.block_type == "generator":
			residual = F.interpolate(residual, size=(h*2,w*2), mode="bilinear")

		elif (self.block_type == "discriminator") and (self.blockno == 0 or self.blockno == 1):
			residual = F.avg_pool2d(residual, 2)

		return residual + out

class SNGAN_Generator(nn.Module):
	def __init__(self):
		super(SNGAN_Generator, self).__init__()
		self.linear = nn.Linear(128, 4*4*256) # z = [batch, 128] -> [batch, 256, 4, 4]
		resblocks = []
		resblocks += [ResNetBlock(256, 256, block_type="generator")]
		resblocks += [ResNetBlock(256, 256, block_type="generator")]
		resblocks += [ResNetBlock(256, 256, block_type="generator")]
		self.resblocks = nn.Sequential(*resblocks)
		self.bn = nn.BatchNorm2d(256)
		self.act = nn.ReLU()
		self.conv = nn.Conv2d(256, 3, kernel_size=3, padding=1)
		self.tanh = nn.Tanh()

	def forward(self, z):
		b_size, z_dim = z.size()
		out = self.linear(z)
		out = out.view(b_size, 256, 4, 4)
		out = self.resblocks(out)
		out = self.conv(self.act(self.bn(out)))
		return self.tanh(out)

class SNGAN_Discriminator(nn.Module):
	def __init__(self):
		super(SNGAN_Discriminator, self).__init__()
		resblocks = []
		resblocks += [ResNetBlock(3, 128, block_type="discriminator", blockno=0)]
		resblocks += [ResNetBlock(128, 128, block_type="discriminator", blockno=1)]
		resblocks += [ResNetBlock(128, 128, block_type="discriminator", blockno=2)]
		resblocks += [ResNetBlock(128, 128, block_type="discriminator", blockno=3)]
		self.resblocks = nn.Sequential(*resblocks)
		self.act = nn.ReLU()
		self.linear = spectral_norm(nn.Linear(128, 1))

	def forward(self, x):
		out = self.resblocks(x)
		out = self.act(out)
		out = F.avg_pool2d(out, out.size(2))
		out = out.view(out.size(0), -1)
		return self.linear(out)


import os
import json

class fiveThreeNineFeatureUtil(object):
    logPath = os.path.join('Log', 'addInformation')

    lockCountsDict = {
        "0": {},
        "1": {},
        "2": {},
        "3": {},
        "4": {},
        "5": {},
        "6": {},
        "7": {},
        "8": {},
        "9": {}
    }

    currentLockDict = {
        "0": 0,
        "1": 0,
        "2": 0,
        "3": 0,
        "4": 0,
        "5": 0,
        "6": 0,
        "7": 0,
        "8": 0,
        "9": 0
    }

    def __init__(self):
        if os.path.exists(self.logPath):
            os.remove(self.logPath)

    def addInformation(self, tailNumbers, issue):
        for key in self.currentLockDict:
            if key in tailNumbers:
                if self.currentLockDict[key] not in self.lockCountsDict[key]:
                    self.lockCountsDict[key].update({
                        self.currentLockDict[key]: 1
                    })
                else:
                    self.lockCountsDict[key][self.currentLockDict[key]] += 1
                self.currentLockDict[key] = 0
            else:
                self.currentLockDict[key] += 1

        with open(self.logPath, 'a+') as logFile:
            logFile.write('Issue: %s\n' % issue)
            logFile.write('lockCountsDict:\n%s\n' % json.dumps(self.lockCountsDict, indent=4))
            logFile.write('currentLockDict:\n%s\n' % json.dumps(self.currentLockDict, indent=4))
            logFile.write('======================\n')


import logging
import os
import tempfile
import webbrowser
from typing import List

from whylogs.core import DatasetProfile
from whylogs.util.protobuf import message_to_json

_MY_DIR = os.path.realpath(os.path.dirname(__file__))

logger = logging.getLogger(__name__)

def profile_viewer(profiles: List[DatasetProfile] = None, output_path=None) -> str:
    """
    open a profile viewer loader on your default browser
    """
    try:
        from pybars import Compiler
    except ImportError as e:
        Compiler = None
        logger.debug(str(e))
        logger.debug("Unable to load pybars; install pybars3 to load profile from directly from the current session ")

        index_path = os.path.abspath(os.path.join(_MY_DIR, os.pardir, "viewer", "index.html"))
        webbrowser.open_new_tab(f"file:{index_path}#")
        return None

    # create json output from profiles
    if profiles:
        if len(profiles) > 1:
            logger.warning("More than one profile not implemented yet, default to first profile in the list ")
        profile_jsons = [message_to_json(each_prof.to_summary()) for each_prof in profiles]
    else:
        index_path = os.path.abspath(os.path.join(_MY_DIR, os.pardir, "viewer", "index.html"))
        webbrowser.open_new_tab(f"file:{index_path}#")
        return None

    index_path = os.path.abspath(os.path.join(_MY_DIR, os.pardir, "viewer", "index-hbs-cdn-all-in.html"))

    with open(index_path, "r") as file_with_template:
        source = file_with_template.read()

    # compile templated files
    compiler = Compiler()
    template = compiler.compile(source)
    # replace handlebars for json profiles
    output_index = template({"profile_from_whylogs": profile_jsons[0]})

    if not output_path:
        output_path = tempfile.mkstemp(suffix=".html")[1]
    else:
        output_path = os.path.abspath(os.path.expanduser(output_path))
    with open(output_path, "w") as f:
        f.write(output_index)

    webbrowser.open_new_tab(f"file:{output_path}#")
    return output_path


import pandas as pd
import json
import math

def calculate_mean(data):
    sum = 0
    len1 = 0
    for val in data:
        sum += val
        len1 += 1
    mean = sum/len1
    return mean

data = pd.read_csv("./Datasets/salary.csv")
header = data.columns.values
# print(data[header[0]])
# print(data["Years of Experience"])

X = data[header[0]]
Y = data[header[1]]
X = X.truncate(0,4899)
Y = Y.truncate(0,4899)
X_mean = calculate_mean(X)
Y_mean = calculate_mean(Y)
upper = 0
lower = 0
for index in range(len(X)):
    upper += (X[index] - X_mean) * (Y[index]-Y_mean)
    lower += math.pow(X[index]-X_mean, 2)
m = upper/lower
c = Y_mean - (m * X_mean)

trained_data = {}
trained_data['m'] = m
trained_data['c'] = c
trained_data["Y_mean"] = Y_mean
with open('./trained/trained_data.txt', 'w') as file:
    file.write(json.dumps(trained_data))


'''
This is the entry-point to the cli application.
'''
import click

from clokta.role_assumer import RoleAssumer

@click.command()
@click.version_option()
@click.option('--verbose', '-v', is_flag=True, help='Show detailed')
@click.option('--profile', '-p', required=True, help='Configuration profile')
def assume_role(profile, verbose=False):
    ''' Click point of entry '''
    assumer = RoleAssumer(profile=profile, verbose=verbose)
    assumer.assume_role()


__version__ = (0, 0, 12)

__all__ = [
    'metrics_middleware',
    'metrics',
    'setup_metrics',
    'Counter',
    'Gauge',
    'Histogram',
    'REGISTRY',
    'run_prometheus_server',
    ]

import asyncio
import base64
import time
from typing import Optional, Dict
from urllib.parse import quote_plus

from aiohttp import web
from aiohttp.client import ClientSession, ClientTimeout
from yarl import URL

from prometheus_client.metrics import (
    Counter,
    Gauge,
    Histogram,
)
from prometheus_client.exposition import (
    generate_latest,
    CONTENT_TYPE_LATEST,
)
from prometheus_client.registry import (
    REGISTRY,
)

request_counter = Counter(
    "requests_total", "Total Request Count", ["method", "route", "status"]
)

request_connection_reset_counter = Counter(
    "requests_connection_reset_total",
    "Total Number of Requests where the connection was reset",
    ["method", "route"]
)

request_cancelled_counter = Counter(
    "requests_cancelled_total",
    "Total Number of Requests that were cancelled",
    ["method", "route"]
)

request_latency_hist = Histogram(
    "request_latency_seconds", "Request latency", ["route"]
)

requests_in_progress_gauge = Gauge(
    "requests_in_progress_total", "Requests currently in progress",
    ["method", "route"]
)

request_exceptions = Counter(
    "request_exceptions_total", "Total Number of Exceptions during Requests",
    ["method", "route"])

async def metrics(request: web.Request) -> web.Response:
    resp = web.Response(body=generate_latest(registry=REGISTRY))
    resp.content_type = CONTENT_TYPE_LATEST
    return resp

@web.middleware
async def metrics_middleware(request: web.Request, handler) -> web.Response:
    start_time = time.time()
    route = request.match_info.route.name
    requests_in_progress_gauge.labels(request.method, route).inc()
    try:
        response = await handler(request)
    except web.HTTPException as e:
        request_counter.labels(request.method, route, e.status_code).inc()
        raise
    except ConnectionResetError:
        request_connection_reset_counter.labels(request.method, route).inc()
        raise
    except asyncio.CancelledError:
        request_cancelled_counter.labels(request.method, route).inc()
        raise
    except Exception:
        request_exceptions.labels(request.method, route).inc()
        raise
    finally:
        resp_time = time.time() - start_time
        request_latency_hist.labels(route).observe(resp_time)
        requests_in_progress_gauge.labels(request.method, route).dec()
    request_counter.labels(request.method, route, response.status).inc()
    return response

def setup_metrics(app: web.Application):
    """Setup middleware and install metrics on app.
    """
    app.middlewares.insert(0, metrics_middleware)
    app.router.add_get("/metrics", metrics, name="metrics")

async def run_prometheus_server(listen_addr: str, port: int):
    """Convenience function to run a web server with metrics only.

    Args:
      listen_addr: Address to listen on
      port: Port to listen on
    """
    app = web.Application()
    setup_metrics(app)
    runner = web.AppRunner(app)
    await runner.setup()
    site = web.TCPSite(runner, listen_addr, port)
    await site.start()

# _escape_grouping_key imported from pprometheus-client @
# https://github.com/prometheus/client_python
def _escape_grouping_key(k, v):
    if v == "":
        # Per https://github.com/prometheus/pushgateway/pull/346.
        return k + "@base64", "="
    elif '/' in v:
        # Added in Pushgateway 0.9.0.
        return (
            k + "@base64",
            base64.urlsafe_b64encode(v.encode("utf-8")).decode("utf-8"))
    else:
        return k, quote_plus(v)

async def push_to_gateway(
        gateway: str, job: str, registry, timeout: int = 30,
        grouping_key: Optional[Dict[str, str]] = None):
    """Push results to a pushgateway.

    Args:
      gateway: URL to the push gateway
      job: Name of the exported job
      registry: Registry to get variables from
      timeout: Timeout in seconds
      grouping_key: Dict with key/values to add
    """
    (k, v) = _escape_grouping_key("job", job)
    url = URL(gateway) / "metrics" / k / v

    for (k, v) in sorted((grouping_key or {}).items()):
        (k, v) = _escape_grouping_key(k, v)
        url = url / k / v

    data = generate_latest(registry)

    async with ClientSession() as session:
        async with session.put(
                url, timeout=ClientTimeout(timeout),
                headers={'Content-Type': CONTENT_TYPE_LATEST}, data=data,
                raise_for_status=True):
            pass


import pandas as pd
df = pd.read_csv("G:/Statistics (Python)/Cases/Real Estate/Housing.csv")
dum_df = pd.get_dummies(df.iloc[:,1:11], drop_first=True)

from sklearn.model_selection import train_test_split
from sklearn.ensemble import BaggingRegressor

X = dum_df
y = df.iloc[:,0]

# Create training and test sets
X_train, X_test, y_train, y_test = train_test_split(X, y,test_size = 0.3,
                                                    random_state=2018)

# Default: Tree Regressor
model_bg = BaggingRegressor(random_state=2021,oob_score=True,
                            max_features = X_train.shape[1],
                            n_estimators=15,
                            max_samples=X_train.shape[0])

# any other model bagging regressor
from sklearn.linear_model import LinearRegression

lr = LinearRegression()

model_bg = BaggingRegressor(base_estimator = lr,
                            random_state=2021,oob_score=True,
                            max_features = X_train.shape[1],
                            n_estimators=15,
                            max_samples=X_train.shape[0])

#### building the model ######
model_bg.fit( X_train , y_train )

print("Out of Bag Score = " + "{:.4f}".format(model_bg.oob_score_))

y_pred = model_bg.predict(X_test)

from sklearn.metrics import mean_squared_error,mean_absolute_error,r2_score
print(mean_squared_error(y_test, y_pred))
print(mean_absolute_error(y_test, y_pred))
print(r2_score(y_test, y_pred))


# https://leetcode.com/problems/missing-number

from typing import List

class Solution:
    def missingNumber(self, nums: List[int]) -> int:
        res = 0
        for num in nums:
            res ^= num
        for num in range(len(nums) + 1):
            res ^= num
        return res

    def missingNumber_gauss(self, nums: List[int]) -> int:
        # res = sum(range(len(nums) + 1))         # O(n)
        res = (len(nums) * (len(nums) + 1)) // 2  # O(1)
        res -= sum(nums)
        return res