from keras import backend as K
import keras
from keras.layers import Layer

import tensorflow as tf

from keras import backend as K

class Attention(Layer):
    def __init__(self, units):

        self.units = units

        super(Attention, self).__init__()

    def build(self, input_shape):

        # Need to know input shapes in order to register
        # number of parameters (weights)

        # These undergo transformations in call(), so can't
        # just build these here and request input_shape
        # and output_shape

        self.W1 = keras.layers.Dense(self.units, activation = 'relu', use_bias = True)
        self.W2 = keras.layers.Dense(self.units, activation = 'relu', use_bias = True)
        self.V = keras.layers.Dense(1, activation = None, use_bias = True)

        super(Attention, self).build(input_shape)

    def compute_output_shape(self, input_shape):

        #Neccessary - automatic inference, gets the shape wrong!

        shape_hidden, shape_values = input_shape
        batch_size = shape_hidden[0]

        shape_context = (batch_size, shape_hidden[1])
        shape_attention_weights = (batch_size, shape_values[1], 1)

        return [shape_context, shape_attention_weights]

    def compute_mask(self, inputs, mask = None):
        return mask

    def count_params(self):
        # A placeholder
        return 42

    def call(self, input):
        query, values = input

        # query = K.print_tensor(query, 'query')
        # values = K.print_tensor(values, 'values')

        # hidden shape == (batch_size, hidden size)
        # hidden_with_time_axis shape == (batch_size, 1, hidden size)
        # we are doing this to perform addition to calculate the score
        hidden_with_time_axis = K.expand_dims(query, 1)

        # score shape == (batch_size, max_length, hidden_size)
        score = self.V(K.tanh(
            self.W1(values) + self.W2(hidden_with_time_axis)))

        # score = K.print_tensor(score, 'score')

        # attention_weights shape == (batch_size, max_length, 1) # 32?
        # we get 1 at the last axis because we are applying score to self.V
        attention_weights = K.softmax(score, axis=1)

        # context_vector shape after sum == (batch_size, hidden_size)
        context_vector = attention_weights * values
        context_vector = K.sum(context_vector, axis=1)

        attention_weights = K.print_tensor(attention_weights, 'attention_weights')

        return [context_vector, attention_weights]

class SoftRecoLayer(Layer):

    def __init__(self, units, **kwargs):
        self.units = units

        self.I = tf.eye(4)
        self.epsilon = 1E-9

        u = tf.constant([[-1, 0, 0, 0]] + 3 * [[0, -1, -1, -1]], tf.float32)

        # Reshape to add batch dimension
        self.u = tf.reshape(u, (1, 4, 4))

        self.attention = Attention(self.units)

        super(SoftRecoLayer, self).__init__(**kwargs)

    def build(self, input_shape):

        super(SoftRecoLayer, self).build(input_shape)

    def call(self, inputs):

        query, values, fourVectorInputs = inputs

        attention_outputs, attention_weights = self.attention([query, values])

        # attention_outputs = K.print_tensor(attention_outputs, 'attention_outputs')
        # attention_weights = K.print_tensor(attention_weights, 'attention_weights')

        restFrame4Vectors = self.calculateWeightedRestFrames(attention_weights, fourVectorInputs)

        # restFrame4Vectors = K.print_tensor(restFrame4Vectors, 'restFrame4Vectors')

        boosts = self.calculateBoosts(restFrame4Vectors)

        fourVectorOutputs = self.applyBoost(boosts, fourVectorInputs)

        return [attention_outputs, attention_weights, fourVectorOutputs]

    def calculateWeightedRestFrames(self, weights, fourVectors):

        # Broadcast weights so that the weight is 'tiled' across each 4v component

        weights = tf.broadcast_to(weights, tf.shape(fourVectors))

        return tf.einsum('Bij, Bij -> Bj', weights, fourVectors)

    def applyBoost(self, boost, fourVectors):

        # (batch, 4, 4) . (batch, n4v, 4) -> (batch, n4v, 4)
        return tf.einsum('Bij, Bki -> Bkj', boost, fourVectors)

    def calculateBoosts(self, restFrame4Vector):

        # Uses the same formulation as arXiv:1812.09722

        # First element (slice to maintain last axis)
        E = restFrame4Vector[:,:1]

        # Last three elements
        p = restFrame4Vector[:,1:]

        beta = p / E

        absBeta = tf.expand_dims(tf.sqrt(tf.reduce_sum(beta ** 2, axis = -1)), -1)

        n = beta / absBeta

        gamma = 1. / tf.sqrt(1. - absBeta ** 2 + self.epsilon)

        e = tf.concat([tf.ones_like(E, tf.float32), -n], -1)

        l1 = self.u + tf.reshape(gamma, (-1, 1, 1))
        l2 = (self.u + 1) * tf.reshape(absBeta, (-1, 1, 1)) - self.u
        l3 = tf.einsum('Bi, Bj -> Bij', e, e)

        lamb = self.I + l1 * l2 * l3

        return lamb

    def compute_output_shape(self, input_shape):

        attentionOutputShape = self.attention.compute_output_shape(input_shape[:-1])

        return attentionOutputShape + [input_shape[-1]]

    def compute_mask(self, inputs, mask = None):

        # Attention outputs has no mask
        # Attention weights has same mask as input to attention
        # Four vectors have same mask as input to attention

        return [None, mask[-1], mask[-1]]

def testAttention():

    inputs = keras.layers.Input((10, 18))
    tracks = keras.layers.Masking(mask_value = -999, name = 'mask')(inputs)

    tracks, hidden = keras.layers.GRU(3, activation = 'relu', return_state = True, return_sequences = True)(tracks)
    context_vector, attention_weights = Attention(128)([hidden, tracks])

    out = keras.layers.Dense(1)(context_vector)

    model = keras.models.Model(inputs = inputs, outputs = out)

    model.summary(line_length = 150)

    testInput = np.random.normal(0, 1, size = (123, 10, 18))
    testTargets = np.random.randint(0, 2, size = 123)

    model.compile(optimizer = 'adam', loss = 'binary_crossentropy', metrics = ['accuracy'])
    model.fit(testInput, testTargets, epochs = 1)

def testReco():

    inputFeatures = keras.layers.Input((10, 18))
    inputFourVectors = keras.layers.Input((10, 4))

    inputFeaturesMasked = keras.layers.Masking(mask_value = -999, name = 'maskFeatures')(inputFeatures)
    inputFourVectorsMasked = keras.layers.Masking(mask_value = -999, name = 'maskFourVectors')(inputFourVectors)

    tracks, hidden = keras.layers.GRU(1, activation = 'relu', return_state = True, return_sequences = True)(inputFeaturesMasked)
    attention_outputs, attention_weights, fourVectorOutputs = SoftRecoLayer(32)([hidden, tracks, inputFourVectorsMasked])

    tracks = keras.layers.Concatenate()([tracks, fourVectorOutputs])

    tracks = keras.layers.GRU(1, activation = 'relu', return_state = False, return_sequences = False)(tracks)

    out = keras.layers.Dense(1)(tracks)

    model = keras.models.Model(inputs = [inputFeatures, inputFourVectors], outputs = out)

    model.summary(line_length = 200)

    testTargets = np.random.randint(0, 2, size = 123)
    testInputFeatures = np.random.normal(0, 1, size = (123, 10, 18))

    import uproot
    import pandas as pd

    dataFile = '/Users/MBP/GoogleDrive/Bu2pipipi_sqDalitz_withVars.h5'
    data = pd.read_hdf(dataFile)

    fourVectorsInput = data[['pip_0_E', 'pip_0_PX', 'pip_0_PY', 'pip_0_PZ']][:123 * 10].values
    fourVectorsInput = fourVectorsInput.reshape((123, 10, 4))

    model.compile(optimizer = 'adam', loss = 'binary_crossentropy', metrics = ['accuracy'])
    model.fit([testInputFeatures, fourVectorsInput], testTargets, epochs = 100)

if __name__ == '__main__':

    import numpy as np

    from pprint import pprint

    testReco()
    # testAttention()


import setuptools

with open("README.md", "r") as fh:
    long_description = fh.read()

with open("requirements.txt", "r") as fh:
    INSTALL_REQUIRES = [l.split('#')[0].strip() for l in fh if not l.strip().startswith('#')]

setuptools.setup(
    name="hurst",
    version="0.0.5",
    author="Dmitry Mottl",
    author_email="dmitry.mottl@gmail.com",
    license="MIT",
    description="Hurst exponent evaluation and R/S-analysis",
    long_description=long_description,
    long_description_content_type="text/markdown",
    url="https://github.com/Mottl/hurst",
    keywords="hurst fractal econometrics time-series",
    packages=setuptools.find_packages(),
    classifiers=[
        "Programming Language :: Python :: 2.7",
        "Programming Language :: Python :: 3",
        "Programming Language :: Python :: 3.4",
        "Programming Language :: Python :: 3.5",
        "Programming Language :: Python :: 3.6",
        "License :: OSI Approved :: MIT License",
        "Operating System :: OS Independent",
        "Topic :: Scientific/Engineering :: Mathematics",
    ],
    install_requires=INSTALL_REQUIRES,
)


import asyncio
import discord
import os
import re
import sys
# import urllib.parse # for links in channel messages
import yaml
from collections import Counter

'''
Tools for interacting with the Discord API - contains functions for:
    - Setting up the Discord client
    - Getting the channel history of a channel
    - Getting the messages from a channel history
    - Getting the content of a message
    - Getting the questions and keywords from messages
'''

with open("utils/yamls/config.yml", "r") as file:
    config = yaml.load(file, Loader=yaml.FullLoader)

# INITIALIZE DISCORD CLIENT
async def init_discord(cancel):
    # Create a Discord client
    if not cancel:
        intents = discord.Intents.default()
        intents.message_content = True
        client = discord.Client(intents=intents)
    else:
        print("CANCELLED")
        return

    if client.is_closed():
        print('Closed client: ', client.status)
        sys.exit()
    else:
        print('Opened client:', client.status)

    @client.event
    async def on_ready():
        # ensure the bot is ready and not stuck in a current activity
        print("The bot is ready!")
        print(f'{client.user} has connected to Discord!')
        print(f'{client.user} status: {client.status}')
        print(f'{client.user} is connected to the following guild:')
        print(f'{client.user} current activity: {client.activity}')

    @client.event
    async def on_disconnect():
        print(f'{client.user} has disconnected from Discord!')

    return client

# GET CHANNEL HISTORY BY ACCOUNT FOR DAYS PASSED IN
async def get_channel_history(channel_id, history_days, cancel):

    print("DISCORD BOT ENTERED")
    # # Create a Discord client
    if not cancel:
        client = await init_discord(cancel)
        discord_token = os.getenv("DISCORD_TOKEN")  # if using python .env file

    else:
        print("CANCELLED")
        return cancel

    try:
        # start discord client
        # TODO: improve logic so that client closes on complete instead of timeout required
        if not cancel:
            task = asyncio.create_task(client.start(discord_token))
            await asyncio.wait_for(task, config["timeout"])
        else:
            print("TASK CANCELLED")
            sys.exit()

        # TODO: modify to display this info properly
        print("Client User: ", client.user)
        print(f'{client.user} status: {client.status}')
        print(f'{client.user} is connected to the following guild:')
        print(f'{client.user} current activity: {client.activity}')
        print("CLIENT STARTED SUCCESSFULLY", client.status)
    except asyncio.TimeoutError:
        print("CLIENT TIMEOUT")
    except discord.errors.LoginFailure as exc:
        print(f'Error: {exc}')
    except discord.errors.ClientException as exc1:
        print(f'Error: {exc1}')
    except discord.errors.HTTPException as exc2:
        print(f'Error: {exc2}')
    except discord.errors.DiscordException as exc4:
        print(f'Error: {exc4}')

    # TODO: add more channels to this list
    print("DISCORD BOT STARTED")

    # UI LOGIC TO PROCESS CHANNEL ID USER INPUT
    # if channel_id == None:
    #     # use channel_id from config id
    #     channel_value = int(config["data_channel_id"])
    #     print("CHANNEL_VALUE: ", channel_value)
    #     channel = client.get_channel(channel_value)
    #     channel_id = channel_value
    #     print("CHANNEL GET SUCCESS FROM NONE: ", channel)

    # else:
    #     print("CHANNEL VALUE RECIEVED: ", channel_id)
    #     # use channel_id passed into UI
    try:
        channel = client.get_channel(int(channel_id))
        print("CHANNEL GET SUCCESS: ", channel)

    except:
        print("CHANNEL GET FAILED")
        sys.exit()

    print("CHANNEL HISTORY: ", history_days)
    print("CHANNEL_ID POST: ", channel_id)
    print("CHANNEL POST: ", channel)

    channel_history = channel.history(limit=history_days, oldest_first=True)

    # done with connection to discord
    # task.cancel()
    # TODO: fix cancel on complete so I don't need to wait whole 15 seconds
    return channel, channel_history

# GET DISCORD MESSAGES IN LOOP AND WRITE TO FILE
async def get_discord_messages(channel_history, outputFile):

    async for message in channel_history:
        # process message here
        # print("MESSAGE CHANNEL: ", message.channel)
        # print("MESSAGE: ", message.content)
        # print("MESSAGE AUTHOR: ", message.author)
        # print("MESSAGE TIMESTAMP: ", message.created_at)
        link = f"https://discord.com/channels/{message.guild.id}/{message.channel.id}/{message.id}"
        # print("LINK TO MESSAGE: ", link)
        # print("\n")
        messages = []
        messages.append(message.content)
        print("DATA: ", message.content, file=outputFile)
        print("AUTHOR: ", message.author, file=outputFile)
        print("TIMESTAMP: ", message.created_at, file=outputFile)
        print("LINK: ", link, file=outputFile)
        outputFile.write("\n")

    return messages, outputFile

messages = []
questions = []

# GET POTENTIAL QUESTIONS FROM DISCORD MESSAGES
async def get_questions(chat_history):
    async for message in chat_history:
        messages.append(message.content)
        # print("MESSAGE: ", message.content)
        question_counts = Counter()
        question_words = ["what", "when", "where", "who",
                          "why", "how", "can", "could", "would", "should"]
        for word in question_words:
            if word in message.content:
                questions.append(message.content)
            question_counts[word] += message.content.lower().count(word)
        # print("QUESTION COUNTS: ", question_counts)
        # print("QUESTIONS: ", questions)
        # top_3_questions = question_counts.most_common(3)
        # return print("Top 3 commonly asked questions: ", top_3_questions)
    return messages

# FIND KEYWORDS IN DISCORD MESSAGES
async def get_keywords(channel_history):
    async for message in channel_history:
        word_counts = Counter()
        stopwords = ["the", "and", "I", "to", "in", "a", "of", "is", "it",
                     "you", "that", "he", "was", "for", "on", "are", "as",
                     "with", "his", "they", "I'm", "at", "be", "this", "have",
                     "from", "or", "one", "had", "by", "word", "but", "not", "what",
                     "all", "were", "we", "when", "your", "can", "said", "there", "use",
                     "an", "each", "which", "she", "do", "how", "their", "if", "will",
                     "up", "other", "about", "out", "many", "then", "them", "these", "so",
                     "some", "her", "would", "make", "like", "him", "into", "time", "has",
                     "look", "two", "more", "write", "go", "see", "number", "no", "way",
                     "could", "people", "my", "than", "first", "water", "been", "call",
                     "who", "oil", "its", "now", "find", "long", "down", "day", "did",
                     "get", "come", "made", "may", "part", "<#943011412219920415>"]
        words = message.content.split()
        words = [word for word in words if word not in stopwords]
        word_counts.update(words)
        top_3_keywords = word_counts.most_common(3)

        # incoporate links when channel that has them is included
        # if re.match(f"^{question_words}", message.content, re.IGNORECASE):
        #     question_counts.update([message.content])
        # if re.search(r'\?$', message.content):
        #     question_counts.update([message.content])

        # print("Top 3 keywords: ", top_3_keywords)
        # print("\n")

        return top_3_keywords


import resources_fin

from PyQt5 import QtCore, QtGui, QtWidgets
from buttons_handler import ButtonsHandler
from db_processor import Insert

class Ui_MainWindow(object):
        def setupUi(self, MainWindow):
                MainWindow.setObjectName("MainWindow")
                MainWindow.resize(822, 600)
                MainWindow.setMinimumSize(QtCore.QSize(822, 600))
                MainWindow.setMaximumSize(QtCore.QSize(822, 600))
                icon = QtGui.QIcon()
                icon.addPixmap(QtGui.QPixmap(":/icons_new/icons_new/analysis (1).svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
                MainWindow.setWindowIcon(icon)
                MainWindow.setStyleSheet("*{\n"
        "    font-family: Bahnschrift;\n"
        "    color: white;\n"
        "    border: nine;\n"
        "}\n"
        "\n"
        "#info_frame{\n"
        "    background-color: rgb(27, 33, 37);\n"
        "    border-radius: 15px;\n"
        "}\n"
        "\n"
        "#stackedWidget{\n"
        "    border: 2px solid  black;\n"
        "    border-radius: 15px;\n"
        "}\n"
        "\n"
        "#frame{\n"
        "    border: 2px solid  black;\n"
        "    border-radius: 15px;\n"
        "}\n"
        "#frame_2{\n"
        "    border: 2px solid  black;\n"
        "    border-radius: 15px;\n"
        "}\n"
        "\n"
        "#menu_frame QPushButton{\n"
        "    background-color: rgb(27, 33, 37);\n"
        "    border-radius: 15px;\n"
        "}\n"
        "\n"
        "#analyse_frame_btns QPushButton{\n"
        "    background-color: rgb(27, 33, 37);\n"
        "    border-radius: 15px;\n"
        "}\n"
        "#analyse_frame_btns QPushButton::hover, #menu_frame QPushButton::hover{\n"
        "   background-color: black;\n"
        "}\n"
        "")
                MainWindow.setToolButtonStyle(QtCore.Qt.ToolButtonIconOnly)
                self.centralwidget = QtWidgets.QWidget(MainWindow)
                self.centralwidget.setStyleSheet("")
                self.centralwidget.setObjectName("centralwidget")
                self.horizontalLayout = QtWidgets.QHBoxLayout(self.centralwidget)
                self.horizontalLayout.setObjectName("horizontalLayout")
                self.frame = QtWidgets.QFrame(self.centralwidget)
                self.frame.setEnabled(True)
                self.frame.setMaximumSize(QtCore.QSize(250, 16777215))
                self.frame.setMouseTracking(False)
                self.frame.setTabletTracking(False)
                self.frame.setStyleSheet("")
                self.frame.setFrameShape(QtWidgets.QFrame.StyledPanel)
                self.frame.setFrameShadow(QtWidgets.QFrame.Raised)
                self.frame.setMidLineWidth(0)
                self.frame.setObjectName("frame")
                self.verticalLayout = QtWidgets.QVBoxLayout(self.frame)
                self.verticalLayout.setObjectName("verticalLayout")
                self.frame_3 = QtWidgets.QFrame(self.frame)
                self.frame_3.setStyleSheet("")
                self.frame_3.setFrameShape(QtWidgets.QFrame.StyledPanel)
                self.frame_3.setFrameShadow(QtWidgets.QFrame.Raised)
                self.frame_3.setObjectName("frame_3")
                self.horizontalLayout_2 = QtWidgets.QHBoxLayout(self.frame_3)
                self.horizontalLayout_2.setObjectName("horizontalLayout_2")
                self.label = QtWidgets.QLabel(self.frame_3)
                font = QtGui.QFont()
                font.setFamily("Bahnschrift")
                self.label.setFont(font)
                self.label.setStyleSheet("")
                self.label.setText("")
                self.label.setPixmap(QtGui.QPixmap(":/images_fin/images_final/bpkey.png"))
                self.label.setScaledContents(False)
                self.label.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter)
                self.label.setObjectName("label")
                self.horizontalLayout_2.addWidget(self.label)
                self.verticalLayout.addWidget(self.frame_3)
                self.menu_frame = QtWidgets.QFrame(self.frame)
                self.menu_frame.setFrameShape(QtWidgets.QFrame.StyledPanel)
                self.menu_frame.setFrameShadow(QtWidgets.QFrame.Raised)
                self.menu_frame.setObjectName("menu_frame")
                self.verticalLayout_2 = QtWidgets.QVBoxLayout(self.menu_frame)
                self.verticalLayout_2.setObjectName("verticalLayout_2")
                self.go_to_analyses_btn = QtWidgets.QPushButton(self.menu_frame)
                self.go_to_analyses_btn.setMinimumSize(QtCore.QSize(0, 40))
                self.go_to_analyses_btn.setMaximumSize(QtCore.QSize(16777215, 50))
                font = QtGui.QFont()
                font.setFamily("Bahnschrift")
                font.setPointSize(16)
                self.go_to_analyses_btn.setFont(font)
                self.go_to_analyses_btn.setStyleSheet("")
                icon1 = QtGui.QIcon()
                icon1.addPixmap(QtGui.QPixmap(":/icons_fin/icons_final/analysis (1).svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
                self.go_to_analyses_btn.setIcon(icon1)
                self.go_to_analyses_btn.setObjectName("go_to_analyses_btn")
                self.verticalLayout_2.addWidget(self.go_to_analyses_btn)
                self.go_to_library_btn = QtWidgets.QPushButton(self.menu_frame)
                self.go_to_library_btn.setMinimumSize(QtCore.QSize(0, 40))
                self.go_to_library_btn.setMaximumSize(QtCore.QSize(16777215, 50))
                font = QtGui.QFont()
                font.setFamily("Bahnschrift")
                font.setPointSize(16)
                self.go_to_library_btn.setFont(font)
                icon2 = QtGui.QIcon()
                icon2.addPixmap(QtGui.QPixmap(":/icons_fin/icons_final/library-books.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
                self.go_to_library_btn.setIcon(icon2)
                self.go_to_library_btn.setObjectName("go_to_library_btn")
                self.verticalLayout_2.addWidget(self.go_to_library_btn)
                self.verticalLayout.addWidget(self.menu_frame)
                self.size_grip_left_1 = QtWidgets.QFrame(self.frame)
                self.size_grip_left_1.setFrameShape(QtWidgets.QFrame.StyledPanel)
                self.size_grip_left_1.setFrameShadow(QtWidgets.QFrame.Raised)
                self.size_grip_left_1.setObjectName("size_grip_left_1")
                self.verticalLayout.addWidget(self.size_grip_left_1)
                self.size_grip_left_2 = QtWidgets.QFrame(self.frame)
                self.size_grip_left_2.setFrameShape(QtWidgets.QFrame.StyledPanel)
                self.size_grip_left_2.setFrameShadow(QtWidgets.QFrame.Raised)
                self.size_grip_left_2.setObjectName("size_grip_left_2")
                self.verticalLayout.addWidget(self.size_grip_left_2)
                self.horizontalLayout.addWidget(self.frame)
                self.frame_2 = QtWidgets.QFrame(self.centralwidget)
                self.frame_2.setMaximumSize(QtCore.QSize(800, 16777215))
                self.frame_2.setFrameShape(QtWidgets.QFrame.StyledPanel)
                self.frame_2.setFrameShadow(QtWidgets.QFrame.Raised)
                self.frame_2.setObjectName("frame_2")
                self.verticalLayout_3 = QtWidgets.QVBoxLayout(self.frame_2)
                self.verticalLayout_3.setObjectName("verticalLayout_3")
                self.stackedWidget = QtWidgets.QStackedWidget(self.frame_2)
                self.stackedWidget.setObjectName("stackedWidget")
                self.analyse_page = QtWidgets.QWidget()
                self.analyse_page.setObjectName("analyse_page")
                self.verticalLayout_6 = QtWidgets.QVBoxLayout(self.analyse_page)
                self.verticalLayout_6.setObjectName("verticalLayout_6")
                self.frame_7 = QtWidgets.QFrame(self.analyse_page)
                self.frame_7.setMinimumSize(QtCore.QSize(0, 50))
                self.frame_7.setFrameShape(QtWidgets.QFrame.StyledPanel)
                self.frame_7.setFrameShadow(QtWidgets.QFrame.Raised)
                self.frame_7.setObjectName("frame_7")
                self.verticalLayout_7 = QtWidgets.QVBoxLayout(self.frame_7)
                self.verticalLayout_7.setObjectName("verticalLayout_7")
                self.analyse_label = QtWidgets.QLabel(self.frame_7)
                self.analyse_label.setText("")
                self.analyse_label.setPixmap(QtGui.QPixmap(":/images_fin/images_final/analyse.png"))
                self.analyse_label.setScaledContents(True)
                self.analyse_label.setObjectName("analyse_label")
                self.verticalLayout_7.addWidget(self.analyse_label)
                self.verticalLayout_6.addWidget(self.frame_7)
                self.analyse_frame = QtWidgets.QFrame(self.analyse_page)
                sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Expanding)
                sizePolicy.setHorizontalStretch(0)
                sizePolicy.setVerticalStretch(0)
                sizePolicy.setHeightForWidth(self.analyse_frame.sizePolicy().hasHeightForWidth())
                self.analyse_frame.setSizePolicy(sizePolicy)
                self.analyse_frame.setFrameShape(QtWidgets.QFrame.StyledPanel)
                self.analyse_frame.setFrameShadow(QtWidgets.QFrame.Raised)
                self.analyse_frame.setObjectName("analyse_frame")
                self.horizontalLayout_4 = QtWidgets.QHBoxLayout(self.analyse_frame)
                self.horizontalLayout_4.setObjectName("horizontalLayout_4")
                self.frame_9 = QtWidgets.QFrame(self.analyse_frame)
                self.frame_9.setFrameShape(QtWidgets.QFrame.StyledPanel)
                self.frame_9.setFrameShadow(QtWidgets.QFrame.Raised)
                self.frame_9.setObjectName("frame_9")
                self.verticalLayout_8 = QtWidgets.QVBoxLayout(self.frame_9)
                self.verticalLayout_8.setObjectName("verticalLayout_8")
                self.note_label_image = QtWidgets.QLabel(self.frame_9)
                self.note_label_image.setMinimumSize(QtCore.QSize(218, 218))
                self.note_label_image.setMaximumSize(QtCore.QSize(218, 218))
                self.note_label_image.setText("")
                self.note_label_image.setPixmap(QtGui.QPixmap(":/images_fin/images_final/note.png"))
                self.note_label_image.setScaledContents(True)
                self.note_label_image.setObjectName("note_label_image")
                self.verticalLayout_8.addWidget(self.note_label_image)
                self.horizontalLayout_4.addWidget(self.frame_9)
                self.info_frame = QtWidgets.QFrame(self.analyse_frame)
                self.info_frame.setMinimumSize(QtCore.QSize(218, 218))
                self.info_frame.setMaximumSize(QtCore.QSize(218, 218))
                self.info_frame.setFrameShape(QtWidgets.QFrame.StyledPanel)
                self.info_frame.setFrameShadow(QtWidgets.QFrame.Raised)
                self.info_frame.setObjectName("info_frame")
                self.gridLayout = QtWidgets.QGridLayout(self.info_frame)
                self.gridLayout.setObjectName("gridLayout")
                self.key_label_image = QtWidgets.QLabel(self.info_frame)
                self.key_label_image.setMinimumSize(QtCore.QSize(0, 0))
                font = QtGui.QFont()
                font.setFamily("Bahnschrift")
                font.setPointSize(16)
                self.key_label_image.setFont(font)
                self.key_label_image.setText("")
                self.key_label_image.setPixmap(QtGui.QPixmap(":/images_fin/images_final/key.png"))
                self.key_label_image.setScaledContents(True)
                self.key_label_image.setObjectName("key_label_image")
                self.gridLayout.addWidget(self.key_label_image, 2, 0, 1, 1)
                self.name_label_image = QtWidgets.QLabel(self.info_frame)
                font = QtGui.QFont()
                font.setFamily("Bahnschrift")
                font.setPointSize(16)
                self.name_label_image.setFont(font)
                self.name_label_image.setText("")
                self.name_label_image.setPixmap(QtGui.QPixmap(":/images_fin/images_final/name.png"))
                self.name_label_image.setScaledContents(True)
                self.name_label_image.setObjectName("name_label_image")
                self.gridLayout.addWidget(self.name_label_image, 0, 0, 1, 1)
                self.bpm_label_image = QtWidgets.QLabel(self.info_frame)
                font = QtGui.QFont()
                font.setFamily("Bahnschrift")
                font.setPointSize(16)
                self.bpm_label_image.setFont(font)
                self.bpm_label_image.setText("")
                self.bpm_label_image.setPixmap(QtGui.QPixmap(":/images_fin/images_final/bpm.png"))
                self.bpm_label_image.setScaledContents(True)
                self.bpm_label_image.setObjectName("bpm_label_image")
                self.gridLayout.addWidget(self.bpm_label_image, 1, 0, 1, 1)
                self.name_label = QtWidgets.QLabel(self.info_frame)
                font = QtGui.QFont()
                font.setFamily("Bahnschrift")
                font.setPointSize(16)
                self.name_label.setFont(font)
                self.name_label.setAlignment(QtCore.Qt.AlignCenter)
                self.name_label.setObjectName("name_label")
                self.gridLayout.addWidget(self.name_label, 0, 1, 1, 1)
                self.bpm_label = QtWidgets.QLabel(self.info_frame)
                font = QtGui.QFont()
                font.setFamily("Bahnschrift")
                font.setPointSize(16)
                self.bpm_label.setFont(font)
                self.bpm_label.setAlignment(QtCore.Qt.AlignCenter)
                self.bpm_label.setObjectName("bpm_label")
                self.gridLayout.addWidget(self.bpm_label, 1, 1, 1, 1)
                self.key_label = QtWidgets.QLabel(self.info_frame)
                font = QtGui.QFont()
                font.setFamily("Bahnschrift")
                font.setPointSize(16)
                self.key_label.setFont(font)
                self.key_label.setAlignment(QtCore.Qt.AlignCenter)
                self.key_label.setObjectName("key_label")
                self.gridLayout.addWidget(self.key_label, 2, 1, 1, 1)
                self.horizontalLayout_4.addWidget(self.info_frame)
                self.verticalLayout_6.addWidget(self.analyse_frame)
                self.analyse_frame_btns = QtWidgets.QFrame(self.analyse_page)
                self.analyse_frame_btns.setMinimumSize(QtCore.QSize(0, 60))
                self.analyse_frame_btns.setFrameShape(QtWidgets.QFrame.StyledPanel)
                self.analyse_frame_btns.setFrameShadow(QtWidgets.QFrame.Raised)
                self.analyse_frame_btns.setObjectName("analyse_frame_btns")
                self.horizontalLayout_3 = QtWidgets.QHBoxLayout(self.analyse_frame_btns)
                self.horizontalLayout_3.setObjectName("horizontalLayout_3")
                self.open_file_btn = QtWidgets.QPushButton(self.analyse_frame_btns)
                self.open_file_btn.setMinimumSize(QtCore.QSize(0, 40))
                font = QtGui.QFont()
                font.setFamily("Bahnschrift")
                font.setPointSize(16)
                self.open_file_btn.setFont(font)
                icon3 = QtGui.QIcon()
                icon3.addPixmap(QtGui.QPixmap(":/icons_fin/icons_final/upload-folder.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
                self.open_file_btn.setIcon(icon3)
                self.open_file_btn.setObjectName("open_file_btn")
                self.horizontalLayout_3.addWidget(self.open_file_btn)
                self.analyse_btn = QtWidgets.QPushButton(self.analyse_frame_btns)
                self.analyse_btn.setEnabled(False)
                self.analyse_btn.setMinimumSize(QtCore.QSize(0, 40))
                self.analyse_btn.setStyleSheet("background-color: grey;")
                font = QtGui.QFont()
                font.setFamily("Bahnschrift")
                font.setPointSize(16)
                self.analyse_btn.setFont(font)
                icon4 = QtGui.QIcon()
                icon4.addPixmap(QtGui.QPixmap(":/icons_fin/icons_final/setting.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
                self.analyse_btn.setIcon(icon4)
                self.analyse_btn.setObjectName("analyse_btn")
                self.horizontalLayout_3.addWidget(self.analyse_btn)
                self.verticalLayout_6.addWidget(self.analyse_frame_btns)
                self.stackedWidget.addWidget(self.analyse_page)
                self.library_page = QtWidgets.QWidget()
                self.library_page.setObjectName("library_page")
                self.verticalLayout_4 = QtWidgets.QVBoxLayout(self.library_page)
                self.verticalLayout_4.setObjectName("verticalLayout_4")
                self.frame_5 = QtWidgets.QFrame(self.library_page)
                self.frame_5.setMinimumSize(QtCore.QSize(0, 50))
                self.frame_5.setFrameShape(QtWidgets.QFrame.StyledPanel)
                self.frame_5.setFrameShadow(QtWidgets.QFrame.Raised)
                self.frame_5.setObjectName("frame_5")
                self.verticalLayout_5 = QtWidgets.QVBoxLayout(self.frame_5)
                self.verticalLayout_5.setObjectName("verticalLayout_5")
                self.library_label = QtWidgets.QLabel(self.frame_5)
                self.library_label.setMinimumSize(QtCore.QSize(480, 53))
                font = QtGui.QFont()
                font.setFamily("Bahnschrift")
                font.setPointSize(22)
                self.library_label.setFont(font)
                self.library_label.setText("")
                self.library_label.setPixmap(QtGui.QPixmap(":/images_fin/images_final/library.png"))
                self.library_label.setScaledContents(True)
                self.library_label.setObjectName("library_label")
                self.verticalLayout_5.addWidget(self.library_label, 0, QtCore.Qt.AlignLeft)
                self.verticalLayout_4.addWidget(self.frame_5, 0, QtCore.Qt.AlignTop)
                self.frame_6 = QtWidgets.QFrame(self.library_page)
                sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Expanding)
                sizePolicy.setHorizontalStretch(0)
                sizePolicy.setVerticalStretch(0)
                sizePolicy.setHeightForWidth(self.frame_6.sizePolicy().hasHeightForWidth())
                self.frame_6.setSizePolicy(sizePolicy)
                self.frame_6.setFrameShape(QtWidgets.QFrame.StyledPanel)
                self.frame_6.setFrameShadow(QtWidgets.QFrame.Raised)
                self.frame_6.setObjectName("frame_6")

                #scroll_area

                self.verticalLayout_9 = QtWidgets.QVBoxLayout(self.frame_6)
                self.verticalLayout_9.setObjectName("verticalLayout_9")
                self.scrollArea = QtWidgets.QScrollArea(self.frame_6)
                self.scrollArea.setMinimumSize(QtCore.QSize(485, 300))
                self.scrollArea.setMaximumSize(QtCore.QSize(485, 300))
                self.scrollArea.setStyleSheet("border-radius: 15px;\n"
                                              "border: nine;")
                self.scrollArea.setWidgetResizable(True)
                self.scrollArea.setObjectName("scrollArea")
                self.scrollAreaWidgetContents_2 = QtWidgets.QWidget()
                self.scrollAreaWidgetContents_2.setGeometry(QtCore.QRect(0, 0, 485, 300))
                self.scrollAreaWidgetContents_2.setObjectName("scrollAreaWidgetContents_2")
                self.scrollArea.setWidget(self.scrollAreaWidgetContents_2)
                self.verticalLayout_9.addWidget(self.scrollArea)

                #end of scroll area

                self.verticalLayout_4.addWidget(self.frame_6)
                self.stackedWidget.addWidget(self.library_page)
                self.verticalLayout_3.addWidget(self.stackedWidget)
                self.size_grip_right_1 = QtWidgets.QFrame(self.frame_2)
                self.size_grip_right_1.setMinimumSize(QtCore.QSize(0, 135))
                self.size_grip_right_1.setFrameShape(QtWidgets.QFrame.StyledPanel)
                self.size_grip_right_1.setFrameShadow(QtWidgets.QFrame.Raised)
                self.size_grip_right_1.setObjectName("size_grip_right_1")
                self.verticalLayout_3.addWidget(self.size_grip_right_1)
                self.horizontalLayout.addWidget(self.frame_2)
                MainWindow.setCentralWidget(self.centralwidget)

                self.retranslateUi(MainWindow)
                self.stackedWidget.setCurrentIndex(0)
                QtCore.QMetaObject.connectSlotsByName(MainWindow)

        def retranslateUi(self, MainWindow):
                _translate = QtCore.QCoreApplication.translate
                MainWindow.setWindowTitle(_translate("BPKEY", "BPKEY"))
                self.go_to_analyses_btn.setText(_translate("MainWindow", "Analyze Audio"))
                self.go_to_library_btn.setText(_translate("MainWindow", "Your Library"))
                self.name_label.setText(_translate("MainWindow", "Unknown"))
                self.bpm_label.setText(_translate("MainWindow", "Unknown"))
                self.key_label.setText(_translate("MainWindow", "Unknown"))
                self.open_file_btn.setText(_translate("MainWindow", "Open Audio File"))
                self.analyse_btn.setText(_translate("MainWindow", "Analyze"))

        # btn connections
        def connections(self):
                btn_handler = ButtonsHandler(self.name_label, self.bpm_label, self.key_label, self.analyse_btn)
                self.open_file_btn.clicked.connect(lambda: btn_handler.open_file())
                self.analyse_btn.clicked.connect(lambda: btn_handler.analyze())
                self.go_to_analyses_btn.clicked.connect(lambda: self.stackedWidget.setCurrentIndex(0))
                self.go_to_library_btn.clicked.connect(lambda: self.stackedWidget.setCurrentIndex(1))
                self.go_to_library_btn.clicked.connect(lambda: Insert().insert(self.scrollArea))


import pandas as pd
import matplotlib.pyplot as plt
import math as math
import numpy as np
from scipy.stats import chisquare
from scipy import stats

# import training data
filepath = 'train.csv'
data = pd.read_csv(filepath)
print(data.describe())

# look into sex feature
survived_sex = pd.crosstab(index=data["Survived"],
                           columns=data["Sex"], margins=True)

print(survived_sex)
# print chisquared test of independence between sex and survival
print(chisquare(f_obs = [81, 468, 233, 109], f_exp = [193.47, 355.53, 120.5, 221.47]))

# look into fare feature
fares_survivors = data.Fare[data.Survived == True]
fares_died = data.Fare[data.Survived == False]
print(stats.ttest_ind(fares_survivors,fares_died, equal_var=False))
print(fares_survivors.mean())
print(fares_died.mean())

# plotting boxplots of age, pclass, sibsp and fare
plt.figure()
boxplot = data.boxplot(column = ['Age', 'Pclass', 'SibSp', 'Fare'])

# passengers with a higher fare were more likely to survive

# could also look into name and extract titles
print(data.Name)

# feature engineering: make a new variable of total family members
familymembers = data.SibSp + data.Parch
print(familymembers)

data_copied = data.copy()
data_copied['fammembers'] = familymembers

plt.figure()
boxplot = data_copied.boxplot(column = ['fammembers'])

survivor_fammembers = data_copied.fammembers[data_copied.Survived == True]
died_fammembers = data_copied.fammembers[data_copied.Survived == False]

# plot family members of surviving passengers
df_fammembers_surv = pd.DataFrame(data = survivor_fammembers)
plt.figure()
boxplot = df_fammembers_surv.boxplot(column = ['fammembers'])

# plot family members of dead passengers
df_fammembers_died = pd.DataFrame(data = died_fammembers)
plt.figure()
boxplot = df_fammembers_died.boxplot(column = ['fammembers'])

print(stats.ttest_ind(survivor_fammembers,died_fammembers, equal_var=True))
print(survivor_fammembers.mean())
print(died_fammembers.mean())

# add 1 (minimum value) to be able to take logs later
survivor_fammembers_ed = survivor_fammembers + 1
died_fammembers_ed = died_fammembers + 1

# add logarithm of family members to survival dataframe
df_fammembers_surv['logfammembers'] = np.log(np.array(survivor_fammembers_ed))

print(df_fammembers_surv.head())

# add logarithm of family members to dead dataframe

df_fammembers_died['logfammembers'] = np.log(np.array(died_fammembers_ed))

print(df_fammembers_died.head())

# t test between the logarithms
print(stats.ttest_ind(df_fammembers_surv['logfammembers'],df_fammembers_died['logfammembers'], equal_var=False))

# plot logs of family members
plt.figure()
boxplot = df_fammembers_surv.boxplot(column = ['logfammembers'])

#df_fammembers_died = pd.DataFrame(data = died_fammembers)

plt.figure()
boxplot = df_fammembers_died.boxplot(column = ['logfammembers'])

print(survivor_fammembers_ed.mean())
print(died_fammembers_ed.mean())
plt.show()

#print(df_fammembers)


import azure.functions as func
try:
    from azure.functions import AsgiMiddleware
except ImportError:
    from _future.azure.functions._http_asgi import AsgiMiddleware

import mimesis
from api_app import app  # Our main API application
from typing import Optional
from pydantic import BaseModel

class FoodItem(BaseModel):
    id: int
    vegetable: str
    dish: str
    drink: str

@app.get("/food/{food_id}")
async def get_food(
    food_id: int,
):
    food = mimesis.Food()
    return {
        "food_id": food_id,
        "vegetable": food.vegetable(),
        "dish": food.dish(),
        "drink": food.drink(),
    }

@app.post("/food/")
async def create_food(food: FoodItem):
    # Write the food item to the database here.
    return food

@app.get("/users/{user_id}")
async def read_item(user_id: int, locale: Optional[str] = None):
    fake_user = mimesis.Person(locale=locale)
    return {
        "user_id": user_id,
        "username": fake_user.username(),
        "fullname": fake_user.full_name(),
        "age": fake_user.age(),
        "firstname": fake_user.first_name(),
        "lastname": fake_user.last_name(),
    }

def main(req: func.HttpRequest, context: func.Context) -> func.HttpResponse:
    return AsgiMiddleware(app).handle(req, context)


import zope.interface
import zope.component

from zope.schema.interfaces import IVocabulary, IVocabularyFactory, ISource
from zope.schema.vocabulary import SimpleVocabulary, SimpleTerm

from pmr2.app.factory import vocab_factory

class SimpleCurationValueVocab(SimpleVocabulary):
    """\
    Simple placeholder vocabulary to loosen up coupling of too many
    concepts.
    """

    def __init__(self, context):
        self.context = context
        values = (
            ('c0', u'0 star'),
            ('c1', u'1 star'),
            ('c2', u'2 star'),
            ('c3', u'3 star'),
        )
        terms = [SimpleTerm(i, title=j) for i, j in values]
        super(SimpleCurationValueVocab, self).__init__(terms)

SimpleCurationValueVocabFactory = vocab_factory(SimpleCurationValueVocab)


import boto3
import pickle
import pandas as pd
from flask import Flask, jsonify, request

# Set AWS access keys
access_key = ''
secret_key = ''

# Create an S3 client
s3 = boto3.client('s3', aws_access_key_id=access_key, aws_secret_access_key=secret_key)

# Load the model from the S3 bucket
#s3 = boto3.client('s3')
s3.download_file('loan-model-bucket-897475', 'loan_model.pkl', '/tmp/model.pkl')
with open('/tmp/model.pkl', 'rb') as f:
    model = pickle.load(f)

# Initialize the Flask application
app = Flask(__name__)

# Define the endpoint to make predictions
@app.route('/predict', methods=['POST'])
def predict():
    # Get the input data from the request
    data = request.get_json()

    # Convert the input data to a DataFrame
    input_data = pd.DataFrame.from_dict(data)

    # Make predictions using the trained model
    predictions = model.predict(data)

    # Return the predictions as a JSON response
    return jsonify({'predictions': predictions.tolist()})

# Start the Flask application
if __name__ == '__main__':
    app.run()


import requests
import json

def show():
    res = session.get(url_original)
    print(json.dumps(res.json(), indent=4))

commanddesp='''请输入cookies指令：
add key=value ，用于增加cookies
del key       ，用于删除cookies
show          ，用于显示当前的cookies
quit          , 退出
'''
commands = input(commanddesp).split()
url_original = 'http://httpbin.org/cookies'
session = requests.session()
while commands[0] != 'quit':
    if commands[0] == 'add':
        url = url_original + '/set?' + commands[1]
        res = session.get(url)
        show()

    elif commands[0] == 'del':
        url = url_original + '/delete?' + commands[1]
        res = session.get(url)
        show()

    elif commands[0] == 'show':
        show()

    commands = input().split()

print('Bye!')


# LEGO sorter project
# Verifies image display
# (c) kol, 2023

import os
import logging
import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt
from absl import app, flags
from root_dir import OUTPUT_DIR
from matplotlib.widgets import Slider

logging.getLogger('lego-tracker').setLevel(logging.ERROR)

from lib.image_dataset import (
    fast_get_class_names,
    _preprocess,
    IMAGE_SIZE,
    zoom_image
)
from lib.model import load_model, make_model

FLAGS = flags.FLAGS

def main(_):
    image = tf.image.decode_image(tf.io.read_file(os.path.join(OUTPUT_DIR, 'roi','3001_0127.png')), channels=3)
    resized_image = tf.keras.preprocessing.image.smart_resize(image, IMAGE_SIZE)

    class_names = fast_get_class_names()
    model = make_model(len(class_names))
    load_model(model)

    params = {
        'contrast': {
            'value': 1.0,
            'lower': -10.0,
            'upper': 10.0,
            'step': 1.0,
        },
        'brightness': {
            'value': 0.0,
            'lower': -30.0,
            'upper': 30.0,
            'step': 10.0,
        },
        'saturation': {
            'value': 0.0,
            'lower': 0.0,
            'upper': 30.0,
            'step': 1.0,
        },
        'zoom': {
            'value': 1.0,
            'lower': 1.0,
            'upper': 3.0,
            'step': 0.25,
        },
    }
    cmap = 'gray' if FLAGS.gray or FLAGS.edges else None

    fig, ax = plt.subplots(figsize=(8, 4))
    plt.title('roi')
    plt.axis('off')

    def apply_adj():
        adj_image = resized_image
        adj_image = zoom_image(adj_image, params['zoom']['value'])
        adj_image = tf.image.adjust_contrast(adj_image, params['contrast']['value'])
        adj_image = tf.image.adjust_brightness(adj_image, params['brightness']['value'])
        adj_image = tf.image.adjust_saturation(adj_image, params['saturation']['value'])

        prepared_image, _ = _preprocess(tf.expand_dims(adj_image, 0))
        image = prepared_image[0].numpy()
        ax.imshow(image.astype('uint8'), cmap=cmap)

        prepared_image = tf.keras.preprocessing.image.smart_resize(prepared_image, IMAGE_SIZE)
        prediction = model.predict(prepared_image, verbose=0)
        most_likely = np.argmax(prediction)
        label = class_names[most_likely]
        prob = prediction[0][most_likely]

        ax.set_title(f'{label} ({prob:.4f})')
        fig.canvas.draw_idle()

    def make_update_func(key):
        def update_func(val):
            nonlocal params
            params[key]['value'] = val
            apply_adj()
        return update_func

    SLIDER_WIDTH = 0.0225
    SLIDER_SPACE = 0.10
    fig.subplots_adjust(left=(SLIDER_WIDTH+SLIDER_SPACE)*len(params), bottom=0.25)
    x = 0.1
    for key, par in params.items():
        par['slider'] = Slider(
            ax=fig.add_axes([x, 0.25, SLIDER_WIDTH, 0.63]),
            label=key,
            valmin=par['lower'],
            valmax=par['upper'],
            valstep=par['step'],
            valinit=par['value'],
            orientation="vertical"
        )
        par['slider'].on_changed(make_update_func(key))
        x += SLIDER_WIDTH+SLIDER_SPACE

    apply_adj()
    plt.show()

if __name__ == '__main__':
    app.run(main)


from flask import Flask, request, jsonify
from flask_cors import CORS, cross_origin
import numpy as np
import librosa
from prediction.prediction import RFprediction, LSTMprediction, SVMprediction
from preprocessing import create_mfcc

app = Flask(__name__)
CORS(app)

@app.route("/api/python/predict", methods=['POST'])
def predict():
    result = 'Something wrong !'
    data = request.get_json()
    method = data['method']
    rate = data['rate']
    data = np.array(data['numeric'])
    resample_data = librosa.resample(data,orig_sr=rate,target_sr=22050)
    feature = create_mfcc(resample_data, 22050)
    if (method == 'SVM'):
        result = SVMprediction(feature)
    if (method == 'LSTM'):
        result = LSTMprediction(feature)
    if (method == 'RF'):
        result = RFprediction(feature)
    response = {"result": result}
    return jsonify(response)


from PIL import ImageGrab
from pynput.mouse import Button, Controller
from ctypes import windll
import time

mouse = Controller()
dc= windll.user32.GetDC(0)
gdi = windll.gdi32
print("Press Ctrl + C to terminate the program.")

screensize = windll.user32.GetSystemMetrics(
    0), windll.user32.GetSystemMetrics(1)
# avoids importing sys
supportedScreenRes = False
print(windll.gdi32.GetPixel(windll.user32.GetDC(0), 950, 460))

if (screensize[0] == 1920 and screensize[1] == 1080):
    mouse.position = (950, 460)
    supportedScreenRes = True
elif (screensize[0] == 2560 and screensize[1] == 1440):
    mouse.position = (950, 460)
    supportedScreenRes = True
else:
    print("Sorry, your resolution isn't supported.")

# click to start the test
mouse.click(Button.left, 1)

if (supportedScreenRes):
    # we do not specifiy a break condition to maximize performance, program has to be quit with Ctrl + C
    while True:
        # different monitors have slightly different values for this green, 7002955 was the green value on my Laptop monitor
        # From what I have found out windll is the fastest way to check a single pixel value (< 10ms)
        if (abs(gdi.GetPixel(dc, 950, 460) - 7002955) <= 500000):
            mouse.click(Button.left, 1)
            time.sleep(0.1)
            #mouse.click(Button.left, 1)


"""HTTP/Socks5 proxy protocol implementation.

Provide an acceptor to accept a http/socks5 (auto detect) proxy
request, and a connector to make raw connection.

Usage example:

  async def proxy_handler(reader, writer):
    # create acceptor and accept proxy request
    acceptor = ProxyAcceptor(reader, writer)
    await acceptor.accept()
    # create connector and make connection
    connector = RawConnector.from_acceptor(acceptor)
    await connector.connect()

  # create server and serve
  server = await asyncio.start_server(proxy_handler, '0.0.0.0', 1080)
  async with server:
    await server.serve_forever()
"""

import re
import struct
from urllib.parse import urlparse
import socket
import asyncio
import logging
import argparse

from typing import Optional, Set
from typing_extensions import Self
from asyncio import Task, StreamReader, StreamWriter

from .defaults import (
    RULE_FILE,
    DIRECTION,
    LOCAL_URL,
    LOCAL_ADDR,
    LOCAL_PORT,
    LOG_LEVEL,
    LOG_FORMAT,
    LOG_DATEFMT,
)
from .rule import Rule, RuleMatcher

class ProxyAcceptor:
    """Accept a proxy request, auto detect http/socks5.

    Accept a proxy request by awaiting acceptor.accept(), and request
    information will be stored in acceptor.addr, acceptor.port and
    acceptor.rest.

    Attributes:
        reader: Client reader.
        writer: Client writer.
        buf: Buffer to store request.
        addr: Addr of requested host.
        port: Port of requested host.
        rest: Payload shipped with request.
    """
    reader: StreamReader
    writer: StreamWriter
    buf: bytes
    addr: str
    port: int
    rest: bytes

    http_request_re = re.compile(r'^(\w+) [^ ]+ (HTTP/[^ \r\n]+)\r\n')
    http_host_re = re.compile(
        r'\r\nHost: ([^ :\[\]\r\n]+|\[[:0-9a-fA-F]+\])(:([0-9]+))?\r\n')

    def __init__(self, reader: StreamReader, writer: StreamWriter):
        """
        Args:
            reader: Accept from start_server as callback args.
            writer: Accept from start_server as callback args.
        """
        self.reader = reader
        self.writer = writer
        self.buf = b''
        self.addr = ''
        self.port = 0
        self.rest = b''

    async def accept(self):
        """Accept a proxy request, auto detect http/socks5.

        Returns:
            self.addr: Addr of requested host.
            self.port: Port of requested host.
            self.rest: Payload shipped with request, should be sent on
              connecting.
        """
        self.buf = await self.reader.read(4096)
        if self.buf[0] == 5:
            await self.accept_socks5()
        else:
            await self.accept_http()

    async def accept_socks5(self):
        """Accept socks5 proxy request.

        Args:
            self.buf: Store socks5 proxy request (auth handshake).

        Return:
            self.addr: Addr of requested host.
            self.port: Port of requested host.
            self.rest: Payload shipped with request, for socks5 is always b''.
        """
        nmeths = self.buf[1]
        ver, nmeths, meths = struct.unpack(f'!BB{nmeths}s', self.buf)
        if ver != 5 or 0 not in meths:
            raise struct.error('invalid socks5 request')
        self.writer.write(b'\x05\x00')
        await self.writer.drain()

        self.buf = await self.reader.read(4096)  # read to buf again
        atype = self.buf[3]
        if atype == 3:  # domain
            alen = self.buf[4]
            ver, cmd, rsv, atype, alen, addr, port = struct.unpack(
                f'!BBBBB{alen}sH', self.buf)
            self.addr = addr.decode()
            self.port = port
        elif atype == 1:  # ipv4
            ver, cmd, rsv, atype, addr, port = struct.unpack(
                '!BBBB4sH', self.buf)
            self.addr = socket.inet_ntop(socket.AF_INET, addr)
            self.port = port
        elif atype == 4:  # ipv6
            ver, cmd, rsv, atype, addr, port = struct.unpack(
                '!BBBB16sH', self.buf)
            self.addr = socket.inet_ntop(socket.AF_INET6, addr)
            self.port = port
        else:
            raise struct.error('invalid socks5 header')

        if ver != 5 or cmd != 1 or rsv != 0:
            raise struct.error('invalid socks5 header')
        self.writer.write(b'\x05\x00\x00\x01\x00\x00\x00\x00\x00\x00')
        await self.writer.drain()

    async def accept_http(self):
        """Accept http proxy request.

        Args:
            self.buf: Store http proxy request.

        Return:
            self.addr: Addr of requested host.
            self.port: Port of requested host.
            self.rest: Payload shipped with request.
        """
        pos = self.buf.find(b'\r\n\r\n')
        if pos < 0:
            raise struct.error('invalid http request')
        headers = self.buf[:pos + 2].decode()
        body = self.buf[pos + 4:]

        request = self.http_request_re.search(headers)
        host = self.http_host_re.search(headers)
        if request is None or host is None:
            raise struct.error('invalid http request')
        method, version = request[1], request[2]
        addr, port = host[1], host[3]

        self.addr = addr if addr[0] != '[' else addr[1:-1]
        self.port = int(port) if port else 80

        if method == 'CONNECT':
            self.writer.write(f'{version} 200 Connection Established\r\n'
                              'Connection close\r\n\r\n'.encode())
            await self.writer.drain()
            self.rest = body
        else:
            headers = '\r\n'.join(header for header in headers.split('\r\n')
                                  if not header.startswith('Proxy-'))
            self.rest = headers.encode() + b'\r\n' + body

async def io_copy(reader: StreamReader, writer: StreamWriter):
    """Python version of Golang::io.Copy, copy from reader to writer.

    Args:
        reader: Accept from start_server as callback args, or open_connection
          as return values.
        writer: Accept from start_server as callback args, or open_connection
          as return values.
    """
    while True:
        buf = await reader.read(4096)
        if len(buf) == 0:
            if writer.can_write_eof():
                writer.write_eof()
            break
        writer.write(buf)
        await writer.drain()

class RawConnector:
    """Make raw connection between client and requested host.

    Connect to requested host self.addr:self.port, send self.rest on
    connecting if possible, and then relay traffic between client and
    requested host, by awaiting connector.connect().

    Attributes:
        reader: Client reader.
        writer: Client writer.
        peer_reader: Peer reader.
        peer_writer: Peer writer.
        addr: Addr of requested host.
        port: Port of requested host.
        rest: Payload shipped with request.
    """
    reader: StreamReader
    writer: StreamWriter
    peer_reader: Optional[StreamReader]
    peer_writer: Optional[StreamWriter]
    addr: str
    port: int
    rest: bytes

    tasks: Set[Task] = set()

    def __init__(self, reader: StreamReader, writer: StreamWriter, addr: str,
                 port: int, rest: bytes):
        """
        Args:
            reader: Accept from start_server as callback args.
            writer: Accept from start_server as callback args.
            addr: Addr of requested host accept by acceptor.
            port: Port of requested host accept by acceptor.
            rest: Payload shipped with request.
        """
        self.reader = reader
        self.writer = writer
        self.peer_reader = None
        self.peer_writer = None
        self.addr = addr
        self.port = port
        self.rest = rest

    @classmethod
    def from_acceptor(cls, acceptor: ProxyAcceptor) -> Self:
        """Create connector from acceptor.

        Args:
            acceptor: An acceptor have awaited acceptor.accept.

        Returns:
            Connector initialized from acceptor.
        """
        return cls(reader=acceptor.reader,
                   writer=acceptor.writer,
                   addr=acceptor.addr,
                   port=acceptor.port,
                   rest=acceptor.rest)

    async def connect(self):
        """Make connection."""
        self.peer_reader, self.peer_writer = await asyncio.open_connection(
            self.addr, self.port)
        if self.rest:
            self.peer_writer.write(self.rest)
            await self.peer_writer.drain()

        # Notice: Must save refs of tasks util cancel performed.
        task1 = asyncio.create_task(io_copy(self.reader, self.peer_writer))
        task2 = asyncio.create_task(io_copy(self.peer_reader, self.writer))
        self.tasks.add(task1)
        self.tasks.add(task2)
        task1.add_done_callback(self.tasks.discard)
        task2.add_done_callback(self.tasks.discard)

        exc = None

        try:
            await asyncio.gather(task1, task2)
        except Exception as e:
            exc = e
            if not task1.cancelled():
                task1.cancel()
            if not task2.cancelled():
                task2.cancel()

        try:
            self.writer.close()
            self.peer_writer.close()
            await self.writer.wait_closed()
            await self.peer_writer.wait_closed()
        except Exception as e:
            if exc is None:
                exc = e

        if exc is not None:
            raise exc

def main():
    """Main entry to run a rule based proxy, auto detect http/socks5."""
    parser = argparse.ArgumentParser()
    parser.add_argument('-l', '--local-url', default=LOCAL_URL)
    parser.add_argument('-d', '--direction', default=DIRECTION)
    parser.add_argument('-r', '--rule-file', default=RULE_FILE)
    args = parser.parse_args()

    local_url = urlparse(args.local_url)
    direction = args.direction
    rule_file = args.rule_file

    logging.basicConfig(level=LOG_LEVEL,
                        format=LOG_FORMAT,
                        datefmt=LOG_DATEFMT)

    rule_matcher = RuleMatcher(direction=direction, rule_file=rule_file)

    async def proxy_handler(reader: StreamReader, writer: StreamWriter):
        try:
            acceptor = ProxyAcceptor(reader, writer)
            await acceptor.accept()
            rule = rule_matcher.match(acceptor.addr)
            logging.info('[%s]\tconnect to %s:%d', rule, acceptor.addr,
                         acceptor.port)
            if rule == Rule.Block:
                writer.close()
                await writer.wait_closed()
                return
            connector = RawConnector.from_acceptor(acceptor)
            await connector.connect()
        except Exception as e:
            logging.debug('[except]\t%s', e)

    async def start_server():
        server = await asyncio.start_server(proxy_handler,
                                            local_url.hostname or LOCAL_ADDR,
                                            local_url.port or LOCAL_PORT,
                                            reuse_address=True)
        addrs = ', '.join(str(sock.getsockname()) for sock in server.sockets)
        logging.info('server start at %s', addrs)
        async with server:
            await server.serve_forever()

    try:
        asyncio.run(start_server())
    except Exception as e:
        logging.error('server except %s', e)
    except KeyboardInterrupt:
        print('keyboard quit')

if __name__ == '__main__':
    main()


from flask import render_template, abort, request, redirect, url_for
from cosplay import app, make_slug, DeleteForm
from database import query_db, update_db
from images import save_image
from about import User
from home import add_update
from flask_wtf import FlaskForm
from wtforms import StringField, TextAreaField
from wtforms.validators import InputRequired
from flask_login import login_required, current_user

def get_tutorial(slug):
    tutorial = query_db('select * from tutorials where slug = ?',
                        [slug], one=True)
    if tutorial is None:
        return None
    tutorial['author'] = User(id=tutorial['author'])
    return tutorial

class TutorialForm(FlaskForm):
    title = StringField('Title', validators=[InputRequired()])
    content = TextAreaField(validators=[InputRequired()], id='tutorial_content')

# Tutorial pages
@app.route('/tutorials/')
def tutorial_index():
    tutorials = query_db("select title, slug from \
                        tutorials order by id desc")
    return render_template('tutorials/index.html', tutorials=tutorials)

@app.route('/tutorials/<slug>')
def tutorial_page(slug):
    tutorial = get_tutorial(slug)
    if tutorial is None:
        abort(404)
    return render_template('tutorials/page.html', tutorial=tutorial)

@app.route('/tutorials/<slug>/edit', methods=['GET', 'POST'])
@login_required
def tutorial_edit(slug):
    tutorial = get_tutorial(slug)
    if tutorial is None:
        abort(404)
    if not current_user.username == tutorial['author'].username:
        abort(401)
    form = TutorialForm(**tutorial)
    if form.validate_on_submit():
        update_db("update tutorials set title = ?, content = ? where slug = ?",
                  [form.title.data, form.content.data, slug])
        add_update("%s updated %s" %  (url_for('user_page', username=current_user.username), current_user.display_name, url_for('tutorial_page', slug=slug), form.title.data))
        return redirect(url_for('tutorial_page', slug=slug))
    return render_template('tutorials/form.html', form=form, slug=slug)

@app.route('/tutorials/new', methods=['GET', 'POST'])
@login_required
def tutorial_new():
    form = TutorialForm()
    if form.validate_on_submit():
        author = current_user.id
        slug = make_slug(form.title.data)
        update_db("insert into tutorials (title, content, author, slug) values (?, ?, ?, ?)",
                  [form.title.data, form.content.data, author, slug])
        add_update("%s added %s" %  (url_for('user_page', username=current_user.username), current_user.display_name, url_for('tutorial_page', slug=slug), form.title.data))
        return redirect(url_for('tutorial_index'))

    return render_template('tutorials/form.html', form=form)

@app.route('/tutorials/<slug>/delete', methods=['GET', 'POST'])
@login_required
def tutorial_delete(slug):
    # look up the costume and its components in the db
    tutorial = get_tutorial(slug)
    if tutorial is None:
        abort(404)

    if not current_user.username == tutorial['author'].username:
        abort(401)

    form = DeleteForm()
    slug = tutorial['slug']
    if form.validate_on_submit():
        update_db("delete from tutorials where slug = ?", [slug])
        return redirect(url_for('tutorial_index'))

    return render_template('delete.html', form=form)


# -*- coding: utf-8 -*-
"""
Created on Wed Oct  6 16:41:51 2021

@author: aso
"""

import numpy as np
import math
import matplotlib.pyplot as plt
from scipy.integrate import cumtrapz

from pyController.pid_control import pid_control
from pyController.on_off_control import on_off_control
from pyController.sensor import sensor

# This example simulates the response of a PID controller when used for keeping
# the pH of a solution constant by adding a base. This is necessary because
# an acid is added with a constant flow rate.

# Define how often the pH sensor collects a signal
sampling_interval = 0.1  # in s
t_min = sampling_interval  # in s
t_max = 2000  # in s

# Define the concentrations of acid and base, the starting volume of the acid
# and the flow rate of the acid
c_acid = 0.01  # in mol/L
c_base = 0.01  # in mol/L
v0 = 0.2  # in L
flow_rate_acid = 0.001  # in L/s

# Define the time points for sensor readouts
time_points = int((t_max-t_min)//sampling_interval+1)
time_values = np.linspace(t_min, t_max, time_points)

# Calculte the added acid amounts for all time points of the simulation
acid_flow = np.full_like(time_values, flow_rate_acid)
acid_vol = cumtrapz(acid_flow, x=time_values, initial=0)
acid_amount = acid_vol * c_acid + 1E-7 * (v0 + acid_vol)  # strongly simplified model

# Set up PID and on/off controller for a set point of 8
pid = pid_control(8, 0.001, 0.00002, 0.005, response_limits=[0, None])
on_off = on_off_control(8, 'lower_limit', 0.002)

# Set up pH sensor as a relatively slow sensor
ph_sensor = {'pid': sensor(7, start_real=7, k=0.05),
             'onoff': sensor(7, start_real=7, k=0.05)}

# initialize lists which collect the simulation data for PID and on/off control
base_flow = {'pid': [0], 'onoff': [0]}
base_vol = {'pid': [0], 'onoff': [0]}
base_amount = {'pid': [0], 'onoff': [0]}
acid_balance = {'pid': [acid_amount[0]], 'onoff': [acid_amount[0]]}
ph = {'pid': [-math.log10(acid_amount[0]/(v0))],
      'onoff': [-math.log10(acid_amount[0]/(v0))]}

# Calulate pH values and the controller responses for all time points
for ii, (curr_time, curr_acid_vol, curr_acid_amount) in enumerate(
        zip(time_values[1:], acid_vol[1:], acid_amount[1:])):

    for curr_key in ['pid', 'onoff']:
        if curr_key == 'pid':
            base_flow[curr_key].append(
                pid.calc_response(ph_sensor[curr_key].sensor_values[-1],
                                  curr_time, d_window=5))
        else:
            base_flow[curr_key].append(
                on_off.calc_response(ph_sensor[curr_key].sensor_values[-1],
                                     curr_time))

        base_vol[curr_key].append(
            base_vol[curr_key][-1] + base_flow[curr_key][-1] *
            sampling_interval)
        base_amount[curr_key].append(base_vol[curr_key][-1] * c_base)
        acid_balance[curr_key].append(
            curr_acid_amount-base_amount[curr_key][-1])

        total_vol = v0 + base_vol[curr_key][-1]

        if acid_balance[curr_key][-1] >= 0:
            ph[curr_key].append(
                -math.log10((acid_balance[curr_key][-1]/total_vol)))
        else:
            ph[curr_key].append(
                14 + math.log10(-acid_balance[curr_key][-1]/total_vol))
        ph_sensor[curr_key].next_sensor_value(ph[curr_key][-1], curr_time)

# Plot the results of the pH value over time with PID and on/off control
fig1, ax1 = plt.subplots(2)
ax1[0].plot(time_values, ph['pid'], label='real pH PID control')
ax1[0].plot(ph_sensor['pid'].times, ph_sensor['pid'].sensor_values,
            label='measured pH PID control')
ax1[1].plot(time_values, ph['onoff'], label='real pH on/off control')
ax1[1].plot(ph_sensor['onoff'].times, ph_sensor['onoff'].sensor_values,
            label='measured pH on/off control')
ax1[0].legend()
ax1[1].legend()
ax1[0].set_xlabel('time [s]')
ax1[0].set_ylabel('pH')
ax1[1].set_xlabel('time [s]')
ax1[1].set_ylabel('pH')
plt.tight_layout()


from maya import cmds as MayaCmds
import maya.OpenMaya as OpenMaya
import os
import subprocess
import unittest
import util

class AnimMeshTest(unittest.TestCase):

    def setUp(self):
        MayaCmds.file(new=True, force=True)
        self.__abcStitcher = [os.environ['AbcStitcher']]
        self.__files = []

    def tearDown(self):
        for f in self.__files :
            os.remove(f)

    def testAnimSPT_HwColor_ReadWrite(self):
        numFaces = 6
        numVertices = 8
        numFaceConnects = 24

        vtx_1 = OpenMaya.MFloatPoint(-0.5, -0.5, -0.5)
        vtx_2 = OpenMaya.MFloatPoint( 0.5, -0.5, -0.5)
        vtx_3 = OpenMaya.MFloatPoint( 0.5, -0.5,  0.5)
        vtx_4 = OpenMaya.MFloatPoint(-0.5, -0.5,  0.5)
        vtx_5 = OpenMaya.MFloatPoint(-0.5,  0.5, -0.5)
        vtx_6 = OpenMaya.MFloatPoint(-0.5,  0.5,  0.5)
        vtx_7 = OpenMaya.MFloatPoint( 0.5,  0.5,  0.5)
        vtx_8 = OpenMaya.MFloatPoint( 0.5,  0.5, -0.5)

        points = OpenMaya.MFloatPointArray()
        points.setLength(8)
        points.set(vtx_1, 0)
        points.set(vtx_2, 1)
        points.set(vtx_3, 2)
        points.set(vtx_4, 3)
        points.set(vtx_5, 4)
        points.set(vtx_6, 5)
        points.set(vtx_7, 6)
        points.set(vtx_8, 7)

        faceConnects = OpenMaya.MIntArray()
        faceConnects.setLength(numFaceConnects)
        faceConnects.set(0, 0)
        faceConnects.set(1, 1)
        faceConnects.set(2, 2)
        faceConnects.set(3, 3)
        faceConnects.set(4, 4)
        faceConnects.set(5, 5)
        faceConnects.set(6, 6)
        faceConnects.set(7, 7)
        faceConnects.set(3, 8)
        faceConnects.set(2, 9)
        faceConnects.set(6, 10)
        faceConnects.set(5, 11)
        faceConnects.set(0, 12)
        faceConnects.set(3, 13)
        faceConnects.set(5, 14)
        faceConnects.set(4, 15)
        faceConnects.set(0, 16)
        faceConnects.set(4, 17)
        faceConnects.set(7, 18)
        faceConnects.set(1, 19)
        faceConnects.set(1, 20)
        faceConnects.set(7, 21)
        faceConnects.set(6, 22)
        faceConnects.set(2, 23)

        faceCounts = OpenMaya.MIntArray()
        faceCounts.setLength(6)
        faceCounts.set(4, 0)
        faceCounts.set(4, 1)
        faceCounts.set(4, 2)
        faceCounts.set(4, 3)
        faceCounts.set(4, 4)
        faceCounts.set(4, 5)

        transFn = OpenMaya.MFnTransform()
        parent = transFn.create()
        transFn.setName('poly')
        meshFn = OpenMaya.MFnMesh()
        meshFn.create(numVertices, numFaces, points, faceCounts,
            faceConnects, parent)
        shapeName = 'polyShape'
        meshFn.setName(shapeName)

        # add SPT_HwColor attributes
        MayaCmds.select( shapeName )
        MayaCmds.addAttr(longName='SPT_HwColor', usedAsColor=True,
            attributeType='float3')
        MayaCmds.addAttr(longName='SPT_HwColorR', attributeType='float',
            parent='SPT_HwColor')
        MayaCmds.addAttr(longName='SPT_HwColorG', attributeType='float',
            parent='SPT_HwColor')
        MayaCmds.addAttr(longName='SPT_HwColorB', attributeType='float',
            parent='SPT_HwColor')

        # set colors
        MayaCmds.setAttr(shapeName+'.SPT_HwColor', 0.50, 0.15, 0.75,
            type='float3')

        MayaCmds.currentTime(1, update=True)
        MayaCmds.setKeyframe('polyShape.vtx[0:7]')
        # colors
        MayaCmds.setKeyframe( shapeName+'.SPT_HwColor')

        MayaCmds.currentTime(24, update=True)
        MayaCmds.setKeyframe('polyShape.vtx[0:7]')
        # colors
        MayaCmds.setKeyframe( shapeName+'.SPT_HwColor')

        MayaCmds.currentTime(12, update=True)

        vtx_11 = OpenMaya.MFloatPoint(-1.0, -1.0, -1.0)
        vtx_22 = OpenMaya.MFloatPoint( 1.0, -1.0, -1.0)
        vtx_33 = OpenMaya.MFloatPoint( 1.0, -1.0,  1.0)
        vtx_44 = OpenMaya.MFloatPoint(-1.0, -1.0,  1.0)
        vtx_55 = OpenMaya.MFloatPoint(-1.0,  1.0, -1.0)
        vtx_66 = OpenMaya.MFloatPoint(-1.0,  1.0,  1.0)
        vtx_77 = OpenMaya.MFloatPoint( 1.0,  1.0,  1.0)
        vtx_88 = OpenMaya.MFloatPoint( 1.0,  1.0, -1.0)
        points.set(vtx_11, 0)
        points.set(vtx_22, 1)
        points.set(vtx_33, 2)
        points.set(vtx_44, 3)
        points.set(vtx_55, 4)
        points.set(vtx_66, 5)
        points.set(vtx_77, 6)
        points.set(vtx_88, 7)
        meshFn.setPoints(points)

        MayaCmds.setAttr( shapeName+'.SPT_HwColor', 0.15, 0.5, 0.15,
            type='float3')

        MayaCmds.setKeyframe('polyShape.vtx[0:7]')
        # colors
        MayaCmds.setKeyframe( shapeName+'.SPT_HwColor')

        self.__files.append(util.expandFileName('animSPT_HwColor.abc'))
        self.__files.append(util.expandFileName('animSPT_HwColor_01_14.abc'))
        self.__files.append(util.expandFileName('animSPT_HwColor_15_24.abc'))

        MayaCmds.AbcExport(j='-atp SPT_ -fr 1 14 -root poly -file ' + self.__files[-2])
        MayaCmds.AbcExport(j='-atp SPT_ -fr 15 24 -root poly -file ' + self.__files[-1])

        subprocess.call(self.__abcStitcher + self.__files[-3:])

        # reading test
        MayaCmds.AbcImport(self.__files[-3], mode='open')

        places = 7

        # check colors

        MayaCmds.currentTime(1, update=True)
        colorVec_1 = MayaCmds.getAttr(shapeName+'.SPT_HwColor')[0]
        self.failUnlessAlmostEqual(colorVec_1[0], 0.50, places)
        self.failUnlessAlmostEqual(colorVec_1[1], 0.15, places)
        self.failUnlessAlmostEqual(colorVec_1[2], 0.75, places)

        MayaCmds.currentTime(2, update=True)
        # only needed for interpolation test on frame 1.422
        colorVec_2 = MayaCmds.getAttr(shapeName+'.SPT_HwColor')[0]

        setTime = MayaCmds.currentTime(1.422, update=True)
        alpha = (setTime - 1) / (2 - 1)
        colorVec = MayaCmds.getAttr(shapeName+'.SPT_HwColor')[0]
        self.failUnlessAlmostEqual(colorVec[0], (1-alpha)*colorVec_1[0]+alpha*colorVec_2[0], places)
        self.failUnlessAlmostEqual(colorVec[1], (1-alpha)*colorVec_1[1]+alpha*colorVec_2[1], places)
        self.failUnlessAlmostEqual(colorVec[2], (1-alpha)*colorVec_1[2]+alpha*colorVec_2[2], places)

        MayaCmds.currentTime(12, update=True)
        colorVec = MayaCmds.getAttr( shapeName+'.SPT_HwColor' )[0]
        self.failUnlessAlmostEqual( colorVec[0], 0.15, places)
        self.failUnlessAlmostEqual( colorVec[1], 0.50, places)
        self.failUnlessAlmostEqual( colorVec[2], 0.15, places)

        MayaCmds.currentTime(24, update=True)
        colorVec = MayaCmds.getAttr(shapeName+'.SPT_HwColor')[0]
        self.failUnlessAlmostEqual(colorVec[0], 0.50, places)
        self.failUnlessAlmostEqual(colorVec[1], 0.15, places)
        self.failUnlessAlmostEqual(colorVec[2], 0.75, places)


from datetime import datetime
from random import choice

from musicleague.errors import UserDoesNotExistError
from musicleague.errors import UserExistsError
from musicleague.persistence.models import User
from musicleague.persistence.select import select_user
from musicleague.persistence.select import select_user_by_email
from musicleague.persistence.update import upsert_user

DEFAULT_AVATARS = [
    'https://s3.amazonaws.com/musicleague-static-assets/avatars/bowie_avatar.svg',
    'https://s3.amazonaws.com/musicleague-static-assets/avatars/daft_avatar.svg',
    'https://s3.amazonaws.com/musicleague-static-assets/avatars/dmc_avatar.svg',
    'https://s3.amazonaws.com/musicleague-static-assets/avatars/elvis_avatar.svg',
    'https://s3.amazonaws.com/musicleague-static-assets/avatars/hendrix_avatar.svg',
    'https://s3.amazonaws.com/musicleague-static-assets/avatars/madonna_avatar.svg',
    'https://s3.amazonaws.com/musicleague-static-assets/avatars/marley_avatar.svg',
    'https://s3.amazonaws.com/musicleague-static-assets/avatars/morrison_avatar.svg',
    'https://s3.amazonaws.com/musicleague-static-assets/avatars/prince_avatar.svg',
    'https://s3.amazonaws.com/musicleague-static-assets/avatars/punk_avatar.svg',
    'https://s3.amazonaws.com/musicleague-static-assets/avatars/siouxie_avatar.svg',
    'https://s3.amazonaws.com/musicleague-static-assets/avatars/supremes_avatar.svg'
]

PROFILE_BACKGROUNDS = [
    'ml_header01.jpg', 'ml_header02.jpg', 'ml_header03.jpg', 'ml_header04.jpg',
    'ml_header05.jpg', 'ml_header06.jpg', 'ml_header07.jpg', 'ml_header08.jpg',
    'ml_header09.jpg', 'ml_header10.jpg', 'ml_header11.jpg', 'ml_header12.jpg',
    'ml_header13.jpg', 'ml_header14.jpg', 'ml_header15.jpg', 'ml_header16.jpg',
    'ml_header17.jpg', 'ml_header18.jpg', 'ml_header19.jpg', 'ml_header20.jpg',
    'ml_header21.jpg', 'ml_header22.jpg', 'ml_header23.jpg', 'ml_header24.jpg'
]

def create_user_from_spotify_user(spotify_user):
    user_id = spotify_user.get('id')
    user_email = spotify_user.get('email')
    user_display_name = spotify_user.get('display_name')
    if user_display_name is None:
        user_display_name = user_id

    user_images = spotify_user.get('images')
    user_image_url = ''
    if user_images:
        user_image_url = user_images[0].get('url', user_image_url)

    return create_user(
        id=user_id, email=user_email, name=user_display_name, image_url=user_image_url)

def update_user_from_spotify_user(user, spotify_user):
    user_images = spotify_user.get('images')
    user_image_url = ''
    if user_images:
        user.image_url = user_images[0].get('url', user_image_url)
        upsert_user(user)

    return user

def create_user(id, name, email, image_url):
    if get_user(id):
        raise UserExistsError('User with id %s already exists' % id)

    if not image_url:
        image_url = choice(DEFAULT_AVATARS)

    profile_background = choice(PROFILE_BACKGROUNDS)

    new_user = User(
        id=id, email=email, image_url=image_url, is_admin=False,
        joined=datetime.utcnow(), name=name, profile_bg=profile_background)

    upsert_user(new_user)

    return new_user

def update_user(id, name, email, image_url):
    user = get_user(id)

    if not user:
        raise UserDoesNotExistError('User with id %s does not exist' % id)

    user.id = id if id else user.id
    user.name = name if name else user.name
    user.email = email if email else user.email
    user.image_url = image_url if image_url else user.image_url

    upsert_user(user)

    return user

def create_or_update_user(id, name, email, image_url):
    user = get_user(id)

    if not user:
        user = create_user(id, name, email, image_url)
    else:
        user = update_user(id, name, email, image_url)

    return user

def get_user(id):
    user = select_user(id)
    if user is None:
        return None

    updated = False

    if not user.image_url:
        user.image_url = choice(DEFAULT_AVATARS)
        updated = True

    if not user.profile_background:
        user.profile_background = choice(PROFILE_BACKGROUNDS)
        updated = True

    if updated:
        upsert_user(user)

    return user

def get_user_by_email(email):
    # TODO No need for this function
    return select_user_by_email(email)


from anndata import AnnData

def save_data_with_pathways(
    adata: AnnData,
    directory: str,
    file: str,
    verbose: bool = True
) -> None:
    """Saves AnnData structure data and pathways annotated metadata.

    Args:
        adata: AnnData object from descartes atlas
        directory: Directory with pathways metadata annotated and
            AnnData struct
        file: Filename of h5ad AnnData file.
        verbose: If True (default), print statements about saving files

    Examples:
        >>> save_data_with_pathways(adata, directory="output", file="Thymus")

    """
    pathways_data = adata.uns["pathways"].copy()
    del adata.uns["pathways"]

    if verbose:
        print(f"Saving AnnData structure to {directory}/{file}.h5ad")

    adata.write(f"{directory}/{file}.h5ad")

    for pathway, df in pathways_data.items():
        pathway_name = pathway.replace(" ", "_")
        if verbose:
            print(
                f"Saving pathway data from {pathway} clusters to {directory}"
            )
        df.to_csv(f"{directory}/{pathway_name}_pathways.csv", index=False)

    adata.uns["pathways"] = pathways_data


#it is similar class to what we have know about unittest
from django.test import TestCase , Client
from .models import *
from django.db.models import Max

# Create your tests here.

class FlightTestCase(TestCase):
    def setUP(self):
        #add samples to the dataset(not the userdata)
        #it is a data specific to test and it is deleted automatically after using test
        a1 = airport.objects.create(code = "AAA" , city = "City A")
        a2 = airport.objects.create(code = "BBB" , city = "City B")
        #creating FLight
        Flight.objects.create(origin = a1 , destination = a2 , duration = 200)
        Flight.objects.create(origin = a1 , destination = a1 , duration = 200)
        Flight.objects.create(origin = a1 , destination = a2 , duration = -4)
    def deparuters_count(self):
        a1 = airport.objects.get(code = "AAA" , city = "City A")
        dep_a = a1.departures.count()
        self.assertEqual(dep_a , 3)
    def arrivals_count(self):
        a1 = airport.objects.get(code = "AAA")
        self.assertEqual(a1.arrivals.count() , 1)
    def test_valid_flight(self):
        # a1 = airport.objects.get(code = "AAA" , city = "City A")
        a2 = airport.objects.get(code = "BBB")
        f = Flight.objects.get(origin = a2 , destination = a2 , duration = 200)
        self.assertTrue(f.flight_is_valid())
    def test_invalid_flight_destination(self):
        a1 = airport.objects.get(code = "AAA")
        f = Flight.objects.get(origin = a1 , destination = a1 , duration = 200)
        self.assertFalse(f.flight_is_valid())
    def test_invalid_flight_destination(self):
        a1 = airport.objects.get(code = "AAA")
        a2 = airport.objects.get(code = "BBB")
        f = Flight.objects.get(origin = a1 , destination = a2 , duration = -4)
        self.assertFalse(f.flight_is_valid())


# IMPORTS
import sys
import torch
import torch.nn as nn
import torch.nn.functional as F
import numpy as np
import torch.optim as optim
import matplotlib
import matplotlib.pyplot as plt
from timeit import default_timer as timer

# IMPORTS FROM OTHER PROJECT FILES
# Add the model folder to the sys path
sys.path.insert(1, '../Model')

# Do the imports from other files in the project
from DepthLSTM import DepthLSTM
from hyperparameters import *
from train_epoch import train_epoch
from test_epoch import test_epoch

# LOAD THE DATA
xyz_data = np.load('../Data/normalized_data.npy')

# PARAMETER DEFINITION
DATA_SIZE = xyz_data.shape[0]
NUM_JOINTS = 26
INPUT_SIZE = 2*NUM_JOINTS

# SEPARATION OF DATA AND GROUND TRUTH
# Separate x and y dimensions and convert into tensors
x_data = torch.tensor(xyz_data[:, :, 0].squeeze())
y_data = torch.tensor(xyz_data[:, :, 1].squeeze())
# Obtain the body_data tensor of shape [DATA_SIZE, 2*NUM_JOINTS]
body_data = torch.empty((DATA_SIZE, 2*NUM_JOINTS))
for i in range(0, 2*NUM_JOINTS):
  if i%2 == 0:
    body_data[:, i] = x_data[:, i//2]
  else:
    body_data[:, i] = y_data[:, i//2]
# Obtain the ground_data tensor of shape [DATA_SIZE, NUM_JOINTS]
ground_data = torch.tensor(xyz_data[:, :, 2].squeeze())

# TRAIN/TEST SPLIT
# Use the last TEST_FRACTION of the data for testing
TRAIN_SIZE = np.int(np.ceil(0.8*DATA_SIZE))
TEST_SIZE = DATA_SIZE - TRAIN_SIZE
train_data = body_data[0:TRAIN_SIZE,:]
train_ground = ground_data[0:TRAIN_SIZE,:]
test_data = body_data[TRAIN_SIZE:,:]
test_ground = ground_data[TRAIN_SIZE:,:]

# DIVIDE TRAINING DATA INTO BATCHES
# Compute the number of samples in each chunk or batch
CHUNK_SIZE = TRAIN_SIZE // BATCH_SIZE
# Obtain the list of BATCH_SIZE chunks where each element is a tensor
# of shape [CHUNK_SIZE, 2*NUM_JOINTS]
trainset = [ train_data[beg_i:end_i] \
            for beg_i, end_i in zip(range(0, TRAIN_SIZE - CHUNK_SIZE, CHUNK_SIZE),
                                    range(CHUNK_SIZE, TRAIN_SIZE, CHUNK_SIZE)) ]
groundset = [ train_ground[beg_i:end_i] \
            for beg_i, end_i in zip(range(0, TRAIN_SIZE - CHUNK_SIZE, CHUNK_SIZE),
                                    range(CHUNK_SIZE, TRAIN_SIZE, CHUNK_SIZE)) ]

# DIVIDE THE TESTING DATA INTO BATCHES
# Compute the number of samples in each chunk or batch
CHUNK_TEST_SIZE = TEST_SIZE // BATCH_SIZE
# Obtain the list of BATCH_SIZE batches where each element is a tensor
# of shape [CHUNK_SIZE, 2*NUM_JOINTS]
testset = [ test_data[beg_i:end_i] \
            for beg_i, end_i in zip(range(0, TEST_SIZE - CHUNK_TEST_SIZE, CHUNK_TEST_SIZE),
                                    range(CHUNK_TEST_SIZE, TEST_SIZE, CHUNK_TEST_SIZE)) ]
groundtestset = [ test_ground[beg_i:end_i] \
            for beg_i, end_i in zip(range(0, TEST_SIZE - CHUNK_TEST_SIZE, CHUNK_TEST_SIZE),
                                    range(CHUNK_TEST_SIZE, TEST_SIZE, CHUNK_TEST_SIZE)) ]

# TRAIN AND TEST THE MODEL
# Initialize the model
model = DepthLSTM(HIDDEN_SIZE, NUM_LAYERS, SEQ_LEN, BATCH_SIZE, NUM_JOINTS)
model.to(device)
# Define the loss function and the optimizer
loss_function = nn.MSELoss()
optimizer = optim.Adam(model.parameters(), lr=0.001)
tr_loss = []
tst_loss = []
state = None
timer_beg = timer()
# Train the model for NUM_EPOCHS epochs
for epoch in range(NUM_EPOCHS):
  print('Starting epoch: ', epoch)
  train_epoch_loss = train_epoch(model, trainset, groundset, optimizer, loss_function, CHUNK_SIZE)
  test_epoch_loss, predY = test_epoch(model, testset, groundtestset, CHUNK_TEST_SIZE)
  timer_end = timer()
  if (epoch + 1) % 10 == 0:
    # Print the training loss of this epoch
    # It is calculated as the average of losses of every window
    print('Training loss in epoch {} is: {}'.format(epoch, sum(train_epoch_loss)/len(train_epoch_loss) ))
    print('Test loss in epoch {} is: {}'.format(epoch, sum(test_epoch_loss)/len(test_epoch_loss) ))
  tr_loss.append(train_epoch_loss)
  tst_loss.append(test_epoch_loss)
  timer_beg = timer()


from fastapi import FastAPI, HTTPException
from fastapi.middleware.cors import CORSMiddleware
import pymysql
from typing import Dict

app = FastAPI(title="LTB Cases API",
              description="API to access and update DB of all Ontario Landlord and Tenant Board decisions")

# Enable CORS
origins = [
    "http://localhost:3000",  # Replace with your frontend URL
]

app.add_middleware(
    CORSMiddleware,
    allow_origins=origins,
    allow_credentials=True,
    allow_methods=["GET", "POST", "PUT", "DELETE"],
    allow_headers=["*"],
)

# Database configuration
DATABASE = {
    'host': 'localhost',
    'user': 'root',
    'password': '',
    'database': 'cases',
    'charset': 'utf8mb4',
    'cursorclass': pymysql.cursors.DictCursor
}

@app.get("/api/", tags=["Case Operations"])
async def get_cases():
    # Establish a new database connection
    connection = pymysql.connect(**DATABASE)

    with connection.cursor() as cursor:
        cursor.execute("SELECT * FROM cases")
        result = cursor.fetchall()

    # Close the database connection
    connection.close()

    return result

@app.get("/api/{case_id}", tags=["Case Operations"])
async def get_case_by_id(case_id: int):
    # Establish a new database connection
    connection = pymysql.connect(**DATABASE)

    with connection.cursor() as cursor:
        cursor.execute("SELECT * FROM cases WHERE id=%s", (case_id,))
        result = cursor.fetchone()

    # Close the database connection
    connection.close()

    if result is None:
        raise HTTPException(status_code=404, detail="Case not found")

    return result

@app.put("/api/{case_id}", tags=["Case Operations"])
async def update_case_by_id(case_id: int, case_details: Dict):
    # Establish a new database connection
    connection = pymysql.connect(**DATABASE)

    with connection.cursor() as cursor:
        # Construct the SQL query
        sql = "UPDATE cases SET " + ", ".join([f"{key} = %s" for key in case_details.keys()]) + " WHERE id = %s"

        # Execute the query with the values
        cursor.execute(sql, list(case_details.values()) + [case_id])

        # Commit the transaction
        connection.commit()

    # Close the database connection
    connection.close()

    return {"message": "Case updated successfully"}


# -*- coding: utf-8 -*-
#!/usr/bin/env python3
"""Tahmatassu Telegram bot runner script
"""
#pylint: disable=W0611
import bot.logger

import logging
import argparse
import os

from configparser import ConfigParser
from bot.tahmatassubot import TahmaTassuBot
from bot.logger import LOGGER_NAME

def create_argparser():
  """Create command line argument parser.

  Returns:
    {argparse.ArgumentParser} -- Command line argument parser object
  """
  parser = argparse.ArgumentParser(description='Description of your program')
  parser.add_argument('-c', '--config',
                      type=str,
                      help='Config file, [setting.ini] file path',
                      default="setting.ini", dest="config")
  parser.add_argument('-g', '--generate',
                      type=str,
                      help='Create initial configuration file, give file name and path as argument',
                      dest="generate")
  parser.add_argument('-f', '--force', action='store_true', dest="force")
  return parser

def create_configuration_file(logger, args):
  """Generate initial configuration file

  Arguments:
    logger {Logger} -- logging object
    args {dict} -- Command line arguments
  """
  if not args.force and os.path.exists(args.generate):
    return logger.info("File exist allready, use -f flag to overwrite the existing file")

  config = ConfigParser()
  config.set('DEFAULT', 'token', 'Telegram Bot API token here')
  config.set('DEFAULT', 'tahmatassuapi', 'http://puumuki.game-server.cc')
  config.set('DEFAULT', 'botname', 'Tahmatassubot')

  with open(args.generate, 'w') as filehandle:
    config.write(filehandle)

  logger.info("Writed configuration to file named: " + args.generate)

def start_bot( logger, args ):
  """Create TahmatassuBot

  Arguments:
    logger {Logger} -- logger
    args {dict} -- Command line arguments
  """
  try:
    config = ConfigParser()
    config.read(args.config)
    tahmatassu = TahmaTassuBot(token=config['DEFAULT']['token'],
                               tahmatassu_base_url=config['DEFAULT']['tahmatassuapi'],
                               bot_name=config['DEFAULT']['botname'])
    tahmatassu.run()
  except Exception as error:
    logger.error(error)
    logger.exception("message")

def main():
  """Main function for starting for Tahmatassu Telegram bot.
  """
  log = logging.getLogger(LOGGER_NAME)

  parser = create_argparser()
  args = parser.parse_args()

  if args.generate:
    create_configuration_file(log, args)
  else:
    start_bot(log, args)

if __name__ == '__main__':
  main()


from collections import defaultdict

def AC3(csp, queue=None, removals=defaultdict(set)):
    """
    this is the main arc-consistency algorithm
    :param csp: SudokuCSP problem
    :param queue: queue of all the arcs
    :param removals: removed domains
    :return:
    """
    # Return False if there is no consistent assignment
    if queue is None:
        queue = [(Xt, X) for Xt in csp.adjList for X in csp.adjList[Xt]]
    # Queue of arcs of our concern
    while queue:
        # Xt --> Xh Delete from domain of Xt
        (Xt, Xh) = queue.pop()
        if remove_inconsistent_values(csp, Xt, Xh, removals):
            if not csp.domains[Xt]:
                return False
            # NOTE: Next two lines only for binary "!=" constraint
            elif len(csp.domains[Xt]) > 1:
                continue
            for X in csp.adjList[Xt]:
                if X != Xt:
                    queue.append((X, Xt))
    return True

def remove_inconsistent_values(csp, Xt, Xh, removals):
    """
    this function checks domain values of tail, coressponding to head
    if there was an incosistency, we remove the value from tail and return True
    :param csp: SudokuCSP instance
    :param t: tail
    :param h: head
    :param removals: removed domains
    :return: True if a value was removed
    """
    # Return True if we remove a value
    revised = False
    # If Xt=x conflicts with Xh=y for every possible y, eliminate Xt=x
    for x in csp.domains[Xt].copy():
        for y in csp.domains[Xh]:
            if not csp.conflicts(*Xt, x, *Xh, y):
                break
        else:
            csp.domains[Xt].remove(x)
            removals[Xt].add(x)
            revised = True
    return revised

def makeArcQue(csp, Xs):
    return [(Xt, Xh) for Xh in Xs for Xt in csp.adjList[Xh]]


# -*- coding: utf-8 -*-
"""
Created Mon 25 March 2019
@author: Ale
"""

import scrapy
from scrapy import Request

class SolidaritySpider(scrapy.Spider):
    name = 'solidarity'
    start_urls = ['https://www.handsoffvenezuela.org/solidarity/']
    user_agent = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.75 Safari/537.36'

    def parse(self, response):
        articles = response.xpath('//h1[@class="title"]')

        for article in articles:
            title = article.xpath('a/text()').extract_first()
            relative_url = article.xpath('a/@href').extract_first()
            absolute_url = response.urljoin(relative_url)

            yield Request(absolute_url, callback=self.parse_page, meta={'URL': absolute_url, 'Title': title})

        relative_next_url = response.xpath('//*[@class="pagination-next"]/a/@href').extract_first()
        absolute_next_url = "https://www.handsoffvenezuela.org" + relative_next_url

        yield Request(absolute_next_url, callback=self.parse)

    def parse_page(self, response):
        url = response.meta.get('URL')
        title = response.meta.get('Title')
        date = response.xpath('//dd[@class="rt-date-posted"]/text()').extract_first()
        author = response.xpath('//dd[@class="rt-author"]/text()').extract_first()
        #images = response.xpath('//div[@id="rt-mainbody"]//img/@src')
        text = " ".join(line for line in response.xpath('//*[@id="rt-mainbody"]/div/article/p//text()').extract())
        post_script = " ".join(line for line in response.xpath('//b/text()').extract())

        #for i in images:
        #    if images[i].startswith('http'):
        #        image_url = images[i].extract_first()
        #    else:
        #        image_url = 'https://www.handsoffvenezuela.org' + image[i].extract_first() #for images stored within handsoffvenezuela

        yield {'URL': url, 'Title': title, 'Date': date, 'Author': author, 'Text': text, 'PS': post_script}