from __future__ import print_function
import keras
from keras.datasets import mnist
from keras.models import load_model
from keras.models import Sequential
from keras.layers import Dense, Dropout, Flatten
from keras. layers import Conv2D, MaxPooling2D
from keras import backend as K

import tensorflow  as tf
from keras.layers import *
from keras.callbacks import ReduceLROnPlateau

import matplotlib.pyplot as plt

"""## Veri Setinin İndirilmesi
 0⃣ 1⃣ 2⃣ 3⃣ 4⃣ 5⃣ 6⃣ 7⃣ 8⃣ 9⃣
"""

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

"""### Yapılandırma Ayarları
Küme boyutu, sınıf sayısı, eğitim epoch sayısı gibi parametreleri tüm optimizasyon denemeleri için aynı şekilde ayarlıyoruz!
"""

batch_size = 128 # Küme Boyutu
num_classes = 10 # Sınıf Sayısı
epochs = 20 # Eğitimin epoch sayısı
w_l2 = 1e-5 # Başlangıç

reduce_lr = ReduceLROnPlateau(monitor='val_loss', factor=0.2, patience=5, min_lr=1e-5)

img_rows, img_cols = 28, 28

if K.image_data_format() == 'channels_first':
    x_train = x_train.reshape(x_train.shape[0], 1, img_rows, img_cols)
    x_test = x_test.reshape(x_test.shape[0], 1, img_rows, img_cols)
    input_shape = (1, img_rows, img_cols)
else:
    x_train = x_train.reshape(x_train.shape[0], img_rows, img_cols, 1)
    x_test = x_test.reshape(x_test.shape[0], img_rows, img_cols, 1)
    input_shape = (img_rows, img_cols, 1)

x_train = x_train.astype('float32')
x_test = x_test.astype('float32')
x_train /= 255
x_test /= 255
print('x_train shape:', x_train.shape)
print(x_train.shape[0], 'train samples')
print(x_test.shape[0], 'test samples')

# sınıf vektörlerini ikili sınıf matrislerine dönüştürmek
y_train = keras.utils.to_categorical(y_train, num_classes)
y_test = keras.utils.to_categorical(y_test, num_classes)

from keras import optimizers

"""### Tüm optimizasyon yöntemlerini eğiteceğimiz evrişimli sinir ağı modelinin oluşturulması"""

model = Sequential()
model.add(Conv2D(32, kernel_size=(3, 3),  kernel_regularizer=regularizers.l2(w_l2),
                 input_shape=input_shape))
model.add(BatchNormalization())
model.add(Activation('relu'))
model.add(Conv2D(64, (3, 3),  kernel_regularizer=regularizers.l2(w_l2)))
model.add(BatchNormalization())
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.25))
model.add(Flatten())
model.add(Dense(128, kernel_regularizer=regularizers.l2(w_l2)))
model.add(BatchNormalization())
model.add(Activation('relu'))
model.add(Dropout(0.5))
model.add(Dense(num_classes, activation='softmax'))

"""### STOKASTİK GRADYAN/BAYIR İNİŞ OPTİMİZASYONU

Tüm örneklerden geçmek yerine, Stokastik Degrade İniş (SGD), her bir örnekte $(x ^ i, y ^ i)$  parametrelerin güncellenmesini gerçekleştirir. Bu nedenle, öğrenme her örnekte gerçekleşir:

$w = w− α∇wJ(x^i,y^i;w,b)$

```
for i in range(num_epochs):
    np.random.shuffle(data)
    for example in data:
        grad = compute_gradient(example, params)
        params = params - learning_rate * grad
```
"""

model.compile(loss=keras.losses.categorical_crossentropy,
              optimizer=keras.optimizers.SGD(),
              metrics=['accuracy'])
model.summary()

"""### Modelin Eğitilm ve Test Sonuçları"""

hist_SGD=model.fit(x_train, y_train,
          batch_size=batch_size,
          epochs=epochs,
          verbose=1,
          validation_data=(x_test, y_test), callbacks=[reduce_lr])
score = model.evaluate(x_test, y_test, verbose=0)
print('Test loss:', score[0])
print('Test accuracy:', score[1])

"""### ADAM OPTİMİZASYONU
***Adam veya adaptif momentum AdaDelta’ya benzer bir algoritmadır. AdaDelta’dan farklı olarak parametrelerin her birinin öğrenme oranlarının yanısıra momentum değişikliklerini de önbellekte (cache) saklar; yani RMSprop ve momentumu birleştirir.***
"""

model.compile(loss=keras.losses.categorical_crossentropy,
              optimizer=keras.optimizers.Adam(),
              metrics=['accuracy'])

model.summary()

"""### Modelin Eğitilm ve Test Sonuçları"""

hist_ADAM=model.fit(x_train, y_train,
          batch_size=batch_size,
          epochs=epochs,
          verbose=1,
          validation_data=(x_test, y_test), callbacks=[reduce_lr])
score = model.evaluate(x_test, y_test, verbose=0)
print('Test loss:', score[0])
print('Test accuracy:', score[1])

"""### RMSprop OPTİMİZASYONU

***RMSprop ve benzeri olan AdaDelta, AdaGrad’ın bu sorununu çözerek bu hızlı düşüşü önler.***
"""

model.compile(loss=keras.losses.categorical_crossentropy,
              optimizer=keras.optimizers.RMSprop(),
              metrics=['accuracy'])
model.summary()

hist_RMSprob=model.fit(x_train, y_train,
          batch_size=batch_size,
          epochs=epochs,
          verbose=1,
          validation_data=(x_test, y_test), callbacks=[reduce_lr])
score = model.evaluate(x_test, y_test, verbose=0)
print('Test loss:', score[0])
print('Test accuracy:', score[1])

"""### ADAGRAD OPTİMİZASYONU

***AdaGrad seyrek parametreler için büyük güncellemeler yaparken sık parametreler için daha küçük güncellemeler yapar. Bu nedenle NLP ve resim tanıma gibi seyrek veriler için daha uygundur.***
AdaGrad’da her parametrenin kendi öğrenme hızı vardır ve algoritmanın özelliklerine bağlı olarak öğrenme oranı giderek azalmaktadır. Bu nedenle öğreneme oranı giderek azalır ve zamanın bir noktasında sistem öğrenmeyi bırakır. Bu AdaGrad’ın en büyük dez avantajıdır.
"""

model.compile(loss=keras.losses.categorical_crossentropy,
              optimizer=keras.optimizers.Adagrad(),
              metrics=['accuracy'])
model.summary()

hist_adagrad=model.fit(x_train, y_train,
          batch_size=batch_size,
          epochs=epochs,
          verbose=1,
          validation_data=(x_test, y_test), callbacks=[reduce_lr])
score = model.evaluate(x_test, y_test, verbose=0)
print('Test loss:', score[0])
print('Test accuracy:', score[1])

"""### ADADELTA OPTİMİZASYONU
***AdaDelta, AdaGrad’ın bu sorununu çözerek bu hızlı düşüşü önler.***
"""

model.compile(loss=keras.losses.categorical_crossentropy,
              optimizer=keras.optimizers.Adadelta(),
              metrics=['accuracy'])
model.summary()

hist_adadelta=model.fit(x_train, y_train,
          batch_size=batch_size,
          epochs=epochs,
          verbose=1,
          validation_data=(x_test, y_test), callbacks=[reduce_lr])
score = model.evaluate(x_test, y_test, verbose=0)
print('Test loss:', score[0])
print('Test accuracy:', score[1])

"""## Kaydedilen sonuçların çizilmesi için plot fonksiyonunun tanımlanması"""

def plot_history(hists, attribute='val_loss', axis=(-1,21,0.85,0.94), loc='lower right'):
    ylabel = {'oss': 'loss', 'acc': 'accuracy'}
    title = {'val_loss': 'valid. loss', 'loss': 'trn. loss', 'val_acc': 'valid. accuracy', 'acc': 'trn. accuracy'}
    num_hists = len(hists)

    plt.figure(figsize=(12, 8))
    plt.axis(axis)
    for i in range(num_hists):
        plt.plot(hists[i].history[attribute])
    plt.title(title[attribute])
    plt.ylabel(ylabel[attribute[-3:]])
    plt.xlabel('epoch')
    plt.legend(['ADAM', 'SGD', 'RMSprob', 'adadelta', 'adagrad'], loc=loc)

    plt.show()

hists = [hist_ADAM, hist_SGD, hist_RMSprob, hist_adadelta, hist_adagrad]

"""## SONUÇLARIN KARŞILAŞTIRILMASI"""

plot_history(hists, attribute='acc', axis=(-1,21,0.985,1.0), loc='lower right')

plot_history(hists, attribute='loss', axis=(-1,21,0.009,0.07), loc='upper right')


import collections
import io

import pytest

from hbp_spatial_backend import transform_graph

def test_transform_graph_sane_usage():
    tg = transform_graph.TransformGraph()
    tg.add_space('A')
    chain = tg.get_transform_chain('A', 'A')
    assert chain == []
    tg.add_space('B')
    chain = tg.get_transform_chain('A', 'B')
    assert chain is None
    tg.add_link('A', 'B', 'Transform A to B')
    chain = tg.get_transform_chain('A', 'B')
    assert chain == ['Transform A to B']
    chain = tg.get_transform_chain('B', 'A')
    assert chain is None
    tg.add_link('B', 'A', 'Transform B to A')
    tg.add_space('C')
    chain = tg.get_transform_chain('A', 'C')
    assert chain is None
    tg.add_link('B', 'C', 'Transform B to C')
    chain = tg.get_transform_chain('A', 'C')
    assert chain == ['Transform A to B', 'Transform B to C']
    tg.remove_link('A', 'B')
    chain = tg.get_transform_chain('A', 'C')
    assert chain is None

def test_transform_graph_cycle():
    tg = transform_graph.TransformGraph()
    # Monkeypatch the tested class to get reliable ordering (with a plain dict
    # Python's hash randomization makes the bug intermittent)
    tg.links = collections.OrderedDict()
    tg.add_space('A')
    tg.add_space('B')
    tg.add_space('C')
    tg.add_link('A', 'B', 'Transform A to B')
    tg.add_link('A', 'C', 'Transform A to C')
    tg.add_link('C', 'A', 'Transform C to A')
    chain = tg.get_transform_chain('A', 'B')
    assert chain == ['Transform A to B']

def test_transform_graph_api_errors():
    tg = transform_graph.TransformGraph()
    tg.add_space('A')
    with pytest.raises(ValueError):
        tg.add_space('A')
    with pytest.raises(KeyError):
        tg.get_transform_chain('A', 'B')
    with pytest.raises(KeyError):
        tg.get_transform_chain('B', 'A')
    tg.add_space('B')
    tg.add_link('A', 'B', 'Transform A to B')
    with pytest.raises(ValueError):
        tg.add_link('A', 'B', 'Duplicate link')

def test_export_graphviz():
    tg = transform_graph.TransformGraph()
    tg.add_space('A')
    tg.add_space('weird"*+chars')
    tg.add_link('A', 'weird"*+chars', 'Transform')
    buf = io.StringIO()
    tg.export_graphviz(buf)

def test_load_from_yaml():
    tg = transform_graph.TransformGraph.from_yaml(b'{A: {B: AtoB}, B: {}}')
    chain = tg.get_transform_chain('A', 'B')
    assert chain == ['AtoB']
    tg = transform_graph.TransformGraph.from_yaml(b'{A: {B: AtoB}}')
    chain = tg.get_transform_chain('A', 'B')
    assert chain == ['AtoB']
    with pytest.raises(ValueError):
        transform_graph.TransformGraph.from_yaml('[A, B, C]')


import numpy.typing as npt
import numpy as np
import voltools as vt
import logging
from scipy.ndimage import center_of_mass, zoom
from scipy.fft import rfftn, irfftn
from typing import Optional
from pytom_tm.weights import create_ctf, create_gaussian_low_pass, radial_average

plotting_available = True
try:
    import matplotlib.pyplot as plt
    import seaborn as sns
    sns.set(context='talk', style='ticks')
except ModuleNotFoundError:
    plotting_available = False

def generate_template_from_map(
        input_map: npt.NDArray[float],
        input_spacing: float,
        output_spacing: float,
        ctf_params: dict,
        center: bool = False,
        filter_to_resolution: Optional[float] = None,
        output_box_size: Optional[int] = None,
        display_filter: bool = False
) -> npt.NDArray[float]:

    # make the map a box with equal dimensions
    if len(set(input_map.shape)) != 1:
        diff = [max(input_map.shape) - s for s in input_map.shape]
        input_map = np.pad(
            input_map,
            tuple([(d // 2, d // 2 + d % 2) for d in diff]),
            mode='edge'
        )

    if filter_to_resolution is None or filter_to_resolution < (2 * output_spacing):
        logging.warning(f'Filter resolution is either not specified (in which case you can ignore this warning) '
                        f'or too low, changing to {2 * output_spacing}A (2 * output voxel size)')
        filter_to_resolution = 2 * output_spacing

    # extend volume to the desired output size before applying convolutions!
    if output_box_size is not None:
        logging.debug(f'size check {output_box_size} > {(input_map.shape[0] * input_spacing) // output_spacing}')
        if output_box_size > (input_map.shape[0] * input_spacing) // output_spacing:
            pad = int(output_box_size * (output_spacing / input_spacing)) - input_map.shape[0]
            logging.debug(f'pad with this number of zeros: {pad}')
            input_map = np.pad(
                input_map,
                (pad // 2, pad // 2 + pad % 2),
                mode='edge'
            )
        elif output_box_size < (input_map.shape[0] * input_spacing) // output_spacing:
            logging.warning('Could not set specified box size as the map would need to be cut and this might '
                            'result in loss of information of the structure. Please decrease the box size of the map '
                            'by hand (e.g. chimera)')

    if center:
        volume_center = np.divide(np.subtract(input_map.shape, 1), 2, dtype=np.float32)
        input_center_of_mass = center_of_mass(input_map)
        shift = np.subtract(volume_center, input_center_of_mass)
        input_map = vt.transform(input_map, translation=shift, device='cpu')

        logging.debug(f'center of mass, before was '
                      f'{np.round(input_center_of_mass, 2)} '
                      f'and after {np.round(center_of_mass(input_map), 2)}')

    # create ctf function and low pass gaussian if desired
    # for ctf the spacing of pixels/voxels needs to be in meters (not angstrom)
    ctf = 1 if ctf_params is None else create_ctf(input_map.shape, **ctf_params).astype(np.float32)
    lpf = create_gaussian_low_pass(input_map.shape, input_spacing, filter_to_resolution).astype(np.float32)

    if display_filter and plotting_available:
        q, average = radial_average(ctf * lpf)
        fig, ax = plt.subplots()
        ax.plot(q / len(q), average)
        ax.set_xlabel('Fraction of Nyquist')
        ax.set_ylabel('Contrast transfer')
        plt.show()
    elif display_filter and not plotting_available:
        logging.info('Plotting not possible as matplotlib is not installed')

    logging.info('Convoluting volume with filter and then downsampling.')
    return zoom(
        irfftn(rfftn(input_map) * ctf * lpf),
        input_spacing / output_spacing
    )


"""
WSGI config for website project.

It exposes the WSGI callable as a module-level variable named ``application``.

For more information on this file, see
https://docs.djangoproject.com/en/dev/howto/deployment/wsgi/
"""

# Print statements may help with gunicorn debugging

print("Importing: %s" % __file__)

import logging  # noqa: F402
import os  # noqa: F402

logging.basicConfig(
    format='%(asctime)s %(levelname)-7s %(thread)-5d %(filename)s:%(lineno)s | %(funcName)s | %(message)s',
    datefmt='%Y-%m-%d %H:%M:%S',
)
logging.getLogger().setLevel(logging.DEBUG)
logging.disable(logging.NOTSET)

logging.info('Loading %s', __name__)

DJANGO_SETTINGS_MODULE = os.environ.setdefault("DJANGO_SETTINGS_MODULE", "website.settings")
print("DJANGO_SETTINGS_MODULE=", DJANGO_SETTINGS_MODULE)
from django.conf import settings  # noqa: F402 isort:skip

# determine where is the single absolute path that
# will be used as a reference point for other directories
SITE_ROOT = os.path.dirname(os.path.dirname(os.path.dirname(__file__)))
logging.debug("SITE_ROOT: %s" % SITE_ROOT)
logging.debug("settings.DEBUG: %s" % settings.DEBUG)

# Obtain WSGIHandler
from django.core.wsgi import get_wsgi_application  # noqa: F402 isort:skip

application = get_wsgi_application()

logging.debug("application: %s" % application)


import sys
import cv2
import numpy as np
import pyautogui
from PyQt5.QtCore import Qt, QThread, pyqtSignal, pyqtSlot
from PyQt5.QtWidgets import QMessageBox, QHBoxLayout, QMainWindow, QPushButton, QStylePainter, QApplication, QVBoxLayout, QWidget, QGridLayout, QCheckBox
from threading import Thread
import pyautogui
import os

# Edit your comp below (Keep champion names in lower case)
comps = {
    "Chosen Brawlers": ["maokai", "tahm kench", "sylas", "vi", "nunu", "ashe", "warwick", "sett"],
    "Chosen Sharpshooters": ["nidalee", "vayne", "teemo", "jinx", "aatrox", "cassiopeia", "jhin", "sejuani", "zilean"],
    "Elderwood Brawlers": ["maokai", "lulu", "nunu", "lux", "ashe", "warwick", "ezreal", "sett"],
    "Chosen Cultists": ["elise", "twisted fate", "pyke", "kalista", "evelynn", "aatrox", "jhin", "zilean"],
    "Chosen Dusks": ["vayne", "thresh", "aatrox", "cassiopeia", "jhin", "riven", "lillia", "zilean"],
    "Dusk Cultists": ["elise", "pyke", "kalista", "aatrox", "cassiopeia", "jhin", "riven", "zilean"],
    "Spirit Vanguards": ["thresh", "yuumi", "aatrox", "ahri", "cassiopeia", "sejuani", "shen", "zilean"],
    "Moonlight Assassins": ["lissandra", "diana", "pyke", "sylas", "akali", "katarina", "talon"],
    "Cultist Shades": ["zed", "pyke", "kalista", "evelynn", "aatrox", "jhin", "kayn", "zilean"],
    "Spirit Shades": ["janna", "teemo", "zed", "evelynn", "kindred", "yuumi", "ahri", "kayn"],
    "Chosen Duelists": ["fiora", "yasuo", "jax", "kalista", "janna", "shen", "lee sin", "yone"],
    "Chosen Warlords": ["garen", "nidalee", "jarvan", "pyke", "vi", "katarina", "xin zhao", "azir"],
    "Enlightened Assassins": ["fiora", "nami", "janna", "pyke", "irelia", "morgana", "shen", "talon"],
    "Keeper Sharpshooters": ["nidalee", "vayne", "jarvan", "jinx", "kennen", "jhin", "riven", "azir"],
    "Dusk Mages": ["hecarim", "lulu", "thresh", "veigar", "yuumi", "cassiopeia", "riven", "lillia"],
    "Moonlight Hunters": ["lissandra", "aphelios", "sylas", "kindred", "yuumi", "ashe", "cassiopeia", "warwick"],
    "Divine Vanguards": ["wukong", "garen", "janna", "irelia", "lux", "aatrox", "sejuani", "shen"]
}

# Storing champion images in champ_cards dictionary
champ_cards = dict()
cwd = os.getcwd()
for champ in os.listdir(".\champ_cards"):
    if champ.endswith(".png"):
        champ_cards[champ[:-4]] = cv2.imread(cwd + f"\\champ_cards\\{champ}", 0)

def crop_ss(selectedComps):
    # cv2.matchTemplate documentation:
    # https://opencv-python-tutroals.readthedocs.io/en/latest/py_tutorials/py_imgproc/py_template_matching/py_template_matching.html
    #
    # Taking screenshot and matching champion images from user selected comp to the screenshot

    while True:
        try:
            img_rgb = pyautogui.screenshot()
            break
        except:
            raise Exception("OSError: screen grab failed")

    img_gray = cv2.cvtColor(np.array(img_rgb), cv2.COLOR_BGR2GRAY)

    lst = np.array([])

    for comp in selectedComps:
        for champ in comps[comp]:
            template = champ_cards[champ]
            res = cv2.matchTemplate(img_gray, template, cv2.TM_CCOEFF_NORMED)

            # Lower threshold variable value if the program gets false negatives
            # Increase threshold variable value if the program gets false positives
            threshold = 0.75

            loc = np.where(res >= threshold)
            lst = np.concatenate([lst, loc[1]])
    return lst

class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.selectedComps = list()
        self.setWindowTitle('TFT Overlay v1.0 by junschoi')
        self.setGeometry(1600,30,0,0)
        self.setupWidgets()

    def setupWidgets(self):
        self.thread = QThread()
        self.thread.start()

        self.worker = Worker()
        self.worker.moveToThread(self.thread)

        self.centralWidget = QWidget(self)

        self.CBdict = dict()
        grid = QGridLayout()

        row = 0
        column = 0
        for comp in list(comps.keys()):
            self.CBdict[comp] = QCheckBox(comp) # Each comp in comps is QCheckBox
            grid.addWidget(self.CBdict[comp], row, column) # Add each comp QCheckBox to grid
            self.CBdict[comp].clicked.connect(lambda _, cb=self.CBdict[comp]: self.CBClicked(cb=cb))
            row += 1
            if row % 12 == 0:
                column += 1
                row = 0

        self.startButton = QPushButton("Start")
        self.stopButton = QPushButton("Stop")
        self.stopButton.setEnabled(False)
        self.startButton.clicked.connect(self.startThread)
        self.stopButton.clicked.connect(self.stopThread)
        mainLayout = QVBoxLayout(self.centralWidget)
        startStopLayout = QHBoxLayout()
        startStopLayout.addWidget(self.startButton)
        startStopLayout.addWidget(self.stopButton)
        mainLayout.addLayout(grid)
        mainLayout.addLayout(startStopLayout)
        self.setCentralWidget(self.centralWidget)
        self.show()

    def CBClicked(self, cb):
        if cb.isChecked():
            self.selectedComps.append(cb.text())
        else:
            self.selectedComps.remove(cb.text())
        self.t3 = Thread(target = self.worker.reload_comps, args=(self.selectedComps,))
        self.t3.start()

    def startThread(self):
        self.startButton.setEnabled(False)
        self.stopButton.setEnabled(True)
        self.t1 = Thread(target = self.worker.run)
        self.t1.start()

    def stopThread(self):
        self.startButton.setEnabled(True)
        self.stopButton.setEnabled(False)
        self.t2 = Thread(target = self.worker.stop)
        self.t2.start()
        self.thread.quit()
        self.thread.wait()

    def closeEvent(self, event):
        reply = QMessageBox.question(self, "Message", "Are you sure to quit?")
        if reply == QMessageBox.Yes:
            self.t2 = Thread(target = self.worker.stop)
            self.t2.start()
            event.accept()
        else:
            event.ignore()

class Worker(QThread):
    active = pyqtSignal(object)

    def __init__(self):
        super(Worker, self).__init__()
        self.selectedComps = list()
        self._sleep = False

    def reload_comps(self, selectedComps):
        self.selectedComps = selectedComps

    @pyqtSlot()
    def run(self):
        self.running = True
        while self.running:
            lst = crop_ss(self.selectedComps)
            QThread.msleep(100)
            self.active.emit(lst)

    def stop(self):
        self.running = False

class Mask(QMainWindow):
    def __init__(self, box):
        super().__init__()
        self.resize(500,500)
        self.box = box

    def paintEvent(self, event=None):
        painter = QStylePainter()
        painter.begin(self)
        painter.setOpacity(0.4)
        painter.setBrush(Qt.green)
        painter.drawRect(self.rect())
        self.setGeometry(self.box[0], self.box[1], self.box[2]-self.box[0], self.box[3]-self.box[1])

    def mousePressEvent(self, event):
        self.close()

class Controller:
    def __init__(self):
        self.Show_MainWindow()

    def Show_MainWindow(self):
        self.box1 = [479, 1038, 672, 1071] # 927 / 1038 for y1
        self.box2 = [680, 1038, 873, 1071]
        self.box3 = [881, 1038, 1074, 1071]
        self.box4 = [1082, 1038, 1275, 1071]
        self.box5 = [1283, 1038, 1476, 1071]
        self.ui = MainWindow()
        self.ui.setWindowFlags(Qt.WindowStaysOnTopHint)
        self.ui.worker.active.connect(self.run)
        self.ui.show()
        self.ui1 = Mask(self.box1)
        self.ui2 = Mask(self.box2)
        self.ui3 = Mask(self.box3)
        self.ui4 = Mask(self.box4)
        self.ui5 = Mask(self.box5)

    def run(self, lst):
        self.mask1() if any([x for x in lst if x in range(479-5, 479+5)]) else self.ui1.close()
        self.mask2() if any([x for x in lst if x in range(680-5, 680+5)]) else self.ui2.close()
        self.mask3() if any([x for x in lst if x in range(881-5, 881+5)]) else self.ui3.close()
        self.mask4() if any([x for x in lst if x in range(1082-5, 1082+5)]) else self.ui4.close()
        self.mask5() if any([x for x in lst if x in range(1283-5, 1283+5)]) else self.ui5.close()

    # Qt.Tool hides app from taskbar
    # https://www.geeksforgeeks.org/pyqt5-how-to-hide-app-from-taskbar/

    def mask1(self):
        self.ui1.setWindowFlags(Qt.FramelessWindowHint | Qt.WindowStaysOnTopHint | Qt.Tool)
        self.ui1.setAttribute(Qt.WA_NoSystemBackground, True)
        self.ui1.setAttribute(Qt.WA_TranslucentBackground, True)
        self.ui1.show()

    def mask2(self):
        self.ui2.setWindowFlags(Qt.FramelessWindowHint | Qt.WindowStaysOnTopHint | Qt.Tool)
        self.ui2.setAttribute(Qt.WA_NoSystemBackground, True)
        self.ui2.setAttribute(Qt.WA_TranslucentBackground, True)
        self.ui2.show()

    def mask3(self):
        self.ui3.setWindowFlags(Qt.FramelessWindowHint | Qt.WindowStaysOnTopHint | Qt.Tool)
        self.ui3.setAttribute(Qt.WA_NoSystemBackground, True)
        self.ui3.setAttribute(Qt.WA_TranslucentBackground, True)
        self.ui3.show()

    def mask4(self):
        self.ui4.setWindowFlags(Qt.FramelessWindowHint | Qt.WindowStaysOnTopHint | Qt.Tool)
        self.ui4.setAttribute(Qt.WA_NoSystemBackground, True)
        self.ui4.setAttribute(Qt.WA_TranslucentBackground, True)
        self.ui4.show()

    def mask5(self):
        self.ui5.setWindowFlags(Qt.FramelessWindowHint | Qt.WindowStaysOnTopHint | Qt.Tool)
        self.ui5.setAttribute(Qt.WA_NoSystemBackground, True)
        self.ui5.setAttribute(Qt.WA_TranslucentBackground, True)
        self.ui5.show()

if __name__ == '__main__':
    app = QApplication(sys.argv)
    controller = Controller()
    sys.exit(app.exec_())


import numpy as np
import pyaudio
import mido
import itertools
import random

DEVICE = ""   # Midi keyboard name

SAMPLE_RATE = 44100
BUFFER_SIZE = 1024
VOICES = 100
DETUNE = 0.2

notes_dict = {}
lfo_dict = {}

p = pyaudio.PyAudio()
stream = p.open(format=pyaudio.paFloat32,
                channels=1,
                rate=SAMPLE_RATE,
                output=True,
                frames_per_buffer=BUFFER_SIZE)

def midi_to_freq(midi_note):
    A = 440
    if DETUNE:
        det = random.uniform(-DETUNE,DETUNE)
        return (A / 32) * (2 ** ((midi_note + det - 9) / 12))
    return (A / 32) * (2 ** ((midi_note - 9) / 12))

def gen_sine(freq, amp=1):
    increment = 2*np.pi*freq/SAMPLE_RATE
    return (np.sin(i)*amp for i in itertools.count(start=0, step=increment))

def get_samples():
    return [sum([next(osc) * np.float32(32767) \
            for _, osc in notes_dict.items()]) \
            for _ in range(BUFFER_SIZE)]

# Run the synth
in_port = mido.open_input(DEVICE)
while True:
    if notes_dict:
        sum_samples = get_samples()
        stream.write(np.float32(sum_samples).tobytes())

    msg = in_port.receive(block=False)
    if msg is not None:
        if msg.type == "note_on":
            if len(notes_dict)+1 > VOICES:
                notes_dict.pop(next(iter(notes_dict)))

            note = msg.note
            freq = midi_to_freq(note)
            amp = msg.velocity/127
            notes_dict[note] = gen_sine(freq, amp)

        if msg.type == "note_off" and msg.note in notes_dict.keys():
            del notes_dict[msg.note]

p.terminate()


from pytest_bdd import (
    given,
    parsers, when, then
)
import pytest
import logging
from random import choices
import string

from resource_manager.src.util import kinesis_analytics_utils as kinan_utils
from resource_manager.src.util.common_test_utils import extract_param_value
from resource_manager.src.util.common_test_utils import put_to_ssm_test_cache
from resource_manager.src.util.boto3_client_factory import client
from botocore.exceptions import ClientError

logger = logging.getLogger(__name__)
logger.setLevel(logging.INFO)

# cache alarm Id dimension value:
cache_kinesis_application_parameters_expression = 'cache Kinesis Data Analytics for "{app_type}" application ' \
                                                  'InputId as KinesisAnalyticsInputId and OutputId as ' \
                                                  'KinesisAnalyticsOutputId "{step_key}" SSM automation execution' \
                                                  '\n{input_parameters}'

@given(parsers.parse(cache_kinesis_application_parameters_expression))
@when(parsers.parse(cache_kinesis_application_parameters_expression))
@then(parsers.parse(cache_kinesis_application_parameters_expression))
def cache_kinesis_analytics_application_parameters(resource_pool, ssm_test_cache, boto3_session,
                                                   app_type, step_key, input_parameters):
    """
    Cache demand for alarm dimensions parameters:
    :InputId and OutputId for SQL application
    :input stream Id and output stream id for Apache Flink application
    """
    kinesis_analytics_application_name = extract_param_value(
        input_parameters, 'KinesisAnalyticsApplicationName', resource_pool, ssm_test_cache)
    kinesis_analytics_input_id, kinesis_analytics_output_id = kinan_utils.cache_kinan_app_seperate_flink_sql(
        kinesis_analytics_application_name, app_type, boto3_session)
    put_to_ssm_test_cache(ssm_test_cache, step_key, 'KinesisAnalyticsInputId', kinesis_analytics_input_id)
    put_to_ssm_test_cache(ssm_test_cache, step_key, 'KinesisAnalyticsOutputId', kinesis_analytics_output_id)

# create s3 bucket for kinesis data analytics apache flink application file and teradown it after test:
create_s3_bucket_for_kinesis_analytics_application_expression = 'create S3 bucket and save the bucket name ' \
                                                                'as "{bucket_cache_name}" to "{cache_property}" ' \
                                                                'cache property' \
                                                                '\n{input_parameters}'

@given(parsers.parse(create_s3_bucket_for_kinesis_analytics_application_expression))
def create_s3_bucket_for_kinesis_analytics_application(resource_pool, ssm_test_cache, boto3_session,
                                                       eliminate_s3_bucket_with_object,
                                                       bucket_cache_name, cache_property, input_parameters):
    s3_client = client('s3', boto3_session)
    bucket_prefix_name = extract_param_value(
        input_parameters, 'S3BucketNamePrefix', resource_pool, ssm_test_cache)
    account_id = boto3_session.client('sts').get_caller_identity().get('Account')
    region_name = boto3_session.region_name
    random_postfix = ''.join(choices(string.ascii_lowercase + string.digits, k=6))

    bucket_name = bucket_prefix_name + "-" + account_id + "-" + region_name + "-" + random_postfix
    try:
        if region_name == 'us-east-1':
            s3_client.create_bucket(ACL='private', Bucket=bucket_name)
        else:
            s3_client.create_bucket(ACL='private', Bucket=bucket_name, CreateBucketConfiguration={
                'LocationConstraint': region_name
            })
        logger.info(f"Bucket with name [{bucket_name}] for region [{region_name}] created")
    except ClientError as ee:
        if ee.response['Error']['Code'] == 'BucketAlreadyOwnedByYou':
            logger.warning(f"Bucket with name [{bucket_name}] for region [{region_name}] already exist.")
        else:
            raise ee
    s3_client.put_bucket_versioning(Bucket=bucket_name, VersioningConfiguration={'Status': 'Enabled'})
    put_to_ssm_test_cache(ssm_test_cache, cache_property, bucket_cache_name, bucket_name)
    # teardown s3 bucket resource:
    commit_s3_bucket_teardown = extract_param_value(
        input_parameters, 'S3BucketTeardown', resource_pool, ssm_test_cache)
    eliminate_s3_bucket_with_object['bucket_name'] = bucket_name
    eliminate_s3_bucket_with_object['account_id'] = account_id
    eliminate_s3_bucket_with_object['S3BucketTeardown'] = commit_s3_bucket_teardown

# upload kinesis data analytics apache flink application to s3 bucket:
upload_kinesis_analytics_application_file_to_s3_bucket_expression = 'upload Kinesis Data Analytics application file ' \
                                                                    'to S3 bucket with given key and save locations ' \
                                                                    'to "{cache_property}" cache property' \
                                                                    '\n{input_parameters}'

@given(parsers.parse(upload_kinesis_analytics_application_file_to_s3_bucket_expression))
def upload_file_to_kinesis_analytics_s3(resource_pool, ssm_test_cache, boto3_session,
                                        cache_property, input_parameters):
    file_rel_path = extract_param_value(
        input_parameters, 'FlinkAppRelativePath', resource_pool, ssm_test_cache)
    s3_key = extract_param_value(
        input_parameters, 'FlinkAppS3Key', resource_pool, ssm_test_cache)
    bucket_name = extract_param_value(
        input_parameters, 'S3KinesisAnalyticsApplicationBucketName', resource_pool, ssm_test_cache)
    s3_client = client('s3', boto3_session)
    logging.info('Uploading file [%s] to S3 bucket [%s]', file_rel_path, bucket_name)
    with open(file_rel_path, 'rb') as file:
        file_upload_to_s3 = s3_client.put_object(
            Bucket=bucket_name,
            Key=s3_key,
            Body=file
        )
    version_id = file_upload_to_s3['VersionId']
    url = s3_client.generate_presigned_url(
        'get_object', Params={
            'Bucket': bucket_name,
            'Key': s3_key},
        ExpiresIn=3600)
    logging.info(f'File uploaded: url = {url}, bucket_name = {bucket_name}, object_key = {s3_key}, '
                 f'version_id = {version_id}')
    put_to_ssm_test_cache(ssm_test_cache, cache_property, 'S3ObjectVersion', version_id)
    put_to_ssm_test_cache(ssm_test_cache, cache_property, 'URI', url)
    put_to_ssm_test_cache(ssm_test_cache, cache_property, 'S3Key', s3_key)
    put_to_ssm_test_cache(ssm_test_cache, cache_property, 'S3Bucket', bucket_name)

# use next expression to test SQL application:
populate_input_stream_with_dummy_ml_data_expression = 'populate input stream with random ml data ' \
                                                      'for "{sec_interval}" seconds' \
                                                      '\n{input_parameters}'

@given(parsers.parse(populate_input_stream_with_dummy_ml_data_expression))
@when(parsers.parse(populate_input_stream_with_dummy_ml_data_expression))
@then(parsers.parse(populate_input_stream_with_dummy_ml_data_expression))
def populate_stream_with_mldata(resource_pool, ssm_test_cache, boto3_session, sec_interval, input_parameters):
    """
    Populate input stream with random 2D data.
    This is a conventional AWS example for SQL applications test
    """
    input_stream_name = extract_param_value(
        input_parameters, 'InputStreamName', resource_pool, ssm_test_cache)
    kinan_utils.generate_ml_stream(input_stream_name, sec_interval, boto3_session)

# use next expression to test Flink application:
populate_input_stream_with_dummy_ticker_data_expression = 'populate input stream with random ticker data ' \
                                                          'for "{sec_interval}" seconds' \
                                                          '\n{input_parameters}'

@given(parsers.parse(populate_input_stream_with_dummy_ticker_data_expression))
@when(parsers.parse(populate_input_stream_with_dummy_ticker_data_expression))
@then(parsers.parse(populate_input_stream_with_dummy_ticker_data_expression))
def populate_stream_with_dummy_ticker_data(resource_pool, ssm_test_cache, boto3_session, sec_interval,
                                           input_parameters):
    """
    Populate input stream with dummy ticker data
    This is a conventional AWS example for Flink applications test
    """
    input_stream_name = extract_param_value(
        input_parameters, 'InputStreamName', resource_pool, ssm_test_cache)
    kinan_utils.generate_dummy_ticker_stream(input_stream_name, sec_interval, boto3_session)

# invoke lambda loader to populate input stream:
populate_input_stream_by_dummy_ticker_lambda_loader_expression = 'populate input stream by lambda ' \
                                                                 'loader "{invoke_attempts:d}" times' \
                                                                 '\n{input_parameters}'

@given(parsers.parse(populate_input_stream_by_dummy_ticker_lambda_loader_expression))
@when(parsers.parse(populate_input_stream_by_dummy_ticker_lambda_loader_expression))
@then(parsers.parse(populate_input_stream_by_dummy_ticker_lambda_loader_expression))
def populate_input_stream_by_dummy_ticker_lambda_loader(resource_pool, ssm_test_cache,
                                                        boto3_session, invoke_attempts,
                                                        input_parameters):
    input_stream_lambda_loader_name = extract_param_value(
        input_parameters, 'InputStreamLambdaLoaderName', resource_pool, ssm_test_cache)
    kinan_utils.trigger_input_stream_lambda_loader_several_times(
        input_stream_lambda_loader_name, invoke_attempts, boto3_session)

# start kinesis analytics expression:
start_kinesis_analytics_application_expression = 'start Kinesis Data Analytics for "{app_type}" application' \
                                                 '\n{input_parameters}'

@given(parsers.parse(start_kinesis_analytics_application_expression))
@when(parsers.parse(start_kinesis_analytics_application_expression))
@then(parsers.parse(start_kinesis_analytics_application_expression))
def start_kinesis_analytics_application(resource_pool, ssm_test_cache, boto3_session,
                                        stop_kinesis_data_analytics_application,
                                        app_type, input_parameters):
    """
    starts Kinesis Data Analytics application (either sql or flink)
    """
    kinesis_analytics_application_name = extract_param_value(input_parameters,
                                                             'KinesisAnalyticsAppName', resource_pool,
                                                             ssm_test_cache)
    kinesis_analytics_input_id = None
    if app_type in ['sql', 'Sql', 'SQL']:
        kinesis_analytics_input_id = extract_param_value(input_parameters,
                                                         'KinesisAnalyticsInputId', resource_pool, ssm_test_cache)
    kinan_utils.start_kinesis_analytics_app(kinesis_analytics_application_name,
                                            kinesis_analytics_input_id, app_type, boto3_session)
    stop_kinesis_data_analytics_application['app_name'] = kinesis_analytics_application_name

# kinesis application shut down:
shut_down_kinesis_analytics_app_expression = 'shut down Kinesis Data Analytics application' \
                                             '\n{input_parameters}'

@then(parsers.parse(shut_down_kinesis_analytics_app_expression))
def application_shut_down(resource_pool, ssm_test_cache, boto3_session, input_parameters):
    """
    stops Kinesis Data Analytics application (either sql or flink)
    force stops kinesis analytics expression if simple stop fails
    """
    kinesis_analytics_application_name = extract_param_value(input_parameters,
                                                             'KinesisAnalyticsAppName', resource_pool,
                                                             ssm_test_cache)
    kinan_utils.stop_kinesis_analytics_app(kinesis_analytics_application_name, boto3_session)

# kinesis data analytics snapshots list cache expression:
cache_existing_snapshots_kinan_application = 'cache existing snapshots of Flink application as ' \
                                             '"{snapshots_list_name}" "{step_key}" SSM automation execution' \
                                             '\n{input_parameters}'

@given(parsers.parse(cache_existing_snapshots_kinan_application))
@when(parsers.parse(cache_existing_snapshots_kinan_application))
@then(parsers.parse(cache_existing_snapshots_kinan_application))
def cache_existing_snapshots_kinesis_analytics_app(resource_pool, ssm_test_cache, boto3_session, snapshots_list_name,
                                                   step_key, input_parameters):
    kinesis_analytics_application_name = extract_param_value(input_parameters,
                                                             'KinesisAnalyticsAppName', resource_pool,
                                                             ssm_test_cache)
    kinesis_analytics_snapshots_list = kinan_utils.cache_kinan_app_snapshpots_list(
        kinesis_analytics_application_name, boto3_session)
    put_to_ssm_test_cache(ssm_test_cache, step_key, snapshots_list_name, kinesis_analytics_snapshots_list)

# prove snapshot exist or create it otherwise:
prove_kinesis_data_analytics_snapshot_exist_expression = 'prove recovery snapshot exists and confect it otherwise'\
                                                         '\n{input_parameters}'

@given(parsers.parse(prove_kinesis_data_analytics_snapshot_exist_expression))
@when(parsers.parse(prove_kinesis_data_analytics_snapshot_exist_expression))
@then(parsers.parse(prove_kinesis_data_analytics_snapshot_exist_expression))
def prove_kda_snapshot_exist_or_create(resource_pool, ssm_test_cache,
                                       boto3_session, eliminate_test_snapshot,
                                       input_parameters):
    kinesis_analytics_application_name = extract_param_value(input_parameters,
                                                             'KinesisAnalyticsAppName', resource_pool,
                                                             ssm_test_cache)
    snapshot_name_to_prove = extract_param_value(input_parameters,
                                                 'KinesisAnalyticsInputSnapshotName', resource_pool,
                                                 ssm_test_cache)
    # "teardown_snapshot_name" will be different from initial "snapshot_name_to_prove",
    # if "snapshot_name_to_prove" was "Latest"
    create_snapshot, teardown_snapshot_name = kinan_utils.prove_snapshot_exist_or_confect(
        kinesis_analytics_application_name, snapshot_name_to_prove, boto3_session)
    # if snapshot did not exist, and we createed a new one, must teardown it:
    if create_snapshot:
        eliminate_test_snapshot['KinesisAnalyticsAppName'] = kinesis_analytics_application_name
        eliminate_test_snapshot['NewSnapshotName'] = teardown_snapshot_name
        eliminate_test_snapshot['Teardown'] = 'Yes'

# cache kinesis analytics new snapshot name expression:
cache_kinan_application_new_snapshot_name_expression = 'provide Kinesis Analytics application new snapshot ' \
                                                       'name as "{cache_name_new_snapshot}" and save ' \
                                                       'locations to "{cache_property}" cache property' \
                                                       '\n{input_parameters}'

@given(parsers.parse(cache_kinan_application_new_snapshot_name_expression))
@when(parsers.parse(cache_kinan_application_new_snapshot_name_expression))
@then(parsers.parse(cache_kinan_application_new_snapshot_name_expression))
def cache_kinesis_analytics_application_new_snapshot_name(resource_pool, ssm_test_cache, boto3_session,
                                                          eliminate_test_snapshot, cache_name_new_snapshot,
                                                          cache_property, input_parameters):
    kinesis_analytics_application_name = extract_param_value(input_parameters,
                                                             'KinesisAnalyticsAppName', resource_pool,
                                                             ssm_test_cache)
    try:
        input_snapshot_name = extract_param_value(input_parameters,
                                                  'KinesisAnalyticsInputSnapshotName', resource_pool,
                                                  ssm_test_cache)
    except Exception:
        input_snapshot_name = None
    try:
        commit_teardown = extract_param_value(input_parameters,
                                              'Teardown', resource_pool, ssm_test_cache)
    except Exception:
        commit_teardown = 'No'
    new_snapshot_name = kinan_utils.provide_test_snapshot_name(kinesis_analytics_application_name,
                                                               input_snapshot_name)
    put_to_ssm_test_cache(ssm_test_cache, cache_property, cache_name_new_snapshot, new_snapshot_name)
    eliminate_test_snapshot['KinesisAnalyticsAppName'] = kinesis_analytics_application_name
    eliminate_test_snapshot['NewSnapshotName'] = new_snapshot_name
    eliminate_test_snapshot['Teardown'] = commit_teardown

# cache kinesis analytics running application snapshot name (if any):
cache_running_kinesis_analytics_application_snapshot_expression = 'cache kinesis data analytics application ' \
                                                                  'running snapshot as "{cache_name_app_snapshot}" '\
                                                                  '"{step_key}" SSM automation execution' \
                                                                  '\n{input_parameters}'

@given(parsers.parse(cache_running_kinesis_analytics_application_snapshot_expression))
@when(parsers.parse(cache_running_kinesis_analytics_application_snapshot_expression))
@then(parsers.parse(cache_running_kinesis_analytics_application_snapshot_expression))
def cache_running_kinesis_analytics_app_snapshot(resource_pool, ssm_test_cache, boto3_session,
                                                 cache_name_app_snapshot, step_key, input_parameters):
    kinesis_analytics_application_name = extract_param_value(input_parameters,
                                                             'KinesisAnalyticsAppName', resource_pool,
                                                             ssm_test_cache)
    app_snapshot_name = kinan_utils.extract_running_app_snapshot_name(kinesis_analytics_application_name,
                                                                      boto3_session)
    put_to_ssm_test_cache(ssm_test_cache, step_key, cache_name_app_snapshot, app_snapshot_name)

# cache kinesis data analytics latest snapshot (if any):
cache_kinesis_analytics_latest_snapshot_expression = 'cache latest existent kinesis data analytics application ' \
                                                     'snapshot as "{cache_latest_snapshot}" and save locations ' \
                                                     'to "{cache_property}" cache property'\
                                                     '\n{input_parameters}'

@given(parsers.parse(cache_kinesis_analytics_latest_snapshot_expression))
@when(parsers.parse(cache_kinesis_analytics_latest_snapshot_expression))
@then(parsers.parse(cache_kinesis_analytics_latest_snapshot_expression))
def cache_kinesis_analytics_latest_snapshot(resource_pool, ssm_test_cache, boto3_session,
                                            cache_latest_snapshot, cache_property, input_parameters):
    kinesis_analytics_application_name = extract_param_value(input_parameters,
                                                             'KinesisAnalyticsAppName', resource_pool,
                                                             ssm_test_cache)
    latest_snapshot_name = kinan_utils.provide_latest_snapshot(kinesis_analytics_application_name,
                                                               boto3_session)
    put_to_ssm_test_cache(ssm_test_cache, cache_property, cache_latest_snapshot, latest_snapshot_name)

# cache kinesis data analytics status code data
cache_kinesis_analytics_status_code_expression = 'get Kinesis Data Analytics application status code and cache ' \
                                                 'as "{cache_status_code_property_name}" "{step_key}" '\
                                                 'SSM automation execution' \
                                                 '\n{input_parameters}'

@given(parsers.parse(cache_kinesis_analytics_status_code_expression))
@when(parsers.parse(cache_kinesis_analytics_status_code_expression))
@then(parsers.parse(cache_kinesis_analytics_status_code_expression))
def cache_kinesis_analytics_status_code(resource_pool, ssm_test_cache, boto3_session,
                                        cache_status_code_property_name, step_key, input_parameters):
    kinesis_analytics_application_name = extract_param_value(input_parameters,
                                                             'KinesisAnalyticsAppName', resource_pool,
                                                             ssm_test_cache)
    app_status_code = kinan_utils.extract_running_app_status_code(kinesis_analytics_application_name,
                                                                  boto3_session)
    put_to_ssm_test_cache(ssm_test_cache, step_key, cache_status_code_property_name, app_status_code)

# cache kinesis data analytics restore type:
cache_kinesis_data_analytics_snapshot_restore_type_expression = 'cache kinesis data analytics application ' \
                                                                'restore type as "{cache_restore_type_name}" ' \
                                                                '"{step_key}" SSM automation execution' \
                                                                '\n{input_parameters}'

@given(parsers.parse(cache_kinesis_data_analytics_snapshot_restore_type_expression))
@when(parsers.parse(cache_kinesis_data_analytics_snapshot_restore_type_expression))
@then(parsers.parse(cache_kinesis_data_analytics_snapshot_restore_type_expression))
def cache_kinesis_analytics_snapshot_restore(resource_pool, ssm_test_cache, boto3_session,
                                             cache_restore_type_name, step_key, input_parameters):
    kinesis_analytics_application_name = extract_param_value(input_parameters,
                                                             'KinesisAnalyticsAppName', resource_pool,
                                                             ssm_test_cache)
    restore_type = kinan_utils.extract_restore_type(kinesis_analytics_application_name,
                                                    boto3_session)
    put_to_ssm_test_cache(ssm_test_cache, step_key, cache_restore_type_name, restore_type)

# add kinesis data analytics application to vpc:
add_kda_application_to_vpc_expression = 'prove kinesis data analytics application is either ' \
                                        'in provided VPC or add to provided VPC otherwise' \
                                        '\n{input_parameters}'

@given(parsers.parse(add_kda_application_to_vpc_expression))
@when(parsers.parse(add_kda_application_to_vpc_expression))
@then(parsers.parse(add_kda_application_to_vpc_expression))
def add_kda_application_to_vpc_foo(resource_pool, ssm_test_cache, remove_kda_application_vpc_bind,
                                   boto3_session, input_parameters):
    kinesis_analytics_application_name = extract_param_value(
        input_parameters, 'KinesisAnalyticsAppName', resource_pool, ssm_test_cache)
    vpc_id = extract_param_value(
        input_parameters, 'VpcId', resource_pool, ssm_test_cache)
    subnet_id = extract_param_value(
        input_parameters, 'SubnetId', resource_pool, ssm_test_cache)
    security_groups_id_list = extract_param_value(
        input_parameters, 'SecurityGroupsIdList', resource_pool, ssm_test_cache)
    (remove_kda_application_vpc_bind['Teardown'],
     remove_kda_application_vpc_bind['VpcConfigurationId']) = kinan_utils.add_kda_application_to_vpc(
        kinesis_analytics_application_name, vpc_id, subnet_id, security_groups_id_list, boto3_session)
    remove_kda_application_vpc_bind['KinesisAnalyticsAppName'] = kinesis_analytics_application_name
    remove_kda_application_vpc_bind['VpcId'] = vpc_id

# cache Kinesis Data Analytics VPC security group:
cache_kinesis_data_analytics_security_group_ids_expression = 'cache Kinesis Data Analytics security group ids ' \
                                                             'and save as "{cache_security_groups_id_list}" '\
                                                             'at "{step_key}" SSM automation execution'\
                                                             '\n{input_parameters}'

@given(parsers.parse(cache_kinesis_data_analytics_security_group_ids_expression))
@when(parsers.parse(cache_kinesis_data_analytics_security_group_ids_expression))
@then(parsers.parse(cache_kinesis_data_analytics_security_group_ids_expression))
def cache_kinesis_analytics_security_group_ids(resource_pool, ssm_test_cache, boto3_session,
                                               cache_security_groups_id_list, step_key, input_parameters):
    kinesis_analytics_application_name = extract_param_value(
        input_parameters, 'KinesisAnalyticsAppName', resource_pool, ssm_test_cache)
    kda_security_group_ids = kinan_utils.get_kda_vpc_security_groups_id_list(
        kinesis_analytics_application_name, boto3_session)
    put_to_ssm_test_cache(ssm_test_cache, step_key, cache_security_groups_id_list, kda_security_group_ids)

# teardown of created snapshot:
@pytest.fixture(scope='function')
def eliminate_test_snapshot(boto3_session):
    test_snapshot_dict = {}
    yield test_snapshot_dict
    if test_snapshot_dict.get('Teardown') in ['YES', 'Yes', 'yes']:
        teardown_snapshot_name = test_snapshot_dict['NewSnapshotName']
        logger.info(f'Start cleanup for snapshot with name: {teardown_snapshot_name}.')
        kinesis_analytics_client = client('kinesisanalyticsv2', boto3_session)
        resp_list = kinesis_analytics_client.list_application_snapshots(
            ApplicationName=test_snapshot_dict['KinesisAnalyticsAppName'],
            Limit=49)
        snapshot_creation_stamp = [kk['SnapshotCreationTimestamp'] for kk in resp_list['SnapshotSummaries']
                                   if kk['SnapshotName'] == teardown_snapshot_name][0]
        snapshot_del_code = kinesis_analytics_client.delete_application_snapshot(
            ApplicationName=test_snapshot_dict['KinesisAnalyticsAppName'],
            SnapshotName=teardown_snapshot_name,
            SnapshotCreationTimestamp=snapshot_creation_stamp)['ResponseMetadata']['HTTPStatusCode']
        logger.info(f'Cleanup for snapshot with name: {teardown_snapshot_name} '
                    f'completed with code: {snapshot_del_code}')

# teardown of created s3 bucket:
@pytest.fixture(scope='function')
def eliminate_s3_bucket_with_object(boto3_session):
    test_s3_bucket_dict = {}
    yield test_s3_bucket_dict
    if test_s3_bucket_dict.get('S3BucketTeardown') in ['YES', 'Yes', 'yes']:
        bucket_name = test_s3_bucket_dict['bucket_name']
        s3_resource = boto3_session.resource('s3')
        s3_client = client('s3', boto3_session)
        account_id = test_s3_bucket_dict['account_id']
        logger.info('Deleting CF bucket with name [%s]', bucket_name)
        bucket = s3_resource.Bucket(bucket_name)
        if s3_resource.BucketVersioning(bucket_name).status == 'Enabled':
            bucket.object_versions.delete(ExpectedBucketOwner=account_id)
        else:
            bucket.objects.delete(ExpectedBucketOwner=account_id)
        s3_client.delete_bucket(Bucket=bucket_name, ExpectedBucketOwner=account_id)

# teardown of start application (i.e. stop application when test commences)
@pytest.fixture(scope='function')
def stop_kinesis_data_analytics_application(boto3_session):
    stop_application_dict = {}
    yield stop_application_dict
    application_name = stop_application_dict['app_name']
    kinan_utils.stop_kinesis_analytics_app(application_name, boto3_session)
    logger.info(f'Stopping kinesis data analytics application: {application_name}')

@pytest.fixture(scope='function')
def remove_kda_application_vpc_bind(boto3_session):
    remove_vpc_application_dict = {}
    yield remove_vpc_application_dict
    if remove_vpc_application_dict.get('Teardown') in ['YES', 'Yes', 'yes']:
        kinesis_analytics_client = client('kinesisanalyticsv2', boto3_session)
        application_name = remove_vpc_application_dict['KinesisAnalyticsAppName']
        conditional_token = kinesis_analytics_client.describe_application(
            ApplicationName=application_name, IncludeAdditionalDetails=True)
        conditional_token = conditional_token['ApplicationDetail']['ConditionalToken']
        vpc_configuration_id = remove_vpc_application_dict['VpcConfigurationId']
        logger.info(f'Excluding Kinesis Data Analytics applicstion {application_name}'
                    f'with vpc configuration id {vpc_configuration_id} from VPC.')
        kinesis_analytics_client.delete_application_vpc_configuration(
            VpcConfigurationId=vpc_configuration_id,
            ApplicationName=application_name,
            ConditionalToken=conditional_token)
        logger.info('Kinesis data analytics application: '
                    f'{remove_vpc_application_dict["KinesisAnalyticsAppName"]} '
                    f'excluded from VPC {remove_vpc_application_dict["VpcId"]}')


import random

from bokeh.io import output_file, show
from bokeh.models import ColumnDataSource
from bokeh.palettes import Spectral6
from bokeh.plotting import figure
from bokeh.transform import factor_cmap

def graph(values, name):

    output_file("colormapped_bars.html")

    times = ['100', '1000', '10000', '100000']
    counts = [5, 3, 4, 2, 4, 6]

    source = ColumnDataSource(data=dict(times=times, values=values))

    p = figure(x_range=times, plot_height=1000, toolbar_location=None, title=name)
    p.vbar(x='times', top='values', width=0.9, source=source, legend_field="times", line_color='white', fill_color=factor_cmap('times', palette=Spectral6, factors=times))
    p.y_range.start = 0
    p.y_range.end = 1
    p.legend.orientation = "horizontal"
    p.legend.location = "top_center"

    show(p)

def tirar_dado(numero_de_tiros):
    secuencia_de_tiros = []

    for i in range(numero_de_tiros):
        tiro = random.randint(2, 12)

        secuencia_de_tiros.append(tiro)
    return secuencia_de_tiros

def main(numero_de_tiros, numero_de_intentos, numero_persona):
    tiros = []

    for _ in range(numero_de_intentos):
        secuencia_de_tiros = tirar_dado(numero_de_tiros)
        tiros.append(secuencia_de_tiros)

    tiros_acertados = 0
    tiros_no_acertados = 0
    for tiro in tiros:
        if numero_persona in tiro:
            tiros_acertados += 1
        else:
            tiros_no_acertados += 1

    probabilidad_de_tiros_acertados = tiros_acertados / numero_de_intentos
    probabilidad_de_tiros_no_acertados = tiros_no_acertados /numero_de_intentos
    # print(f"La probabilad de obtener por lo menos un 1 en un numero de intentos de {numero_de_intentos} es de {probabilidad_tiros_con_1}")
    print(f"La probabilad de obtener por lo menos un {numero_persona} en {numero_de_tiros} tiros\nSimulando este proceso {numero_de_intentos} veces es de {probabilidad_de_tiros_acertados}")
    print(f"La probabilad de NO obtener por lo menos un {numero_persona} en {numero_de_tiros} tiros\nSimulando este proceso {numero_de_intentos} veces es de {probabilidad_de_tiros_no_acertados}")
    print("=================================================================")
    return (probabilidad_de_tiros_acertados, probabilidad_de_tiros_no_acertados)

if __name__ == "__main__":
    all_prob_acert = []
    all_prob_no_acert = []

    numero_de_tiros = int(input("Cuantos veces quieres tirar los dos dados: "))
    numero_persona = int(input("A que numero le apuestas: "))
    while numero_persona > 12 or numero_persona < 2:
        numero_persona = int(input("El numero maximo con dos dados en 12 y el minimo es 2\n A que numero le apuestas:  "))
    numero_de_intentos = [100, 1000, 10000, 100000]

    for interval in numero_de_intentos:
        prob_acert, prob_no_acert = main(numero_de_tiros, interval, numero_persona)
        all_prob_acert.append(prob_acert)
        all_prob_no_acert.append(prob_no_acert)

    print("Graficando las probabilidades: ")
    print(f"Acertado: {all_prob_acert}")
    print(f"No Acertado: {all_prob_no_acert}")

    graph( all_prob_no_acert, f"Probabilidades no acertar con {numero_de_tiros} tiros" )
    graph( all_prob_acert, f"Probabilidades acertar con {numero_de_tiros} tiros" )

    print("=================================================================")


"""empty message

Revision ID: 32d423c8abbe
Revises: cfc8c12e45e3
Create Date: 2020-08-24 15:32:00.758205

"""
from alembic import op
import sqlalchemy as sa
from sqlalchemy.dialects import mysql

# revision identifiers, used by Alembic.
revision = '32d423c8abbe'
down_revision = 'cfc8c12e45e3'
branch_labels = None
depends_on = None

def upgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    op.add_column('user', sa.Column('available', sa.Boolean(), nullable=True))
    op.alter_column('user_subjects', 'user_selected',
               existing_type=mysql.TINYINT(display_width=1),
               nullable=True)
    # ### end Alembic commands ###

def downgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    op.alter_column('user_subjects', 'user_selected',
               existing_type=mysql.TINYINT(display_width=1),
               nullable=False)
    op.drop_column('user', 'available')
    # ### end Alembic commands ###


from django.urls import path
from django.views.generic import RedirectView
from rest_framework.routers import DefaultRouter

from mailing import views

app_name = 'mailing'

urlpatterns = [
    path('', RedirectView.as_view(url='/backend/docs/')),
    path(
        'admin/login/',
        views.CustomLoginView.as_view(),
        name='custom_admin_login'
    ),
]

router = DefaultRouter()
router.register('mailings', views.MailingViewSet, basename='mailings')
router.register('clients', views.ClientViewSet, basename='clients')
router.register(
    'mobile_operators', views.MobileOperatorViewSet,
    basename='mobile_operators'
)
router.register('tags', views.TagViewSet, basename='tags')

urlpatterns += router.urls


#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Sun Jan 17 21:51:29 2021
@author: JGSnyder
@email: jakegsnyder43@gmail.com
File of Strings -> File of Strings
Converts VM lines of text to asm lines of text
Code built as part of nand2tetris class on https://www.coursera.org/learn/build-a-computer/
"""
import sys, os, re, logging
import AssemblyTable

def main():
    assert len(sys.argv) == 2, "Usage: python VMTranslator.py <inputfile.vm>"
    logging.basicConfig(filename='logs/VMTranslator.log', level=logging.DEBUG)

    inf = sys.argv[1] #01/FunctionDirectory/Function.vm
    filename = os.path.splitext(os.path.basename(inf))[0] + '.asm' #Function.asm
    code = CodeWriter(filename)
    try:
        if inf.endswith('.vm'):
            filepath = os.path.splitext(inf)[0] + '.asm' #/01/FunctionDirectory/Function.asm
            with open(filepath, 'w') as outf:
                #write initial setup code
                outf.write(code.asm_init())
                translateFile(code, inf, outf)

        elif os.path.isdir(inf): #FunctionDirectory
            if inf.endswith('/'):
                inf = inf[0:-1] #../main/ -> ../main
            filepath = inf + '/' + filename #01/FunctionDirectory/FunctionDirectory.asm
            with open(filepath, 'w') as outf:
                #write initial setup code
                outf.write(code.asm_init())
                for file in os.listdir(inf):
                    if file.endswith('.vm'):
                        translateFile(code, inf + '/' + file, outf)
                        code.staticsCounter += 1
        else:
            logging.exception("Error opening file.", exc_info=True)
    #TODO not logging properly
    except PermissionError:
        logging.exception("You do not have the appropriate permissions. Run chmod a+x on the file you are working with and try again.")
    except FileNotFoundError:
        logging.exception("The file was not found. Please try again.")

def translateFile(code, inf, outf):
    line_no = 0
    #parse each line, convert, and write to outf
    for line in open(inf, 'r'):
        try:
            p = Parser(line)
            if p.line == '': #ignore empty lines
                continue
            elif p.command_type() == 'C_ARITHMETIC':
                commandString = code.asm_arithmetic(p.arg1())
            elif p.command_type() in ('C_PUSH', 'C_POP'):
                commandString = code.asm_pushpop(p.arg1(), p.arg2(), p.arg3())
            elif p.command_type() == 'C_LABEL':
                commandString = code.asm_label(p.arg2())
            elif p.command_type() == 'C_GOTO':
                commandString = code.asm_goto(p.arg2())
            elif p.command_type() == 'C_IF':
                commandString = code.asm_if(p.arg2())
            elif p.command_type() == 'C_FUNCTION':
                commandString = code.asm_function(p.arg2(), p.arg3())
            elif p.command_type() == 'C_CALL':
                commandString = code.asm_call(p.arg2(), p.arg3())
            elif p.command_type() == 'C_RETURN':
                commandString = code.asm_return()
            else:
                commandString = ""
        except Exception:
            logging.exception(f"Error on {inf} line {line_no}.")

        #increment line count and write to file
        else:
            line_no += 1
            if p.line:
                if not p.line.startswith("//"):
                    outf.write("\n//" + line + commandString)
                else:
                    outf.write(line)
    """
    infinite loop addition for early nand2tetris tests
    outf.write("\n(INFINITE_LOOP)\n" \
                "@INFINITE_LOOP\n"
                "0;JMP")
    """

class Parser(object):
    def __init__(self, line):
        #removes comments and extra space
        self.line = re.sub("(//).+", "", line).strip()

    def command_type(self):
        command_types = {'push': 'C_PUSH', 'pop': 'C_POP', ('add', 'sub', 'neg', 'eq', 'gt', 'lt', 'and', 'or', 'not'): 'C_ARITHMETIC',
        'label': 'C_LABEL', 'goto': 'C_GOTO', 'if-goto': 'C_IF', 'function': 'C_FUNCTION', 'return': 'C_RETURN', 'call': 'C_CALL'}
        try:
            return next(v for k, v in command_types.items() if self.arg1() in k)
        except Exception:
            logging.exception("Not a valid command type.")

    def arg1(self):
        """
        String -> String
        """
        return self.line.strip().split()[0]

    def arg2(self):
        """
        String -> String
        Returns 'static' in push static i OR 'LCL' in pop local i
        """
        memory_abbreviations = {'local': 'LCL', 'argument': 'ARG', 'this': 'THIS', 'that': 'THAT'}
        var = self.line.split()[1] # 'static' or 'constant'
        return memory_abbreviations[var] if var in memory_abbreviations else var

    def arg3(self):
        """
        String -> Int
        Returns i in 'push constant i' or 'pop static i'
        """
        return int(self.line.split()[2])

class CodeWriter(object):
    def __init__(self, filename):
        self.compareCounter = 0 #increments every time two stack numbers are compared; ensures no duplicate variable names
        self.callCounter = 0 #increments every time function is called; ensures no duplicate function names
        self.staticsCounter = 0 #increments every time new '.vm' file is opened for translation; ensures no duplicate static names
        self.filename = filename #argument passed to CodeWriter
        self.function_name = '' #necessary to create label_name
        self.label_name = self.filename + '.' + self.function_name #once code object is created
                                                                    #this label_name does not update
        self.fixed_memory_locations = AssemblyTable.AssemblyTable()
        self.additional_memory_locations = {'pointer': 3, 'temp': 5}

    def asm_init(self):
        init_setup_lines = "//Startup code\n" \
                            "@256\n" \
                            "D=A\n" \
                            "@SP\n" \
                            "M=D\n" \
                            "@700\n" \
                            "D=A\n" \
                            "@LCL\n" \
                            "M=D\n" \
                            "@800\n" \
                            "D=A\n" \
                            "@ARG\n" \
                            "M=D\n" \
                            "@900\n" \
                            "D=A\n" \
                            "@THIS\n" \
                            "M=D\n" \
                            "@1000\n" \
                            "D=A\n" \
                            "@THAT\n" \
                            "M=D\n" + \
                            self.asm_call('Sys.init', 0)
        return init_setup_lines

    def asm_arithmetic(self, arg1):
        if arg1 == 'add':
            return self.combine_op('+')
        elif arg1 == 'sub':
            return self.combine_op('-')
        elif arg1 == 'and':
            return self.combine_op('&')
        elif arg1 == 'or':
            return self.combine_op('|')
        elif arg1 == 'neg':
            return self.single_op('-')
        elif arg1 == 'not':
            return self.single_op('!')
        elif arg1 in ('gt', 'lt', 'eq'):
            return self.compare_op(arg1)
        else:
            logging.exception('Improper arithmetic command used.')

    def single_op(self,operator):
        convertedLine = "@SP\n" \
                        "M=M-1\n" \
                        "A=M\n" \
                        "M=" + operator + "M\n" \
                        "@SP\n" \
                        "M=M+1\n"
        return convertedLine

    def combine_op(self,operator):
        convertedLine = "@SP\n" \
                        "M=M-1\n" \
                        "A=M\n" \
                        "D=M\n" \
                        "@SP\n" \
                        "M=M-1\n" \
                        "A=M\n" \
                        "M=M" + operator + "D\n" \
                        "@SP\n" \
                        "M=M+1\n"
        return convertedLine

    def compare_op(self, operator):
        convertedLine = "@SP\n" \
                        "M=M-1\n" \
                        "A=M\n" \
                        "D=M\n" \
                        "@SP\n" \
                        "M=M-1\n" \
                        "A=M\n" \
                        "D=M-D\n" \
                        "@OUTPUT_TRUE_" + str(self.compareCounter) + "\n" \
                        "D;J" + operator.upper() + "\n" \
                        "D=0\n" \
                        "@NEXT_COMMAND_" + str(self.compareCounter) + "\n" \
                        "0;JMP\n" \
                        \
                        "(OUTPUT_TRUE_" + str(self.compareCounter) + ")" + "\n" \
                        "D=-1\n" \
                        "@NEXT_COMMAND_" + str(self.compareCounter) + "\n" \
                        "0;JMP\n" \
                        \
                        "(NEXT_COMMAND_" + str(self.compareCounter) + ")" + "\n" \
                        "@SP\n" \
                        "A=M\n" \
                        "M=D\n" \
                        "@SP\n" \
                        "M=M+1\n"
        self.compareCounter += 1
        return convertedLine

    def arg2_memory_location(self,arg2):
        """
        String -> Int
        """
        if self.fixed_memory_locations.contains(arg2):
            return self.fixed_memory_locations.get_entry(arg2)
        elif arg2 in ('pointer', 'temp'):
            return self.additional_memory_locations[arg2]
        else:
            pass

    def pushpop_firstlines(self, arg2, arg3):
        if arg2 in ('LCL', 'ARG', 'THIS', 'THAT'):
            first_lines = "@" + str(arg3) + "\n" \
                            "D=A\n" \
                            "@" + str(self.arg2_memory_location(arg2)) + "\n" \
                            "D=M+D\n"
        elif arg2 == 'constant':
            first_lines = "@" + str(arg3) + "\n" \
                            "D=A\n"
        elif arg2 == 'static':
            first_lines = "@" + self.filename + "." + 'static' + str(self.staticsCounter) + str(arg3) + "\n" \
                            "D=A\n"
        elif arg2 in ('temp', 'pointer'):
            first_lines = "@" + str(arg3) + "\n" \
                            "D=A\n" \
                            "@" + str(self.arg2_memory_location(arg2)) + "\n" \
                            "D=A+D\n"
        else:
            first_lines = "@" + arg2 + "\n" \
                            "D=A\n"
        return first_lines

    def asm_pushpop(self, arg1, arg2, arg3):
        if arg1 == 'push':
            if arg2 == 'constant':
                second_lines = "@SP\n" \
                            "A=M\n" \
                            "M=D\n" \
                            "@SP\n" \
                            "M=M+1\n"
            else:
                second_lines = "@addr\n" \
                            "M=D\n" \
                            "A=M\n" \
                            "D=M\n" \
                            "@SP\n" \
                            "A=M\n" \
                            "M=D\n" \
                            "@SP\n" \
                            "M=M+1\n"
            return self.pushpop_firstlines(arg2, arg3) + second_lines
        elif arg1 == 'pop':
            second_lines = "@addr\n" \
                            "M=D\n" \
                            "@SP\n" \
                            "M=M-1\n" \
                            "A=M\n" \
                            "D=M\n" \
                            "@addr\n" \
                            "A=M\n" \
                            "M=D\n"
            return self.pushpop_firstlines(arg2, arg3) + second_lines

    def asm_label(self, arg2):
        """
        label label
        """
        return "(" + self.label_name + arg2 + ")\n"

    def asm_goto(self, arg2):
        """
        goto label
        """
        return "@" + self.label_name + arg2 + "\n" \
                "0;JMP\n"

    def asm_if(self, arg2):
        """
        if-goto label
        """
        convertedLine = "@SP\n" \
                        "M=M-1\n" \
                        "A=M\n" \
                        "D=M\n" \
                        "@" + self.label_name + arg2 + "\n" \
                        "D; JNE\n"
        return convertedLine

    def asm_function(self, arg2, arg3):
        """
        function function_name nVars
        """
        self.function_name = arg2
        return "(" + self.filename + '.' + self.function_name + ")\n" + \
                (arg3 * self.asm_pushpop('push','constant', 0)) # push constant 0 as LCL variables arg3 times

    def save_mem_space(self):
        """
        pushes memory address to top of the stack
        """
        return "@SP\n" \
                "A=M\n" \
                "M=D\n" \
                "@SP\n" \
                "M=M+1\n"

    def asm_call(self, arg2, arg3):
        """
        call function_name nArgs
        """
        self.function_name = arg2
        self.callCounter +=1
        retAddr = self.filename + '.' + self.function_name +'$ret.' + str(self.callCounter)
        save_caller_frame = "//call. save_caller_frame\n" + \
                            "@" + retAddr + "\n" \
                            "D=A\n" + \
                            self.save_mem_space() + \
                            \
                            "//call. push local\n" + \
                            "@LCL\n" \
                            "D=M\n" + \
                            self.save_mem_space() + \
                            \
                            "//call. push ARG\n" + \
                            "@ARG\n" \
                            "D=M\n" + \
                            self.save_mem_space() + \
                            \
                            "//call. push THIS\n" + \
                            "@THIS\n" \
                            "D=M\n" + \
                            self.save_mem_space() + \
                            \
                            "//call. push THAT\n" + \
                            "@THAT\n" \
                            "D=M\n" + \
                            self.save_mem_space()
        set_new_arg =   "//call. set_new_arg\n" \
                        "@SP\n" \
                        "D=M\n" \
                        "@" + str(arg3 + 5) + "\n" \
                        "D=D-A\n" \
                        "@ARG\n" \
                        "M=D\n"
        set_new_lcl =   "//call. set_new_lcl\n" \
                        "@SP\n" \
                        "D=M\n" \
                        "@LCL\n" \
                        "M=D\n"
        goto_called_function = self.asm_goto(arg2)

        return save_caller_frame + set_new_arg + set_new_lcl + goto_called_function + "(" + retAddr + ")"

    def restore_mem_space(self, pointer):
        """
        only used for asm_return function to restore locations in callee's stack to caller's original memory values
        """
        restored_pointer = "@endframe\n" \
                            "M=M-1\n" \
                            "A=M\n" \
                            "D=M\n" \
                            "@" + pointer + "\n" \
                            "M=D\n"
        return restored_pointer

    def asm_return(self):
        """
        return
        """
        endframe_equals_lcl = "@LCL\n" \
                                "D=M\n" \
                                "@endframe\n" \
                                "M=D\n"
        retAddr_designation = "@5\n" \
                                "D=A\n" \
                                "@endframe\n" \
                                "D=M-D\n" \
                                "A=D\n" \
                                "D=M\n" \
                                "@retAddr\n" \
                                "M=D\n"
        pop_arg_zero = self.asm_pushpop('pop', 'ARG', 0)
        move_sp = "@ARG\n" \
                    "D=M+1\n" \
                    "@SP\n" \
                    "M=D\n"
        #THAT, THIS, ARG, LCL needs to be in this order for the restore_mem_space function to work properly
        #since THAT = *(endframe-1), THIS = *(endframe-2), etc.
        restore_that = self.restore_mem_space("THAT")
        restore_this = self.restore_mem_space("THIS")
        restore_arg = self.restore_mem_space("ARG")
        restore_lcl = self.restore_mem_space("LCL")
        goto_retaddr = "@retAddr\n" \
                        "A=M\n" \
                        "0;JMP\n"

        return endframe_equals_lcl + retAddr_designation + pop_arg_zero + move_sp + \
                restore_that + restore_this + restore_arg + restore_lcl + goto_retaddr

if __name__ == '__main__':
    main()


from torch.optim import lr_scheduler

class SchedulerManager:
    @staticmethod
    def build_scheduler(optimizer, cfg):
        """
        Return a learning rate scheduler
            For 'linear', we keep the same learning rate for the first <cfg.niter_warmup> epochs
        and linearly decay the rate to zero over the next <cfg.niter_decay> epochs.
        For other schedulers (step, plateau, and cosine), we use the default PyTorch schedulers.
        See https://pytorch.org/docs/stable/optim.html for more details.
        Args:
            optimizer (torch.optim): the optimizer of the network
            cfg: cfg.lr_decay_method is the name of the decay method of learning rate: linear | step | plateau | cosine
        return: scheduler
        """
        if cfg.lr_decay_method == "step":
            scheduler = lr_scheduler.StepLR(optimizer, step_size=cfg.lr_decay_niters, gamma=cfg.gama)
        elif cfg.lr_decay_method == "plateau":
            scheduler = lr_scheduler.ReduceLROnPlateau(optimizer, mode="min", factor=0.2, threshold=0.01, patience=5)
        elif cfg.lr_decay_method == "cosine":
            scheduler = lr_scheduler.CosineAnnealingLR(optimizer, T_max=cfg.max_iter, eta_min=0)
        else:
            raise NotImplementedError("lr_decay_method '{}' is not implemented".format(cfg.lr_decay_method))


import matplotlib.pyplot as plt

# Dados de exemplo
amostra = [
    ['Módulo 1', 32, 1.66, 65],
    ['Módulo 1', 18, 1.74, 80],
    ['Módulo 1', 19, 1.76, 60],
    ['Módulo 2', 30, 1.84, 90],
    ['Módulo 2', 33, 1.81, 94],
    ['Módulo 3', 30, 1.74, 75],
    ['Módulo 4', 21, 1.83, 110],
    ['Módulo 5', 26, 1.74, 64]
]

# Separar as variáveis "altura", "peso", "módulo" e "idade"
altura = [amostra[i][3] for i in range(len(amostra))]
idades = [amostra[i][1] for i in range(len(amostra))]

# Criar o gráfico de dispersão com o eixo x representando o módulo e o eixo y representando a idade
plt.scatter(altura, idades)

# Personalizar os rótulos dos eixos x e y e adicionar um título
plt.xlabel('peso')
plt.ylabel('Idade')
plt.title('Gráfico de Dispersão para a Variável Idade em Função do Módulo')

# Exibir o gráfico
plt.show()


import itertools

from utils import get_grid

class Cube:
    """Class representing the Cube::Bit."""

    def __init__(self):
        """Construct."""
        self.grid = get_grid()

    def display(self, colours):
        """Realign and display a 3x3 grid of colours."""
        fixed_colours = reorder(flatten(colours))
        for i in range(27):
            self.grid[i] = fixed_colours[i]

        self.grid.show()

def reorder(colours):
    """
    Reorder the colours to fit the Cube::Bit's weird space-filling curve.

    This is horribly hard-coded - if I ever get a cube that's not a 3x3x3, I'll
    do it properly
    """
    indeces = [
        0,
        3,
        6,
        7,
        4,
        1,
        2,
        5,
        8,
        17,
        16,
        15,
        12,
        13,
        14,
        11,
        10,
        9,
        18,
        21,
        24,
        25,
        22,
        19,
        20,
        23,
        26,
    ]
    reordered = []
    for i in range(27):
        reordered.append(colours[indeces[i]])
    return reordered

def flatten(colours):
    """Flatten the cubular array into one long list."""
    return list(itertools.chain.from_iterable(itertools.chain.from_iterable(colours)))


"""
LetMeDoIt AI Plugin - bible

read, compare or search the bible

[FUNCTION_CALL]
"""

try:
    import apsw
except:
    from letmedoit.utils.install import *
    installmodule(f"--upgrade apsw")
from letmedoit import config
import os, re, json, shutil
from prompt_toolkit import print_formatted_text, HTML
from letmedoit.utils.file_utils import FileUtil
from letmedoit.plugins.bibleTools.utils.TextUtil import TextUtil
from letmedoit.plugins.bibleTools.utils.BibleBooks import BibleBooks

def getBibleList(version=""):
    bibleFolder = os.path.join(config.bibleDataCurrent, "bibles")
    bibleList = FileUtil.fileNamesWithoutExtension(bibleFolder, "bible")
    if version in bibleList:
        config.mainText = version
    if not config.mainText in bibleList:
        config.mainText = "NET"
    return bibleList

def search_bible(function_args):
    terminal_width = shutil.get_terminal_size().columns
    # get the sql query statement
    query = function_args.get("query") # required
    if not query.startswith("SELECT "):
        query = f"SELECT * FROM Verses WHERE {query}"
    version = function_args.get("version") # required
    allVersions = getBibleList(version)
    # exclude mainText from allVersions
    if config.mainText in allVersions:
        allVersions.remove(config.mainText)
    compare = function_args.get("compare") # required
    compareMode = (compare == "yes")
    versions = function_args.get("versions", "")
    if versions:
        try:
            compareVersions = eval(versions) if isinstance(versions, str) else versions
            compareVersions = [i for i in compareVersions if i in allVersions]
            if config.mainText in compareVersions:
                compareVersions.remove(config.mainText)
            if not compareVersions:
                compareVersions = allVersions
        except:
            compareVersions = allVersions
    else:
        compareVersions = allVersions
    # formulate a list of search words
    searchWordsRegex = [m for m in re.findall("Scripture REGEXP ['\"](.*?)['\"]", query)]
    searchWordsPlain = [m for m in re.findall("Scripture LIKE ['\"]%(.*?)%['\"]", query)]
    searchWords = searchWordsRegex + searchWordsPlain

    def highlightSearchResults(textContent):
        for eachString in searchWords:
            textContent = TextUtil.highlightSearchString(textContent, eachString)
        # fix highlighting
        textContent = TextUtil.fixTextHighlighting(textContent)
        return TextUtil.htmlToPlainText(textContent)
    def displaySingleVerse(bible, c, v, verseText):
        selectedBible = bible
        if searchWords:
            verseText = highlightSearchResults(verseText)
        verseText = verseText.strip()
        if bible == config.mainText and compareMode and compareVersions:
            bible = f"<{config.terminalPromptIndicatorColor2}>{bible}</{config.terminalPromptIndicatorColor2}>"
            verseText = f"<{config.terminalPromptIndicatorColor2}>{verseText}</{config.terminalPromptIndicatorColor2}>"
        bible = f"[{bible}] " if compareMode and compareVersions else ""
        thisVerse = f"<{config.terminalResourceLinkColor}>{c}:{v}</{config.terminalResourceLinkColor}> {verseText}"
        verseContent = f"{bible}{thisVerse}"
        if config.wrapWords and not selectedBible in config.noWordWrapBibles:
            verseContent = config.getWrappedHTMLText(verseContent, terminal_width)
        print_formatted_text(HTML(verseContent))
        config.addPagerText(verseContent)
        return thisVerse
    def getSingleVerse(bible, b, c, v):
        database = os.path.join(config.bibleDataCurrent, "bibles", f"{bible}.bible")
        if os.path.isfile(database):
            with apsw.Connection(database) as connection:
                cursor = connection.cursor()
                query = "SELECT * FROM Verses WHERE Book=? AND Chapter=? AND Verse=?"
                cursor.execute(query, (b, c, v))
                result = cursor.fetchone()
                if result:
                    return result if result[-1] else ()
                else:
                    return ()
        return ()

    addText = f"loading bible {config.mainText} ..."
    config.print(addText)
    config.addPagerText(addText)
    # display sql query statement for developer
    if config.developer:
        config.print(query)
        config.addPagerText(query)

    database = os.path.join(config.bibleDataCurrent, "bibles", f"{config.mainText}.bible")
    if os.path.isfile(database):
        config.tempContent = ""
        config.stopSpinning()
        with apsw.Connection(database) as connection:
            # support regular expression
            connection.createscalarfunction("REGEXP", TextUtil.regexp)
            cursor = connection.cursor()
            # support case sensitive search in query prefix
            cursor.execute(TextUtil.getQueryPrefix()+query)
            if not query.lower().startswith("select * from verses where"):
                results = cursor.fetchall()
                # return information, e.g. how many chapters in Genesis
                return json.dumps(results)
            book = 0
            bookName = ""
            total = 0
            subTotal = 0
            subTotals = {}
            config.print(config.divider)
            config.addPagerText(config.divider)
            for b, c, v, verseText in cursor.fetchall():
                config.mainB, config.mainC, config.mainV = b, c, v
                if not book == b:
                    if not book == 0 and bookName:
                        total += subTotal
                        bookName = re.sub("|", "", bookName)
                        subTotals[bookName] = subTotal
                        subTotal = 0
                    book = b
                    bookName = abbrev[str(b)][-1]
                    config.tempContent += f"{bookName}\n"
                    bookName = f"<{config.terminalHeadingTextColor}>{bookName}</{config.terminalHeadingTextColor}>"
                    print_formatted_text(HTML(bookName))
                    config.addPagerText(bookName)
                displaySingleVerse(config.mainText, c, v, verseText)
                config.tempContent += f"{c}:{v}\n"
                # thisVerse = displaySingleVerse(config.mainText, c, v, verseText)
                # config.tempContent += f"{thisVerse}\n"
                subTotal += 1
                # bible comparison
                if compareMode and compareVersions:
                    for bible in compareVersions:
                        singleVerse = getSingleVerse(bible, b, c, v)
                        if singleVerse:
                            _, c, v, verseText = getSingleVerse(bible, b, c, v)
                            displaySingleVerse(bible, c, v, verseText)
            # include statistics of the last book
            if bookName:
                total += subTotal
                bookName = re.sub("|", "", bookName)
                subTotals[bookName] = subTotal
            config.tempContent = re.sub("<[^<>]*?>", "", config.tempContent)
            config.print(config.divider)
            config.addPagerText(config.divider)
            for key, value in subTotals.items():
                addText = f"{key} x {value}"
                print_formatted_text(HTML(addText))
                config.addPagerText(addText)
            config.print(config.divider)
            config.addPagerText(config.divider)
            addText = f"Total: {total} verse(s)"
            print_formatted_text(HTML(addText))
            config.addPagerText(addText)
    return ""

# add bible books to input suggestions
config.inputSuggestions += [
    "go to ",
    "go to chapter ",
    "next chapter",
    "previous chapter",
    "search for verses that ",
    "enable comparison",
    "disable comparison",
]
abbrev = BibleBooks.abbrev["eng"]
for i in abbrev:
    abb, fullname = abbrev[i]
    if abb:
        config.inputSuggestions += [abb, fullname]
# configs particular to this plugin
# persistent
persistentConfigs = (
    ("mainText", "NET"),
    ("mainB", 43),
    ("mainC", 3),
    ("mainV", 16),
    ("bibleData", ""),
    ("enableCaseSensitiveSearch", False),
    ("noWordWrapBibles", []), # some bibles display better, without word wrap feature, e.g. CUV
)
config.setConfig(persistentConfigs)
# temporary
temporaryConfigs = (
    ("runMode", "terminal"),
    ("bibleDataCurrent", config.bibleData if config.bibleData else os.path.join(config.letMeDoItAIFolder, "plugins", "bibleTools", "bibleData")),
)
config.setConfig(temporaryConfigs, temporary=True)

bibleList = getBibleList()
functionSignature = {
    "name": "search_bible",
    "description": "read, compare or search the bible",
    "parameters": {
        "type": "object",
        "properties": {
            "query": {
                "type": "string",
                "description": """Formulate a sql query over a table created with statement "CREATE TABLE Verses (Book INT, Chapter INT, Verse INT, Scripture TEXT)".
The book numbers range from 1 to 66, corresponding to the canonical order from Genesis to Revevlation in the bible.
Give me only the sql query statement, starting with "SELECT * FROM Verses WHERE " without any extra explanation or comment.""",
            },
            "version": {
                "type": "string",
                "description": "Specify a bible version to read.  Answer 'XXX' if none is specified.",
                "enum": ['XXX'] + bibleList,
            },
            "compare": {
                "type": "string",
                "description": "Tell if comparison is intended. Answer 'no' if none is indicated.",
                "enum": ['yes', 'no'],
            },
            "versions": {
                "type": "string",
                "description": f"List of bible versions for comparison, e.g. {bibleList}",
            },
        },
        "required": ["query", "version", "compare"],
    },
}

# make available for function calling
config.pluginsWithFunctionCall.append("search_bible")
config.chatGPTApiFunctionSignatures.append(functionSignature)
config.chatGPTApiAvailableFunctions["search_bible"] = search_bible

##############################

# a dummy function to pass back the original query to ChatGPT without function call
# this function was created to help ChatGPT to distinguish between different requests described in plugins "search_bible" and "bible_qa"
def bible_qa(function_args):
    return "[INVALID]"

functionSignature = {
    "name": "bible_qa",
    "description": f'''Answer questions or provide information about the bible''',
    "parameters": {
        "type": "object",
        "properties": {
            "qa": {
                "type": "string",
                "description": "empty string ''",
            },
        },
    },
}
#config.pluginsWithFunctionCall.append("bible_qa")
config.chatGPTApiFunctionSignatures.append(functionSignature)
config.chatGPTApiAvailableFunctions["bible_qa"] = bible_qa


# Simple demo of reading the difference between channel 1 and 0 on an ADS1x15 ADC.
# Author: Tony DiCola
# License: Public Domain
import time
import math
import matplotlib.pyplot as plt
import logging

# Import the ADS1x15 module.
from ADS1x15 import ADS1115

# Create an ADS1115 ADC (16-bit) instance.
#adc = ADS1115()

# Or create an ADS1015 ADC (12-bit) instance.
adc = ADS1115()

# Note you can change the I2C address from its default (0x48), and/or the I2C
# bus by passing in these optional parameters:
#adc = ADS1015(address=0x49, busnum=1)

# Choose a gain of 1 for reading voltages from 0 to 4.09V.
# Or pick a different gain to change the range of voltages that are read:
#  - 2/3 = +/-6.144V
#  -   1 = +/-4.096V
#  -   2 = +/-2.048V
#  -   4 = +/-1.024V
#  -   8 = +/-0.512V
#  -  16 = +/-0.256V
# See table 3 in the ADS1015/ADS1115 datasheet for more info on gain.
GAIN = 16

voltList = []
stressList = []
timeList = []

logging.basicConfig(filename='data.log', filemode='w',level=logging.DEBUG)

Vex = 5
R = 350
GF = 123
E = 69 * 10 ** 9

print('Press Ctrl-C to quit...')
timeStart = time.time()
try:
    while True:
        # Read the difference between channel 0 and 1 (i.e. channel 0 minus channel 1).
        # Note you can change the differential value to the following:
        #  - 0 = Channel 0 minus channel 1
        #  - 1 = Channel 0 minus channel 3
        #  - 2 = Channel 1 minus channel 3
        #  - 3 = Channel 2 minus channel 3
        value = adc.read_adc_difference(0, gain=GAIN)
        # Note you can also pass an optional data_rate parameter above, see
        # simpletest.py and the read_adc function for more information.
        # Value will be a signed 12 or 16 bit integer value (depending on the ADC
        # precision, ADS1015 = 12-bit or ADS1115 = 16-bit).
        factor = value / 32767
        volts = factor * 4.096/GAIN
        voltList.append(volts)

        timerec = time.time()
        delta = timerec -timeStart

        timeList.append(delta)
        #print(volts)
        logging.info("volts {}".format(volts) + ", " + "time {}".format(delta))
        print('Channel 0 minus 1: {0}'.format(value))
        print('Voltage: {0}'.format(volts))

        # Pause for 0.01 seconds.
        time.sleep(0.01)

except KeyboardInterrupt:
    for volts in voltList:
        deltaR = volts / Vex * R
        strain = deltaR / (R * GF)
        stress = E * strain
        stressList.append(stress)

    plt.plot(timeList, stressList)
    plt.ylabel("Stress (N/m2)")
    plt.xlabel("Time(s)")
    plt.show()
except Exception as e:
    print(e)


# K-Means Clustering

# Importing the libraries
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd

# Importing the dataset
dataset = pd.read_csv('Mall_Customers.csv')
X = dataset.iloc[:, [3, 4]].values

# Using the elbow method to find the optimal number of clusters
from sklearn.cluster import KMeans
wcss = []

for i in range(1, 11):
    # Choose k from 1 to 10
    kmeans = KMeans(n_clusters = i, init = 'k-means++', max_iter = 300, random_state = 42)
    # 'k-means++' is a more powerful method than 'random'
    # max_iter: Maximum # of iterations of the k-means algorithm for a single run
    kmeans.fit(X)
    wcss.append(kmeans.inertia_)
    # .inertia_ automatically compute the WCSS

plt.plot(range(1, 11), wcss)
plt.title('The Elbow Method')
plt.xlabel('Number of clusters')
plt.ylabel('WCSS')
plt.show()
# After running this, we can choose k=5

# Fitting K-Means to the dataset
kmeans = KMeans(n_clusters = 5, init = 'k-means++', random_state = 42)
y_kmeans = kmeans.fit_predict(X)
# y_kmeans have 5 values which are 0 to 4, and it shows 5 classes of X dataset

# Visualising the clusters

# scatter(x,y,s,c,marker,cmap,norm,vmin,vmax,alpha,linewidths,verts,edgecolors,hold,data)
# x: first column, y: second column...
# s: visualize 100 points is fine in this plot. You can change the number to view.
plt.scatter(X[y_kmeans == 0, 0], X[y_kmeans == 0, 1], s = 100, c = 'red', label = 'Cluster 1')
plt.scatter(X[y_kmeans == 1, 0], X[y_kmeans == 1, 1], s = 100, c = 'blue', label = 'Cluster 2')
plt.scatter(X[y_kmeans == 2, 0], X[y_kmeans == 2, 1], s = 100, c = 'green', label = 'Cluster 3')
plt.scatter(X[y_kmeans == 3, 0], X[y_kmeans == 3, 1], s = 100, c = 'cyan', label = 'Cluster 4')
plt.scatter(X[y_kmeans == 4, 0], X[y_kmeans == 4, 1], s = 100, c = 'magenta', label = 'Cluster 5')

plt.scatter(kmeans.cluster_centers_[:, 0], kmeans.cluster_centers_[:, 1], s = 300, c = 'yellow', label = 'Centroids')

plt.title('Clusters of customers')
plt.xlabel('Annual Income (k$)')
plt.ylabel('Spending Score (1-100)')
plt.legend()
# plt.legend() creates the side window in the plot showing points corresponding with labels.
plt.show()

Machine Learning A-Z Template Folder/Part 4 - Clustering/Section 24 - K-Means Clustering/K_Means/kmeans.py


from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker
from sqlalchemy_utils import database_exists, create_database

from logger import logger
from settings import settings

SQLALCHEMY_DATABASE_URL = f"postgresql+psycopg2://{settings.DB_USERNAME}:{settings.DB_PASSWORD}@{settings.DB_HOST}/{settings.DB_DATABASE}"

engine = create_engine(SQLALCHEMY_DATABASE_URL)
if not database_exists(engine.url):
    create_database(engine.url)

SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine, expire_on_commit=False)

Base = declarative_base()

def get_db():
    Base.metadata.create_all(bind=engine)
    db = SessionLocal()
    try:
        yield db
    except Exception:
        db.rollback()
    finally:
        db.close()