import pyttsx3
import pyaudio
import speech_recognition as sr
import sys
import webbrowser
import bs4, requests
import random
from bs4 import BeautifulSoup
from requests_html import HTMLSession

session = HTMLSession()
engine = pyttsx3.init()
#Manual Override
manual = False
print("Enable manual override? (Y/N)")
engine.say("Enable manual override?")
engine.runAndWait()
override = input()
if(override.lower() == "y"):
    print("Manual override enabled")
    engine.say("Manual override enabled")
    manual = True
else:
    print("Voice recognition enabled")
    engine.say("Voice recognition enabled")
print("What's on your mind?")
engine.say("What's on your mind?")
engine.runAndWait()
while(True):
    query = ""
    search = ""
    question = ""
    insert = ""
    output = []
    #Input
    r = sr.Recognizer()
    end = False
    skip = False
    if(manual == False):
        with sr.Microphone() as source:
            audio = r.listen(source)
            try:
                text = r.recognize_google(audio)
            except:
                skip = True
    else:
        text = input()
    #Categories
            #Terminate, Math, Google, Youtube, Trivia, Store, Joke, Translate
    store = ["make", "acquire", "build", "read", "clear", "delete", "destroy"]
    trivia = ["who", "what", "when", "where", "why", "how","How", "Who", "What", "Where", "When", "Why"]
    youtube = ["YouTube", "play", "Play"]
    google = ["Google", "search"]
    math = ["math", "calculate"]
    terminate = ["exit", "terminate", "end", "stop", "bye", "goodbye", "close"]
    joke = ["joke", "laugh", "smile"]
    translate = ["translate", "language"]

    #Output
        #Terminate
    if(skip == False):
        tokens = text.split(" ")
        for i in range(len(terminate)):
            if(text == terminate[i]):
                end = True
                break

        if(end == False):
            if(skip == False):
                #Sentiment Values
                disgust = 0
                anger = 0
                sadness = 0
                suprise = 0
                fear = 0
                joy = 0
                trust = 0
                anticipation = 0
                sentiment = 0
                #Sentiment Analysis
                    ##Optimize Using Keystones
                    #Enable/Disable
                data = open(r"sentimentdata.txt","r")
                info = data.readlines()
                for e in range(len(tokens)):
                    for w in range(len(info)):
                        term = info[w].split(",")
                        if(term[0] == tokens[e]):
                            if(term[1] == "anger"):
                                anger += 1
                            if(term[1] == "sadness"):
                                sadness += 1
                            if(term[1] == "fear"):
                                fear += 1
                            if(term[1] == "joy"):
                                joy += 1
                            if(term[1] == "trust"):
                                trust += 1
                            if(term[1] == "anticipation"):
                                anticipation += 1
                            if(term[4] == "negative"):
                                sentiment -= 1
                            if(term[4] == "positive"):
                                sentiment += 1
                            break
                print(sentiment)
                print("Joy: " + str(joy))
                print("Anticipation: " + str(anticipation))
                print("Trust: " + str(trust))
                print("Sadness: " + str(sadness))
                print("Fear: " + str(fear))
                print("Anger: " + str(anger))
                #Joke
                reserve = ["Today at the bank, an old lady asked me to help check her balance. So I pushed her over.",
                           "I bought some shoes from a drug dealer. I don't know what he laced them with, but I've been tripping all day.",
                           "My dog used to chase people on a bike a lot. It got so bad, finally I had to take his bike away.",
                           "I couldn't figure out why the baseball kept getting larger. Then it hit me.",
                           "Why did the old man fall in the well? Because he couldn't see that well.",
                           "Where do you find a cow with no legs? Right where you left it.",
                           "What did one hat say to the other? You stay here. I’ll go on ahead.",
                           "Why did it take so long for the pirates to learn the Alphabet? They got stuck at C.",
                           "I think i would like a job cleaning mirrors, it's just something I could really see myself doing.",
                           "When a deaf person sees someone yawn do they think it’s a scream?"]
                for jk in range(len(joke)):
                    if(joke[jk] in tokens):
                        jok = random.randrange(0,9)
                        text = (reserve[jok])
                #Translate
                        #Refine Dictionary
                if(tokens[0] == translate[0] or tokens[0] == translate[1]):
                    try:
                        text = ""
                        dictionary = ""
                        msg = 1
                        while(msg < len(tokens)):
                            for tra in range(len(dictionary)):
                                word = dictionary[tra].split(" ")
                                if(tokens[msg] == word[0]):
                                    text += word[1]+" "
                                    break;
                                elif(tokens[msg] == word[1]):
                                    text += word[0]+" "
                                    break;
                            msg += 1
                    except:
                        text = "Please use the proper format, translate command, message. (EN-FR)"

                #Math
                for k in range(len(math)):
                    if(tokens[0] == math[k]):
                        if(len(tokens) > 3):
                            if(tokens[2] == "+" or tokens[2] == "add"):
                                text = int(tokens[1]) + int(tokens[3])
                            if(tokens[2] == "-" or tokens[2] == "subtract" or tokens[2] == "minus"):
                                text = int(tokens[1]) - int(tokens[3])
                            if(tokens[2] == "*" or tokens[2] == "multiply"):
                                text = int(tokens[1]) * int(tokens[3])
                            if(tokens[2] == "divide" or tokens[2] == "divided"):
                                text = int(tokens[1]) / int(tokens[3])
                            if(tokens[2] == "exponent"):
                                text = int(tokens[1]) ** int(tokens[3])
                            if(tokens[2] == "remainder" or tokens[2] == "modulus"):
                                text = int(tokens[1]) % int(tokens[3])
                        break
                #Google
                for j in range(len(google)):
                    if(tokens[0] == google[j]):
                        for m in range(len(tokens)):
                            if(m != 0):
                                query += tokens[m] + " "
                        webbrowser.open("https://google.com/search?q=%s" % query)
                        text = "Searching for: " + query
                        break
                #Youtube
                for b in range(len(youtube)):
                    if(tokens[0] == youtube[b]):
                        for n in range(len(tokens)):
                            if(n != 0):
                                search += tokens[n]
                                if(n != len(tokens)-1):
                                    search += "+"
                        results = requests.get("https://www.youtube.com/results?search_query=%s" % search).content
                        soup = BeautifulSoup(results, "html.parser")
                        for a in soup.find_all("a", href=True):
                            case = a['href']
                            if(len(case) > 1):
                                if(case[1] == "w"):
                                    webbrowser.open("https://www.youtube.com%s" % case)
                                    break
                        text = "Searching for: " + search.replace("+", " ")
                        break
                #Trivia
                for p in range(len(trivia)):
                    if(tokens[0] == trivia[p]):
                        for y in range(len(tokens)):
                            question += tokens[y]
                            if(y != len(tokens)-1):
                                question += " "
                        results = session.get("https://google.com/search?q=%s" % question).content
                        soup = BeautifulSoup(results, "html.parser")
                        try:
                            case = soup.find('div',{'class':'Z0LcW'})
                            if(case == None):
                                case = soup.find('span',{'class':'e24Kjd'})
                            text = case.text
                        except:
                            text = "Sorry, Kiwi encountered an issue"
                #Store
                for q in range(len(store)):
                    if(tokens[0] == store[q]):
                        if(tokens[0] == "make" or tokens[0] == "build"):
                            for v in range(len(tokens)):
                                if(v != 0):
                                    insert += tokens[v] + " "
                            file = open(r"notes.txt", "a")
                            file.write(insert)
                            text = "Notes updated successfully"
                        if(tokens[0] == "acquire" or tokens[0] == "read"):
                            file = open(r"notes.txt", "r")
                            try:
                                output = file.readlines()
                                text = output[0]
                            except:
                                text = "No notes found"
                        if(tokens[0] == "destroy" or tokens[0] == "delete" or tokens[0] == "clear"):
                            file = open(r"notes.txt", "w+")
                            file.write("")
                            text = "Notes successfully cleared"
                engine.say(text)
                print(text)
                engine.runAndWait()
        else:
            engine.say("Kiwi successfully terminated")
            print("Kiwi successfully terminated...")
            engine.runAndWait()
            break


# This file contains the common graphical elements that can be used by both
# ChordSelectionDisplay and PlaybackDisplay.

import sys
from common.gfxutil import *

from kivy.graphics.instructions import InstructionGroup
from kivy.graphics import Color, Ellipse, Line, Rectangle
from kivy.graphics import PushMatrix, PopMatrix, Translate, Scale, Rotate
from kivy.uix.widget import Widget
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.relativelayout import RelativeLayout
from kivy.uix.button import Button
from kivy.uix.label import Label

import random
import math

# A menu button.
class MenuButton(Button):
    def __init__(self, pos_hint, size_hint, label):
        super(MenuButton, self).__init__(pos_hint=pos_hint, size_hint=size_hint, text=label)
        self.label = label
        self.background_normal = ''
        self.background_color = [0, .7, 0, .8]

    def set_background_color(self, rgba):
        self.background_color = rgba

    def set_text_color(self, rgb):
        sel.color = rgb

    def set_callback(self, callback):
        self.bind(on_press=callback)

# A button representing a node in the graph (either a chord or phrase.)
class NodeButton(Button):
    def __init__(self, pos_hint, size_hint, block, preview=False):
        super(NodeButton, self).__init__(pos_hint=pos_hint, size_hint=size_hint, text=block.get_name())
        self.block = block
        self.background_normal = ''
        if preview:
            self.background_color = [0, .2, .8, .8]
            # self.background_color = [.8, 0, .2, .8]
        else:
            self.background_color = [0, .2, .8, .8]

    def set_callback(self, callback):
        self.bind(on_press=callback)

class BubbleWiggleToCenter(InstructionGroup):
    def __init__(self, pos, r, color, duration = 3):
        super(BubbleWiggleToCenter, self).__init__()

        center_x = Window.width/2
        center_y = Window.height/2
        x = []
        x.append((0,r))
        # this creates a bunch of tuples so that we can make a kfanim across
        # a lot of different points. It basically adds a sin wave on top of the
        # regularly scheduled decrease in radius
        for i in range(100):
            time = .1 + i*duration/100.
            radius = 2 * r * (100. - i) / 100 * (1 + 0.2 * np.sin(i / 2.))
            x.append((time, radius))

        self.radius_anim = KFAnim(*x)

        # the position still goes linearly
        self.pos_anim = KFAnim((0, pos[0], pos[1]), (duration, center_x, center_y))

        self.color = Color(*color)
        self.add(self.color)

        self.circle = CEllipse(cpos = pos, size = (2*r, 2*r), segments = 40)
        self.add(self.circle)

        self.time = 0
        self.on_update(0)

    def on_update(self, dt):
        # animate radius
        rad = self.radius_anim.eval(self.time)
        self.circle.csize = (2*rad, 2*rad)

        # animate position
        pos = self.pos_anim.eval(self.time)
        self.circle.cpos = pos

        # advance time
        self.time += dt
        # continue flag
        return self.radius_anim.is_active(self.time)

# A generic bubble.
class Bubble(InstructionGroup):
    def __init__(self, pos, rgb, size):
        super(Bubble, self).__init__()
        self.pos = pos
        self.size = size
        self.color = Color(*rgb)

        self.add(self.color)
        self.ellipse = CEllipse(cpos=pos, csize=(self.size, self.size))
        self.add(self.ellipse)

    def set_color(self, rgb):
        self.color.rgb = rgb

    def set_alpha(self, a):
        self.color.a = a

    def set_pos(self, pos):
        self.pos = pos
        self.ellipse.set_pos(pos)

    def on_update(self, dt):
        pass

class LineDivider(InstructionGroup):
    def __init__(self,first_point,second_point,rgba):
        super(LineDivider, self).__init__()
        self.first_point = first_point
        self.second_point = second_point
        self.color = Color(*rgba)
        self.add(self.color)
        self.points = [first_point[0],first_point[1],second_point[0],second_point[1]]
        self.line = Line(points=self.points,width=5)
        self.add(self.line)

    def on_update(self, dt):
        return True

class RandomMovingBubble(InstructionGroup):
    def __init__(self, pos, size=40):
        super(RandomMovingBubble, self).__init__()
        self.pos = pos
        self.size = size
        h = random.random()
        self.color = Color(hsv=(h,1,1))
        self.add(self.color)
        self.ellipse = CEllipse(cpos=pos, csize=(1, 1))
        self.add(self.ellipse)
        self.angle = random.random() * 2 * math.pi
        total_distance = ((Window.height ** 2 + Window.width ** 2) ** 0.5) / 2.
        final_pos_x = self.pos[0] + total_distance * math.sin(self.angle)
        final_pos_y = self.pos[1] + total_distance * math.cos(self.angle)
        self.pos_anim = KFAnim((0,self.pos[0],self.pos[1]),(1.5,final_pos_x,final_pos_y))
        self.size_anim = KFAnim((0,0),(0.2, self.size),(1.5,0))
        self.time = 0

    def on_update(self, dt):
        self.time += dt
        new_pos = self.pos_anim.eval(self.time)
        new_size = self.size_anim.eval(self.time)
        self.ellipse.cpos = new_pos
        self.ellipse.csize = (new_size,new_size)
        return self.pos_anim.is_active(self.time)


import allure
from assertpy import assert_that, soft_assertions

from bases.test_base import TestBase
from models.pet import Pet
from models.category import Category
from models.tag import Tag
from requests_api.post_new_pet_request import PostNewPetRequest
from utils.utils import Utils

@allure.suite("New Pet Feature")
class TestPostNewPet(TestBase):

    @allure.tag("API Test")
    @allure.title("Add new pet sucess with Pet object")
    @allure.description("test adding new pet successfully")
    def test_add_new_pet_success(self):
        # arranges
        payload = Pet()
        payload.id = "44"
        category = Category()
        category.id = "55"
        category.name = "Dogs"
        payload.category = category
        payload.name = "Ro"
        payload.photoUrls = ["fotinhafofinha.com.br/foto1", "fotinhafofinha.com.br/foto2"]
        payload.tags = []
        tag1 = Tag()
        tag1.id = 1
        tag1.name = "Pinscher"
        payload.tags.append(tag1)
        tag2 = Tag()
        tag2.id = 2
        tag2.name = "Bravo"
        payload.tags.append(tag2)
        payload.status = "sold"

        request = PostNewPetRequest()

        # actions
        request.set_json_body(payload)
        response = request.execute_request()
        response_body = Utils.get_json_in_response(response)

        # asserts
        assert_that(response.status_code).is_equal_to(200)
        with soft_assertions():
            assert_that(response_body["name"]).contains("Ro")
            assert_that(response_body["tags"][0]["name"]).is_equal_to("Pinscher")
            assert_that(response_body["tags"]).extracting("name").contains("Bravo")
            assert_that(response_body["tags"]).extracting("name").is_equal_to(['Pinscher', 'Bravo'])

    @allure.tag("API Test")
    @allure.title("Add new pet sucess with json file")
    @allure.description("test adding new pet successfully with json file")
    def test_add_new_pet_success_with_json_file(self):
        # arranges
        id = "55"
        category_id = "66"
        category_name = "Dogs"
        name = "Titi"
        photo_urls = "fotinhastiti.com.br"
        tag_id = "1"
        tag_name = "Basset"
        status = "sold"
        request = PostNewPetRequest()

        # actions
        request.set_json_body_from_file(id, category_id, category_name, name, photo_urls, tag_id, tag_name, status)
        response = request.execute_request()
        response_body = Utils.get_json_in_response(response)

        # asserts
        assert_that(response.status_code).is_equal_to(200)

    @allure.tag("API Test")
    @allure.title("Add new pet sucess with Pet text")
    @allure.description("test adding new pet successfully with Pet text")
    def test_add_new_pet_success_with_text(self):
        # arranges
        id = "77"
        category_id = "88"
        category_name = "Dogs"
        name = "Dogo"
        photo_urls = "fotinhasdogo.com.br"
        tag_id = "1"
        tag_name = "Srd"
        status = "sold"
        request = PostNewPetRequest()

        # actions
        request.set_json_body_from_text(id, category_id, category_name, name, photo_urls, tag_id, tag_name, status)
        response = request.execute_request()
        response_body = Utils.get_json_in_response(response)

        # asserts
        assert_that(response.status_code).is_equal_to(200)


import os
from setuptools import setup, find_packages

def read_file(filename):
    basepath = os.path.dirname(os.path.dirname(__file__))
    filepath = os.path.join(basepath, filename)
    if os.path.exists(filepath):
        return open(filepath).read()
    else:
        return ''

setup(
    name='raimon49.guestbook',
    version='1.1.1',
    description='A guestbook web application.',
    long_description=read_file('README.rst'),
    author='raimon49',
    author_email='raimon49@hotmail.com',
    url='https://github.com/raimon49/pypro2-guestbook-webapp',
    classifiers=[
        'Development Status :: 4 - Beta',
        'Framework :: Flask',
        'License :: OSI Approved :: BSD License',
        'Programming Language :: Python',
        'Programming Language :: Python :: 3.8',
    ],
    packages=find_packages(),
    include_package_data=True,
    keywords=['web', 'guestbook'],
    license='BSD License',
    install_requires=[
        'Flask',
        'bpmappers',
    ],
    entry_points="""
        [console_scripts]
        guestbook = guestbook:main
    """
)


"""
    Setting for stock price model
"""
import enum
# https://www.infobyip.com/detectmonitordpi.php
DPI = 144

# SIZE OF INPUT IMAGE TO CNN
IMG_W = 112
IMG_H = 112

# THE DIRECTORY FOR STORING CHART DATA
CHART_DIR = "C:\\Users\\a18822\\Desktop\\StockPrice\\CHART"
# TO CACHE THE DATASET
CACHE_DIR = "C:\\Users\\a18822\\Desktop\\StockPrice\\CACHE"

class ChartType(enum.Enum):
    BAR = "bar"
    LINE = "line"
    FLINE = "filled_line"
    CANDLESTICK = "candlestick"
    BAR_CANDLESTICK_FUSION = "bar_candlestick_fusion"
    BAR_LINE_FUSION = "bar_line_fusion"
    BAR_FLINE_FUSION = "bar_filled_line_fusion"

# tw_spydata_train.csv
TRAIN_SP500_DATA_FILE = "C:\\Users\\a18822\\Desktop\\StockPrice\\tw_spydata_train.csv"
TEST_SP500_DATA_FILE = "C:\\Users\\a18822\\Desktop\\StockPrice\\tw_spydata_test.csv"
VALIDATION_SP500_DATA_FILE = "C:\\Users\\a18822\\Desktop\\StockPrice\\tw_spydata_validation.csv"

ALPHA = 0.2
BETA = 1
GAMMA = 0.2

# When generating the dataset, please set it to False
# When training or testing: set it to True
ENABLE_IMAGE_DECODE = True

WINDOW_SIZE = 30
PREDICT_SIZE = 5
BATCH_SIZE = 32
EPOCH = 100

# NUMBER OF VALIDATION RECORD / BATCH_SIZE
VALIDATION_STEPS = int(9999 / BATCH_SIZE)
# VALIDATION_STEPS = int(500 / BATCH_SIZE)

NUMBER_OF_VALIDATION = 9999

LEARNING_RATE = 0.003
EPSILON = 0.1


from flask import Blueprint, Response, current_app, stream_with_context

from CTFd.models import db
from CTFd.utils import get_app_config
from CTFd.utils.decorators import authed_only, ratelimit

events = Blueprint("events", __name__)

@events.route("/events")
@authed_only
@ratelimit(method="GET", limit=150, interval=60)
def subscribe():
    @stream_with_context
    def gen():
        for event in current_app.events_manager.subscribe():
            yield str(event)

    enabled = get_app_config("SERVER_SENT_EVENTS")
    if enabled is False:
        return ("", 204)

    # Close the db session to avoid OperationalError with MySQL connection errors
    db.session.close()

    return Response(gen(), mimetype="text/event-stream")


#!/user/bin/env python3
"""
Author: Nicolás Barrón Sour
Date Created: 09/10/2023
Description: Allows you to track and update your ELO rating as you compete with yourself in daily habit-tracking games, providing a numerical measure of your progress and skill in maintaining these habits.
"""

# Imports
import sqlite3
import climage
from datetime import datetime

# Global Values
numberHabits = 5
elo_deduction = 50  # ELO deduction for each missed day

# Function declarations
def db_innit():
    conn = sqlite3.connect("elo_ratings.db")
    cursor = conn.cursor()

    cursor.execute(
        """
		CREATE TABLE IF NOT EXISTS games (
			id INTEGER PRIMARY KEY AUTOINCREMENT,
			player_name TEXT,
			opponent_name TEXT,
			player_result INTEGER,
			game_date TIMESTAMP DEFAULT CURRENT_TIMESTAMP
		)
	"""
    )

    cursor.execute(
        """
		CREATE TABLE IF NOT EXISTS players (
			id INTEGER PRIMARY KEY AUTOINCREMENT,
			name TEXT UNIQUE,
			elo INTEGER
		)
	"""
    )

    conn.commit()
    conn.close()

def calculate_elo_rating(player_rating, opponent_rating, result):
    k = 10  # K-factor, determines how much ratings change after a game
    expected_result = 1 / (1 + 10 ** ((opponent_rating - player_rating) / 400))
    new_rating = player_rating + k * (result - expected_result)
    return round(new_rating)

def record_game(player_name, opponent_name, player_result, game_date=None):
    conn = sqlite3.connect("elo_ratings.db")
    cursor = conn.cursor()

    if game_date is None:
        game_date = datetime.now()

    # Insert the game record into the "games" table with the provided or current timestamp
    cursor.execute(
        "INSERT INTO games (player_name, opponent_name, player_result, game_date) VALUES (?, ?, ?, ?)",
        (player_name, opponent_name, player_result, game_date),
    )

    # Get the ID of the last inserted record
    record_id = cursor.lastrowid

    # Get the current ratings for the players
    cursor.execute("SELECT elo FROM players WHERE name = ?", (player_name,))
    player_rating = cursor.fetchone()[0]

    cursor.execute("SELECT elo FROM players WHERE name = ?", (opponent_name,))
    opponent_rating = cursor.fetchone()[0]

    # Calculate the new ratings
    new_player_rating = calculate_elo_rating(
        player_rating, opponent_rating, player_result
    )
    new_opponent_rating = calculate_elo_rating(
        opponent_rating, player_rating, 1 - player_result
    )

    # Update the ratings in the database
    cursor.execute(
        "UPDATE players SET elo = ? WHERE name = ?", (new_player_rating, player_name)
    )
    cursor.execute(
        "UPDATE players SET elo = ? WHERE name = ?",
        (new_opponent_rating, opponent_name),
    )

    conn.commit()
    conn.close()
    return record_id

def get_player_rating(player_name):
    conn = sqlite3.connect("elo_ratings.db")
    cursor = conn.cursor()

    cursor.execute("SELECT elo FROM players WHERE name = ?", (player_name,))
    rating = cursor.fetchone()[0]

    conn.close()
    return rating

def deductMissingDays():
    conn = sqlite3.connect("elo_ratings.db")
    cursor = conn.cursor()

    cursor.execute("SELECT game_date FROM games ORDER BY game_date DESC LIMIT 1")
    result = cursor.fetchone()

    if not result:
        print("No records found in the games table.")
        return

    last_day = datetime.strptime(result[0], "%Y-%m-%d %H:%M:%S.%f")
    elapsed_time = datetime.today() - last_day
    if elapsed_time.days > 1:
        elo_deduction_total = elapsed_time.days * elo_deduction
        new_elo = get_player_rating("NBS") - elo_deduction_total
        print("More than 1 day has passed since the last record.")
        print(
            f"You missed {elapsed_time.days} days. Deducted {elo_deduction_total} ELO."
        )
        print(f"Your new rank is {get_rank_name(new_elo)} with {new_elo}")
    else:
        # Perform other logic when the difference in days is 1 or less
        print(f"{elapsed_time} has passed since the last record.")
        # Your other logic here

    conn.close()

def get_rank_name(elo):
    if elo < 800:
        return "Iron"
    elif elo < 1000:
        return "Bronze"
    elif elo < 1200:
        return "Silver"
    elif elo < 1400:
        return "Gold"
    elif elo < 1600:
        return "Platinum"
    elif elo < 1800:
        return "Diamond"
    elif elo < 2000:
        return "Master"
    elif elo < 2200:
        return "Grandmaster"
    else:
        return "Challenger"

def print_rank(elo):
    if elo < 800:
        output = climage.convert("RankImages/iron.png")
    elif elo < 1000:
        output = climage.convert("RankImages/bronze.png")
    elif elo < 1200:
        output = climage.convert("RankImages/silver.png")
    elif elo < 1400:
        output = climage.convert("RankImages/gold.png")
    elif elo < 1600:
        output = climage.convert("RankImages/platinum.png")
    elif elo < 1800:
        output = climage.convert("RankImages/diamond.png")
    elif elo < 2000:
        output = climage.convert("RankImages/master.png")
    elif elo < 2200:
        output = climage.convert("RankImages/grandmaster.png")
    else:
        output = climage.convert("RankImages/challenger.png")

    print(output)

def main():
    # Initialize the database
    db_innit()

    # Welcome message
    prev_elo = get_player_rating("NBS")
    print(
        f'Hello welcome to ELO habit tracker, your current rank is {get_rank_name(get_player_rating("NBS"))} with {get_player_rating("NBS")}'
    )
    print_rank(get_player_rating("NBS"))

    num_habits = int(input("How many habits did you do:"))

    # Deduct ELO for missed days
    deductMissingDays()

    for _ in range(num_habits):
        # Record a game where you won against yourself
        record_game("NBS", "NBS", 0)

    new_elo = get_player_rating("NBS")

    if prev_elo < new_elo:
        print(f"You won some ELO, your rank is {get_rank_name(new_elo)} with {new_elo}")
    else:
        print(
            f"You lost some ELO, your rank is {get_rank_name(new_elo)} with {new_elo}"
        )

    print_rank(get_player_rating("NBS"))
    exit()

# Main body
if __name__ == "__main__":
    main()


from concurrent import futures
import logging

import grpc

import os
import lba2pba_pb2
import lba2pba_pb2_grpc

import shard

def getGlusterHost():
	cmd = 'gluster peer status | grep Hostname'
	err, res = subprocess.getstatusoutput(cmd)

	hosts = ['localhost']
	if res:
		for line in res.split('\n'):
			hosts.append(line.split(": ")[1])

		return hosts

def getFM(volume,fName):
	shardList = shard.getShardList()

#	re = {}

	for t in shardList.keys():
		if not volume in shardList[t].keys():
			continue

		for f in shardList[t][volume].keys():
			if fName in f:
				fName = f

		#if not volume in re.keys():
		#	re[volume] = {}

		#if not fList:
		#	flist = shardList[t][volume].keys()

		if t == 'replica':
		#	for fName in flist:
			FM = {'FileName':fName,'Type':t,'rPba':[]}
			for host in shardList[t][volume][fName].keys():
				rPba = {}
				pba = []
				for f in shardList[t][volume][fName][host]:
					with grpc.insecure_channel(f'{host}:23829') as channel:
						stub = lba2pba_pb2_grpc.WorkerStub(channel)
						res = stub.Get(lba2pba_pb2.WGetPbaRequest(FileName=f))

						for p in res.Pba:
							tdict = {
								'Disk': res.Disk,
								'Host': host,
								'Offset': p.Offset,
								'Length': p.Length,
							}

							pba.append(tdict)

				rPba['Pba'] = pba
				rPba['Node'] = host

				FM['rPba'].append(rPba)

			#re[volume][fName]=FM
			return FM

		elif t == 'distribute':
			#for fName in flist:
			FM = {'FileName':fName, 'Type':t, 'Pba':[]}

			for fInfo in shardList[t][volume][fName]:
				host, f = fInfo.split(' ')

				with grpc.insecure_channel(f'{host}:23829') as channel:
					stub = lba2pba_pb2_grpc.WorkerStub(channel)
					res = stub.Get(lba2pba_pb2.WGetPbaRequest(FileName=f))

					pba = []
					for p in res.Pba:
						tdict = {
							'Disk': res.Disk,
							'Host': host,
							'Offset': p.Offset,
							'Length': p.Length,
							'Major': p.Major,
							'Minor': p.Minor
						}

						FM['Pba'].append(tdict)

			return FM

	return

class Trace(lba2pba_pb2_grpc.TraceServicer):
	def Get(self,request,context):

		fName = request.FileName
		volume = request.VolName

		data = getFM(volume,fName)

		if data['Type'] == 'distribute':
			return lba2pba_pb2.TGetPbaResponse(Pba=data['Pba'])
		elif data['Type'] == 'replica':
			return lba2pba_pb2.TGetPbaResponse(RPba=data['rPba'])

def serve():
	server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
	lba2pba_pb2_grpc.add_TraceServicer_to_server(Trace(),server)
	server.add_insecure_port('[::]:23830')
	print("LBA2PBA Trace Start !!")
	server.start()
	server.wait_for_termination()

if __name__ == "__main__":
	logging.basicConfig()
	serve()


#!/usr/bin/env python3

import argparse
import os

from file_organizer import InteractiveFileOrganizer

SOURCE_ROOTS = [
    os.path.join(os.environ["HOME"], "dl"),
]
TARGET_ROOTS = [
    os.path.join(os.environ["HOME"], "dl/books"),
]

RULES = {
    "Tolkien": os.path.join(os.environ["HOME"], "dl/books/others"),
}

def main(argv=None):
    parser = argparse.ArgumentParser()
    parser.add_argument(
        "-t",
        "--threshold",
        default=3,
        type=int,
        help="Minimum word length to consider in candidates.",
    )
    args = parser.parse_args()

    organizer = InteractiveFileOrganizer(
        sources=SOURCE_ROOTS,
        rules=RULES,
        length_threshold=args.threshold,
    )
    for target in TARGET_ROOTS:
        organizer.calculate_actions(target)
    organizer.run()

if __name__ == "__main__":
    from sys import argv

    main(argv)


import sqlite3
from typing import Any, Optional, Tuple

from pypika import Order, Query, Table
from pypika import functions as fn

from entities.http_flow import HttpFlow
from entities.http_request import HttpRequest
from repos.base_repo import BaseRepo

class HttpFlowRepo(BaseRepo):
    table: Table

    def __init__(self):
        super().__init__()
        self.table = Table('http_flows')

    def save(self, flow: HttpFlow):
        # Update or insert the HttpFlow
        if flow.id > 0:
            self.generic_update(flow, self.table)
        else:
            self.generic_insert(flow, self.table)

    def delete(self, flow: HttpFlow):
        self.generic_delete(flow, self.table)

    def find(self, id: int) -> Optional[HttpFlow]:
        query = Query.from_(self.table).select('*').where(self.table.id == id)
        results = self.__find_by_query(query.get_sql(), [])

        if len(results) == 0:
            return None
        return results[0]

    def find_by_uuid(self, uuid: str) -> Optional[HttpFlow]:
        query = Query.from_(self.table).select('*').where(self.table.uuid == uuid)
        results = self.__find_by_query(query.get_sql(), [])

        if len(results) == 0:
            return None
        return results[0]

    def find_for_table(self, search_term: str, offset: int, limit: int) -> Tuple[list[HttpFlow], int]:
        # TODO: These needs to apply host filters from Settings
        if len(search_term) > 0:
            return self.__find_by_search(search_term, offset, limit)

        query = Query.from_(self.table).select('*') \
            .where(self.table.type == HttpFlow.TYPE_PROXY) \
            .orderby(self.table.id, order=Order.desc) \
            .offset(offset).limit(limit)

        count_query = Query.from_(self.table).select(fn.Count('*', alias='count')) \
            .where(self.table.type == HttpFlow.TYPE_PROXY)

        http_flows = self.__find_by_query(query.get_sql(), [])
        count = self.__count_query(count_query.get_sql())

        return http_flows, count

    def find_by_ids(self, ids: list[int]) -> list[HttpFlow]:
        query = Query.from_(self.table).select('*').where(self.table.id.isin(ids))
        return self.__find_by_query(query.get_sql(), [])

    # This is used to find all example flows for a set of flows
    def find_by_http_flow_id(self, http_flow_ids: list[int]) -> list[HttpFlow]:
        query = Query.from_(self.table).select('*').where(self.table.http_flow_id.isin(http_flow_ids))
        return self.__find_by_query(query.get_sql(), [])

    # See https://www.sqlite.org/fts5.html
    #
    # Example queries:
    # host:^"www.google.com"
    # host:"www.google.com" AND path:"complete"
    def __find_by_search(self, search_term: str, offset: int, limit: int) -> Tuple[list[HttpFlow], int]:
        # Wrap quotes around search text if none provided
        # User may want to for more advanced search queries like:
        # host:"synack.com" path:"solutions/talent"
        if '"' not in search_term:
            search_term = f'"{search_term}"*'

        query = "SELECT * FROM http_requests_fts WHERE http_requests_fts MATCH ? ORDER BY rank;"
        cursor = self.conn.cursor()
        cursor.execute(query, [search_term])
        rows: list[sqlite3.Row] = cursor.fetchall()

        request_ids = [r['id'] for r in rows]

        # NOTE: FTS5 will include the http_flow id in the search. We may want to exclude the result if the id
        # matches the search term perfectly. This could exclude valid results however.

        query = Query.from_(self.table).select('*') \
            .where(self.table.request_id.isin(request_ids)).where(self.table.type == HttpFlow.TYPE_PROXY) \
            .orderby(self.table.id, order=Order.desc) \
            .offset(offset).limit(limit)

        count_query = Query.from_(self.table).select(fn.Count('*', alias='count')) \
            .where(self.table.request_id.isin(request_ids)).where(self.table.type == HttpFlow.TYPE_PROXY)

        http_flows = self.__find_by_query(query.get_sql(), [])
        count = self.__count_query(count_query.get_sql())

        return http_flows, count

    def __count_query(self, sql_query: str) -> int:
        cursor = self.conn.cursor()
        cursor.execute(sql_query)
        rows: list[sqlite3.Row] = cursor.fetchall()
        return rows[0]['count']

    def __find_by_query(self, sql_query: str, sql_params: list[Any]) -> list[HttpFlow]:
        cursor = self.conn.cursor()
        cursor.execute(sql_query, sql_params)
        rows: list[sqlite3.Row] = cursor.fetchall()

        # Instantiate the flows
        flows: list[HttpFlow] = []
        for row in rows:
            row_values = self.row_to_dict(row)

            # Load Request
            row_values['request'] = HttpRequest.build_blank_placeholder()

            flow = HttpFlow(**row_values)
            flow.id = row['id']
            flow.created_at = row['created_at']
            flows.append(flow)

        return flows


import requests
import re
import region
a = requests.get('http://tech.emercit.com/state.html')
station_warning = {}
with open('1.txt','w',  encoding='UTF-8') as bb:
    bb.write(a.text.strip())
with open('1.txt', 'r', encoding='UTF-8') as vl:
    b = open('2.txt', 'a', encoding='UTF-8' )
    number_complex = []
    number_bb = []
    post = {}
    for x in vl:
        c = re.findall(r'АГК-....', str(x))
        d = re.findall(r'<td>............</td>', str(x))

        if c != []:
            for y in c:
                number_complex.append(y)
        if d != []:
            for x in d:
                number_bb.append(x[4:-5])

    for i in range(len(number_complex)):
        post[number_complex[i]] = number_bb[i]
        b.write(str(number_bb[i]) + ' ' + '-------->' + ' ' + str(number_complex[i]) + '\n')
    b.close()

    result = open('3.txt', 'a', encoding='UTF-8')
    low_voltage = open('danger.txt','a', encoding='UTF-8')
    chetchik = 0
    chetchik3 = 0
    for z in range(len(number_complex)):
        volt = requests.get('http://emercit.com/tech3/log.php?bb=' + str(number_bb[z]))
        data = re.findall(r'volt\(main=.....', str(volt.content))

        if data != [] and float(data[-2][-5:]) <= 12.0:
            if data[-1][-5:] not in station_warning.keys():
                station_warning[data[-2][-5:]] = number_complex[z]
            else:
                station_warning[data[-2][-5:]+ ' '*chetchik3] = number_complex[z]
            low_voltage.write(str(number_complex[z]) + '-------->' + str(data[-1])[-5:] + '\n')
            chetchik3 += 1
        elif data != []:
            result.write(str(number_bb[z]) + ' ' + '-------->' + ' ' + str(number_complex[z]) + ' ' + '-------->' + ' ' + str(data[-1])[-5:] + '\n')
        else:
            result.write(str(number_bb[z]) + ' ' + '-------->' + ' ' + str(number_complex[z]) + ' ' + '-------->' + ' ' + 'нет данных' + '\n')
            if 'нет данных' not in  station_warning.keys():
                station_warning['нет данных'] = number_complex[z]
            else:
                station_warning['нет данных'+ (" " * chetchik3)] = number_complex[z]
            continue
    result.close()

    low_sorted = open('low_sorted.txt', 'a' , encoding="UTF-8")
    for k in sorted(station_warning.keys()):

        nomer_agk = int(str(station_warning[k])[4:])
        #print(str(nomer_agk))
        print(station_warning[k], '-------->', k)
        for i in region.dict_r.keys():
            for j in region.dict_r[i]:
                if int(j) == nomer_agk:
                    print(str(station_warning[k]) + ' ' + '-------->' + ' '+  str(k) + str(i) + '\n')
                    low_sorted.write(str(station_warning[k]) + ' ' + '-------->' + ' '+  str(k) + ' '+ str(i) + '\n')

    low_sorted.close()


import tkinter
from tkinter import filedialog
import pandas as panda
import numpy as np
import dash
import webbrowser
from dash import dcc
from dash import html
import plotly.express as express
from threading import Timer

root = tkinter.Tk()
root.withdraw()

files = filedialog.askopenfilename()
data = panda.read_csv(files)

data['Categories'] = np.where(data['Description 1' or 'Description 2'].str.contains(
    '', case=False), 'Takeout', "")

data['Categories'] += np.where(data['Description 1' or 'Description 2'].str.contains(
    '', case=False), 'Grocery', "")

data['Categories'] += np.where(data['Description 1' or 'Description 2'].str.contains(
    '', case=False), 'Education', "")

data['Categories'] += np.where(data['Description 1' or 'Description 2'].str.match(
    'fee|Fee|FEE', case=False), 'Debit Charges', "")

Total_Monthly_Expenses_Table = data.groupby(
    'Transaction Date')['Amount'].sum().reset_index(name="sum")
Total_Monthly_Expenses_Chart = express.bar(
    Total_Monthly_Expenses_Table, x="Transaction Date", y="sum", title="Total Monthly Expenses")
Total_Monthly_Expenses_Chart.update_yaxes(
    title="Expenses ($)", visible=True, showticklabels=True)
Total_Monthly_Expenses_Chart.update_xaxes(
    title="Date", visible=True, showticklabels=True)

Expenses_Breakdown_Table = panda.pivot_table(data, values=['Amount'], index=[
                            "Categories",
                            "Transaction Date"], aggfunc=sum).reset_index()
Expenses_Breakdown_Table.columns = [x.upper()
                                    for x in Expenses_Breakdown_Table.columns]
Expenses_Breakdown_Chart = express.line(
    Expenses_Breakdown_Table,
    x="TRANSACTION DATE", y="AMOUNT", title="Expenses Breakdown", color="CATEGORIES")
Expenses_Breakdown_Chart.update_yaxes(
    title="Expenses ($)", visible=True, showticklabels=True)
Expenses_Breakdown_Chart.update_xaxes(
    title="Date", visible=True, showticklabels=True)

app = dash.Dash()

colours = {
    "background": "#333333",
    "HeadText": "#f6f6f6",
    "SubText": "#e3e3e3"
}

Total_Monthly_Expenses_Chart.update_layout(
    plot_bgcolor=colours["background"],
    paper_bgcolor=colours["background"],
    font_color=colours["SubText"]
)

Expenses_Breakdown_Chart.update_layout(
    plot_bgcolor=colours["background"],
    paper_bgcolor=colours["background"],
    font_color=colours["SubText"]
)

latest_date = Expenses_Breakdown_Table['TRANSACTION DATE'].max()
data_latest_date = Expenses_Breakdown_Table.loc[Expenses_Breakdown_Table['TRANSACTION DATE'] == latest_date]

app.layout = html.Div(style={"backgroundColor": colours["background"]},
                      children=[
    html.H1(str(latest_date)+" Total Monthly Expenses ",
            style={"text-align": "c enter", "color": colours["HeadText"]}),
        dcc.Graph(figure=Total_Monthly_Expenses_Chart),
        dcc.Graph(figure=Expenses_Breakdown_Chart)
    ])

port = 8050  #default port (CHANGE IF PORT IS BUSY)

def open_website():
    webbrowser.open_new("http://localhost:{}".format(port))

if __name__ == "__main__":
    Timer(1, open_website).start()
    app.run_server(debug=False, port=port, dev_tools_hot_reload=True)


from typing import List, Tuple

from bs4 import BeautifulSoup

class HtmlGenerator:
    def __init__(self):
        self.last_html_separator = None
        self.html = None
        self.finished_html = False
        self.soup = BeautifulSoup()

    def begin_html_tag(self):
        self.html = self.soup.new_tag("html")
        return self

    def finish_html(self):
        if self.finished_html:
            raise ValueError("Invalid state. Already finished html.")
        if not self.html:
            raise ValueError("Invalid state. Please call 'begin_html_tag' first.")

        self.soup.append(self.html)
        self.finished_html = True
        return self

    def render(self):
        if not self.finished_html:
            self.finish_html()
        return self.soup.prettify()

    def add_basic_table_style(self):
        if not self.html:
            raise ValueError("Invalid state. Please call 'begin_html_tag' first.")

        head = self.soup.new_tag("head")
        style = self.soup.new_tag("style")
        style.string = """
table, th, td {
  border: 1px solid black;
}
"""
        head.append(style)
        self.html.append(head)
        return self

    def append_paragraphs(self, strings: List[str]):
        for line in strings:
            self.append_paragraph(line)
        return self

    def append_paragraph(self, string):
        p = self.soup.new_tag("p")
        p.append(string)
        self.soup.append(p)
        return self

    @staticmethod
    def generate_separator(tag="hr", breaks=2):
        html_sep: str = f"<{tag}/>"
        html_sep += breaks * "
"
        return html_sep

    def append_html_tables(self,
                           table_tups: List[Tuple[str, str]],
                           separator=None,
                           additional_separator_at_beginning=False,
                           header_type="h1"):
        if not self.html:
            raise ValueError("Invalid state. Please call 'begin_html_tag' first.")

        tables_html = ""
        if not separator:
            separator = ""
        ht = header_type

        if additional_separator_at_beginning:
            tables_html += separator

        # header = tup[0], table = tup[1]
        tables_html += separator.join([f"
{tup[0]}
" + tup[1] for tup in table_tups])
        gen_tables_soup = BeautifulSoup(tables_html, "html.parser")
        self.html.append(gen_tables_soup)
        return self


## -*- coding: utf-8 -*-
##
##  Copyright (c) 2008 Ashish Kulkarni <kulkarni.ashish@gmail.com>
##
##  This software is provided 'as-is', without any express or implied
##  warranty.  In no event will the authors be held liable for any damages
##  arising from the use of this software.
##
##  Permission is granted to anyone to use this software for any purpose,
##  including commercial applications, and to alter it and redistribute it
##  freely, subject to the following restrictions:
##
##  1. The origin of this software must not be misrepresented; you must not
##     claim that you wrote the original software. If you use this software
##     in a product, an acknowledgment in the product documentation would be
##     appreciated but is not required.
##  2. Altered source versions must be plainly marked as such, and must not be
##     misrepresented as being the original software.
##  3. This notice may not be removed or altered from any source distribution.

from trac.util.html import Markup
from trac.wiki import format_to_oneliner
from trac.wiki.macros import WikiMacroBase
from genshi.builder import tag

import re, StringIO, inspect

revison = "$Rev$"
url     = "$URL$"

KEY_REGEX    = re.compile('^([^\s]+.*)\:\s*$', re.I)
ATTRIB_REGEX = re.compile('^(\s+)@([^@\s]+?)\:\s*(.+)?$', re.I)

class FlatTableProcessor(WikiMacroBase):
    """WikiProcessor for displaying a table with the markup being entered in a flat form."""

    CONFIG_KEY = 'flat-table'
    DESC_KEY   = '.description'

    def __init__(self):
        self.CONFIG = {}
        self.DESC   = {}
        conf = self.env.config
        for key, ignored in conf.options(self.CONFIG_KEY):
            if key.endswith(self.DESC_KEY):
                continue
            cols = conf.getlist(self.CONFIG_KEY, key)
            self.CONFIG[key] = self._parse_config(cols)
            self.DESC  [key] = conf.get(self.CONFIG_KEY, key+self.DESC_KEY)

    def _parse_config(self, cols):
        config = []
        for col in cols:
            name, val = col.split(':', 1)
            config.append( (name.strip(), [item.strip() for item in val.split()]) )
        return config

    def get_macros(self):
        yield self.CONFIG_KEY
        for key in self.CONFIG.keys():
            yield key

    def get_macro_description(self, name):
        if name == self.CONFIG_KEY:
            return inspect.getdoc(self.__class__)

        doc = self.DESC[name] + '\n'
        doc += " || '''Column Name''' || '''Aliases''' || \n"
        for desc, keys in self.CONFIG[name]:
            doc += ' || ' + desc + ' || ' + ', '.join(keys) + ' || \n'
        return doc

    def expand_macro(self, formatter, name, args):
        if not args:
            return Markup()

        config = None
        if name == self.CONFIG_KEY:
            lines = args.splitlines()
            if not lines or not lines[0].startswith('#!'):
                return Markup()
            config = self._parse_config([i.strip() for i in lines[0][2:].split(',')])
        else:
            config = self.CONFIG[name]

        if not config:
            return Markup()

        def to_html(text):
            if not text:
                return ''
            return Markup('<br>'.join([format_to_oneliner(self.env, formatter.context, line) \
                                for line in text.splitlines()]))

        def has_keys(dict, keys):
            for key in keys:
                if dict.has_key(key):
                    return True
            return False

        rows = self.parse_doc(args)
        if not rows:
            return Markup()

        seen = []
        for desc, keys in config:
            if [row for row in rows if has_keys(row, keys)]:
                seen.append(desc)

        thead = tag.thead()
        for desc, keys in config:
            if not desc in seen:
                continue
            thead(tag.td(tag.b(desc)))

        tbody = tag.tbody()
        for row in rows:
            trow = tag.tr()
            for desc, keys in config:
                if not desc in seen:
                    continue
                tcol = tag.td()
                for key in keys:
                    if row.has_key(key):
                        tcol(to_html(row[key]))
                trow(tcol)
            tbody(trow)

        return tag.table([thead, tbody], class_='wiki')

    def parse_doc(self, text):
        columns = []
        column  = {}
        attr, val, spaces = '', '', ''
        for line in text.splitlines():
            if not line.strip() or line.startswith('#'):
                continue

            match = KEY_REGEX.match(line)
            if match:
                if column:
                    if attr and val:
                        column[attr] = val.strip()
                    columns.append(column)
                column, attr, val, spaces = {}, '', '', ''
                column['key'] = match.group(1)
                continue

            match = ATTRIB_REGEX.match(line)
            if match:
                if val:
                    column[attr] = val.strip()
                spaces = match.group(1)
                attr   = unicode(match.group(2))
                val    = match.group(3) or ''
                continue

            if line.startswith(spaces):
                val += line.strip() + '\n'

        if column:
            if attr and val:
                column[attr] = val.strip()
            columns.append(column)
        return columns


import torch
import torch.nn.functional as F
import lightning.pytorch as pl
import torchmetrics

import os
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.metrics import roc_curve, confusion_matrix, classification_report, auc, ConfusionMatrixDisplay

class VideoClassificationLightningModule(pl.LightningModule):
    def __init__(self, model, args):
        super().__init__()

        self.args = args
        self.model = model
        self.dataloader_length = 0
        self.classes = sorted([i for i in os.listdir(args.train_data_path) if i != '.DS_Store'])

        self.save_hyperparameters("args")

        # For logging outputs
        self.epoch_logits = []
        self.epoch_incorrect_samples = set()

    def forward(self, x):
        return self.model(x)

    def training_step(self, batch, batch_idx):
        return self._common_step(batch, batch_idx, stage='train')

    def validation_step(self, batch, batch_idx):
        self._common_step(batch, batch_idx, stage='val')

    def _common_step(self, batch, batch_idx, stage='train'):
        X, y = batch['video'], batch['label']

        output = self(X.permute(0, 2, 1, 3, 4)) # (8, 3, 16, 224, 224) -> (8, 16, 3, 224, 224)

        loss = F.cross_entropy(output.logits, y)
        acc = torchmetrics.functional.accuracy(output.logits, y, task="multiclass", num_classes=len(self.classes))

        self.log(
            f"{stage}_loss", loss.item(), batch_size=self.args.batch_size, on_step=False, on_epoch=True, prog_bar=True
        )
        self.log(
            f"{stage}_acc", acc, batch_size=self.args.batch_size, on_step=False, on_epoch=True, prog_bar=True
        )
        if stage == 'train':
            return loss
        elif stage == 'val':
            predictions = torch.argmax(output.logits, dim=1)
            incorrect_indices = torch.nonzero(predictions != y).squeeze()  # Get indices of incorrect samples
            incorrect_indices = incorrect_indices.tolist()

            if isinstance(incorrect_indices, int):
                incorrect_indices = [incorrect_indices]
            incorrect_samples = [batch['video_name'][idx] for idx in incorrect_indices]
            self.epoch_logits.extend(output.logits)
            for i in list(set(incorrect_samples)):
                self.epoch_incorrect_samples.add(i)

    def predict_step(self, batch, batch_idx, dataloader_idx=0):
        X, y = batch['video'], batch['label']
        output = self(X.permute(0, 2, 1, 3, 4))

        # Convert the predicted probabilities to class predictions
        y_pred = torch.argmax(output.logits, dim=1)
        y_prob = torch.softmax(output.logits, dim=1)
        y_probs = y_prob.cpu().numpy()

        if batch_idx == 0:
            self.all_y = y.cpu().numpy()
            self.all_y_probs = y_probs
        else:
            self.all_y = np.concatenate([self.all_y, y.cpu().numpy()])
            self.all_y_probs = np.concatenate([self.all_y_probs, y_probs])

        # Perform the computations for the last batch
        if batch_idx == self.dataloader_length - 1:
            # Compute the ROC curve
            fprs = []
            tprs = []
            for i in range(len(self.classes)):
                fpr, tpr, threshold = roc_curve((self.all_y == i), self.all_y_probs[:, i])
                fprs.append(fpr)
                tprs.append(tpr)

            self._plot_roc_curve(fprs, tprs)

            # Generate the confusion matrix
            cm = confusion_matrix(self.all_y, np.argmax(self.all_y_probs, axis=1))

            # Plot the confusion matrix
            self._plot_confusion_matrix(cm)

            # Compute the classification report
            report = classification_report(self.all_y, np.argmax(self.all_y_probs, axis=1), target_names=self.classes)
            print(report)

        return output.logits

    def configure_optimizers(self):
        optimizer = torch.optim.Adam(
            self.parameters(),
            lr=self.args.lr,
        )
        return [optimizer]

    def _plot_roc_curve(self, fprs, tprs):
        # Plot the ROC curve for each class
        plt.figure()
        for i in range(len(self.classes)):
            plt.plot(fprs[i], tprs[i], label=f'Class {self.classes[i]}')
        plt.plot([0, 1], [0, 1], 'k--', label='Random')
        plt.xlabel('FPR')
        plt.ylabel('TPR')
        plt.title('ROC Curve')
        plt.legend()
        plt.savefig('fly_roc.png')

    def _plot_confusion_matrix(self, cm):
        disp = ConfusionMatrixDisplay(confusion_matrix=cm,display_labels=self.classes)
        disp.plot()
        plt.savefig('fly_cm.png')


import sys
from pathlib import Path

import pytorch_lightning as pl
import yaml
from pytorch_lightning.callbacks import ModelCheckpoint
from torch.utils.data import DataLoader
from transformers import set_seed

sys.path.insert(1, "./src")
from datasets.class_dataset import CSVDataset
from models.deroberta_model import PretrainedDeRoBertaClass
from utils.log_reader import TensorBoardReader

if __name__ == '__main__':
    set_seed(42)
    # Config initialisation
    data_config = yaml.load(open("configs/multi_data_config.yaml", 'r'), Loader=yaml.Loader)
    model_config = yaml.load(open("configs/deberta_model_config.yaml", 'r'), Loader=yaml.Loader)
    # Data processing
    train_dataset = CSVDataset(data_config["train_data_path"],
                               is_uncased=data_config["is_uncased"],
                               pretrained_tokenizer=data_config["pretrained_tokenizer_path"],
                               max_length=data_config["max_token_number"])
    val_dataset = CSVDataset(data_config["validate_data_path"],
                             is_uncased=data_config["is_uncased"],
                             pretrained_tokenizer=data_config["pretrained_tokenizer_path"],
                             max_length=data_config["max_token_number"])
    train_dataloader = DataLoader(train_dataset, shuffle=True,
                                  batch_size=data_config["batch_size"])
    val_dataloader = DataLoader(val_dataset, shuffle=False,
                                batch_size=data_config["batch_size"], drop_last=True)
    # Pytorch lightning
    class_model = PretrainedDeRoBertaClass(pretrained_name=model_config["pretrained_model_path"],
                                           model_type=model_config["model_type"],
                                           encoder_vocab_size=len(train_dataset.tokenizer.index2word),
                                           num_classes=len(train_dataset.index2label), lr=model_config["lr"],
                                           total_steps=model_config["epochs"] * len(train_dataloader),
                                           adaptation_epochs=model_config["adaptation_epochs"],
                                           div_factor=model_config["div_factor"],
                                           human_index=train_dataset.label2index[data_config["human_label"]],
                                           is_pooling=model_config["is_pooling"])
    print(class_model)
    class_checkpoint_callback = ModelCheckpoint(filename='best-{epoch}', monitor='val_acc', mode='max', save_top_k=1)
    trainer_args = {
        "accelerator": "gpu",
        "max_epochs": model_config["epochs"],
        "default_root_dir": model_config["log_dir"],
        "callbacks": class_checkpoint_callback
    }
    trainer = pl.Trainer(**trainer_args, enable_progress_bar=True)
    trainer.fit(class_model, train_dataloader, val_dataloader)
    # Plot graphics
    t_reader = TensorBoardReader(Path(model_config["log_dir"]) / Path("lightning_logs"))
    t_reader.plot_tensorboard_graphics()


from firebase_admin import credentials, firestore, initialize_app, _apps, get_app

initialized = False

# Functions needed:
# - List clubs by school ID
# - List students in club by club ID
# - Add student to a club
# - Add administrator to a club
# - Add a club with a school id
def get_interactor():
    global initialized
    dbapp = None
    if initialized == False:
        cred = credentials.Certificate("key.json")
        dbapp = initialize_app(cred, name="Schaumburg Library Hackathon")
        initialized = True
    else:
        dbapp = get_app(name="Schaumburg Library Hackathon")
    print("before")
    db = firestore.client(dbapp)
    print("after")
    interactor = DatabaseInteractor(db)
    return interactor

class Collection:
    collection = None

    def __init__(self, db, collection):
        self.collection = db.collection(collection)

    def create(self, object):
        id = len(self.read_all())
        object["id"] = id
        self.collection.document(str(id)).set(object)
        return id

    def update(self, id, object):
        self.collection.document(str(id)).update(object)

    def read_all(self):
        items = [doc.to_dict() for doc in self.collection.stream()]
        return items

    def read(self, id):
        item = self.collection.document(str(id)).get()
        return item.to_dict()

    def delete(self, id):
        self.collection.document(id).delete()

class DatabaseInteractor:
    def __init__(self, db):
        self.school_collection = Collection(db, 'school')
        self.student_collection = Collection(db, 'student')
        self.club_collection = Collection(db, 'club')
        self.post_collection = Collection(db, 'post')
        self.sponsor_collection = Collection(db, 'sponsor')
        self.comment_collection = Collection(db, 'comment')

    def get_collection(self, collection):
        mapper = {
            'school': self.school_collection,
            'student': self.student_collection,
            'club': self.club_collection,
            'post': self.post_collection,
            'sponsor': self.sponsor_collection,
        }

        return mapper.get(collection)

    def create_comment(self, postId, authorName, content, timestamp):
        # Create school and return ID
        id = self.comment_collection.create({
            "post": postId,
            "author": authorName,
            "content": content,
            "timestamp": timestamp,
        })

        return id

    def create_school(self, name, emailSuffixes, adminEmail):
        # Check that school does not already exist
        schools = self.school_collection.read_all()
        for school in schools:
            if school["name"] == name:
                raise ValueError("School with that name already exists")

        # Create school and return ID
        id = self.school_collection.create({
            "name": name,
            "emailSuffixes": emailSuffixes,
            "adminEmail": adminEmail
        })

        return id

    def create_student(self, schoolId, name, email):
        # Check that school does not already exist
        students = self.student_collection.read_all()
        for student in students:
            if student["name"] == name:
                raise ValueError("Student with that name already exists")

        # Create student and return ID
        id = self.student_collection.create({
            "name": name,
            "email": email,
            "school": schoolId,
            "clubs": [],
        })

        return id

    def create_sponsor(self, schoolId, name, email, tags):
        # Check that school does not already exist
        sponsors = self.sponsor_collection.read_all()
        for sponsor in sponsors:
            if sponsor["name"] == name:
                raise ValueError("Sponsor with that name already exists")

        # Create student and return ID
        id = self.sponsor_collection.create({
            "name": name,
            "email": email,
            "school": schoolId,
            "tags": [],
            "clubs": []
        })

        return id

    def create_club(self, name, tags, studentId, description):
        student = self.student_collection.read(studentId)

        # Check that school does not already exist
        clubs = self.club_collection.read_all()
        for club in clubs:
            if club["name"] == name and club["school"] == student["school"]:
                raise ValueError("Club with that name at that school already exists")

        id = self.club_collection.create({
            "school": student["school"],
            "name": name,
            "tags": tags,
            "posts": 0,
            "administrator": None,
            "students": [studentId],
            "description": description,
        })

        return id

    def create_club_as_sponsor(self, name, tags, sponsorId, description):
        student = self.student_collection.read(sponsorId)

        # Check that school does not already exist
        clubs = self.club_collection.read_all()
        for club in clubs:
            if club["name"] == name and club["school"] == school["id"]:
                raise ValueError("Club with that name at that school already exists")

        id = self.club_collection.create({
            "school": student["school"],
            "name": name,
            "tags": tags,
            "posts": 0,
            "administrator": student,
            "students": [],
            "description": description,
        })

        return id

    def create_club_as_admin(self, name, tags, adminId, description):
        school = self.school_collection.read(adminId)

        # Check that school does not already exist
        clubs = self.club_collection.read_all()
        for club in clubs:
            if club["name"] == name and club["school"] == school["id"]:
                raise ValueError("Club with that name at that school already exists")

        id = self.club_collection.create({
            "school": school["id"],
            "name": name,
            "tags": tags,
            "posts": 0,
            "administrator": None,
            "students": [],
            "description": description,
        })

        return id

    def create_post(self, content, clubId, title, authorName, date):
        id = self.post_collection.create({
            "content": content,
            "title": title,
            "club": clubId,
            "author": authorName,
            "timestamp": date,
        })

        return id

    def add_student_to_club(self, studentId, clubId):
        prevStudent = self.student_collection.read(studentId)
        prevStudent["clubs"].append(clubId)
        self.student_collection.update(studentId, {
            "clubs": prevStudent["clubs"]
        })

        prevClub = self.club_collection.read(clubId)
        prevClub["students"].append(studentId)
        self.club_collection.update(clubId, {
            "students": prevClub["students"]
        })

    def add_sponsor_to_club(self, clubId, sponsorId):
        self.club_collection.update(clubId, {
            "administrator": sponsorId,
        })

    def clubs_by_school_id(self, schoolId):
        clubs = self.club_collection.read_all()
        clubResult = []
        for club in clubs:
            if club["school"] == schoolId:
                clubResult.append(club)

        return clubResult

    def posts_by_club_id(self, clubId):
        posts = self.post_collection.read_all()
        postArr = []
        for post in posts:
            if post["club"] == clubId:
                postArr.append(post)

        return postArr

    def get_student_by_email(self, email):
        students = self.student_collection.read_all()
        for student in students:
            if student["email"] == email:
                return student

        return None

    def get_sponsor_by_email(self, email):
        students = self.sponsor_collection.read_all()
        for student in students:
            if student["email"] == email:
                return student

        return None

    def get_school_by_admin_email(self, email):
        students = self.school_collection.read_all()
        for student in students:
            if student["adminEmail"] == email:
                return student

        return None

    def get_school_by_name(self, name):
        students = self.school_collection.read_all()
        for student in students:
            if student["name"] == email:
                return student

        return None

    def get_school_by_email_ending(self, email_ending):
        students = self.school_collection.read_all()
        for student in students:
            emailSuffixes = student["emailSuffixes"]
            for emailSuffix in emailSuffixes:
                if emailSuffix == email_ending:
                    return student

        return None

    def get_comments_by_post_id(self, postId):
        commResult = []
        comments = self.comment_collection.read_all()
        for comment in comments:
            if int(comment["post"]) == int(postId):
                commResult.append(comment)

        return commResult


import base64
import hashlib

from fastapi.testclient import TestClient
import pytest

from test.conftest import set_preferred_colourmap, unset_preferred_colourmap

class TestChannelSummary:
    @pytest.mark.parametrize(
        "channel_name, expected_summary",
        [
            pytest.param(
                "N_COMP_FF_E",
                {
                    "first_date": "2022-04-07T14:16:16",
                    "most_recent_date": "2022-04-08T16:58:57",
                    "recent_sample": [
                        {"2022-04-08T16:58:57": -8535000.0},
                        {"2022-04-08T16:41:36": -8461000.0},
                        {"2022-04-08T16:29:56": -8582000.0},
                    ],
                },
                id="Scalar channel (number) summary",
            ),
            pytest.param(
                "GEM_SHOT_TYPE_STRING",
                {
                    "first_date": "2022-04-07T14:16:16",
                    "most_recent_date": "2022-04-08T16:58:57",
                    "recent_sample": [
                        {"2022-04-08T16:58:57": "FP"},
                        {"2022-04-08T16:41:36": "FP"},
                        {"2022-04-08T16:29:56": "FP"},
                    ],
                },
                id="Scalar channel (string) summary",
            ),
        ],
    )
    def test_valid_scalar_channel_summary(
        self,
        test_app: TestClient,
        login_and_get_token,
        channel_name,
        expected_summary,
    ):
        test_response = test_app.get(
            f"/channels/summary/{channel_name}",
            headers={"Authorization": f"Bearer {login_and_get_token}"},
        )

        assert test_response.status_code == 200
        assert test_response.json() == expected_summary

    @pytest.mark.parametrize(
        "channel_name, expected_summary, use_preferred_colourmap",
        [
            pytest.param(
                "N_COMP_FF_IMAGE",
                {
                    "first_date": "2022-04-07T14:16:16",
                    "most_recent_date": "2022-04-08T16:58:57",
                    "recent_sample": [
                        {"2022-04-08T16:58:57": "b6a2da4589c22afc212d2dd9079aabe0"},
                        {"2022-04-08T16:41:36": "bff557f25cc563f292d7a65f8cbd6ea4"},
                        {"2022-04-08T16:29:56": "0ed38c29e8eddb50e469b6d6ab4fc5c9"},
                    ],
                },
                False,
                id="Image channel summary (using system default colourmap)",
            ),
            # repeat the above test but with the user's preferred colour map set to
            # check that the preference overrides the system default colour map
            pytest.param(
                "N_COMP_FF_IMAGE",
                {
                    "first_date": "2022-04-07T14:16:16",
                    "most_recent_date": "2022-04-08T16:58:57",
                    "recent_sample": [
                        {"2022-04-08T16:58:57": "3e78b905df05f4b08a188e0fbd7fcc2a"},
                        {"2022-04-08T16:41:36": "d3e6761e20d18344ade71bd5329b1a36"},
                        {"2022-04-08T16:29:56": "183898d6a41f1b3cb1debdcc8ef0942f"},
                    ],
                },
                True,
                id="Image channel summary (using user's preferred colourmap)",
            ),
            pytest.param(
                "N_COMP_SPEC_TRACE",
                {
                    "first_date": "2022-04-07T14:16:16",
                    "most_recent_date": "2022-04-08T16:58:57",
                    "recent_sample": [
                        {"2022-04-08T16:58:57": "c0e0f944d8589c6ac866ffb013a05598"},
                        {"2022-04-08T16:41:36": "6ee54947b79040480bf2a75220d71889"},
                        {"2022-04-08T16:29:56": "928527492ca3bd051d7771c14c61f0f4"},
                    ],
                },
                False,
                id="Waveform channel summary",
            ),
        ],
    )
    def test_valid_thumbnail_channel_summary(
        self,
        test_app: TestClient,
        login_and_get_token,
        channel_name,
        expected_summary,
        use_preferred_colourmap,
    ):

        """
        Compare the response with the expected result, but convert the returned base64
        thumbnails to an MD5 checksum beforehand (to prevent bloating this file with
        long base64 strings)
        """

        set_preferred_colourmap(test_app, login_and_get_token, use_preferred_colourmap)

        test_response = test_app.get(
            f"/channels/summary/{channel_name}",
            headers={"Authorization": f"Bearer {login_and_get_token}"},
        )

        assert test_response.status_code == 200
        json_output = test_response.json()
        for sample in json_output["recent_sample"]:
            for timestamp, checksum in sample.items():
                bytes_thumbnail = base64.b64decode(checksum)
                sample[timestamp] = hashlib.md5(bytes_thumbnail).hexdigest()

        unset_preferred_colourmap(
            test_app,
            login_and_get_token,
            use_preferred_colourmap,
        )

        assert json_output == expected_summary

    @pytest.mark.parametrize(
        "channel_name",
        [
            pytest.param(
                "RANDOM_CHANNEL_NAME",
                id="Channel that doesn't exist",
            ),
            pytest.param(
                1234567,
                id="Integer channel",
            ),
        ],
    )
    def test_invalid_channel_summary(
        self,
        test_app: TestClient,
        login_and_get_token,
        channel_name,
    ):
        test_response = test_app.get(
            f"/channels/summary/{channel_name}",
            headers={"Authorization": f"Bearer {login_and_get_token}"},
        )
        assert test_response.status_code == 400


#coding:utf-8
import time

from lib.protocol.report.GPSReport_protocol import GPSReport_protocol
from lib.protocol.report.ProtocolBase import ProtocolBase
from lib.protocol.appendix.EventClass import EventClass
from lib.protocol.report.SecurityStatusReport_protocol import SecurityStatusReport_protocol

'''
终端上事件数据包
'''

class EventReport_protocol(ProtocolBase):
    #data = {"WATER_CODE":"0003","DEV_ID":"M121501010001","gpsInfo":{"UTCTime":"2020-04-14 11:03:20","latitude":"40.22077","longitude":"116.23128","speed":"80.8","directionAngle":"80.8","elevation":"2999.9","positionStar":"3","Pdop":"0.3","Hdop":"0.4","Vdop":"0.5","statusBit":162,"valtage":"36.9","OBDSpeed":"60.9","engineSpeed":"3000","GPSTotalMileage":"12800","totalOil":"100000","totalTime":"2020002","GPSTimestamp":"1586833400"},"securityData":{"securityStatus":107,"doorStatus":0,"lockStatus":0,"windowStatus":0,"lightStatus":0,"onoffStatusA":0,"onoffStatusB":112,"dataByte":249},"event":{}}
    data = {}
    def __init__(self,msgCount = 1,WATER_CODE = 26,DEV_ID = "M202003060520",locationType=1,eventType="0030",data={}):
        super().__init__()
        self.data = data
        if len(data) == 0:
            self.msgCount = msgCount                             #数据包个数

            self.WATER_CODE = int(WATER_CODE)                    #消息流水号
            self.DEV_ID = DEV_ID                                 #设备id

            self.locationType = int(locationType)                # 定位类型
            #self.GPSPkg = GPSpkg & BaseStationPkg  # GPS包或者基站包
            timeStamp = time.time()
            timeArray = time.localtime(int(timeStamp - 8 * 3600))
            dateTimeM = time.strftime("%Y-%m-%d %H:%M:%S", timeArray)
            timeHex = self.getUTCTime(dateTimeM)
            self.GPSPkg = timeHex + "0265b86206ed8c70026103280000752f03030405af017102610bb800003200000186a0001ed2a25e16fe3a"
            # self.GPSPkg = "1401091213260265b86206ed8c70026103280000752f03030405af017102610bb800003200000186a0001ed2a25e16fe3a"
            self.BaseStationPkg = "1401140a0c050207e407e607e807ea07ec4eea4eec4eee4ef04efc4efe4f004f024f040024025e07d00007a125000927c60000ea610100"
            self.eventType = eventType                           #事件类别
        else:
            self.msgCount = 1  # 数据包个数

            self.WATER_CODE = int(data["WATER_CODE"])               # 消息流水号
            self.DEV_ID = data["DEV_ID"]                            # 设备id

            self.locationType = 1                                   # 定位类型
            gpsInfo = data["gpsInfo"]
            self.gpsInfo = gpsInfo
            securityData = data["securityData"]
            self.securityData = securityData
            event = data["event"]
            self.event = event
            self.GPSPkg = GPSReport_protocol(1,self.WATER_CODE,self.DEV_ID,gpsInfo["UTCTime"],gpsInfo["latitude"],gpsInfo["longitude"]  \
                          ,gpsInfo["speed"],gpsInfo["directionAngle"],gpsInfo["elevation"],gpsInfo["positionStar"],gpsInfo["Pdop"]  \
                          ,gpsInfo["Hdop"],gpsInfo["Vdop"],gpsInfo["statusBit"],gpsInfo["valtage"],gpsInfo["OBDSpeed"],gpsInfo["engineSpeed"]  \
                          ,gpsInfo["GPSTotalMileage"],gpsInfo["totalOil"],gpsInfo["totalTime"],gpsInfo["GPSTimestamp"]).generateGpsData()

            self.securityPkg = SecurityStatusReport_protocol(1,self.WATER_CODE,self.DEV_ID,1,self.GPSPkg,"ffffffffffffffffffff" \
                               ,securityData["securityStatus"],securityData["doorStatus"],securityData["lockStatus"]  \
                               ,securityData["windowStatus"],securityData["lightStatus"],securityData["onoffStatusA"]  \
                               ,securityData["onoffStatusB"],securityData["dataByte"]).generateSecurityStatusData()
            self.BaseStationPkg = "1401140a0c050207e407e607e807ea07ec4eea4eec4eee4ef04efc4efe4f004f024f040024025e07d00007a125000927c60000ea610100"

    def setLatitude(self,data):
        self.latitude = data
    def setLongtitude(self,data):
        self.longitude = data
    def setEventType(self,data):
        self.eventType = data
    def setLocationType(self,data):
        self.locationType = data
    def setGPSPkg(self,data):
        self.GPSPkg = data
    def setBaseStationPkg(self,data):
        self.BaseStationPkg = data

    #####################################################
    #               生成事件信息消息
    #####################################################
    def generateEventMsg(self):
        self.getProtocalHeader()
        info = ""
        #消息头
        HEADER = "4040"
        #消息流水号
        WATER_CODE = self.getWaterCode(self.WATER_CODE)
        #设备id
        DEV_ID = self.devid2hexString(self.DEV_ID)
        # 功能id(GPS功能id)
        FUN_ID = "0021"
        #数据段
        data = ""
        if len(self.data) == 0:
            for i in range(0,self.msgCount):
                data += self.generateEventPkg(self.msgCount,self.generateEventData())
        else:
            for i in range(0,self.msgCount):
                data += self.generateEventPkg(self.msgCount,self.generateEventData_GUI())
            # data += self.generateEventData_GUI()
        # 消息长度
        LENGTH = self.getMsgLength(int(len(WATER_CODE + DEV_ID + FUN_ID + data)/2))

        info += HEADER
        info += LENGTH
        info += WATER_CODE
        info += DEV_ID
        info += FUN_ID
        info += data
        # 校验字段
        CHECK_CODE = self.getCheckCode(info)
        info += CHECK_CODE
        return info

    #####################################################
    #               创建GPS数据包，包含包个数
    #               data:传入GPS数据包的多条数据段
    #####################################################
    def generateEventPkg(self,pkgNum,data):
        pkgNumHex = self.int2hexString(int(pkgNum))
        pkg = pkgNumHex + data
        return pkg

    #####################################################
    #               创建事件信息数据段
    #####################################################
    def generateEventData(self):
        data = ""
        locationType = self.int2hexString(self.locationType)               #定位类型
        locationData = ""                                                  #GPS包或基站包
        if self.locationType == 1:
            locationData = self.GPSPkg
        elif self.locationType == 2:
            locationData = self.BaseStationPkg
        eventType = self.eventType
        extraInfo = self.getExtraData(eventType)                                      #附带信息
        extraInfoLen = self.int2hexStringByBytes(int((len(extraInfo) / 2)),2)                #附带信息长度
        data = locationType + locationData + eventType + extraInfoLen + extraInfo
        return data
    def generateEventData_GUI(self):
        data = ""
        locationType = self.int2hexString(self.locationType)               #定位类型
        locationData = ""                                                  #GPS包或基站包
        if self.locationType == 1:
            locationData = self.GPSPkg
        elif self.locationType == 2:
            locationData = self.BaseStationPkg
        eventData = self.getExtraData_GUI(self.event)
        data = locationType + locationData + eventData
        return data

    #####################################################
    #               获取附带信息
    #####################################################
    def getExtraData(self,eventType):
        if eventType == "0001":                                          #终端插入报警
            return EventClass().terminalInsertionAlarmExtraInfo()
        elif eventType == "0002":                                        #终端拔出报警
            return EventClass().terminalPulloutAlarmExtraInfo()
        elif eventType == "0003":                                        #汽车电瓶低电压报警
            return ""
        elif eventType == "0004":                                        #终端主电断电报警
            return ""
        elif eventType == "0005":                                        #GPS模块故障报
            return ""
        elif eventType == "0006":                                        #GPS天线开路报警
            return ""
        elif eventType == "0007":                                        #GPS天线短路报警
            return ""
        elif eventType == "0008":                                        #GPS定位时间过长报警
            return ""
        elif eventType == "0009":                                        #FLASH故障报警
            return ""
        elif eventType == "000A":                                        #CAN模块故障报警
            return ""
        elif eventType == "000B":                                        #3D传感器故障报警
            return ""
        elif eventType == "000C":                                        #RTC模块故障报警
            return ""
        elif eventType == "000D":                                        #TF卡故障报警
            return ""
        elif eventType == "000E":                                        #刷卡器故障报警
            return ""
        elif eventType == "000F":                                        #汽车预点火上报
            return EventClass().preFiringExtraInfo()
        elif eventType == "0010":                                        #汽车点火上报
            eventObj = EventClass()
            eventObj.setGPSpkg(self.GPSPkg)
            return eventObj.fireExtraInfo()
        elif eventType == "0011":                                        #汽车熄火上报
            eventObj = EventClass()
            eventObj.setGPSpkg(self.GPSPkg)
            return eventObj.misFireExtraInfo()
        elif eventType == "0012":                                        #汽车设防上报
            return EventClass().setUpDefencesExtraInfo()
        elif eventType == "0013":                                        #汽车撤防上报
            return EventClass().setDownDefencesExtraInfo()
        elif eventType == "0014":                                        #锁车未成功提醒
            return EventClass().lockCarFaillExtraInfo()
        elif eventType == "0015":                                        #超时未设防提醒
            return EventClass().noDefencesWithTimeoutExtraInfo()
        elif eventType == "0016":                                        #设防玻璃未关提醒
            return EventClass().defencesGlassNoCloseExtraInfo()
        elif eventType == "0017":                                        #设防非法开门报警
            return EventClass().defencesIllegalCloseDoorExtraInfo()
        elif eventType == "0023":                                        #碰撞告警
            return EventClass().collisionAlarmExtraInfo()
        elif eventType == "0027":                                        #超速报警
            return EventClass().overSpeedAlarm()
        elif eventType == "0028":                                        #疲劳驾驶报警
            return EventClass().tiredDrivingAlarm()
        elif eventType == "0030":                                        #水温报警
            return EventClass().waterTemperatureAlarm()
        elif eventType == "0031":                                        #低水温高转速报警
            return EventClass().lowWaterTemperatureHighEngineSpeed()
        elif eventType == "0032":                                        #怠速时间过长报警
            return EventClass().idlingOverTime()
        elif eventType == "0033":                                        #高速空挡滑行报警
            return EventClass().highSpeedNeutralGearSlide()
        elif eventType == "0036":                                        #低档高速报警
            return EventClass().lowGearHighSpeedAlarm()
        elif eventType == "0037":                                        #高档低速报警
            return EventClass().highGearLowSpeedAlarm()
        elif eventType == "004A":                                        #剩余油量异常告警
            return EventClass().surplusOilAlarm()

    #####################################################
    #               获取附带信息(针对图形界面)
    #####################################################
    def getExtraData_GUI(self,eventData):
        data = ""
        if ("0001" in eventData.keys()):                                           # 终端插入报警
            eventObj = EventClass()
            theData = eventObj.terminalInsertionAlarmExtraInfo()
            data = data + "0001" + self.int2hexStringByBytes(int((len(theData) / 2)), 2) + theData
        if ("0002" in eventData.keys()):                                           # 终端拔出报警
            eventObj = EventClass()
            theData = eventObj.terminalInsertionAlarmExtraInfo()
            data = data + "0002" + self.int2hexStringByBytes(int((len(theData) / 2)), 2) + theData
        if("0003" in eventData.keys()):                                            #汽车电瓶低电压报警
            theData = ""
            data = data + "0003" + self.int2hexStringByBytes(int((len(theData) / 2)),2) + theData
        if ("0004" in eventData.keys()):                                          #终端主电断电报警
            theData = ""
            data = data + "0004" + self.int2hexStringByBytes(int((len(theData) / 2)), 2) + theData
        if ("0010" in eventData.keys()):                                          #汽车点火上报
            eventObj = EventClass()
            eventObj.setGPSpkg(self.GPSPkg)
            eventObj.setSecurityData(self.securityPkg)
            theData = eventObj.fireExtraInfo(int(eventData["0010"]["allRapidlyAccelerateCount"]), int(eventData["0010"]["allSharpSlowdownCount"]), int(eventData["0010"]["allSharpTurn"]))
            data = data + "0010" + self.int2hexStringByBytes(int((len(theData) / 2)), 2) + theData
        if ("0011" in eventData.keys()):                                          #汽车熄火上报
            eventObj = EventClass()
            eventObj.setGPSpkg(self.GPSPkg)
            eventObj.setSecurityData(self.securityPkg)
            theData = eventObj.misFireExtraInfo(int(eventData["0011"]["allRapidlyAccelerateCount"]), int(eventData["0011"]["allSharpSlowdownCount"]), int(eventData["0011"]["allSharpTurn"]))
            data = data + "0011" + self.int2hexStringByBytes(int((len(theData) / 2)), 2) + theData
        if ("0012" in eventData.keys()):                                          #汽车设防上报
            eventObj = EventClass()
            eventObj.setGPSpkg(self.GPSPkg)
            eventObj.setSecurityData(self.securityPkg)
            theData = eventObj.setUpDefencesExtraInfo()
            data = data + "0012" + self.int2hexStringByBytes(int((len(theData) / 2)), 2) + theData
        if ("0013" in eventData.keys()):                                          #汽车撤防上报
            eventObj = EventClass()
            eventObj.setGPSpkg(self.GPSPkg)
            eventObj.setSecurityData(self.securityPkg)
            theData = eventObj.setDownDefencesExtraInfo()
            data = data + "0013" + self.int2hexStringByBytes(int((len(theData) / 2)), 2) + theData
        if ("0020" in eventData.keys()):                                          #急加速
            eventObj = EventClass()
            eventObj.setGPSpkg(self.GPSPkg)
            eventObj.setSecurityData(self.securityPkg)
            theData = eventObj.rapidlyAccelerateExtraInfo(int(eventData["0020"]["allRapidlyAccelerateCount"]),int(eventData["0020"]["allSharpSlowdownCount"]),int(eventData["0020"]["allSharpTurn"]),int(eventData["0020"]["dataProperty"]))
            data = data + "0020" + self.int2hexStringByBytes(int((len(theData) / 2)), 2) + theData
        if ("0021" in eventData.keys()):                                          #急减速
            eventObj = EventClass()
            eventObj.setGPSpkg(self.GPSPkg)
            eventObj.setSecurityData(self.securityPkg)
            theData = eventObj.sharpSlowdownExtraInfo(int(eventData["0021"]["allRapidlyAccelerateCount"]),
                                                          int(eventData["0021"]["allSharpSlowdownCount"]),
                                                          int(eventData["0021"]["allSharpTurn"]),
                                                          int(eventData["0021"]["dataProperty"]))
            data = data + "0021" + self.int2hexStringByBytes(int((len(theData) / 2)), 2) + theData
        if ("0022" in eventData.keys()):                                          #急转弯
            eventObj = EventClass()
            eventObj.setGPSpkg(self.GPSPkg)
            eventObj.setSecurityData(self.securityPkg)
            theData = eventObj.sharpTurnExtraInfo(int(eventData["0022"]["allRapidlyAccelerateCount"]),
                                                          int(eventData["0022"]["allSharpSlowdownCount"]),
                                                          int(eventData["0022"]["allSharpTurn"]),
                                                          int(eventData["0022"]["direction"]),
                                                          int(eventData["0022"]["dataProperty"]))
            data = data + "0022" + self.int2hexStringByBytes(int((len(theData) / 2)), 2) + theData
        if ("0023" in eventData.keys()):                                          # 碰撞告警
            eventObj = EventClass()
            theData = eventObj.collisionAlarmExtraInfo(int(eventData["0023"]["totalCount"]),
                                                  int(eventData["0023"]["dataProperty"]),)
            data = data + "0023" + self.int2hexStringByBytes(int((len(theData) / 2)), 2) + theData
        if ("0027" in eventData.keys()):                                          # 超速告警
            eventObj = EventClass()
            theData = eventObj.overSpeedAlarm(int(eventData["0027"]["alarmType"]),
                                                  int(eventData["0027"]["durationTime"]))
            data = data + "0027" + self.int2hexStringByBytes(int((len(theData) / 2)), 2) + theData
        if ("0028" in eventData.keys()):                                          # 疲劳驾驶告警
            eventObj = EventClass()
            theData = eventObj.tiredDrivingAlarm(int(eventData["0028"]["alarmType"]),
                                                  int(eventData["0028"]["durationTime"]),)
            data = data + "0028" + self.int2hexStringByBytes(int((len(theData) / 2)), 2) + theData
        if ("002A" in eventData.keys()):                                          # 急变道告警
            eventObj = EventClass()
            theData = eventObj.rapidChangeLanes(int(eventData["002A"]["nums"]),
                                                int(eventData["002A"]["direction"]),
                                                float(eventData["002A"]["lng"]),
                                                float(eventData["002A"]["lat"]))
            data = data + "002A" + self.int2hexStringByBytes(int((len(theData) / 2)), 2) + theData
        if ("0032" in eventData.keys()):                                          # 怠速时间过长报警
            eventObj = EventClass()
            theData = eventObj.idlingOverTime(int(eventData["0032"]["alarmType"]),int(eventData["0032"]["durationTime"]),int(eventData["0032"]["oilExpend"]))
            data = data + "0032" + self.int2hexStringByBytes(int((len(theData) / 2)), 2) + theData
        if ("0036" in eventData.keys()):                                          # 低档高速报警
            eventObj = EventClass()
            theData = eventObj.lowGearHighSpeedAlarm(int(eventData["0036"]["alarmType"]),int(eventData["0036"]["durationTime"]))
            data = data + "0036" + self.int2hexStringByBytes(int((len(theData) / 2)), 2) + theData
        if ("0037" in eventData.keys()):                                          # 高档低速报警
            eventObj = EventClass()
            theData = eventObj.lowGearHighSpeedAlarm(int(eventData["0037"]["alarmType"]),int(eventData["0037"]["durationTime"]))
            data = data + "0037" + self.int2hexStringByBytes(int((len(theData) / 2)), 2) + theData
        if ("004A" in eventData.keys()):                                          # 高档低速报警
            eventObj = EventClass()
            theData = eventObj.surplusOilAlarm(int(eventData["004A"]["surplusOilType"]),int(eventData["004A"]["value"]))
            data = data + "004A" + self.int2hexStringByBytes(int((len(theData) / 2)), 2) + theData
        return data

    #####################################################
    #               将UTC时间转换为16进制，
    #        例如：2020-01-02   20:30:00 （年取后面2字节）则将20,01，02,20,30,00 转换为对应的6个字节
    #        theTime:传入一个类似：2020-01-03 13:05:13的一个字符串
    #####################################################
    def getUTCTime(self,theTime):
        # 获取当前时间，时间格式为：2020-01-03 13:05:13
        # now_time = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
        # 将2020-01-03 13:05:13时间格式转换为一个数组
        # timeStr = "2020-01-03 13:05:13"
        timeStr = theTime
        timeArr = []
        timeArr.append(timeStr[2:4])
        timeArr.append(timeStr[5:7])
        timeArr.append(timeStr[8:11])
        timeArr.append(timeStr[11:13])
        timeArr.append(timeStr[14:16])
        timeArr.append(timeStr[17:19])
        UTCTime = ""
        for i in range(0, len(timeArr)):
            UTCTime += self.int2hexString(int(timeArr[i]))
        return UTCTime

if __name__ == "__main__":
    data = {"a":1,"b":2,"c":{"d":3}}
    data = {}
    print(len(data))