import sys
from PyQt4.QtGui import (QApplication, QWidget, QFont, QListWidget,
    QHBoxLayout, QVBoxLayout, QShortcut, QKeySequence)
import numpy as np
from spyderlib.widgets.sourcecode.codeeditor import CodeEditor
from spyderlib.widgets.internalshell import InternalShell
from spyderlib.widgets.dicteditor import DictEditorWidget

class Demo(QWidget):
    def __init__(self):
        super(Demo, self).__init__()
        self.code_editor = CodeEditor(self)
        self.code_editor.setup_editor(
            language = "python",
            font = QFont("Courier New")
        )
        run_sc = QShortcut(QKeySequence("F5"), self, self.run)

        self.shell = InternalShell(self, {"demo":self},
            multithreaded = False,
            max_line_count = 3000,
            font = QFont("Courier new", 10),
            message='caonima'
        )

        self.dict_editor = DictEditorWidget(self, {})
        self.dict_editor.editor.set_filter(self.filter_namespace)
        self.dict_editor.set_data(self.shell.interpreter.namespace)
        vbox = QVBoxLayout()
        vbox.addWidget(self.code_editor)
        vbox.addWidget(self.shell)

        hbox = QHBoxLayout()
        hbox.addWidget(self.dict_editor)
        hbox.addLayout(vbox)

        self.setLayout(hbox)
        self.resize(800, 600)

    def filter_namespace(self, data):
        result = {}
        support_types = [np.ndarray, int, float, str, tuple, dict, list]
        for key, value in data.items():
            if not key.startswith("__") and type(value) in support_types:
                result[key] = value
        return result

    def run(self):
        code = str(self.code_editor.toPlainText())
        namespace = self.shell.interpreter.namespace
        exec (code,namespace )
        self.dict_editor.set_data(namespace)

if __name__ == '__main__':
    import sys
    app = QApplication(sys.argv)
    try:
        demo = Demo()
        demo.show()
    except Exception as ex:
        import traceback
        sys.__stdout__.write(traceback.format_exc())
    sys.exit(app.exec_())


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

import logging

from src.ui.winsWidgetView import WinsWidgetView

logging.basicConfig(level=logging.DEBUG) # change to 'DEBUG' to see more

from PyQt5 import QtWidgets, QtGui

def setFontFamily(font):
    allFamillies = QtGui.QFontDatabase().families()
    familyName = font.defaultFamily()
    if "微软雅黑" in allFamillies:
        familyName = "微软雅黑"
    font.setFamily(familyName)

if __name__ == "__main__":
    import sys
    app = QtWidgets.QApplication(sys.argv)
    font = QtGui.QFont()
    setFontFamily(font)
    font.setPixelSize(14)
    app.setFont(font)
    with open('qml\Main.qml', 'r') as qss:
        app.setStyleSheet(qss.read())
    mainview = WinsWidgetView()
    mainview.show()
    sys.exit(app.exec_())


#
# This is an example script to plot seconday chemical shifts.
# by Woonghee Lee, Ph.D. (woonghee.lee@ucdenver.edu)
#
# To run this script:
#   In Poky Notepad,
#     File -> Run Python Module

print('\n\n\n------------------------------------------------------')
print('POKY Secondary Shift Plot')
print('by Woonghee Lee, Ph.D. (woonghee.lee@ucdenver.edu)')
print('Department of Chemistry, University of Colorado Denver')
print('------------------------------------------------------')

# Reference to J. Biomol. NMR 1995.5 67-81
refCSdict = {# CA    CB    C       H      N       AA
      'A':(  52.5,  19.1,  177.8,  8.24,  123.8),  # Ala
      'Cr':( 58.2,  28.0,  174.6,  8.32,  118.8),  # Cys_r
      'Co':( 55.4,  41.1,  174.6,  8.43,  118.6),  # Cys_o
      'D':(  54.2,  41.1,  176.3,  8.34,  120.4),  # Asp
      'E':(  56.6,  29.9,  176.6,  8.42,  120.2),  # Glu
      'F':(  57.7,  39.6,  175.8,  8.30,  120.3),  # Phe
      'G':(  45.1,  0.00,  174.9,  8.33,  108.8),  # Gly
      'H':(  55.0,  29.0,  174.1,  8.42,  118.2),  # His
      'I':(  61.1,  38.8,  176.4,  8.00,  119.9),  # Ile
      'K':(  56.2,  33.1,  176.6,  8.29,  120.4),  # Lys
      'L':(  55.1,  42.4,  177.6,  8.16,  121.8),  # Leu
      'M':(  55.4,  32.9,  176.3,  8.28,  119.6),  # Met
      'N':(  53.1,  38.9,  175.2,  8.40,  118.7),  # Asn
      'P':(  63.3,  32.1,  177.3,  0.00,   0.00),  # Pro
      'Q':(  55.7,  29.4,  176.0,  8.32,  119.8),  # Gln
      'R':(  56.0,  30.9,  176.3,  8.23,  120.5),  # Arg
      'S':(  58.3,  63.8,  174.6,  8.31,  115.7),  # Ser
      'T':(  61.8,  69.8,  174.7,  8.15,  113.6),  # Thr
      'V':(  62.2,  32.9,  176.3,  8.03,  119.2),  # Val
      'W':(  57.5,  29.6,  176.1,  8.25,  121.3),  # Trp
      'Y':(  57.9,  38.8,  175.9,  8.12,  120.3)   # Tyr
    }

import __main__
s = __main__.main_session
clist = s.project.condition_list()
if len(clist) > 1:
  cname = s.show_conditionselectiondialog('Select a condition to evaluate.', 0)
  from sputil import name_to_condition
  c = name_to_condition(cname, s)
else:
  c = clist[0]

btn_list = ('CA', 'CB', 'C', 'H', 'N', 'Cancel')
idx = s.show_selectionexdialog('Atom type', 'Select an atom type.', btn_list)
if idx in [-1, len(btn_list)-1]:
  raise SystemExit

x_list, y_list, err_list = [], [], []
for resn in c.resonance_list():
  a = resn.group.symbol
  cs = resn.frequency
  if cs == 0.0 or resn.atom.name != btn_list[idx]:
    continue
  try:
    if a != 'C':
      row = refCSdict[resn.group.symbol]
      if row[idx] == 0.0:
        continue
      dcs = cs - row[idx]
    else: # CYS will be evaluated to the closer value from r. vs o.
      row = refCSdict[resn.group.symbol + 'r']
      dcs = cs - row[idx]
      row2 = refCSdict[resn.group.symbol + 'o']
      dcs2 = cs - row2[idx]
      if abs(dcs2) < abs(dcs):
        dcs = dcs2
  except:
    continue

  x_list.append(resn.group.number)
  y_list.append(dcs)
  err_list.append(resn.deviation)

# plotting
from matplotlib import use as matplotlib_use
matplotlib_use('TkAgg')

import matplotlib.pyplot as plt
xlabel = 'Residue Number'
ylabel = 'd(CSobs - CSref)'
plt.figure()

plt.errorbar(x_list, y_list, err_list, fmt='bo', markersize=5)
plt.xlabel(xlabel)
plt.ylabel(ylabel)
ylim = max(max(y_list), abs(min(y_list))) * 1.1
plt.ylim((-1 * ylim, ylim))
plt.title('Poky Secondary Shift Plot: ' + btn_list[idx])
plt.pause(0.1)
plt.show(block=False)


import sys
sys.path.append("../")
import pymysql
import math
import pandas as pd
import numpy as np
from scipy.spatial import distance
import csv
from InsertDataBase.CreateTables import *
from DBtools.init_db import init_DB

def GetMinDistanceLane(local_x, local_y):
    radius = 5
    node_list = list()
    way_list = list()
    while len(node_list) < 3:
        node_list = list()
        way_list = list()
        min_x = local_x - radius
        max_x = local_x + radius
        min_y = local_y - radius
        max_y = local_y + radius
        sql = "select Node_To_Way.node_id, way_id " \
              "from Node_To_Way " \
              "join Node_Info on Node_To_Way.node_id = Node_Info.node_id " \
              "where local_x BETWEEN %s and %s and local_y BETWEEN %s and %s group by Node_To_Way.node_id,way_id" \
              % (min_x, max_x, min_y, max_y)
        cursor.execute(sql)
        node_list = list()
        for i in cursor.fetchall():
            node_list.append(i[0])
            way_list.append(i[1])
        radius = 2 * radius

    way_list = list(set(way_list))
    vehicle_position_list = np.array([[local_x, local_y]])
    dist = np.inf
    lane = None
    for way_id in way_list:
        temp_position_list = list()
        sql = "select Node_Info.node_id, local_x, local_y " \
              "from Node_Info " \
              "join Node_To_Way on Node_Info.node_id = Node_To_Way.node_id " \
              "where way_id = %s" % (way_id)
        cursor.execute(sql)
        for i in cursor.fetchall():
            temp_position_list.append([float(i[1]), float(i[2])])
        temp_position_list = np.array(temp_position_list)
        new_dist = distance.cdist(vehicle_position_list, temp_position_list).min(axis=1).min(axis=0)
        if new_dist < dist:
            dist = new_dist
            lane = str(way_id)
    return lane

def InsertTable(cursor, VehicleInfo, table):
    insertTimingSql = "insert into Traffic_timing_state" + table + "(time_stamp,vehicle_id,local_x,local_y,orientation,lane_id) " \
                "values(%s,%s,%s,%s,%s,%s)"
    for i in range(len(VehicleInfo)):
        time_stamp = int(float(VehicleInfo[i][0]) * 1e+3)
        id_str = VehicleInfo[i][1].split('-')
        vehicle_id = int(id_str[-1])
        local_x = float(VehicleInfo[i][3])
        local_y = float(VehicleInfo[i][4])
        lane = GetMinDistanceLane(local_x, local_y)
        orien = 0.000
        cursor.execute(insertTimingSql,(time_stamp, vehicle_id, local_x, local_y, orien, lane))
        if (i % 100 == 0):
            print(i)

    insertPropertySql = "insert into Traffic_participant_property" + table + "(vehicle_id,vehicle_class) " \
                "values(%s,%s) ON DUPLICATE KEY UPDATE vehicle_class = vehicle_class"
    for i in range(len(VehicleInfo)):
        vehicle_type = VehicleInfo[i][2]
        id_str = VehicleInfo[i][1].split('-')
        vehicle_id = int(id_str[-1])
        vehicle_class = int(1)
        cursor.execute(insertPropertySql,(vehicle_id, vehicle_class))
        if (i % 100 == 0):
            print(i)

    UpdateParticipantSql = "Update Traffic_timing_state" + table + " set orientation = %s where time_stamp = %s and vehicle_id = %s"
    stampsql = "select time_stamp from Traffic_timing_state" + table
    vehiclesql = "select vehicle_id from Traffic_timing_state" + table + " where time_stamp = %s"
    positionsql = "select local_x, local_y from Traffic_timing_state" + table + " where time_stamp = %s and vehicle_id = %s"
    oriensql = "select orientation from Traffic_timing_state" + table + " where time_stamp = %s and vehicle_id = %s"
    cursor.execute(stampsql)
    timestampresult = cursor.fetchall()
    timestamp_set = set()
    for i in range(len(timestampresult)):
        timestamp_set.add(timestampresult[i][0])
    timestamp_list = list(timestamp_set)
    timestamp_list.sort()
    vehicle_zero_orien_list = list()
    for t in range(len(timestamp_list) - 1):
        vehicle_list = list()
        cursor.execute(vehiclesql, timestamp_list[t + 1])
        for vehicle in cursor.fetchall():
            vehicle_list.append(vehicle[0])
        if t == 0:
            cursor.execute(vehiclesql, timestamp_list[t])
            for vehicle_zero in cursor.fetchall():
                vehicle_zero_orien_list.append(vehicle_zero[0])
        for vehicle in vehicle_list:
            local_x = 0
            local_y = 0
            last_x = 0
            last_y = 0
            cursor.execute(positionsql, (timestamp_list[t + 1], vehicle))
            for i in cursor.fetchall():
                local_x = i[0]
                local_y = i[1]
            cursor.execute(positionsql, (timestamp_list[t], vehicle))
            for j in cursor.fetchall():
                last_x = j[0]
                last_y = j[1]
            if local_x != None and local_y != None and last_x != None and last_y != None:
                if last_x == 0 and last_y == 0:
                    vehicle_zero_orien_list.append(vehicle)
                    continue
                direction = [local_x - last_x, local_y - last_y]
                orien = math.atan2(direction[1], direction[0])
                if local_x == last_x and local_y == last_y:
                    cursor.execute(oriensql, (timestamp_list[t], vehicle))
                    last_orien = cursor.fetchall()[0][0]
                    cursor.execute(UpdateParticipantSql, (last_orien, timestamp_list[t + 1], vehicle))
                else:
                    cursor.execute(UpdateParticipantSql, (orien, timestamp_list[t + 1], vehicle))
                if vehicle in vehicle_zero_orien_list:
                    cursor.execute(UpdateParticipantSql, (orien, timestamp_list[t], vehicle))
                    vehicle_zero_orien_list.remove(vehicle)

if __name__ == '__main__':
    conn, cursor = init_DB("Argoverse_MIA_Scenario_DB")
    csv_reader = csv.reader(open("../Annotator/sample_record.csv", encoding='utf-8'))
    for i, rows in enumerate(csv_reader):
        table = str(rows[0])
        print("table: ", table)
        VehicleInfo = list()
        file = "../../argoverse_trajectory/forecasting_train_v1.1/train/data/" + table + ".csv"
        VehicleInfo = pd.read_csv(file, decimal=",", low_memory=False)
        VehicleInfo = np.array(VehicleInfo)
        table = "_" + table
        CreateTrafficParticipantPropertyTable(cursor, table)
        CreateTrafficTimingStateTable(cursor, table)
        InsertTable(cursor, VehicleInfo, table)

    cursor.close()
    conn.commit()
    conn.close()


#!/usr/bin/env python
import argparse
import glob
import os
import re

import cv2
import numpy as np
import pandas as pd
from skimage import transform as tf

from utils import create_dictionary_lang

CHROME_PATH = "/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome"

lang_code_dict = create_dictionary_lang()
root_dir = "Data/FLORES/"

# TODO: font weight?
dict_properties = {
    "color": ["black"],
    "opacity": ["1", "0.3"],
    "font_size": ["20px"],
    "letter_spacing": ["normal", "0.2em", "-0.2em"],
    "italic": [True, False],
    "bold": [True, False],
    "gauss": [True, False],
    "skew": [True, False]
}

def read_fonts_file():
    df = pd.read_csv('Data/misc/languages_fonts_codes.csv')
    lang_codes = df["Code"].tolist()
    lang_fonts = df["Fonts"].tolist()
    return lang_codes, lang_fonts

def create_style_file(
        font, color, opacity, font_size, letter_spacing, italic, bold, name_style
):
    str_font = "src: url(fonts/" + font + ".ttf);"
    full_style = (
            """
        @font-face {
        font-family: defined_font;
        """
            + str_font
            + """
    }
    p {
        font-family: defined_font;
        color: """
            + color
            + ";"
            + """
        opacity: """
            + opacity
            + ";"
            + """
        letter-spacing:"""
            + letter_spacing
            + ";"
            + """
        font-size:"""
            + font_size
            + ";"
    )
    if italic:
        full_style += """
        font-style: italic;"""
    if bold:
        full_style += """
        font-weight: bold;"""

    full_style += """
    }
    """
    with open("Data/augmentation/styles/" + name_style + ".css", "w+") as f:
        f.write(full_style)

def create_html_file(root_path, list_sentences, name_html_file, name_style):
    str_style = (
            f"""<link rel="stylesheet" href="{os.path.abspath('Data/augmentation/styles/' + name_style + '.css')}">"""
    )
    str_html_head = (
            """
        <!DOCTYPE html>
        <html lang="en">

        <head>
        <meta charset="UTF-8">
        <meta name="viewport" content=
              "width=device-width, initial-scale=1.0">
        """
            + str_style
            + """
    </head>
    <body>
    """
    )
    # put all text into one paragraph
    str_html_text = "<p>" + "".join(list_sentences) + "</p>"
    str_html_head_close = """
    </body>
    </html>
    """
    full_text = str_html_head + str_html_text + str_html_head_close
    with open(os.path.join(root_path, name_html_file + ".html"), "w") as f:
        f.write(full_text)

def save_html_to_pdf(root_save_pdfs: str, root_html_url: str, name_html_file: str) -> None:
    os.system(
        CHROME_PATH
        + " --headless --print-to-pdf-no-header --print-to-pdf="
        + root_save_pdfs
        + name_html_file
        + ".pdf "
        + root_html_url
        + name_html_file
        + ".html"
    )

def save_pdf_to_png(lang_name, name_file, name_html_file, root_path: str = "Data/FLORES/"):
    # if entire pdf -> need to first split into pages
    root_save_pdfs = "Data/augmentation/pdfs/"
    os.makedirs(root_path + lang_name + "/png/" + name_file, exist_ok=True)
    path_png_out = root_path + lang_name + "/png/" + name_file + "/" + name_html_file
    path_pdf_in = root_save_pdfs + name_html_file + ".pdf"
    print("Saving pdf to png for " + lang_name)
    os.system("convert -density 300 -trim " + path_pdf_in + " -quality 100 " + path_png_out + "%02d.png")

def add_gaussian_noise(lang_name, name_file, name_html_file, root_path: str = "Data/FLORES/"):
    img = cv2.imread(root_path + lang_name + "/png/" + name_file + "/" + name_html_file + ".png")
    # Generate Gaussian noise
    gauss = np.random.normal(0, 1, img.size)
    gauss = gauss.reshape(img.shape[0], img.shape[1], img.shape[2]).astype("uint8")
    # Add the Gaussian noise to the image
    img_gauss = cv2.add(img, gauss)

    img_gauss = cv2.cvtColor(img_gauss, cv2.COLOR_BGR2GRAY)
    cv2.imwrite(
        root_path
        + lang_name
        + "/png/"
        + name_file
        + "/"
        + name_html_file
        + "_gauss"
        + ".png",
        img_gauss,
    )

def add_salt_pepper_noise(lang_name, name_file, name_html_file, amount, s_vs_p, root_path: str = "Data/FLORES/"):
    image = cv2.imread(
        root_path + lang_name + "/png/" + name_file + "/" + name_html_file + ".png"
    )
    img_noise = np.copy(image)
    # Salt mode
    num_salt = np.ceil(amount * image.size * s_vs_p)
    coords = [np.random.randint(0, i - 1, int(num_salt)) for i in image.shape]
    img_noise[coords] = 1

    # Pepper mode
    num_pepper = np.ceil(amount * image.size * (1. - s_vs_p))
    coords = [np.random.randint(0, i - 1, int(num_pepper)) for i in image.shape]
    img_noise[coords] = 0
    img_noise = cv2.cvtColor(img_noise, cv2.COLOR_BGR2GRAY)
    cv2.imwrite(
        root_path
        + lang_name
        + "/png/"
        + name_file
        + "/"
        + name_html_file
        + "_salt_pepper"
        + ".png",
        img_noise,
    )

def add_speckle_noise(lang_name, name_file, name_html_file, root_path: str = "Data/FLORES/"):
    img = cv2.imread(
        root_path + lang_name + "/png/" + name_file + "/" + name_html_file + ".png"
    )
    gauss = np.random.normal(0, 1, img.size)
    gauss = gauss.reshape(img.shape[0], img.shape[1], img.shape[2]).astype('uint8')
    img_noise = img + img * gauss
    img_noise = cv2.cvtColor(img_noise, cv2.COLOR_BGR2GRAY)

    cv2.imwrite(
        root_path
        + lang_name
        + "/png/"
        + name_file
        + "/"
        + name_html_file
        + "_gauss"
        + ".png",
        img_noise,
    )

def add_skew(lang_name, name_file, name_html_file, root_path: str = "Data/FLORES/"):
    img = cv2.imread(
        root_path + lang_name + "/png/" + name_file + "/" + name_html_file + ".png"
    )
    # Create Affine transform
    affine_tf = tf.AffineTransform(shear=0.1)
    # Apply transform to image data
    img_skew = tf.warp(img, inverse_map=affine_tf) * 255
    cv2.imwrite(
        root_path
        + lang_name
        + "/png/"
        + name_file
        + "/"
        + name_html_file
        + "_skew"
        + ".png",
        img_skew,
    )

def run_augmentation_udhr(lang_code):
    lang_name = lang_code_dict[lang_code]

    lang_codes, lang_fonts = read_fonts_file()
    index_lang_code = lang_codes.index(lang_code)

    fonts = lang_fonts[index_lang_code].split("; ")

    color = dict_properties["color"][0]
    opacity = dict_properties["opacity"][0]
    letter_spacing = dict_properties["letter_spacing"][0]
    italic = dict_properties["italic"][1]
    bold = dict_properties["bold"][1]

    font = fonts[0]
    root = os.path.join('Data/UDHR/', lang_name)
    root_path = os.path.join('Data/UDHR/annotations/', lang_code, "pdfs_synth")
    os.makedirs(root_path, exist_ok=True)
    txt_files = glob.glob(root + '/*[0-9].txt')
    name_style = font + "_" + color.replace("#", "") + "_" + opacity + "_" + letter_spacing
    if italic:
        name_style += "_" + "italic"
    if bold:
        name_style += "_" + "bold"

    for txt_file in txt_files:
        with open(txt_file, encoding="utf8") as file:
            list_sentences = file.read()
        name_file = txt_file.split("/")[-1][:-4]
        nb = str(re.findall(r'\d+', name_file)[0])
        name_html_file = f"{lang_code}_{nb}"
        create_html_file(root_path, list_sentences, name_html_file, name_style)

        root_save_pdfs = root_path
        root_html_url = root_path
        save_html_to_pdf(root_save_pdfs, root_html_url, name_html_file)
        print("Saving pdf to png for " + name_html_file)
        path_png_out = os.path.join(root_path, name_html_file + ".png")
        path_pdf_in = os.path.join(root_path, name_html_file + ".pdf")
        os.system("convert -density 300 -trim " + path_pdf_in + " -quality 100 " + path_png_out)

def run_augmentation(lang_code):
    lang_name = lang_code_dict[lang_code]
    root_lang_name = root_dir + lang_name + "/"

    lang_codes, lang_fonts = read_fonts_file()
    index_lang_code = lang_codes.index(lang_code)

    fonts = lang_fonts[index_lang_code].split("; ")

    color = dict_properties["color"][0]
    opacity = dict_properties["opacity"][0]
    letter_spacing = dict_properties["letter_spacing"][0]
    italic = dict_properties["italic"][1]
    bold = dict_properties["bold"][1]
    gauss = dict_properties["gauss"][1]
    skew = dict_properties["skew"][1]

    font = fonts[0]
    name_file = lang_code
    with open(os.path.join(root_lang_name, name_file + ".txt"), encoding="utf-8") as file:
        list_sentences = file.readlines()

    name_style = font + "_" + color.replace("#", "") + "_" + opacity + "_" + letter_spacing
    if italic:
        name_style += "_" + "italic"
    if bold:
        name_style += "_" + "bold"
    name_html_file = name_file + "_" + name_style

    root_path = "Data/augmentation/htmls"
    create_html_file(root_path, list_sentences, name_html_file, name_style)

    root_save_pdfs = "Data/augmentation/pdfs"
    root_html_url = f"file://{os.path.abspath('Data/augmentation/htmls')}"
    save_html_to_pdf(root_save_pdfs, root_html_url, name_html_file)
    save_pdf_to_png(lang_name, name_file, name_html_file)
    if gauss:
        add_salt_pepper_noise(lang_name, name_file, name_html_file, amount=0.005, s_vs_p=0.5)
    if skew:
        add_skew(lang_name, name_file, name_html_file)

def parse_args() -> argparse.Namespace:
    parser = argparse.ArgumentParser()
    parser.add_argument("--dataset", choices=["FLORES", "UDHR"], default="FLORES")
    return parser.parse_args()

def main() -> None:
    args = parse_args()

    for lang_code in lang_code_dict:
        if args.dataset == "FLORES":
            run_augmentation(lang_code)
        elif args.dataset == "UDHR":
            run_augmentation_udhr(lang_code)
        else:
            raise ValueError(f"Unknown dataset: {args.dataset}")

if __name__ == "__main__":
    main()


import logging
import sys
import os

LOG_CONFIG = {
    'name': 'event-tracker',
    'level': logging.DEBUG,
    'stream_handler': logging.StreamHandler(sys.stdout),
    'format': '%(asctime)s: %(module)s: %(levelname)s: %(message)s'
}

TWITTER_CONFIG = {
    'api_key': os.environ["TWITTER_API_KEY"],
    'api_secret': os.environ["TWITTER_API_KEY_SECRET"],
    'bearer_token': os.environ["TWITTER_BEARER_TOKEN"],
}

REDDIT_CONFIG = {
    'client_id': os.environ["REDDIT_CLIENT_ID"],
    'client_secret': os.environ["REDDIT_CLIENT_SECRET"],
    'user_agent': os.environ["REDDIT_USER_AGENT"]
}

TELEGRAM_CONFIG = {
    'bot_token': os.environ["TELEGRAM_BOT_TOKEN"]
}


from config import TG_KEY, GPT_KEY
from keybrds import kb
from redis_client import redis_client

import openai
from aiogram import Bot, Dispatcher, executor, types

openai.api_key = GPT_KEY

bot = Bot(token=TG_KEY)
dispatcher = Dispatcher(bot)

@dispatcher.message_handler(commands=["start"])
async def start_func(message: types.Message):
    print("Bot has started!")
    await message.reply(
        "Welcome to Chat_bot. This bot uses ChatGPT3!\n\nTo clear cache use command /del.",
        reply_markup=kb,
    )

@dispatcher.message_handler(commands=["del"])
async def clear_cache(message: types.Message):
    user_id = types.User.get_current().id
    redis_client.delete(user_id)
    redis_client.close()
    await message.reply("Cache was cleared!", reply_markup=kb)

@dispatcher.message_handler()
async def get_message(message: types.Message) -> None:
    user_id = types.User.get_current().id
    user_name = types.User.get_current().username

    print(user_id, "==", user_name)

    if redis_client.get(user_id):
        db_message = redis_client.get(user_id).decode()
    else:
        db_message = str(redis_client.set(user_id, ""))
    redis_client.close()

    chat_history = db_message + "\n\nHuman: " + message.text + "\n\nAI:"

    if len(chat_history) > 2000:
        chat_history = chat_history[-2000:]
    print("CHAT LENGTH: ", len(chat_history))

    try:
        response = openai.ChatCompletion.create(
            model="gpt-3.5-turbo",
            messages=[{"role": "user", "content": chat_history}],
            temperature=1.5,
        )
        answer = response["choices"][0]["message"]["content"]
        await message.reply(f"{answer}", parse_mode="html")
    except:
        await message.reply(
            "An error occured!\nTry again!\n\nПроизошла ошибка!\nПопробуйте еще раз!",
            parse_mode="html",
        )
        print("\n\n\n======EXCEPTION HANDELED!=======\n\n\n")
        answer = ""

    chat_history = chat_history + answer
    # print('CHAT_HISTORY: ',  chat_history)
    redis_client.set(user_id, chat_history.encode(), ex=1800)
    # print('RDB: ', redis_client.get(user_id).decode())

    redis_client.close()

if __name__ == "__main__":
    executor.start_polling(dispatcher, skip_updates=True)


# pylint: disable=W0621,C0114,C0116,W0212,W0613
import pathlib
import textwrap
import pytest
import numpy as np

from dae.genomic_resources.testing import build_inmemory_test_repository
from dae.genomic_resources.repository import GR_CONF_FILE_NAME, \
    GenomicResourceRepo
from dae.gene.gene_scores import build_gene_score_from_resource, \
    GeneScoreImplementation

@pytest.fixture
def scores_repo(tmp_path: pathlib.Path) -> GenomicResourceRepo:
    scores_repo = build_inmemory_test_repository({
        "LinearHist": {
            GR_CONF_FILE_NAME: """
                type: gene_score
                filename: linear.csv
                scores:
                - id: linear
                  desc: linear gene score
                  histogram:
                    type: number
                    number_of_bins: 3
                    x_log_scale: false
                    y_log_scale: false
                """,
            "linear.csv": textwrap.dedent("""
                gene,linear
                G1,1
                G2,2
                G3,3
                G4,1
                G5,2
                G6,3
            """),
            "statistics": {
                "histogram_linear.yaml": textwrap.dedent("""
                    bars:
                    - 2
                    - 2
                    - 2
                    bins:
                    - 1.0
                    - 1.665
                    - 2.333
                    - 3.0
                    config:
                      type: number
                      number_of_bins: 3
                      score: linear
                      view_range:
                        max: 3.0
                        min: 1.0
                      x_log_scale: false
                      y_log_scale: false
                """)
            }
        },
        "LogHist": {
            GR_CONF_FILE_NAME: """
                type: gene_score
                filename: log.csv
                scores:
                - id: log
                  desc: log gene score
                  histogram:
                    type: number
                    number_of_bins: 5
                    view_range:
                      min: 0.0
                      max: 1.0
                    x_min_log: 0.001
                    x_log_scale: true
                    y_log_scale: false
                """,
            "log.csv": textwrap.dedent("""
                gene,log
                G1,0
                G2,0.0001
                G3,0.001
                G4,0.01
                G5,0.1
                G6,1.0
            """),
            "statistics": {
                "histogram_log.yaml": textwrap.dedent("""
                    bars:
                    - 2
                    - 1
                    - 1
                    - 1
                    - 1
                    bins:
                    - 0.0,
                    - 0.001,
                    - 0.005623413251903491,
                    - 0.03162277660168379,
                    - 0.1778279410038923,
                    - 1.0
                    config:
                      type: number
                      number_of_bins: 5
                      view_range:
                        min: 0.0
                        max: 1.0
                      x_min_log: 0.001
                      x_log_scale: true
                      y_log_scale: false
                """)
            }
        },
        "NaNTest": {
            GR_CONF_FILE_NAME: """
                type: gene_score
                filename: scores.csv
                scores:
                - id: score1
                  desc: linear gene score
                  histogram:
                    type: number
                    number_of_bins: 3
                    x_log_scale: false
                    y_log_scale: false
                """,
            "scores.csv": textwrap.dedent("""
                gene,score1
                G1,1
                G2,2
                G3,nan
                G4,1
                G5,nan
                G6,3
            """),
            "statistics": {
                "histogram_linear.yaml": textwrap.dedent("""
                    bars:
                    - 2
                    - 2
                    - 2
                    bins:
                    - 1.0
                    - 1.665
                    - 2.333
                    - 3.0
                    config:
                      type: number
                      number_of_bins: 3
                      score: linear
                      view_range:
                        max: 3.0
                        min: 1.0
                      x_log_scale: false
                      y_log_scale: false
                """)
            }
        },
        "Oops": {
            GR_CONF_FILE_NAME: "",
        },
        "OopsHist": {
            GR_CONF_FILE_NAME: """
                type: gene_score
                filename: oops.csv
                scores:
                - id: linear
                  desc: linear gene score
                """,
            "oops.csv": textwrap.dedent("""
                gene,linear
                G1,1
                G2,2
                G3,3
            """)
        },
        "OopsScores": {
            GR_CONF_FILE_NAME: """
                type: gene_score
                filename: oops.csv
                """,
            "oops.csv": textwrap.dedent("""
                gene,linear
                G1,1
                G2,2
                G3,3
            """)
        },
    })
    return scores_repo

def test_load_linear_gene_scores_from_resource(
        scores_repo: GenomicResourceRepo) -> None:

    res = scores_repo.get_resource("LinearHist")
    assert res.get_type() == "gene_score"

    result = build_gene_score_from_resource(res)
    scores = result.get_scores()
    assert len(scores) == 1
    score_id = scores[0]

    assert result.get_x_scale(score_id) == "linear"
    assert result.get_y_scale(score_id) == "linear"

    hist = result.get_histogram(score_id)
    assert hist is not None
    assert len(hist.bins) == 4

    assert np.all(hist.bars == np.array([2, 2, 2]))

def test_load_log_gene_scores_from_resource(
        scores_repo: GenomicResourceRepo) -> None:

    res = scores_repo.get_resource("LogHist")
    assert res.get_type() == "gene_score"

    result = build_gene_score_from_resource(res)
    scores = result.get_scores()
    assert len(scores) == 1
    score_id = scores[0]

    assert result.get_x_scale(score_id) == "log"
    assert result.get_y_scale(score_id) == "linear"

    hist = result.get_histogram(score_id)
    assert hist is not None
    assert len(hist.bins) == 6

    assert np.all(hist.bars == np.array([2, 1, 1, 1, 1]))

def test_load_wrong_resource_type(
        scores_repo: GenomicResourceRepo) -> None:
    res = scores_repo.get_resource("Oops")
    with pytest.raises(ValueError, match="invalid resource type Oops"):
        build_gene_score_from_resource(res)

def test_load_gene_score_without_histogram(
        scores_repo: GenomicResourceRepo) -> None:
    res = scores_repo.get_resource("OopsHist")
    with pytest.raises(
        ValueError,
        match="Missing histogram config for linear in OopsHist"
    ):
        build_gene_score_from_resource(res)

def test_load_gene_score_without_gene_scores(
        scores_repo: GenomicResourceRepo) -> None:
    res = scores_repo.get_resource("OopsScores")
    with pytest.raises(ValueError,
                       match="missing scores config in OopsScores"):
        build_gene_score_from_resource(res)

def test_gene_score(scores_repo: GenomicResourceRepo) -> None:

    res = scores_repo.get_resource("LinearHist")
    gene_score = build_gene_score_from_resource(res)

    assert gene_score is not None

    assert gene_score.get_gene_value("linear", "G2") == 2
    assert gene_score.get_gene_value("linear", "G3") == 3

def test_gene_score_nan(scores_repo: GenomicResourceRepo) -> None:
    res = scores_repo.get_resource("NaNTest")
    gene_score = build_gene_score_from_resource(res)

    assert len(gene_score.df) == 6
    df = gene_score.get_score_df("score1")
    assert len(df) == 4

def test_calculate_histogram(scores_repo: GenomicResourceRepo) -> None:
    res = scores_repo.get_resource("LinearHist")
    result = build_gene_score_from_resource(res)
    assert result is not None

    histogram = GeneScoreImplementation._calc_histogram(res, "linear")
    assert histogram is not None
    print(histogram.config.view_range[0])
    print(type(histogram.config.view_range[0]))
    print(histogram.serialize())


import os
import torch
import argparse
import numpy as np
import PIL.Image as Image
from matplotlib import pyplot as plt
from torch.utils.data import DataLoader
from torch import nn, optim, autograd
from torchvision.transforms import transforms
from dataset import Train_Dataset, Validation_Dataset, Test_Dataset, Single_Train_Dataset
import skimage.io as io
import shutil
import stable_seed

stable_seed.setup_seed()

threshold = 0.5  # 二分类阈值
# 是否使用cuda
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")

x_transforms = transforms.Compose([
    transforms.ToTensor(),
    transforms.Normalize([0.5], [0.5])
])

# mask只需要转换为tensor
y_transforms = transforms.ToTensor()

l2_regularizer_weight = 0.001
lr = 0.001
penalty_anneal_iters = 300
penalty_weight = 0.01

def makedir(new_path):
    folder = os.path.exists(new_path)
    if not folder:
        os.makedirs(new_path)
    else:
        shutil.rmtree(new_path)
        os.makedirs(new_path)

def init_work_space(args):
    makedir('./' + args.project_name + '/results')
    makedir(args.ckpt)
    makedir('./' + args.project_name + '/runs')

def train_model(args, writer, model, criterion, optimizer, dataload, regular=''):
    save_epoch, best_val_acc, best_val_mIoU = 0, -0.1, -0.1
    for epoch in range(args.epoch):
        print('Epoch {}/{}'.format(epoch, args.epoch - 1))
        print('-' * 10)
        epoch_loss = 0
        epoch_correct_pixels, epoch_total_pixels = [], []
        step = 0
        for x, y in dataload:
            step += 1
            inputs = x.to(device)
            labels = y.to(device)
            # zero the parameter gradients
            optimizer.zero_grad()

            # forward
            outputs = model(inputs).to(device)
            del inputs
            loss = criterion(outputs, labels)
            loss.backward()
            optimizer.step()

            # calculate accuracy
            predicted = outputs.detach().cpu().numpy()
            predicted[predicted >= threshold] = 1
            predicted[predicted < threshold] = 0
            correct = (predicted == labels.detach().cpu().numpy()).sum()
            del predicted
            pixel_num = 1.0
            for i in range(len(labels.size())):
                pixel_num *= labels.size()[i]

            epoch_correct_pixels.append(correct)
            epoch_total_pixels.append(pixel_num)
            epoch_loss += float(loss.item())
            del labels
            del loss
        val_accuracy, val_mIoU = validation(args, model, method='train')
        epoch_loss = epoch_loss / step
        epoch_train_accuracy = np.mean(epoch_correct_pixels) / np.mean(epoch_total_pixels)
        print(
            "epoch %d loss:%0.3f train accuracy:%0.3f val accuracy:%0.3f val mIoU:%0.3f best_val_acc:%0.4f best_mIoU:%0.4f" % (
                epoch, epoch_loss, epoch_train_accuracy, val_accuracy, val_mIoU, best_val_acc, best_val_mIoU))
        writer.add_scalar('loss', epoch_loss / step, global_step=epoch)
        writer.add_scalar('train accuracy', epoch_train_accuracy, global_step=epoch)
        writer.add_scalar('validated accuracy', val_accuracy, global_step=epoch)
        writer.add_scalars('accuracy/group',
                           {'train_accuracy': epoch_train_accuracy, 'validated accuracy': val_accuracy},
                           global_step=epoch)
        if best_val_acc < val_accuracy:
            # save_epoch = epoch
            # torch.save(model, args.ckpt + '/' + args.model + '.pth')
            best_val_acc = val_accuracy
        if best_val_mIoU < val_mIoU:
            save_epoch = epoch
            torch.save(model, args.ckpt + '/' + args.model + '.pth')
            best_val_mIoU = val_mIoU
    print("Model:", args.model)
    print("Dataset:", args.data_file)
    print("Best epoch is" + str(save_epoch))
    print("Best val acc is " + str(best_val_acc))
    print("Best val mIoU is " + str(best_val_mIoU))
    torch.cuda.empty_cache()
    return model

def mean_accuracy(outputs, labels):
    predicted = outputs.detach().cpu().numpy()
    predicted[predicted >= threshold] = 1
    predicted[predicted < threshold] = 0
    correct = (predicted == labels.detach().cpu().numpy()).sum()

    pixel_num = 1.0
    for i in range(len(labels.size())):
        pixel_num *= labels.size()[i]
    epoch_train_accuracy = np.mean(correct) / np.mean(pixel_num)
    return epoch_train_accuracy
    # debug code
    # a = torch.rand([10, 1, 20, 20])
    # b = torch.randint(low=0, high=2, size=(10, 1, 20, 20))
    # print(mean_accuracy(a, b)) # =0.5

def meanIoU(imgPredict, imgLabel, numClass=2):
    # ref:https://blog.csdn.net/sinat_29047129/article/details/103642140
    imgLabel = imgLabel.cpu()
    imgPredict[imgPredict >= threshold] = 1
    imgPredict[imgPredict < threshold] = 0

    def genConfusionMatrix(numClass, imgPredict, imgLabel):
        # remove classes from unlabeled pixels in gt image and predict
        mask = (imgLabel >= 0) & (imgLabel < numClass)
        label = numClass * imgLabel[mask] + imgPredict[mask]
        count = np.bincount(label, minlength=numClass ** 2)  # 核心代码
        confusionMatrix = count.reshape(numClass, numClass)
        return confusionMatrix

    confusionMatrix = genConfusionMatrix(numClass, imgPredict, imgLabel)
    # Intersection = TP Union = TP + FP + FN
    # IoU = TP / (TP + FP + FN)
    intersection = np.diag(confusionMatrix)  # 取对角元素的值，返回列表
    union = np.sum(confusionMatrix, axis=1) + np.sum(confusionMatrix, axis=0) - np.diag(
        confusionMatrix)  # axis = 1表示混淆矩阵行的值，返回列表； axis = 0表示取混淆矩阵列的值，返回列表
    IoU = intersection / union  # 返回列表，其值为各个类别的IoU
    mIoU = np.nanmean(IoU)  # 求各类别IoU的平均
    return mIoU

def penalty(logits, y, criterion=nn.BCELoss()):
    # torch.nan_to_num(mid, nan=1e-8, posinf=1.0 - 1e-8)
    scale = torch.tensor(1.).requires_grad_()
    loss = criterion(logits * scale, y)
    grad = autograd.grad(loss, [scale], create_graph=True)[
        0]  # reference https://blog.csdn.net/qq_36556893/article/details/91982925
    return torch.sum(grad ** 2)

def train_IRM_model(args, writer, model, criterion, optimizer, env_dataloaders, regular=''):
    # def penalty(logits, y):
    #     scale = torch.tensor(1.).to(device).requires_grad_()
    #     loss = criterion(logits * scale, y)
    #     grad = autograd.grad(loss, [scale], create_graph=True)[
    #         0]  # reference https://blog.csdn.net/qq_36556893/article/details/91982925
    #     return torch.sum(grad ** 2)
    global l2_regularizer_weight
    global lr
    global penalty_anneal_iters
    global penalty_weight
    save_epoch, best_val_acc = 0, -0.1
    for epoch in range(args.epoch):
        print('Epoch {}/{}'.format(epoch, args.epoch - 1))
        print('-' * 10)
        optimizer.zero_grad()
        envs = []
        for env_dataloader in env_dataloaders:
            env = {'nll': [], 'acc': [], 'penalty': []}
            for x, y in env_dataloader:
                inputs = x  # .half()
                labels = y  # .half()
                outputs = model(inputs.to(device)).cpu()
                torch.nan_to_num(outputs, nan=1e-8, posinf=1.0 - 1e-8)
                torch.nan_to_num(labels, nan=1e-8, posinf=1.0 - 1e-8)
                env['nll'].append(criterion(outputs, labels))
                env['acc'].append(mean_accuracy(outputs, labels))
                env['penalty'].append(penalty(outputs, labels))
                del inputs, labels, outputs
                torch.cuda.empty_cache()
            envs.append(env)
        mid_train_nll, mid_train_acc, mid_train_penalty = [], [], []
        for i_env in range(len(env_dataloaders) - 1):
            mid_train_nll.extend(envs[i_env]['nll'])
            mid_train_acc.extend(envs[i_env]['acc'])
            mid_train_penalty.extend(envs[i_env]['penalty'])
        print('mid_train_penalty', mid_train_penalty)
        train_nll = torch.stack(mid_train_nll).mean()
        train_acc = float(np.mean(mid_train_acc))
        train_penalty = torch.stack(mid_train_penalty).mean()

        weight_norm = torch.tensor(0.).to(device)
        for w in model.parameters():
            weight_norm += w.norm().pow(2)

        loss = train_nll.clone().to(device)
        loss += l2_regularizer_weight * weight_norm
        # penalty_weight = (penalty_weight if epoch >= penalty_anneal_iters else 1.0)
        # loss += penalty_weight * train_penalty
        if penalty_weight > 1.0:
            # Rescale the entire loss to keep gradients in a reasonable range
            loss /= penalty_weight

        loss.backward()
        optimizer.step()

        val_accuracy, val_mIoU = validation(args, model, method='train')
        print("epoch %d loss:%0.3f train accuracy:%0.3f val accuracy:%0.3f train_penalty:%0.4f  best_val_acc:%0.4f" % (
            epoch, float(loss.item()), train_acc, val_accuracy, penalty_weight * train_penalty, best_val_acc))
        writer.add_scalar('loss', train_nll, global_step=epoch)
        writer.add_scalar('train accuracy', train_acc, global_step=epoch)
        writer.add_scalar('validated accuracy', val_accuracy, global_step=epoch)
        writer.add_scalars('accuracy/group',
                           {'train_accuracy': train_acc, 'validated accuracy': val_accuracy},
                           global_step=epoch)
        if best_val_acc < val_accuracy:
            save_epoch = epoch
            torch.save(model, args.ckpt + '/' + args.model + '.pth')
            best_val_acc = val_accuracy
    print("Model:", args.model)
    print("Dataset:", args.data_file)
    print("Best epoch is" + str(save_epoch))
    print("Best val acc is " + str(best_val_acc))
    torch.cuda.empty_cache()
    return model

# 训练模型
def train(args, writer, model, regular=''):
    # args == IRM
    # generate 4 single_train datasets as envs
    # define new loss function
    # model.half()
    if args.loss == "IRM":
        model.to(device)
        criterion = nn.BCEWithLogitsLoss()  # nn.BCELoss()
        optimizer = optim.Adam(model.parameters(), )
        env_dataloaders = []
        for i in range(args.total_folds):
            if i == args.k_fold:
                continue
            mid_env_dataset = Single_Train_Dataset(args.data_file, args, transform=x_transforms,
                                                   target_transform=y_transforms, k_single_set=i)
            mid_env_dataloader = DataLoader(mid_env_dataset, batch_size=args.batch_size, shuffle=True, num_workers=1)
            print('mid_env_dataloader', len(mid_env_dataloader))
            env_dataloaders.append(mid_env_dataloader)
        train_IRM_model(args, writer, model, criterion, optimizer, env_dataloaders, regular)
    else:
        model.to(device)
        criterion = nn.BCELoss()
        optimizer = optim.Adam(model.parameters(), )
        liver_dataset = Train_Dataset(args.data_file, args, transform=x_transforms, target_transform=y_transforms)
        dataloaders = DataLoader(liver_dataset, batch_size=args.batch_size, shuffle=True, num_workers=1)
        train_model(args, writer, model, criterion, optimizer, dataloaders, regular)

# 用于测试模型在有image有label的数据中的表现
def validation(args, model, print_each=False, method='train'):
    liver_dataset = Validation_Dataset(args.data_file, args, transform=x_transforms, target_transform=y_transforms)  #
    dataloaders = DataLoader(liver_dataset, batch_size=1)
    if method == 'train':
        dataloaders = DataLoader(liver_dataset, batch_size=8)
    model.eval()
    epoch_correct_pixels, epoch_total_pixels, epoch_acc, epoch_mIoU = [], [], [], []
    with torch.no_grad():
        for x, y, x_path in dataloaders:
            inputs = x.to(device)
            labels = y.to(device)
            predicted = model(inputs).detach().cpu().numpy()
            predicted[predicted >= threshold] = 1
            predicted[predicted < threshold] = 0
            correct = (predicted == labels.detach().cpu().numpy()).sum()
            pixel_num = 1.0
            for i in range(len(labels.size())):
                pixel_num *= labels.size()[i]
            epoch_correct_pixels.append(correct)
            epoch_total_pixels.append(pixel_num)
            epoch_mIoU.append(meanIoU(predicted, labels))
            if print_each:
                print(x_path, 'acc', correct / pixel_num)
                mid_x_path = x_path
                epoch_acc.append(correct / pixel_num)
        if print_each:
            print('\nepoch_acc', epoch_acc, '\nepoch_mIoU', epoch_mIoU)
    return np.mean(epoch_correct_pixels) / np.mean(epoch_total_pixels), np.mean(epoch_mIoU)

# 用于测试只有image但没有label的数据
def test(args, save_gray=False, manual=False, weight_path=''):
    model = None
    if not manual:
        model = torch.load(args.ckpt + '/' + args.model + '.pth', map_location='cpu')
    if manual:
        model = torch.load(weight_path, map_location='cpu')  # use certain model weight.

    liver_dataset = Test_Dataset(args.data_file, transform=x_transforms, target_transform=y_transforms)
    dataloaders = DataLoader(liver_dataset, batch_size=1)

    model.eval()
    with torch.no_grad():
        for x, pic_name_i in dataloaders:
            pic_name_i = pic_name_i[0]
            mid_x = torch.squeeze(x).numpy()
            if len(mid_x.shape) == 2:
                io.imsave(args.project_name + "/results/" + pic_name_i.split('.')[0] + "_x.png", mid_x)
            elif len(mid_x.shape) == 3:
                mid_x_image = np.array(mid_x[0])
                # io.imsave(args.project_name + "/results/" + pic_name_i.split('.')[0] + "_x.png", mid_x)
            predict = model(x)
            predict = torch.squeeze(predict).detach().numpy()
            if save_gray:
                io.imsave(args.project_name + "/results/" + pic_name_i.split('.')[0] + "_gray_pre.png", predict)

            predict[predict >= threshold] = 1
            predict[predict < threshold] = 0
            io.imsave(args.project_name + "/results/" + pic_name_i.split('.')[0] + "_label_pre.png", predict)

class SaveOutput:
    def __init__(self):
        self.outputs = []

    def __call__(self, module, module_in, module_out):
        self.outputs.append(module_out)

    def clear(self):
        self.outputs = []

def model_forward_visualization(image_path, weight_path, model_name=''):
    """输入一张测试图像和训练好的模型权重，可视化每一步卷积的结果"""
    model = torch.load(weight_path, map_location='cpu')  # load trained model

    save_output = SaveOutput()  # register hooks for each layer
    hook_handles, k1, k2 = [], 0, 0
    for layer in model.modules():
        k1 += 1
        if isinstance(layer, torch.nn.modules.conv.Conv2d):
            k2 += 1
            handle = layer.register_forward_hook(save_output)
            hook_handles.append(handle)

    x = x_transforms(Image.open(image_path).convert('L').resize(size=(512, 512))).unsqueeze(0)
    print(x, x.dtype)
    y = model(x)

    def module_output_to_numpy(tensor):
        return tensor.detach().to('cpu').numpy()

    for layer_idx in range(len(save_output.outputs)):
        images = module_output_to_numpy(save_output.outputs[layer_idx])
        # 这里的0代表读取output里第一个卷积层的输出

        print(type(images))
        print(images.shape)
        mid_1 = images.shape[1]
        mid_idx = 0
        while mid_idx < mid_1:
            # mid_idx is the index of feature
            with plt.style.context("seaborn-white"):
                plt.figure(frameon=False)
            for idx in range(64):
                # idx is the index of subplot
                if mid_idx == mid_1:
                    break
                plt.subplot(8, 8, idx + 1)
                plt.imshow(images[0, mid_idx])
                mid_idx += 1
            plt.setp(plt.gcf().get_axes(), xticks=[], yticks=[])
            plt.savefig(
                './model_visualization/' + model_name + '/layer_' + str(layer_idx) + '_mid_' + str(mid_idx) + '.png')
            plt.cla()
            plt.close('all')

def model_print(model):
    total_num = sum(p.numel() for p in model.parameters())
    trainable_num = sum(p.numel() for p in model.parameters() if p.requires_grad)
    return {'Total': total_num, 'Trainable': trainable_num}


import re
import os

def readFile():
    path = os.path.join(os.path.expanduser('~'), 'listaSadow', 'listaSadow.txt')
    with open(path,"r") as file:
        for line in file.readlines():
            yield line

def writeMongoCommand(listaCommand):
    path = os.path.join(os.path.expanduser('~'), 'listaSadow', 'dbPopulate.txt')
    with open(path,"w") as file:
        for i in listaCommand:
            file.write(i)
            file.write("\n")

court_name = "TT"
s = "Sąd Rejonowy w Wysokiem Mazowieckiem dla miasta Skarżysko-Kamienna oraz gmin: Bliżyn, Łączna, Skarżysko Kościelne i Suchedniów"

def takeBiggerIndex(index, list_of_indexes):
    for item in list_of_indexes:
        if index < item:
            return item
    return None

def takeString(s,start,stop):
    if stop:
        return s[start:stop]
    else:
        return s[start:]

def getCourtName(s:str):
    index_for = s.find("dla")
    court_name = takeString(s, 0,index_for)
    return court_name

def separate(s:str):
    index_city = s.find("miasta")
    index_region = s.find("gmina")
    index_city_part = s.find("dzielnic")
    indexes = [index_city,index_region,index_city_part]
    city = takeString(s,index_city,takeBiggerIndex(index_city,indexes))
    region = takeString(s,index_region,takeBiggerIndex(index_region,indexes))
    city_parts = takeString(s,index_city_part,takeBiggerIndex(index_city_part,indexes))
    # for item in twoString:
    #     if item.find("miast")>0:
    #         city=item
    #     elif item.find("dzielnic")>0:
    #         region = item
    #     else:
    #         dzielnic = item
    #     print(dzielnica)
    return {"city":city,"region":region, "city_parts": city_parts}

def generateListOfResults(s:str):
    strings= separate(s)
    citys = regexCreateArray(strings["city"])
    regions = regexCreateArray(strings["region"])
    city_parts = regexCreateArray(strings["city_parts"])
    return {"citys":citys,"regions":regions, "city_parts":city_parts}

def regexCreateArray(s):
    return re.findall(r"\b[A-ZŚĆĘŻŹ]\w+",s)

def createMongoCommand(s):
    name = getCourtName(s)
    generatedResults=generateListOfResults(s)
    citys = generatedResults["citys"]
    regions = generatedResults["regions"]
    city_parts = generatedResults["city_parts"]
    template = 'db.courtCollection.insert({{name:"{}", level:"rejonowy", coverCitys:{} coverRegions:{}, coverCityParts:{}}})'.format(name,citys,regions,city_parts)
    return template

def createObjToInsert(s):
    name = getCourtName(s)[0:-1]
    generatedResults=generateListOfResults(s)
    citys = generatedResults["citys"]
    regions = generatedResults["regions"]
    city_parts = generatedResults["city_parts"]
    obj = {"name":name, "level":"rejonowy", "coverCitys":citys, "coverRegions":regions, "coverCityParts":city_parts}
    return obj

# createMongoCommand(s)

# separate(s)

# readFile()
from random import randint
from pymongo import MongoClient

client = MongoClient("192.168.1.143", 27017)

db = client.dbs
def createInputToMongoDb():
    arrayWithCommands = []
    for line in readFile():
        comand = createMongoCommand(line)
        arrayWithCommands.append(comand)
        obj=createObjToInsert(line)
        print(obj)
        db.courtCollection.insert_one(obj)
    writeMongoCommand(arrayWithCommands)
    pass

# createInputToMongoDb()
# print(createObjToInsert(s))

def createCourtCollection():
    for i,line in enumerate(readFile()):
        # print(line)
        index = line.find(";")
        court_name = line[:index-1]
        wlasciwosc = line[index+5:]
        print(court_name)
        print(wlasciwosc)
        db.court.update_one({"name":court_name},{"$set":{"coverArea":wlasciwosc}})

        # if(i>10):
        #     return "koniec"
    pass

createCourtCollection()


import numpy as np
import _pickle as pickle
import copy

from collections import OrderedDict
from ConstantVariables import *
from pathlib import Path

class Network:
    def __init__(self, name='', inputs=0, outputs=0):
        self.name = name
        self.inputs = inputs
        self.outputs = outputs
        self.layers_info = []
        self.layers = {}
        self.connections = OrderedDict()
        self.input_data_set = []
        self.output_data_set = []

    def add_layer(self, amount):
        self.layers_info.append(amount)

    def add_data_set(self, input_data_set, output_data_set):
        if len(input_data_set) == len(output_data_set):
            self.input_data_set = input_data_set
            self.output_data_set = output_data_set

    def connect(self):
        self.layers['input'] = 0

        current_layer = self.inputs
        current_layer_name = 'input'
        for index, value in enumerate(self.layers_info):
            self.layers['hidden_' + str(index)] = 0
            self.connections[current_layer_name +'_to_' + 'hidden_' + str(index)] = 2 * np.random.random((current_layer, value)) - 1
            current_layer = value
            current_layer_name = 'hidden_' + str(index)

        self.layers['output'] = 0
        self.connections[current_layer_name +'_to_output'] = 2 * np.random.random((current_layer, self.outputs)) - 1

    def activate(self, input_data):
        self.layers['input'] = input_data
        current_layer_name = 'input'
        for index, value in enumerate(self.layers_info):
            connections = self.connections[current_layer_name +'_to_' + 'hidden_' + str(index)]

            self.layers['hidden_' + str(index)] = self.sigmoid(np.dot(self.layers[current_layer_name], connections))

            current_layer_name = 'hidden_' + str(index)

        connections = self.connections[current_layer_name + '_to_output']
        self.layers['output'] = self.sigmoid(np.dot(self.layers[current_layer_name], connections))

    def learn(self, learning_rate=0.1):
        self.activate(self.input_data_set)

        l2_error = self.output_data_set - self.layers['output']
        print("Error:" + str(np.mean(np.abs(l2_error))))

        error = l2_error
        delta = None
        for name in reversed(self.connections):
            start, end = name.split('_to_')

            self.connections[name], delta = self.get_weight(
                self.connections[name],
                self.layers[start],
                self.layers[end],
                error,
                learning_rate
            )

            error = delta.dot(self.connections[name].T)

    def get_weight(self, connections_layer, start_layer, end_layer, error, learning_rate):
        delta = error * self.sigmoid(end_layer, deriv=True)

        connections_layer += start_layer.T.dot(delta) * learning_rate

        return connections_layer, delta

    def print_output(self, converted=False):
        output = self.get_output(convert=converted)
        if converted:
            if output.shape == (4,):
                if output[0]:
                    print('up')
                if output[1]:
                    print('right')
                if output[2]:
                    print('down')
                if output[3]:
                    print('left')
            else:
                for result in output:
                    print(result)
                    if result[0]:
                        print('up')
                    if result[1]:
                        print('right')
                    if result[2]:
                        print('down')
                    if result[3]:
                        print('left')
                    print('---------')
        else:
            print(self.layers['output'])

    def convert_output(self):
        if len(self.layers['output'].shape) > 1:
            for (x, y), result in np.ndenumerate(self.layers['output']):
                if result > 0.6:
                    self.layers['output'][x][y] = 1
                else:
                    self.layers['output'][x][y] = 0
        else:
            for x, result in np.ndenumerate(self.layers['output']):
                if result > 0.6:
                    self.layers['output'][x] = 1
                else:
                    self.layers['output'][x] = 0

    def get_output(self, convert=False):
        if convert:
            self.convert_output()
        return self.layers['output']

    def sigmoid(self, x, deriv=False):
        if deriv:
            return x * (1 - x)
        return 1 / (1 + np.exp(-x))

    def save(self):
        with open(networks_directory_save + 'Network_' + self.name + '.dump', 'wb') as output:
            pickle.dump(copy.copy(self), output, -1)

    def load(self):
        file = Path(networks_directory_save + 'Network_' + self.name + '.dump')
        if file.exists():
            with open(networks_directory_save + 'Network_' + self.name + '.dump', 'rb') as input:
                network = pickle.load(input)
                return network
        else:
            with open(networks_directory_save + 'Network_1.dump', 'rb') as input:
                network = pickle.load(input)
                network.name = self.name
                # network.save()
                return network


from django.contrib.auth.decorators import login_required
from django.contrib.auth.views import LoginView
from django.shortcuts import get_object_or_404
from rest_framework.authentication import BasicAuthentication, SessionAuthentication
from rest_framework.decorators import api_view, permission_classes, authentication_classes
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
from django.views import View
from .models import *
from django.contrib.auth.models import User
from .serializers import *
from rest_framework.permissions import IsAuthenticatedOrReadOnly, IsAuthenticated
from django_filters.rest_framework import DjangoFilterBackend

@api_view(['GET', 'POST'])
def genre_list(request):
    if request.method == 'GET':
        genres = Genre.objects.all()
        serializer = GenreSerializer(genres, many=True)
        return Response(serializer.data)

    elif request.method == 'POST':
        serializer = GenreSerializer(data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

@api_view(['GET', 'PUT', 'DELETE'])
def genre_detail(request, pk):
    try:
        genre = Genre.objects.get(pk=pk)
    except Genre.DoesNotExist:
        return Response(status=status.HTTP_404_NOT_FOUND)

    if request.method == 'GET':
        serializer = GenreSerializer(genre)
        return Response(serializer.data)

    elif request.method == 'PUT':
        serializer = GenreSerializer(genre, data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

    elif request.method == 'DELETE':
        genre.delete()
        return Response(status=status.HTTP_204_NO_CONTENT)

@api_view(['GET', 'POST'])
def movie_list(request):
    if request.method == 'GET':

        movie = Movie.objects.all()
        serializer = MovieSerializer(movie, many=True)
        return Response(serializer.data)
    elif request.method == 'POST':
        serializer = MovieSerializer(data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

@api_view(['GET', 'PUT', 'DELETE'])
def movie_detail(request, pk):
    try:
        movie = Movie.objects.get(pk=pk)
    except Movie.DoesNotExist:
        return Response(status=status.HTTP_404_NOT_FOUND)

    if request.method == 'GET':
        serializer = MovieSerializer(movie)
        return Response(serializer.data)

    elif request.method == 'PUT':
        serializer = MovieSerializer(movie, data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

    elif request.method == 'DELETE':
        movie.delete()
        return Response(status=status.HTTP_204_NO_CONTENT)

@api_view(['GET', 'POST'])
def raitingStar_list(request):
    """
    List all code snippets, or create a new snippet.
    """
    if request.method == 'GET':
        star = RaitingStar.objects.all()
        serializer = RaitingStarSerializer(star, many=True)
        return Response(serializer.data)

    elif request.method == 'POST':
        serializer = RaitingStarSerializer(data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

@api_view(['GET', 'PUT', 'DELETE'])
def raitingStar_detail(request, pk):
    try:
        star = RaitingStar.objects.get(pk=pk)
    except RaitingStar.DoesNotExist:
        return Response(status=status.HTTP_404_NOT_FOUND)

    if request.method == 'GET':
        serializer = RaitingStarSerializer(star)
        return Response(serializer.data)

    elif request.method == 'PUT':
        serializer = RaitingStarSerializer(star, data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

    elif request.method == 'DELETE':
        star.delete()
        return Response(status=status.HTTP_204_NO_CONTENT)

@api_view(['GET', 'POST'])
def reviews_list(request):
    if request.method == 'GET':
        reviews = Reviews.objects.all()
        serializer = ReviewsSerializer(reviews, many=True)
        return Response(serializer.data)

    elif request.method == 'POST':
        serializer = ReviewsSerializer(data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

@api_view(['POST'])
def aut(request):
    try:
        user = User.objects.get(username=request.data['username'])
        if (user.password == request.data['password']):
            return Response(status=status.HTTP_200_OK)
        else:
            return Response(request.data['password'], status=status.HTTP_404_NOT_FOUND)
    except User.DoesNotExist:
        return Response(status=status.HTTP_404_NOT_FOUND)

@api_view(['GET', 'PUT', 'DELETE'])
def reviews_detail(request, pk):
    try:
        reviews = Reviews.objects.get(pk=pk)
    except Reviews.DoesNotExist:
        return Response(status=status.HTTP_404_NOT_FOUND)

    if request.method == 'GET':
        serializer = ReviewsSerializer(reviews)
        return Response(serializer.data)

    elif request.method == 'PUT':
        serializer = ReviewsSerializer(reviews, data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

    elif request.method == 'DELETE':
        reviews.delete()
        return Response(status=status.HTTP_204_NO_CONTENT)

@api_view(['GET', 'POST'])
def raiting_list(request):
    if request.method == 'GET':
        raiting = Raiting.objects.all()
        serializer = RaitingSerializer(raiting, many=True)
        return Response(serializer.data)

    elif request.method == 'POST':
        serializer = RaitingSerializer(data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

@api_view(['GET', 'PUT', 'DELETE'])
def raiting_detail(request, pk):
    try:
        raiting = Raiting.objects.get(pk=pk)
    except Raiting.DoesNotExist:
        return Response(status=status.HTTP_404_NOT_FOUND)

    if request.method == 'GET':
        serializer = RaitingSerializer(raiting)
        return Response(serializer.data)

    elif request.method == 'PUT':
        serializer = RaitingSerializer(raiting, data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

    elif request.method == 'DELETE':
        raiting.delete()
        return Response(status=status.HTTP_204_NO_CONTENT)


from typing import List

class UserCard():
    gCardIds = []

    def __init__(self, tPackage: tuple=()) -> None:
        """
        Parameters
        ----------
        tPackage : tuple
            (id, userId, cardCode, level, bond, userTags, moves, skills)
        + id : str
        + userId : str
        + code : str
        + level : int
        + bond : int
        + userTags : iterable
        + moves : iterable
        + skills : iterable
        """

        self.mId = ''
        self.mUserId = ''
        self.mCode = ''

        self.mLevel = 0
        self.mExp = 0
        self.mBond = 0
        self._mUserTags = []

        self.mMoves = {}
        self.mSkills = []

        if tPackage:
            self.mId, self.mUserId, self.mCode, self.mLevel, self.mBond, tUserTags, self.mMoves, self.mSkills = tPackage
            # _mUserTags
            for userTag in tUserTags:
                self.AddUserTag(userTag)
            return

    def GetUserTags(self) -> List[str]:
        return self._mUserTags

    def SetUserTags(self, tUserTags: list) -> None:
        self._mUserTags = tUserTags

    def AddUserTag(self, tUserTag: str) -> None:
        """
        Add user's tag. If dupes is found, return False.
        """
        if tUserTag in self._mUserTags: return False
        self._mUserTags.append(tUserTag)

    @property
    def mId(self):
        return self.mId

    @mId.setter
    def mId(self, tCardId):
        if int(tCardId) == -1:  # Find best fit in the ID list
            i = 0
            while True:
                if int(tCardId) not in UserCard.gCardIds:
                    tCardId = str(i)
                    break
                i += 1
        UserCard.gCardIds.append(tCardId)

        return tCardId


# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
#         http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.

"""
Utility methods for serializing responses
"""

import datetime

from oslo_config import cfg
from oslo_log import log as logging
from oslo_serialization import jsonutils
from oslo_utils import encodeutils
import webob

from senlin.common import exception
from senlin.common.i18n import _

LOG = logging.getLogger(__name__)

def is_json_content_type(request):

    content_type = request.content_type
    if not content_type or content_type.startswith('text/plain'):
        content_type = 'application/json'

    if (content_type in ('JSON', 'application/json') and
            request.body.startswith(b'{')):
        return True
    return False

class JSONRequestDeserializer(object):

    def has_body(self, request):
        """Return whether a Webob.Request object will possess an entity body.

        :param request: A Webob.Request object
        """
        if request is None or request.content_length is None:
            return False

        if request.content_length > 0 and is_json_content_type(request):
            return True

        return False

    def from_json(self, datastring):
        try:
            if len(datastring) > cfg.CONF.senlin_api.max_json_body_size:
                msg = _('JSON body size (%(len)s bytes) exceeds maximum '
                        'allowed size (%(limit)s bytes).'
                        ) % {'len': len(datastring),
                             'limit': cfg.CONF.senlin_api.max_json_body_size}
                raise exception.RequestLimitExceeded(message=msg)
            return jsonutils.loads(datastring)
        except ValueError as ex:
            raise webob.exc.HTTPBadRequest(str(ex))

    def default(self, request):
        if self.has_body(request):
            return {'body': self.from_json(request.body)}
        else:
            return {}

class JSONResponseSerializer(object):

    def to_json(self, data):
        def sanitizer(obj):
            if isinstance(obj, datetime.datetime):
                return obj.isoformat()
            return str(obj)

        response = jsonutils.dumps(data, default=sanitizer, sort_keys=True)
        LOG.debug("JSON response : %s", response)
        return response

    def default(self, response, result):
        response.content_type = 'application/json'
        response.body = encodeutils.safe_encode(self.to_json(result))


# -*- coding: utf-8 -*-
"""
Created on Wed Sep 29 13:12:03 2021

@author: thuang

Plots the sensitivity delta = master_branch - my_branch
for 1e3 and 1e4.
"""

from matplotlib import pyplot as plt
import numpy as np

class delta_bars:

    def __init__(self, data_dict, tolerance):
        """
        Parameters
        ----------

        data_dict : dictionary
            A dictionary containing the data to write to the Excel file.
            Dictionary shall contain: {'names':[name1, name2], mode_id:{t1_blf:{'T1': t1, 'BLF': blf, 'name1':[1e3, 1e4], 'name2':[1e3, 1e4], 'delta':[1e3, 1e4]}}}

        Returns
        -------
        None.

        """
        self.data_dict = data_dict.copy()
        self.tolerance = tolerance

    def plot_delta(self):
        """
        Plots the delta for each scenario of each mode as a bar graph.
        """

        self.data_dict.pop('names', None)

        num_modes = len(self.data_dict) #number of modes
        num_cols = int(np.ceil(np.sqrt(num_modes))) #make the plot grid as square as possible to save space
        num_rows = num_cols
        fig1, *ax = plt.subplots(num_rows, num_cols)
        fig1.tight_layout()

        if num_cols*num_rows>1: #if only one axis, then can't flatten
            ax = ax[0].flatten('F')

        if num_modes < len(ax): #remove excess axes exceeding the number of plots
            for this_ax in ax[num_modes:]:
                this_ax.remove()

        for n, mode_id in enumerate(self.data_dict.keys()):
            labels = []
            delta_e3 = []
            delta_e4 = []
            for t1_blf in self.data_dict[mode_id].keys():
                labels += [self.data_dict[mode_id][t1_blf]['T1'] + ',' + self.data_dict[mode_id][t1_blf]['BLF']]
                delta_e3 += [self.data_dict[mode_id][t1_blf]['delta'][0]]
                delta_e4 += [self.data_dict[mode_id][t1_blf]['delta'][1]]
            ax[n].bar(np.arange(len(labels)), delta_e3, tick_label=labels, color='tab:blue', width=.25)
            ax[n].bar(np.arange(len(labels))+.25, delta_e4, tick_label=labels, color='tab:red', width=.25)
            ax[n].legend(['1e-3', '1e-4'], fontsize='xx-large')
            ax[n].grid(True, which='both', axis='both')
            ax[n].set_xlabel('T1, BLF', fontsize='xx-large')
            ax[n].set_ylabel(chr(916)+'sensitivity (dBm)', fontsize='xx-large')
            if (np.array(delta_e3) < -self.tolerance).any():
                ax[n].set_title(f'Mode {mode_id}', fontsize='xx-large', color='red')
            else:
                ax[n].set_title(f'Mode {mode_id}', fontsize='xx-large', color='green')
            ax[n].tick_params(axis='both', labelsize='xx-large')
            ax[n].minorticks_on()


"""
This script is meant to be iterated many times to replicate the spawning of many error popups.
"""

from PySide2 import QtWidgets
import random
from PySide2.QtWidgets import QMainWindow, QApplication
from PySide2.QtGui import QIcon
from configparser import ConfigParser
import sys
app = QApplication(sys.argv)
appcfg = ConfigParser()
appcfg.read('configs/appsettings.ini')

if appcfg.getint('popup_properties', 'popup_style_index') == 0:
    app.setStyle('windowsvista')
elif appcfg.getint('popup_properties', 'popup_style_index') == 1:
    app.setStyle('Fusion')
elif appcfg.getint('popup_properties', 'popup_style_index') == 2:
    app.setStyle('Windows')

class MainWindow(QMainWindow):
    def __init__(self):
        super(MainWindow, self).__init__()

        self.msg = QtWidgets.QMessageBox(self)
        self.msg.setWindowTitle(appcfg.get('popup_strings', 'popup_win_title'))
        self.msg.setText(appcfg.get('popup_strings', 'popup_message'))
        self.msg.move(random.randint(0, 1000), random.randint(0, 600))
        if appcfg.getint('popup_properties', 'popup_type_index') == 0:
            self.msg.setIcon(QtWidgets.QMessageBox.Information)
        elif appcfg.getint('popup_properties', 'popup_type_index') == 1:
            self.msg.setIcon(QtWidgets.QMessageBox.Question)
        elif appcfg.getint('popup_properties', 'popup_type_index') == 2:
            self.msg.setIcon(QtWidgets.QMessageBox.Warning)
        elif appcfg.getint('popup_properties', 'popup_type_index') == 3:
            self.msg.setIcon(QtWidgets.QMessageBox.Critical)
        self.setWindowIcon(QIcon(appcfg.get('popup_properties', 'popup_icon_path')))
        self.msg.exec_()
        sys.exit()

def window():
    global app
    MainWindow()

    sys.exit(app.exec_())

window()


# Import the libraries
import nltk
from nltk.chat.util import Chat, reflections
import tkinter as tk
from tkinter import *

# Define the responses
pairs = [
    ['hi', ['Hello!', 'Hi there!']],
    ['what is your name', ['My name is Chatbot', 'I am Chatbot']],
    ['how are you', ['I am doing well', 'I am fine, thanks']],
    ['bye', ['Goodbye', 'See you later']],
]

# Create the chatbot
chatbot = Chat(pairs, reflections)

# Create the user interface
def send():
    msg = EntryBox.get("1.0", "end-1c").strip()
    EntryBox.delete("0.0", END)
    if msg != "":
        ChatLog.config(state=NORMAL)
        ChatLog.insert(END, "You: " + msg + "\n\n")
        ChatLog.config(foreground="#442265", font=("Verdana", 12 ))

        res = chatbot.respond(msg)
        ChatLog.insert(END, "Chatbot: " + res + "\n\n")

        ChatLog.config(state=DISABLED)
        ChatLog.yview(END)

root = Tk()
root.title("Chatbot")
root.geometry("400x500")
root.resizable(width=FALSE, height=FALSE)

ChatLog = Text(root, bd=0, bg="purple", height="8", width="50", font="Arial",)
ChatLog.config(state=DISABLED)

scrollbar = Scrollbar(root, command=ChatLog.yview, cursor="heart")
ChatLog['yscrollcommand'] = scrollbar.set

SendButton = Button(root, font=("Verdana", 12, 'bold'), text="Send", width="12", height=5, bd=0, bg="#32de97", activebackground="#3c9d9b", fg='#ffffff', command=send)

EntryBox = Text(root, bd=0, bg="white", width="29", height="5", font="Arial")

scrollbar.place(x=376, y=6, height=386)
ChatLog.place(x=6, y=6, height=386, width=370)
EntryBox.place(x=128, y=401, height=60, width=265)
SendButton.place(x=6, y=401, height=60)

root.mainloop()


import json

import requests
from config.const import SPOTIFY_HEADERS, SPOTIFY_URLS
from config.tokens import SPOTIFY_OAUTH_TOKEN, SPOTIFY_USER_ID

class SpotifyAPI:

    name = 'spotify'

    @staticmethod
    def __get_request_headers():
        headers = SPOTIFY_HEADERS
        headers["Authorization"] = headers["Authorization"].format(spotify_oauth_token=SPOTIFY_OAUTH_TOKEN)
        return headers

    @staticmethod
    def __get_playlists_url():
        return SPOTIFY_URLS["playlists_url"]

    @staticmethod
    def __get_tracks_url():
        return SPOTIFY_URLS["tracks_url"]

    @classmethod
    def _ARS_retrieve_track_info(cls, song_info):
        try:
            track_id = song_info['metadata']['music'][0]['external_metadata']['spotify']['track']['id']
        except (KeyError, IndexError):
            return None
        return 'spotify:track:{}'.format(track_id)

    @classmethod
    def retrieve_track_info(cls, ARS_name, song_info):
        if ARS_name == 'acrcloud':
            return cls._ARS_retrieve_track_info(song_info)
        # raise ARS_NOT_RECOGNISED but who cares

    @classmethod
    def _retrieve_playlist_id(cls, playlist_request):
        return json.loads(playlist_request.text)['id']

    @classmethod
    def get_playlist_id(cls, playlist_request):
        return cls._retrieve_playlist_id(playlist_request)

    @classmethod
    def create_playlist(cls, playlist_name: str, description="", public=False):
        playlists_url = cls.__get_playlists_url().format(spotify_user_id=SPOTIFY_USER_ID)
        request_body = {
            "name": playlist_name,
            "description": description,
            "public": public
        }
        payload = json.dumps(request_body)
        return requests.post(playlists_url, data=payload, headers=cls.__get_request_headers())

    @classmethod
    def add_tracks_to_playlist(cls, tracks_ids: str, playlist_id: str):
        tracks_url = cls.__get_tracks_url().format(playlist_id=playlist_id)
        params = {
            "uris": ",".join(tracks_ids)
        }
        return requests.post(tracks_url, params=params, headers=cls.__get_request_headers())


from django.urls import path

from repairshop import views

urlpatterns = [
    path("", views.home, name="home"),
    path("categories/<slug:sub_category>/", views.sub_category, name="sub_category"),
    path("about/", views.about, name="about"),
    path("categories/", views.categories, name="categories"),
    path("contacts/", views.contacts, name="contacts"),
    path("products/<slug:product_url>/", views.product, name="product"),
]


from flask import Flask, request
import json
from datetime import datetime
import requests
from lights import light

from constants import Tables, Params, PHUE
from sqlite import sqlite

app = Flask(__name__)

Light1 = light.Light(1)
Light2 = light.Light(3)

@app.route("/listener")
def generate_refresh_token():
    code = request.args.get(Params.CODE.value)
    url = f"https://api.meethue.com/oauth2/token?code={code}&grant_type=authorization_code"
    generated_at = datetime.now().strftime("%Y-%m-%d %H:%M:%S.%f")
    response = json.loads(requests.post(url, auth=PHUE.AUTH.value).text)
    access_token = response[Params.ACCESS_TOKEN.value]
    refresh_token = response[Params.REFRESH_TOKEN.value]
    c = sqlite.SQLite()
    response, code = c.delete_all(Tables.TOKENS.value)
    if code == 409:
        c.close_conn()
        return response
    response, code = c.insert(
        Tables.TOKENS.value, (generated_at, access_token, refresh_token))
    if code == 409:
        c.close_conn()
        return response
    Light1.tokens.pull_tokens()
    Light2.tokens.pull_tokens()
    Light1.pull_light_data()
    Light2.pull_light_data()
    return "Success! Tokens have been generated!", 201

@app.route("/create-table", methods=['POST'])
def create_table():
    body = request.json
    columns = body[Params.COLUMNS.value]
    table_columns = ""
    for key in columns:
        try:
            assert (columns[key] in Tables.COLUMN_TYPES.value)
        except:
            message = f"Table column '{key}' can only be of type 'text', 'real' or 'integer'. '{columns[key]}' is not allowed."
            return message, 409
        else:
            table_columns += f"{key} {columns[key]},\n"
    table_columns = table_columns[:-2]
    c = sqlite.SQLite()
    response = c.create_table(body['table_name'], table_columns)
    c.close_conn()
    return response

@app.route("/lights/<id>/power-on", methods=['POST'])
def power_on(id):
    light = Light1 if int(id) == 1 else Light2
    return light.set_light("on")

@app.route("/lights/<id>/power-off", methods=['POST'])
def power_off(id):
    assert id == request.view_args[Params.ID.value]
    light = Light1 if int(id) == 1 else Light2
    return light.set_light("off")

@app.route("/db/<table>", methods=['GET'])
def get_dblight_data(table):
    assert table == request.view_args['table']
    c = sqlite.SQLite()
    response, code = c.get_all(table)
    c.close_conn()
    return response, code

@app.route("/lights/state", methods=["GET"])
def curr_light_state():
    state = []
    state.append(Light1.get_light_data())
    state.append(Light2.get_light_data())
    return state