import os, sys, asyncio
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtWidgets import QApplication, QWidget, QLineEdit, QTextEdit
from PyQt5.QtWidgets import QPushButton, QGridLayout, QLabel, QInputDialog
from PyQt5.QtWidgets import QFileDialog, QComboBox
from PyQt5.QtGui import QIcon, QFont

from quamash import QEventLoop

from joycontrol.server import create_hid_server
from joycontrol.protocol import controller_protocol_factory, Controller
import auto_joy

save_path = './set_files/'

class MainWindow(QWidget):
    def __init__(self):
        super().__init__()
        self.key_list = [
                                ['', 'zl', '', '', '', '', '', '','', 'zr', ''],
                                ['', 'l', '', '', '', '', '', '','', 'r', ''],
                                ['', '', '', '', 'minus', '', 'plus', '','', '', ''],
                                ['l1', 'l2', 'l3', '', '', '', '','', '', 'x', ''],
                                ['l4', 'l5', 'l6', '', '', '', '','', 'y', '', 'a'],
                                ['l7', 'l8', 'l9', '', '', '', '','', '', 'b', ''],
                                ['', '', '', '', 'capture', '', 'home', '','', '', ''],
                                ['', 'up', '', '', '', '', '','', 'r1', 'r2', 'r3',],
                                ['left', '', 'right', '', '', '', '','', 'r4', 'r5', 'r6'],
                                ['', 'down', '', '', '', '', '','', 'r7', 'r8', 'r9'],
                                ]

        self.key_icon = [
                                        'l1', 'l2', 'l3',   'r1', 'r2', 'r3',
                                        'l4', 'l5', 'l6',   'r4', 'r5', 'r6',
                                        'l7', 'l8', 'l9',   'r7', 'r8', 'r9'
                                        ]

        #初始化
        self.window = QWidget()

        self.mMain_layout = QGridLayout()
        self.mSet_gui_layout = QGridLayout()

        #初始化按钮gui
        self.init_button_gui()
        #初始化set_gui
        self.init_button_set_gui()
        #显示文本初始化
        self.init_display_set()
        #初始化蓝牙gui
        self.init_BlueTooth_gui()

        #设置主界面参数
        self.setLayout(self.mMain_layout)
        self.setFixedSize(1250, 550)
        self.move(150, 300)
        self.setWindowTitle('poke_auto任务生成器')

        self.loading_name = ''

    #初始化按钮gui
    def init_button_gui(self):
        for i in range(len(self.key_list)):
            for j in range(len(self.key_list[i])):
                if self.key_list[i][j] == '':
                    self.mMain_layout.addWidget(QLabel(''), i, j)
                else:
                    #创建switch按钮
                    mButton = QPushButton()
                    mButton.setObjectName(self.key_list[i][j])
                    mButton.setFixedSize(80, 40)
                    if self.key_list[i][j] in self.key_icon:
                        icom_path = './image/button/' + self.key_list[i][j] + '.png'
                        mButton.setIcon(QIcon(icom_path))
                    else:
                        mButton.setText(self.key_list[i][j])
                    mButton.clicked.connect(lambda checked: self.joy_button_clicked())
                    self.mMain_layout.addWidget(mButton, i, j)

    #初初始化按钮设置gui
    def init_button_set_gui(self):
        self.mSet_gui = QWidget()
        mLabel_release_time = QLabel('按键按住时间')
        self.mText_release_time = QLineEdit()
        #限制只能输入double类型数据
        self.mText_release_time.setValidator(QtGui.QDoubleValidator())
        self.mSet_gui_layout.addWidget(mLabel_release_time, 0, 0)
        self.mSet_gui_layout.addWidget(self.mText_release_time, 0, 1)

        mLabel_delay_time = QLabel('按键延时时间')
        self.mText_delay_time = QLineEdit()
        #限制只能输入double类型数据
        self.mText_delay_time.setValidator(QtGui.QDoubleValidator())
        self.mSet_gui_layout.addWidget(mLabel_delay_time, 1, 0)
        self.mSet_gui_layout.addWidget(self.mText_delay_time, 1, 1)

        mLabel_cycle_num = QLabel('执行次数')
        self.mText_cycle_num = QLineEdit()
        #限制只能输入int类型数据
        self.mText_cycle_num.setValidator(QtGui.QIntValidator())
        self.mSet_gui_layout.addWidget(mLabel_cycle_num, 2, 0)
        self.mSet_gui_layout.addWidget(self.mText_cycle_num, 2, 1)

        self.mButton_sure = QPushButton('确定')
        self.mButton_sure.clicked.connect(lambda :self.button_set_sure_clicked())
        self.mButton_sure.setFixedSize(60, 20)
        self.mSet_gui_layout.addWidget(self.mButton_sure, 3, 1)

        self.mSet_gui_layout.setAlignment(QtCore.Qt.AlignRight)
        self.mSet_gui.setLayout(self.mSet_gui_layout)

    #按钮按下回调函数
    def joy_button_clicked(self):
        button = self.sender()
        mPos = self.pos()
        mSize = self.size()
        self.mSet_gui.move(mPos.x() + mSize.width() / 4, mPos.y() + mSize.height() / 2)
        #窗口置于最顶层显示
        self.mSet_gui.setWindowFlag(QtCore.Qt.WindowStaysOnTopHint)
        self.mSet_gui.show()
        self.strbutton_value = button.objectName()
        # print('button = %s' %(self.strbutton_value))

    #显示文本初始化
    def init_display_set(self):
        #设置显示文本标题
        mDisplay_set_label = QLabel('任务执行步骤')
        self.mMain_layout.addWidget(mDisplay_set_label, 0, 11)

        #初始化clear按钮
        mButton_clear = QPushButton('Clear')
        mButton_clear.setFixedSize(48, 35)
        mButton_clear.clicked.connect(lambda : self.button_clear_clicked())
        self.mMain_layout.addWidget(mButton_clear, 0, 12)

        #初始化clear按钮
        mButton_module = QPushButton('Module')
        mButton_module.setFixedSize(48, 35)
        mButton_module.clicked.connect(lambda : self.button_clear_clicked())
        self.mMain_layout.addWidget(mButton_module, 0, 13)

        #初始化module按钮
        mButton_load = QPushButton('Load')
        mButton_load.setFixedSize(48, 35)
        mButton_load.clicked.connect(lambda: self.button_load_clicked())
        self.mMain_layout.addWidget(mButton_load, 0, 14)

        #初始化save按钮
        mButton_save = QPushButton('Save')
        mButton_save.setFixedSize(48, 35)
        mButton_save.clicked.connect(lambda : self.button_save_clicked())
        self.mMain_layout.addWidget(mButton_save, 0, 15)

        #设置显示文本
        self.mDisplay_set = QTextEdit()
        self.mDisplay_set.setFont(QFont('微软雅黑', 12))
        # mDisplay_set.setReadOnly(True)
        self.mDisplay_set.setFixedSize(460, 432)
        self.mMain_layout.addWidget(self.mDisplay_set, 1, 11)

    #设置按钮参数gui确定按钮回调函数
    def button_set_sure_clicked(self):
        iRelease_time = self.mText_release_time.text()
        iDelay_time = self.mText_delay_time.text()
        iCycle_num = self.mText_cycle_num.text()
        if iRelease_time != '' and iDelay_time != '' and iCycle_num != '':
            cmd_str = self.strbutton_value + ', ' + iRelease_time + ', ' + iDelay_time + ', ' + iCycle_num
            self.mDisplay_set.append(cmd_str)
            # print('release_time = %s\ndelay_time = %s\ncycle_num = %s' % (iRelease_time, iDelay_time, iCycle_num))
        #隐藏窗口
        self.mSet_gui.hide()

    #save按钮回调函数
    def button_save_clicked(self):
        self.mDisplay_set.toPlainText()
        mInputDialog = QInputDialog()
        strNane, get_ok = mInputDialog.getText(self, '保存', '文件命名')
        if get_ok:
            # text_line_list = str(self.mDisplay_set.toPlainText()).split('\n')
            if strNane ==  '':
                with open(self.loading_name, 'w') as wf:
                    wf.write(self.mDisplay_set.toPlainText() + '\nend')
            else:
                with open(save_path + strNane, 'w') as wf:
                    wf.write(self.mDisplay_set.toPlainText() + '\nend')
                self.loading_name = save_path +  strNane
                self.combox_set_refresh()

    #clear按钮回调函数
    def button_clear_clicked(self):
        self.mDisplay_set.clear()

    #load按钮回调函数
    def button_load_clicked(self):
        page = QFileDialog.getOpenFileName(self, 'Open file', save_path)
        if page[0]:
            self.loading_name = page[0]
            print(page[0])
            rf = open(page[0], 'r')
            with rf:
                data = rf.read()
                self.mDisplay_set.setText(data)

    #lmodule按钮回调函数
    def button_module_clicked(self):
        pass

    #初始化运行蓝牙操作界面
    def init_BlueTooth_gui(self):
        self.mBlueTooth_gui = QWidget()
        # self.mBlueTooth_gui.setFixedSize(300, 50)
        self.mMain_layout.addWidget(self.mBlueTooth_gui, 10, 11)

        self.mBlueTooth_layout = QGridLayout()
        self.mBlueTooth_gui.setLayout(self.mBlueTooth_layout)

        #初始化运行任务按钮
        self.mButton_run  = QPushButton('运行任务')
        self.mButton_run.setFixedSize(58, 35)
        self.mButton_run.clicked.connect(lambda : self.buuton_run_clicked())
        self.mBlueTooth_layout.addWidget(self.mButton_run, 0, 1)

        #初始化运行完成任务按钮
        self.mButton_TaskComplete  = QPushButton('自动关机')
        self.mButton_TaskComplete.setFixedSize(58, 35)
        self.mButton_TaskComplete.clicked.connect(lambda : self.buuton_TaskComplete_clicked())
        self.mBlueTooth_layout.addWidget(self.mButton_TaskComplete, 0, 0)

        #初始化任务周期设置栏
        self.mText_task_cycles  = QLineEdit()
        self.mText_task_cycles.setText('1')
        self.mText_task_cycles.setValidator(QtGui.QIntValidator())
        self.mText_task_cycles.returnPressed.connect(lambda :self.set_task_cycles_cb())
        self.mText_task_cycles.setFixedSize(60, 35)
        self.mBlueTooth_layout.addWidget(self.mText_task_cycles, 0, 2)

        #初始化任务配置选择栏
        self.mCombox_set  = QComboBox()
        self.mCombox_set.setFixedSize(120, 35)
        self.mCombox_set.currentIndexChanged.connect(lambda :self.combox_set_choose())
        self.get_all_set_file()
        self.mMain_layout.addWidget(self.mCombox_set,  10, 13)

    #运行按钮回调函数
    def buuton_run_clicked(self):
        if self.mButton_run.text() == '运行任务':
            auto_joy.task_cycles = int(self.mText_task_cycles.text())
            auto_joy.stop_state = False
            self.mButton_run.setText('停止任务')
        else:
            self.mButton_run.setText('运行任务')
            auto_joy.stop_state = True

     #获取所有配置文件

    #获取所有配置文件
    def get_all_set_file(self, path_str_ = './set_files/'):
        for root, dirs, files in os.walk(path_str_):
            self.strSet_root = root + '/'
            self.vecSet_files = files
        for i in self.vecSet_files:
            self.mCombox_set.addItem(i)

    #刷新配置选择项
    def combox_set_refresh(self):
        self.mCombox_set.clear()
        self.get_all_set_file()

    #选中配置回调函数
    def combox_set_choose(self):
        auto_joy.task_file_name =  self.mCombox_set.currentText()
        # print(auto_joy.task_file_name)

    #设置任务周期回调函数
    def set_task_cycles_cb(self):
        auto_joy.task_cycles = int(self.mText_task_cycles.text())

    def buuton_TaskComplete_clicked(self):
        if auto_joy.sleep_state == False:
            self.mButton_TaskComplete.setStyleSheet("background-color: rgb(255,0,0)");
            auto_joy.shut_state = True
        else:
            self.mButton_TaskComplete.setStyleSheet("background-color: rgb(255,255,255)");
            auto_joy.shut_state = False

async def _main(date_list_):
    controller_ = Controller.PRO_CONTROLLER
    factory = controller_protocol_factory(controller_)
    transport, protocol = await create_hid_server(factory, 17, 19)

    dr = protocol.get_controller_state()
    while 1:
        if await dr.connect():
            print("蓝牙连接成功......")
            break

    mAutoJoy = auto_joy.AutoJoy (dr, date_list_[0], date_list_[1], date_list_[2])
    await mAutoJoy.run_in_gui()
    logger.info('Stopping communication...')
    await transport.close()

if __name__ == '__main__':
    # check if root
    if not os.geteuid() == 0:
        raise PermissionError('Script must be run as root!')

    app = QApplication(sys.argv)

    mMainWindow = MainWindow()
    mMainWindow.show()

    loop = QEventLoop(app)
    asyncio.set_event_loop(loop)

    date_list_num = [2020, 3, 10]
    with loop:
        loop.run_until_complete(_main(date_list_num))

    # start.


#!/usr/bin/python
'''
author: Christian M
'''
import cv2
import numpy as np
import logging
from services.Base import *

class Webcam(Base):

    def __init__(self, serviceRunner):
        super(Webcam, self).__init__()
        self.logger = logging.getLogger(__name__)
        self.serviceRunner = serviceRunner
        self.config = self.defaultConfig()
        self.image = None

    def defaultConfig(self):
        return {"x": 0, "y": 0, "Interval": 1, "resx": 640, "resy": 480, "device": 0}

    def init(self):
        self.capture = cv2.VideoCapture(self.config['device'])
        if not self.capture.isOpened():
            self.logger.error("Could not open camera ", self.config['device'])
            img = np.zeros((self.config["resy"], self.config["resx"], 3), np.uint8)
            img += np.array([0,255,0], np.uint8)
            cv2.putText(img, 'No image, device %d'%(self.config["device"]), (10,self.config["resy"]/2), cv2.FONT_HERSHEY_SIMPLEX, 1, (0,0,0),1)
            self.image = img[:,::-1,:] #will be displayed mirrored
        else:
            self.capture.set(3,self.config["resx"])
            self.capture.set(4,self.config["resy"])

            ret, self.image = self.capture.read()

    def update(self):
        if self.capture.isOpened():
            ret, self.image = self.capture.read()
            self.image = cv2.cvtColor(self.image, cv2.COLOR_BGR2RGB)

    def currentImage(self):
        return self.image


from jax._src.api import value_and_grad, vmap
from jax._src.numpy.lax_numpy import array
from jax.scipy.special import logsumexp
from jax.experimental import optimizers
from jax import random, jit
import jax.numpy as np

from torch.utils.data.dataloader import DataLoader
from torchvision import datasets, transforms

import time

key = random.PRNGKey(1)
batch_size = 100

train_loader = DataLoader(
    datasets.MNIST(
        "./data", train=True, download=True,
        transform=transforms.Compose([
            transforms.ToTensor(),
            transforms.Normalize(
                  (0.1307,), (0.3081,)
            )
        ])
    ), batch_size=batch_size, shuffle=True
)

test_loader = DataLoader(
    datasets.MNIST(
        "./data", train=False, download=True,
        transform=transforms.Compose([
            transforms.ToTensor(),
            transforms.Normalize(
                  (0.1307,), (0.3081,)
            )
        ])
    ), batch_size=batch_size, shuffle=True
)

def initialize_mlp(sizes, key):
    keys = random.split(
        key, len(sizes)
    )

    def initialize_layer(m, n, key, scale=1e-2):
        w_key, b_key = random.split(key)
        return scale * random.normal(
            w_key, (n, m)
        ), scale * random.normal(
            b_key, (n,)
        )
    return [
        initialize_layer(m, n, k) for m, n, k in zip(
            sizes[:-1], sizes[1:], keys
        )
    ]

layer_sizes = [784, 512, 512, 10]

params = initialize_mlp(
    layer_sizes, key
)

def forward_pass(params, in_array):
    """
    forward pass
    """
    def relu_layer(params, x):
        def ReLU(x):
            return np.maximum(0, x)
        return ReLU(np.dot(params[0], x) + params[1])

    activations = in_array

    for w, b in params[:-1]:
        activations = relu_layer([w, b], activations)

    final_w, final_b = params[-1]
    logits = np.dot(
        final_w, activations
    ) + final_b

    return logits - logsumexp(logits)

batch_forward = vmap(
    forward_pass, in_axes=(None, 0), out_axes=0
)

def one_hot(x, k, dtype=np.float32):
    """
    docstring
    """
    return np.array(
        x[:, None] == np.arange(k), dtype
    )

def loss(params, in_array, targets):

    preds = batch_forward(
        params, in_array
    )

    return -np.sum(preds * targets)

num_classes = 10

def accuracy(params, data_loader):
    acc_total = 0

    for batch_idx, (data, target) in enumerate(data_loader):
        images = np.array(data).reshape(
            data.size(0), 28*28
        )
        targets = one_hot(
            np.array(target), num_classes
        )

        target_class = np.argmax(
            targets, axis=1
        )

        predicted_class = np.argmax(
            batch_forward(params, images), axis=1
        )

        acc_total += np.sum(
            predicted_class == target_class
        )

    return acc_total/len(data_loader.dataset)

step_size = 1e-3
opt_init, opt_update, get_params = optimizers.adam(step_size)
opt_state = opt_init(params)

@jit
def update(params, x, y, opt_state):
    """
    Compute the gradient for batch and update the params
    """
    value, grads = value_and_grad(loss)(params, x, y)
    opt_state = opt_update(
        0, grads, opt_state
    )

    return get_params(
        opt_state
    ), opt_state, value

num_epochs = 10

def run_mnist_training_loop(num_epochs, opt_state, net_type="MLP"):
    """
    traing loop
    """
    log_acc_train, log_acc_test, train_loss = [], [], []

    params = get_params(opt_state)

    train_acc = accuracy(params, train_loader)
    test_acc = accuracy(params, test_loader)
    log_acc_train.append(train_acc)
    log_acc_test.append(test_acc)

    for epoch in range(num_epochs):
        start_time = time.time()

        for batch_idx, (data, target) in enumerate(train_loader):
            if net_type == "MLP":
                x = np.array(data).reshape(
                    data.size(0), 28*28
                )

            y = one_hot(
                np.array(target), num_classes
            )

            params, opt_state, loss = update(
                params, x, y, opt_state
            )

            train_loss.append(loss)

        epoch_time = time.time() - start_time
        train_acc = accuracy(params, train_loader)
        test_acc = accuracy(params, test_loader)
        log_acc_train.append(train_acc)
        log_acc_test.append(test_acc)
        print("Epoch {} | T: {:0.2f} | Train A: {:0.3f} | Test A: {:0.3f}".format(
            epoch+1, epoch_time, train_acc, test_acc))
    return train_loss, log_acc_train, log_acc_test

train_loss, train_log, test_log = run_mnist_training_loop(
    num_epochs, opt_state, net_type="CNP"
)


# -*- coding: utf-8 -*-
from __future__ import absolute_import
from datetime import datetime
import operator

from vilya.libs.store import store, mc, cache, mc_gets, bdb
from vilya.models.tag import Tag, TagName
from vilya.models.issue_vote import Upvote
from vilya.models.issue_participant import IssueParticipant
from vilya.models.issue_comment import IssueComment

MC_KEY_ISSUE = 'issue:v3:%s'
MC_KEY_ISSUES_DATA_BY_TARGET = 'issues_data:v3:type:%s:target_id:%s'
MC_KEY_ISSUES_IDS_BY_CREATOR_ID = 'issue_ids_by_creator_id:v3:%s'
MC_KEY_ISSUES_IDS_BY_ASSIGNEE_ID = 'issues_ids_by_assignee_id:v3:%s'
MC_KEY_USER_ISSUE_IDS_BY_CREATOR_ID = 'user_issue:v3:%s'
BDB_ISSUE_DESCRIPTION_KEY = 'issue_description:%s'
ISSUE_DATA_FIELDS = dict(issue_id=0, closer_id=1, updated_at=2, rank_score=3)

def filter_issue_ids_by_score(ids, order):
    if order == 'hot':
        index = ISSUE_DATA_FIELDS['rank_score']
        ids = [info for info
               in sorted(ids, key=operator.itemgetter(index), reverse=True)]
    else:
        index = ISSUE_DATA_FIELDS['updated_at']
        ids = [info for info
               in sorted(ids, key=operator.itemgetter(index), reverse=True)]
    return ids

def filter_issue_ids_by_state(ids, state):
    index = ISSUE_DATA_FIELDS['closer_id']
    if state:
        if state == 'open':
            ids = [info for info in ids if not info[index]]
        elif state == 'closed':
            ids = [info for info in ids if info[index]]
    return ids

class Issue(object):
    target_type = 'default'
    tag_type = 0  # not exists type
    provided_features = []  # Interface

    def __init__(self, id, title,
                 creator, assignee=None, closer=None,
                 created_at=None, updated_at=None, closed_at=None,
                 type='default', target_id=0):
        self.id = id
        self.issue_id = id
        self.title = title
        bdb_description = bdb.get(BDB_ISSUE_DESCRIPTION_KEY % id)
        self.description = bdb_description
        self.creator_id = creator
        self.assignee_id = assignee
        self.closer_id = closer
        self.created_at = created_at
        self.updated_at = updated_at
        self.closed_at = closed_at
        self.type = type
        self.number = 0
        self.target_id = target_id

    def __repr__(self):
        return '<%s(%s)>' % (self.__class__.__name__, self.id)

    @property
    def url(self):
        raise NotImplementedError('Subclasses should implement this!')

    @property
    def target(self):
        raise NotImplementedError('Subclasses should implement this!')

    def provide(self, name):
        '''检查是否提供某功能，即是否提供某接口'''
        return name in self.provided_features

    @property
    def state(self):
        if self.closer_id:
            return 'closed'

        return 'open'

    @property
    def is_closed(self):
        return self.state == 'closed'

    @property
    def creator(self):
        if self.creator_id:
            from vilya.models.user import User
            return User(self.creator_id)
        return None

    @property
    def closer(self):
        if self.closer_id:
            from vilya.models.user import User
            return User(self.closer_id)
        return None

    @property
    def assignee(self):
        if self.assignee_id:
            from vilya.models.user import User
            return User(self.assignee_id)
        return None

    def clear_cache(self):
        mc.delete(MC_KEY_ISSUE % self.issue_id)

    def update(self, title, description):
        store.execute("update issues "
                      "set title=%s, updated_at=null "
                      "where id=%s", (title, self.issue_id))
        store.commit()
        bdb.set(BDB_ISSUE_DESCRIPTION_KEY % self.issue_id, description)
        self.clear_cache()
        mc.delete(MC_KEY_ISSUES_DATA_BY_TARGET % (self.type, self.target_id))

    def close(self, user_id):
        store.execute("update issues "
                      "set closer_id=%s, closed_at=null "
                      "where id=%s", (user_id, self.issue_id))
        store.commit()
        self.clear_cache()
        mc.delete(MC_KEY_ISSUES_IDS_BY_CREATOR_ID % self.creator_id)
        mc.delete(MC_KEY_ISSUES_DATA_BY_TARGET % (self.type, self.target_id))
        self.closer_id = user_id

    def open(self):
        store.execute("update issues "
                      "set closer_id=null, closed_at=null "
                      "where id=%s", (self.issue_id,))
        store.commit()
        self.clear_cache()
        mc.delete(MC_KEY_ISSUES_IDS_BY_CREATOR_ID % self.creator_id)
        mc.delete(MC_KEY_ISSUES_DATA_BY_TARGET % (self.type, self.target_id))
        self.closer_id = None

    def add_tag(self, tag, type, target_id, author=None):
        author_id = author if author else self.creator_id
        # create tag if not exists
        tag_name = TagName.get_by_name_and_target_id(tag, type, target_id)
        if not tag_name:
            tag_name = TagName.add(tag, author_id, type, target_id)
        if not tag_name:
            return
        # add tag to issue if not already be added
        issue_tag = Tag.get_by_type_id_and_tag_id(
            type, self.issue_id, tag_name.id)
        if issue_tag:
            return
        Tag.add_to_issue(
            tag_name.id, type, self.issue_id, author_id, target_id)

    def add_tags(self, tags, target_id, author=None):
        for tag in tags:
            self.add_tag(tag, self.tag_type, target_id, author)

    def remove_tag(self, tag, type, target_id):
        # check if tag exists
        tag_name = TagName.get_by_name_and_target_id(tag, type, target_id)
        if not tag_name:
            return
        # delete tag relationship if exists
        issue_tag = Tag.get_by_type_id_and_tag_id(
            type, self.issue_id, tag_name.id)
        if issue_tag:
            issue_tag.delete()

    def remove_tags(self, tags, target_id):
        for tag in tags:
            self.remove_tag(tag, self.tag_type, target_id)

    def upvote_by_user(self, user_id):
        if user_id and (user_id != self.creator_id) and not self.is_closed:
            vote = Upvote.add(self.issue_id, user_id)
            if vote:
                self.update_rank_score()
        return self.vote_count

    def cancel_upvote_by_user(self, user_id):
        ok = Upvote.delete(self.issue_id, user_id)
        if ok:
            self.update_rank_score()
        return self.vote_count

    def has_user_voted(self, user_id):
        if user_id:
            vote = Upvote.get_by_issue_id_and_user_id(self.issue_id, user_id)
            return True if vote else False
        return False

    @property
    def vote_count(self):
        return Upvote.count_by_issue_id(self.issue_id)

    @property
    def comments(self):
        return IssueComment.gets_by_issue_id(self.issue_id)

    @property
    def comment_count(self):
        return IssueComment.count_by_issue_id(self.issue_id)

    def add_comment(self, content, user):
        res = IssueComment.add(self.issue_id, content, user)
        self.update_rank_score()
        return res

    def update_rank_score(self):
        vote_count = self.vote_count
        comment_count = self.comment_count
        time_delta = (datetime.now() - datetime(2011, 1, 1)).total_seconds()
        divider = (datetime(2013, 7, 8) - datetime(2011, 1, 1)).total_seconds()
        time_factor = time_delta / divider * 5
        score = (vote_count * 0.5 + comment_count) * time_factor
        store.execute(
            "update issues "
            "set rank_score=%s , updated_at=updated_at "  # 防止字段更新
            "where id=%s ",
            (score, self.issue_id))
        store.commit()
        mc.delete(MC_KEY_ISSUES_DATA_BY_TARGET % (self.type, self.target_id))
        return score

    def add_participants(self, user_ids):
        for user_id in user_ids:
            self.add_participant(user_id)

    def add_participant(self, user_id):
        p = IssueParticipant.get_by_issue_id_and_user_id(self.issue_id,
                                                         user_id)
        if not p:
            IssueParticipant.add(self.issue_id, user_id)

    def delete_participant(self, user_id):
        p = IssueParticipant.get_by_issue_id_and_user_id(self.issue_id,
                                                         user_id)
        if p:
            p.delete()

    def has_participated(self, user_id):
        return bool(IssueParticipant.get_by_issue_id_and_user_id(
            self.issue_id, user_id))

    @property
    def participants(self):
        return IssueParticipant.gets_by_issue_id(self.issue_id)

    def assign(self, user_id):
        old_id = self.assignee_id
        store.execute("update issues "
                      "set assignee_id=%s "
                      "where id=%s", (user_id, self.issue_id))
        store.commit()
        self.clear_cache()
        mc.delete(MC_KEY_ISSUES_IDS_BY_ASSIGNEE_ID % old_id)
        mc.delete(MC_KEY_ISSUES_IDS_BY_ASSIGNEE_ID % user_id)

    @classmethod
    def add(cls, title, description, creator, assignee=None, closer=None,
            created_at=None, updated_at=None, closed_at=None,
            type='default', target_id=0):
        time = datetime.now()
        issue_id = store.execute(
            'insert into issues (title, creator_id, '
            'assignee_id, closer_id, created_at, updated_at, type, target_id) '
            'values (%s, %s, %s, %s, NULL, NULL, %s, %s)',
            (title, creator, assignee, closer, type, target_id))
        store.commit()
        mc.delete(MC_KEY_ISSUE % issue_id)
        mc.delete(MC_KEY_ISSUES_IDS_BY_CREATOR_ID % creator)
        mc.delete(MC_KEY_ISSUES_IDS_BY_ASSIGNEE_ID % assignee)
        mc.delete(MC_KEY_ISSUES_DATA_BY_TARGET % (type, target_id))
        bdb.set(BDB_ISSUE_DESCRIPTION_KEY % issue_id, description)
        issue = cls(issue_id, title, creator, assignee, closer, time, time)
        issue.add_participant(creator)
        return issue

    def delete(self):
        store.execute('delete from issues where id=%s', (self.id,))
        store.commit()
        mc.delete(MC_KEY_ISSUE % self.id)
        mc.delete(MC_KEY_ISSUES_IDS_BY_CREATOR_ID % self.creator_id)
        mc.delete(MC_KEY_ISSUES_IDS_BY_ASSIGNEE_ID % self.assignee_id)
        mc.delete(MC_KEY_ISSUES_DATA_BY_TARGET % (type, self.target_id))
        bdb.set(BDB_ISSUE_DESCRIPTION_KEY % self.id, '')

    @classmethod
    def get(cls, id):
        rs = store.execute(
            "select id, title, creator_id, assignee_id, closer_id, "
            "created_at, updated_at, closed_at, type, target_id "
            "from issues where id=%s", (id,))
        return rs and cls(*rs[0]) or None

    @classmethod
    def get_by_issue_id(cls, id, state=None):
        issue = Issue.get(id)
        if not issue:
            return None

        if state and issue.state != state:
            return None

        return issue

    @classmethod
    @cache(MC_KEY_ISSUES_DATA_BY_TARGET % ('{cls.target_type}', '{target_id}'))
    def get_data_by_target(cls, target_id):
        rs = store.execute('select id, closer_id, updated_at, rank_score '
                           'from issues where type=%s and target_id=%s',
                           (cls.target_type, target_id))
        return rs

    @classmethod
    def gets_by_target(cls, target_id, state=None, order='',
                       limit=0, start=0):
        data = cls.get_data_by_target(target_id)
        data = filter_issue_ids_by_state(data, state)
        data = filter_issue_ids_by_score(data, order)
        ids = [issue_id for (issue_id, _, _, _) in data]
        if limit:
            ids = ids[start:start + limit]
        return Issue.get_cached_issues(ids)

    @classmethod
    def gets_by_creator_id(cls, id, state='open'):
        # FIXME 子类中的这个方法，参数非常不一致。需要尽快解决
        result = cls.get_ids_by_creator_id(id)
        if state == 'open':
            ids = [i for (i, closer_id) in result if not closer_id]
            return Issue.get_cached_issues(ids)
        else:
            ids = [i for (i, closer_id) in result if closer_id]
            return Issue.get_cached_issues(ids)

    @classmethod
    @cache(MC_KEY_ISSUES_IDS_BY_CREATOR_ID % '{id}')
    def get_ids_by_creator_id(cls, id):
        rs = store.execute("select id, closer_id "
                           "from issues "
                           "where creator_id = %s",
                           (id,))
        return rs

    @classmethod
    def gets_by_assignee_id(cls, id, state='open'):
        # FIXME 子类中的这个方法，参数非常不一致。需要尽快解决
        result = cls.get_ids_by_assignee_id(id)
        if state == 'open':
            ids = [i for (i, closer_id) in result if not closer_id]
            return Issue.get_cached_issues(ids)
        else:
            ids = [i for (i, closer_id) in result if closer_id]
            return Issue.get_cached_issues(ids)

    @classmethod
    def gets_by_participated_user(cls, user_id, state='open'):
        ps = IssueParticipant.gets_by_user_id(user_id)
        issue_ids = [p.issue_id for p in ps]
        issues = Issue.get_cached_issues(issue_ids)
        issues_with_state = [issue for issue in issues
                             if (state == 'open') is (not issue.closer_id)]
        return issues_with_state

    @classmethod
    @cache(MC_KEY_ISSUES_IDS_BY_ASSIGNEE_ID % '{id}')
    def get_ids_by_assignee_id(cls, id):
        rs = store.execute("select id, closer_id "
                           "from issues "
                           "where assignee_id = %s",
                           (id,))
        return rs

    @classmethod
    def gets_by_closer_id(cls, id):
        rs = store.execute("select id, title, "
                           "creator_id, assignee_id, closer_id, "
                           "created_at, updated_at, closed_at, type "
                           "from issues "
                           "where closer_id = %s ",
                           (id, ))
        return [cls(*r) for r in rs]

    @property
    def tags(self):
        return Tag.gets_by_issue_id(self.issue_id, self.tag_type)

    @staticmethod
    @cache(MC_KEY_ISSUE)
    def get_cached_issue(id):
        from vilya.models.issue_utils import ISSUE_TYPE_CLASS
        issue = Issue.get(id)
        if issue:
            subcls = ISSUE_TYPE_CLASS[issue.type]
            return subcls.get_by_issue_id(id)

    @staticmethod
    def get_cached_issues(ids):
        issues = mc_gets(MC_KEY_ISSUE, Issue.get_cached_issue, ids)
        return [i for i in issues if i]

def get_project_issues(issues):
    project_issues = []
    for issue in issues:
        project_issue = get_issue_by_id_and_state(issue.issue_id)
        if project_issue:
            project_issues.append(project_issue)
    return project_issues

# return project_issue or team_issue
def get_issue_by_id_and_state(id, state=None):
    issue = Issue.get_cached_issue(id)
    if not issue:
        return None

    if state and issue.state != state:
        return None

    return issue

{'User': 'vilya.models.user.User', 'ISSUE_TYPE_CLASS': 'vilya.models.issue_utils.ISSUE_TYPE_CLASS'}.get_cached_issue


import boto3

import config

database = boto3.resource(
    'dynamodb',
    endpoint_url = config.USER_STORAGE_URL,
    region_name = 'ru-central1',
    aws_access_key_id = config.AWS_PUBLIC_KEY,
    aws_secret_access_key = config.AWS_SECRET_KEY
)

forecast = database.Table('ИМЯ ВАШЕЙ ТАБЛИЦЫ')


# Oytun Demirbilek
# 150150032

import pyautogui
import time
import os
import subprocess

import numpy as np
import cv2
import matplotlib.pyplot as plt
import scipy.stats as st

# You need to set the path to the game in order to open it in the program.
GAMEPATH = "./saturdaynightfilter_pc/SaturdayNightFilter.exe"

# Part1 function.
def sobel_filter():
    shapes = cv2.imread("shapes.png")

    # Define Sobel Operator Filters. Horizontal and vertical masks.
    mask_row = np.array([1, 2, 1])
    y_mask = np.array([-1 * mask_row, np.zeros(3), mask_row])
    x_mask = y_mask.transpose()

    # Image Smoothing before Edge Detection.
    shapes = cv2.blur(shapes, (5, 5))

    # Convolutions implemented with Sobel masks. Horizontal and vertical separately.
    x_edges = cv2.filter2D(shapes, -1, x_mask)
    y_edges = cv2.filter2D(shapes, -1, y_mask)

    # You can compare it with built-in Sobel results.
    # sobelx = cv2.Sobel(shapes,cv2.CV_64F,1,0,ksize=5)
    # sobely = cv2.Sobel(shapes,cv2.CV_64F,0,1,ksize=5)
    # plt.imshow(sobelx)
    # plt.show()
    # plt.close()
    # plt.imshow(sobely)
    # plt.show()
    # plt.close()

    # Save Results.
    plt.imshow(y_edges)
    plt.savefig("sobel_y.png")
    plt.close()

    plt.imshow(x_edges)
    plt.savefig("sobel_x.png")
    plt.close()

# Part3 function.
def generate_gaussian(ksize=7, sigma=5):
    # Utility to generate a gaussian window.
    x = np.linspace(-sigma, sigma, ksize + 1)
    dist = np.diff(st.norm.cdf(x))
    kernel = np.outer(dist, dist)
    return kernel / kernel.sum()

# Part3 function.
def hardcode_corners(image, kernel):
    import math

    # Size of the image and the kernel.
    (i_height, i_width) = image.shape[:2]
    (k_height, k_width) = kernel.shape[:2]

    # Half of the kernel size is the padding size.
    ksize = (k_width - 1) // 2
    # We need to pad the image in order to avoid indexes are not in image.
    image = cv2.copyMakeBorder(image, ksize, ksize, ksize, ksize, cv2.BORDER_REPLICATE)
    # Initialize output matrix. Will be the same size as image.
    output = np.zeros((i_height, i_width), dtype="float32")

    # Sliding window iteration.
    for y in np.arange(ksize, i_height + ksize):
        for x in np.arange(ksize, i_width + ksize):
            # Estimate mean difference between pixels.
            Ix = np.diff(image[y, x - ksize : x + ksize + 1]).mean()
            Iy = np.diff(image[y - ksize : y + ksize + 1, x]).mean()

            # Convolve image derivatives y-wise and x-wise separately.
            roi_x = Ix * kernel
            roi_y = Iy * kernel

            # Construct the image structure tensor.
            b = (roi_x * Iy).sum()
            a = (roi_x * roi_x).sum()
            d = (Iy * Iy).sum()
            # Calculate min eigenvalue and it is the kernel center.
            output[y - ksize, x - ksize] = (
                (a + d) - math.sqrt((a - d) ** 2 + 4 * (b**2))
            ) / 2

    return output

# Part3 function.
def corner_detector(image):

    # Sobel windows.
    mask_row = np.array([1, 2, 1])
    y_mask = np.array([-1 * mask_row, np.zeros(3), mask_row])
    x_mask = y_mask.transpose()

    # Gaussian window.
    gaussian_mask = generate_gaussian()

    # Method 1: Use separate kernels in the built-in convolution function.
    G12 = cv2.sepFilter2D(
        image, -1, kernelX=np.array([-1, 0, 1]), kernelY=np.array([-1, 0, 1])
    )  # Ix.Iy --> This can be problematic.
    G11 = cv2.sepFilter2D(
        image**2, -1, kernelX=np.array([-1, 0, 1]), kernelY=np.array([0, 0, 0])
    )  # Ix^2
    G22 = cv2.sepFilter2D(
        image**2, -1, kernelX=np.array([0, 0, 0]), kernelY=np.array([-1, 0, 1])
    )  # Iy^2

    # Calculate min eigenvalue matrices using filtered structures.
    first = G11 + G22
    second = np.sqrt(np.square(G11 - G22) + 4 * np.square(G12))
    min_eigens = (first - second) / 2
    # max_eigens = (first + second) / 2
    # corners = min_eigens*max_eigens - 0.04*np.square(min_eigens+max_eigens)

    # Method 2: Hardcoded convolution. Note that python iterations much slower and this method will take some time.
    # Everything is implemented with formulas.
    min_eigens = hardcode_corners(image, gaussian_mask)

    np.save("star_corners.npy", min_eigens)

    # In order to highlight corners in the image.
    # If the minimum eigenvalue takes very high values, the point is very much likely to be a corner.
    # image = image // 2
    # image[np.where(min_eigens>10000)] = 255
    return min_eigens

# Part4 function.
def detect(c):
    shape = "A"  # DEFAULT

    # Perimeter of the contour is needed for the approximation algorithm.
    peri = cv2.arcLength(c, True)

    # Contour approximation uses Ramer-Douglas-Peucker algorithm
    # to reduce the number of points in the curve.
    approx = cv2.approxPolyDP(c, 0.04 * peri, True)

    # Assign keyboard presses for each type of result of the approximation.
    if len(approx) < 4:
        shape = "A"  # TRIANGLE
    elif len(approx) == 4:
        shape = "S"  # SQUARE
    elif len(approx) == 6:
        shape = "F"  # HEXAGON
    elif len(approx) > 6:
        shape = "D"  # STAR
    return shape

# Part4 function.
def see_and_respond(ss):
    screensize = pyautogui.size()
    # To grayscale.
    ss = cv2.cvtColor(ss, cv2.COLOR_BGR2GRAY).astype(np.uint8)
    # Getting the frame from the image.
    # Shape fits between x = (1050, 1350)  y = (821, 1080) Tested on 1920 x 1080 resolution.
    # ** These parameters are really tricky, you need to catch the shape in a frame.
    # ** Game results may vary due to the resolution differences.
    slide_y = int(screensize[1] * 0.76) + 1
    slide_x_down = int(screensize[0] * 0.5468) + 1
    slide_x_up = int(screensize[0] * 0.7031) + 1
    frame = ss[slide_y:, slide_x_down:slide_x_up]

    # Get edges and contours.
    edges = cv2.Canny(frame, 400, 500)
    contours, hierarchy = cv2.findContours(
        edges, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE
    )

    # If no contours are found, there are no shapes in the frame yet.
    if len(contours) == 0:
        return "A"

    # cnts is a coordinate array defining the boundary curve.
    cnts = contours[0]
    if len(cnts.shape) == 3:
        # Since there should be only one shape at a time,
        # Get rid of the 1-sized dimension.
        cnts = cnts.squeeze(1)

    # Contours can be used to detect number of edges of a shape.
    polygon = detect(cnts)
    print("PRESS:", polygon)

    return polygon

# Part4 function.
def play_game():
    game = subprocess.Popen(GAMEPATH)
    screensize = pyautogui.size()
    time.sleep(6)

    # Play Vabank
    pyautogui.click(screensize[0] * 0.9, screensize[1] * 0.25)
    game_end = False
    prev_ss = pyautogui.screenshot()
    time.sleep(1)

    while not game_end:
        ss = pyautogui.screenshot()
        if ss == prev_ss:
            game_end = True
        prev_ss = ss
        key = see_and_respond(np.array(ss))
        pyautogui.press(key)

    pyautogui.press("Esc")

    # Play Shame
    pyautogui.click(screensize[0] * 0.9, screensize[1] * 0.36)
    game_end = False
    prev_ss = pyautogui.screenshot()
    time.sleep(1)

    while not game_end:
        ss = pyautogui.screenshot()
        if ss == prev_ss:
            game_end = True
        prev_ss = ss
        key = see_and_respond(np.array(ss))
        pyautogui.press(key)

    game.terminate()

# Part 1 & 2 function
def get_shapes():
    # Open the game as a subprocess in the program.
    game = subprocess.Popen(GAMEPATH)
    # Screen size will be used to find the button locations
    # Therefore the screen resolution itself will not change things.
    screensize = pyautogui.size()
    time.sleep(5)
    # Click All Shapes
    pyautogui.click(screensize[0] * 0.9, screensize[1] * 0.13)
    # Get screenshot of All Shapes
    ss = pyautogui.screenshot()

    ss.save("shapes.png")
    # Go to the main page from All Shapes.
    pyautogui.click(screensize[0] * 0.9, screensize[1] * 0.9)
    game.terminate()

def part1():
    # Get the All Shapes page screenshot from the game and save.
    get_shapes()
    # Apply sobel filter to saved image from All Shapes page and save the results.
    sobel_filter()

def part2():
    try:
        # If the All Shapes is already saved, read it.
        img = cv2.imread("shapes.png")
    except:
        # If the file does not exist, get the screenshot again.
        get_shapes()
        img = cv2.imread("shapes.png")

    # Canny edge detection.
    edges = cv2.Canny(img, 400, 500)
    plt.imshow(edges, cmap="gray")
    plt.savefig("canny_edges.png")
    plt.close()

def part3():
    try:
        # If the All Shapes is already saved, read it.
        img = cv2.imread("shapes.png")
    except:
        # If the file does not exist, get the screenshot again.
        get_shapes()
        img = cv2.imread("shapes.png")
    img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY).astype(np.float32)
    all_shapes = np.array_split(img, 4, axis=1)
    newimage = corner_detector(all_shapes[2])
    corners = np.load("star_corners.npy")
    # corners = cv2.cornerHarris(all_shapes[2],2,3,0.04)

    plt.imshow(newimage)
    plt.show()

def part4():

    # You can check the methods on all shapes page.
    # Works perfectly when the shape is not moving.

    # all_shapes = cv2.imread('shapes.png')

    ## Changes with resolution. **********************************************************
    # all_shapes = all_shapes[420:700,:]

    # all_shapes = cv2.cvtColor(all_shapes, cv2.COLOR_BGR2GRAY).astype(np.uint8)
    # all_shapes = np.array_split(all_shapes, 4,axis=1)

    # edgelist=[]
    # for shape in all_shapes:
    #    edges = cv2.Canny(shape,400,500)
    #    edgelist.append(edges)
    #    contours, hierarchy = cv2.findContours(edges, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
    #    print(contours[0].shape)
    #    detect(contours[0].squeeze())

    play_game()

part4()


import bitarray
from hashlib import sha256
import json
import time
import os
import math
from flask import Flask, request, redirect,render_template
import requests

class Block:
    def __init__(self, index, transactions, timestamp, previous_hash, nonce=0):
        self.index = index
        self.transactions = transactions
        self.timestamp = timestamp
        self.previous_hash = previous_hash
        self.nonce = nonce

    def compute_hash(self):
        """
        A function that return the hash of the block contents.
        """
        block_string = json.dumps(self.__dict__, sort_keys=True)
        return sha256(block_string.encode()).hexdigest()

class Blockchain:
    # difficulty of our PoW algorithm
    difficulty = 2

    def __init__(self):
        self.unconfirmed_transactions = []
        self.chain = []

    def create_genesis_block(self):
        """
        A function to generate genesis block and appends it to
        the chain. The block has index 0, previous_hash as 0, and
        a valid hash.
        """
        genesis_block = Block(0, [], time.time(), "0")
        genesis_block.hash = genesis_block.compute_hash()
        self.chain.append(genesis_block)

    @property
    def last_block(self):
        return self.chain[-1]

    def add_block(self, block, proof):
        """
        A function that adds the block to the chain after verification.
        Verification includes:
        * Checking if the proof is valid.
        * The previous_hash referred in the block and the hash of latest block
          in the chain match.
        """
        previous_hash = self.last_block.hash

        if previous_hash != block.previous_hash:
            return False

        if not Blockchain.is_valid_proof(block, proof):
            return False

        block.hash = proof
        self.chain.append(block)
        return True

    def proof_of_work(self, block):
        """
        Function that tries different values of nonce to get a hash
        that satisfies our difficulty criteria.
        """
        block.nonce = 0

        computed_hash = block.compute_hash()
        while not computed_hash.startswith('0' * Blockchain.difficulty):
            block.nonce += 1
            computed_hash = block.compute_hash()

        return computed_hash

    def add_new_transaction(self, transaction):
        self.unconfirmed_transactions.append(transaction)

    @classmethod
    def is_valid_proof(cls, block, block_hash):
        """
        Check if block_hash is valid hash of block and satisfies
        the difficulty criteria.
        """
        return (block_hash.startswith('0' * Blockchain.difficulty) and
                block_hash == block.compute_hash())

    @classmethod
    def check_chain_validity(cls, chain):
        result = True
        previous_hash = "0"

        for block in chain:
            block_hash = block.hash
            # remove the hash field to recompute the hash again
            # using `compute_hash` method.
            delattr(block, "hash")

            if not cls.is_valid_proof(block, block.hash) or \
                    previous_hash != block.previous_hash:
                result = False
                break

            block.hash, previous_hash = block_hash, block_hash

        return result

    def mine(self):
        """
        This function serves as an interface to add the pending
        transactions to the blockchain by adding them to the block
        and figuring out Proof Of Work.
        """
        if not self.unconfirmed_transactions:
            return False

        last_block = self.last_block

        new_block = Block(index=last_block.index + 1,
                          transactions=self.unconfirmed_transactions,
                          timestamp=time.time(),
                          previous_hash=last_block.hash)

        proof = self.proof_of_work(new_block)
        self.add_block(new_block, proof)

        self.unconfirmed_transactions = []
        # announce it to the network
        announce_new_block(new_block)
        return new_block.index

project_root = os.path.dirname(__file__)
template_path = os.path.join(project_root, 'app/templates')
app = Flask(__name__, template_folder=template_path)
#app = Flask(__name__)

# the node's copy of blockchain
blockchain = Blockchain()
blockchain.create_genesis_block()

# the address to other participating members of the network
peers = set()

@app.route('/revoke1')
def revoke1():
    return render_template('revoke.html',
                           title='CERTIFICATE REVOCATION')

@app.route('/revoke', methods=['POST'])
def revoke():
    version = request.form["version"]
    post_object = {
        'version': version,
    }
    tx_data = post_object
    required_fields = ["version"]

    for field in required_fields:
        if not tx_data.get(field):
            return "Invalid transaction data", 404

    tx_data["timestamp"] = time.time()
    blockchain.add_new_transaction(tx_data)

    fh=open("revoke_list.txt","a")
    fh.write(version)
    fh.write("\n")
    fh.close()
    fh1=open("details.txt","a")
    str1="The certificate "+version+" has been revoked"
    fh1.write(str1)
    fh1.write("\n")
    fh1.close()
    return redirect('/revoke1')

@app.route('/validate1')
def validate1():
    return render_template('validate.html',
                           title='CERTIFICATE VALIDATION')

@app.route('/validate', methods=['POST'])
def validate():
    version = request.form["version"]

    class BloomFilter:
        def __init__(self, list1):
               number_words = len(list1)

               self.calc_optimal_hash(number_words)
               self.bit_array = self.array_length * bitarray.bitarray('0')
               for word in list1:
                   for seed in range(self.seed_count):
                       t=(word,seed)
                       hashIndex = hash(t) % self.array_length
                       self.bit_array[hashIndex] = True

        def calc_optimal_hash(self, number_words):

                 m = -number_words * math.log(0.01) / math.log(2) ** 2
                 k = m / number_words * math.log(2)

       	         self.array_length = int(m)
       	         self.seed_count = int(math.ceil(k))

        def probable_member(self, word):
            for seed in range(self.seed_count):
                t=(word,seed)
                candidateHash = hash(t) % self.array_length
                if not self.bit_array[candidateHash]:
                       return False

            return True

        def lookup(self, word):
            if self.probable_member(word):
               return '"{}" is most likely in the revoked list'.format(word)
            else:
               return '"{}" is not in the revoked list'.format(word)

    list1=[]
    list1 = [line.rstrip('\n') for line in open('revoke_list.txt', 'r')]
    bloom_filter = BloomFilter(list1)
    str11= bloom_filter.lookup(version)

    return str11

# endpoint to submit a new transaction. This will be used by
# our application to add new data (posts) to the blockchain
@app.route('/new_transaction', methods=['POST'])
def new_transaction():
    version = request.form["version"]
    serial = request.form["serial"]
    signature = request.form["signature"]
    issuer = request.form["issuer"]
    validity = request.form["validity"]
    subject = request.form["subject"]
    public_key = request.form["public_key"]
    subject_id = request.form["subject_id"]
    issuer_id = request.form["issuer_id"]
    extension = request.form["extension"]
    post_object = {
        'version': version,
        'serial': serial,
	'signature': signature,
	'issuer': issuer,
	'validity': validity,
	'subject': subject,
	'public_key': public_key,
	'subject_id': subject_id,
	'issuer_id': issuer_id,
	'extension': extension,
    }
    tx_data = post_object
    required_fields = ["version", "serial", "signature", "issuer", "validity", "subject", "public_key", "issuer_id", "subject_id", "extension"]

    for field in required_fields:
        if not tx_data.get(field):
            return "Invlaid transaction data", 404

    tx_data["timestamp"] = time.time()
    blockchain.add_new_transaction(tx_data)
    fh = open("details.txt", "a")
    i=0
    data = {}
    data['cert'] = []
    data['cert'].append({
        'version': tx_data.get('version'),
        'serial': tx_data.get('serial'),
	'signature': tx_data.get('signature'),
	'issuer': tx_data.get('issuer'),
	'validity': tx_data.get('validity'),
	'public_key': tx_data.get('public_key'),
	'issuer_id': tx_data.get('issuer_id'),
	'subject_id': tx_data.get('subject_id'),
	'extension': tx_data.get('extension'),
	})

    with open('details.txt', 'a') as outfile:
       json.dump(data, outfile)

    return redirect('/index')

@app.route('/display', methods=['GET','POST'])
def display():
    fh1= open("details.txt", "r")
    fh2=json.dumps(fh1.readlines())

    return fh2

# endpoint to return the node's copy of the chain.
# Our application will be using this endpoint to query
# all the posts to display.
@app.route('/chain', methods=['GET'])
def get_chain():
    # make sure we've the longest chain
    consensus()
    chain_data = []
    for block in blockchain.chain:
        chain_data.append(block.__dict__)
    return json.dumps({"length": len(chain_data),
                       "chain": chain_data,
                       "peers": list(peers)})

# endpoint to request the node to mine the unconfirmed
# transactions (if any). We'll be using it to initiate
# a command to mine from our application itself.
@app.route('/mine', methods=['GET'])
def mine_unconfirmed_transactions():
    result = blockchain.mine()
    if not result:
        return "No transactions to mine"
    return "Block #{} is mined.".format(result)

# endpoint to add new peers to the network.
@app.route('/register_node', methods=['POST'])
def register_new_peers():
    node_address = request.get_json()["node_address"]
    #node_address = request.form["version"]
    if not node_address:
        return "Invalid data", 400

    # Add the node to the peer list
    peers.add(node_address)

    # Return the consensus blockchain to the newly registered node
    # so that he can sync
    return get_chain()

@app.route('/register_with', methods=['POST'])
def register_with_existing_node():
    """
    Internally calls the `register_node` endpoint to
    register current node with the node specified in the
    request, and sync the blockchain as well as peer data.
    """
    node_address = request.get_json()["node_address"]
    if not node_address:
        return "Invalid data", 400

    data = {"node_address": request.host_url}
    headers = {'Content-Type': "application/json"}

    # Make a request to register with remote node and obtain information
    response = requests.post(node_address + "/register_node",
                             data=json.dumps(data), headers=headers)

    if response.status_code == 200:
        global blockchain
        global peers
        # update chain and the peers
        chain_dump = response.json()['chain']
        blockchain = create_chain_from_dump(chain_dump)
        peers.update(response.json()['peers'])
        return "Registration successful", 200
    else:
        # if something goes wrong, pass it on to the API response
        return response.content, response.status_code

@app.route('/index')
def index():
	return render_template('index.html',
                           title='CERTIFICATES')
        #return "hi"

def create_chain_from_dump(chain_dump):
    blockchain = Blockchain()
    for idx, block_data in enumerate(chain_dump):
        block = Block(block_data["index"],
                      block_data["transactions"],
                      block_data["timestamp"],
                      block_data["previous_hash"])
        proof = block_data['hash']
        if idx > 0:
            added = blockchain.add_block(block, proof)
            if not added:
                raise Exception("The chain dump is tampered!!")
        else:  # the block is a genesis block, no verification needed
            blockchain.chain.append(block)
    return blockchain

# endpoint to add a block mined by someone else to
# the node's chain. The block is first verified by the node
# and then added to the chain.
@app.route('/add_block', methods=['POST'])
def verify_and_add_block():
    block_data = request.get_json()
    block = Block(block_data["index"],
                  block_data["transactions"],
                  block_data["timestamp"],
                  block_data["previous_hash"])

    proof = block_data['hash']
    added = blockchain.add_block(block, proof)

    if not added:
        return "The block was discarded by the node", 400

    return "Block added to the chain", 201

@app.route('/submit', methods=['POST'])
def submit_textarea():
    """
    Endpoint to create a new transaction via our application.
    """
    version = request.form["version"]
    serial = request.form["serial"]
    signature = request.form["signature"]
    issuer = request.form["issuer"]
    validity = request.form["validity"]
    subject = request.form["subject"]
    public_key = request.form["public_key"]
    subject_id = request.form["subject_id"]
    issuer_id = request.form["issuer_id"]
    extension = request.form["extension"]
    post_object = {
        'version': version,
        'serial': serial,
	'signature': signature,
	'issuer': issuer,
	'validity': validity,
	'subject': subject,
	'public_key': public_key,
	'subject_id': subject_id,
	'issuer_id': issuer_id,
	'extension': extension,
    }

    # Submit a transaction
    new_tx_address = "{}/new_transaction".format(CONNECTED_NODE_ADDRESS)

    requests.post(new_tx_address,
                  json=post_object,
                  headers={'Content-type': 'application/json'})

    return redirect('/index')

# endpoint to query unconfirmed transactions
@app.route('/pending_tx')
def get_pending_tx():
    if len(blockchain.unconfirmed_transactions)==0:
        return "No unconfirmed transactions"
    return json.dumps(blockchain.unconfirmed_transactions)

def consensus():
    """
    Our simple consnsus algorithm. If a longer valid chain is
    found, our chain is replaced with it.
    """
    global blockchain

    longest_chain = None
    current_len = len(blockchain.chain)

    for node in peers:
        print('{}/chain'.format(node))
        response = requests.get('{}/chain'.format(node))
        print("Content", response.content)
        length = response.json()['length']
        chain = response.json()['chain']
        if length > current_len and blockchain.check_chain_validity(chain):
            current_len = length
            longest_chain = chain

    if longest_chain:
        blockchain = longest_chain
        return True

    return False

def announce_new_block(block):
    """
    A function to announce to the network once a block has been mined.
    Other blocks can simply verify the proof of work and add it to their
    respective chains.
    """
    for peer in peers:
        url = "{}add_block".format(peer)
        requests.post(url, data=json.dumps(block.__dict__, sort_keys=True))


import requests
import json
from os import path
import asyncio
import time

def emitRequest(url):
  # retry if "Too many request (429)"
  while True:
    r = requests.get(url)
    if r.status_code == 200:
      return r
    elif r.status_code == 429 or r.status_code == 502:
      time.sleep(1)
    else:
      raise Exception(r.status_code, url)

def getRouteStop(co):
    # define output name
    ROUTE_LIST = 'routeList.'+co+'.json'
    STOP_LIST = 'stopList.'+co+'.json'

    # load route list and stop list if exist
    routeList = {}
    if path.isfile(ROUTE_LIST):
        return
    else:
        # load routes
        r = emitRequest('https://rt.data.gov.hk/v2/transport/nlb/route.php?action=list')
        routeList = []
        for route in r.json()['routes']:
            routeList.append({
                "id": route['routeId'],
                "route": route['routeNo'],
                "bound": "O",
                "orig_en": route['routeName_e'].split(' > ')[0],
                "orig_tc": route['routeName_c'].split(' > ')[0],
                "dest_en": route['routeName_e'].split(' > ')[1],
                "dest_tc": route['routeName_c'].split(' > ')[1],
                "service_type": str(1 + route['overnightRoute'] * 2 + route['specialRoute'] *4),
                "stops": [],
                "co": ["nlb"]
            })

    _stops = []
    stopList = {}
    if path.isfile(STOP_LIST):
        with open(STOP_LIST) as f:
            stopList = json.load(f)

    def getRouteStop(routeId):
        r = emitRequest('https://rt.data.gov.hk/v2/transport/nlb/stop.php?action=list&routeId='+routeId)
        try:
            return r.json()['stops']
        except Exception as err:
            print(r)
            raise err

    async def getRouteStopList ():
        loop = asyncio.get_event_loop()
        futures = [loop.run_in_executor(None, getRouteStop, route['id']) for route in routeList]
        ret = []
        for future in futures:
            ret.append(await future)
        for route, stops in zip(routeList, ret):
            stopIds = []
            fares = []
            faresHoliday = []
            for stop in stops:
                if stop['stopId'] not in stopList:
                    stopList[stop['stopId']] = {
                        'stop': stop['stopId'],
                        'name_en': stop['stopName_e'],
                        'name_tc': stop['stopName_c'],
                        'lat': stop['latitude'],
                        'long': stop['longitude']
                    }
                stopIds.append(stop['stopId'])
                fares.append(stop['fare'])
                faresHoliday.append(stop['fareHoliday'])
            route['stops'] = stopIds
            route['fares'] = fares[0:-1]
            route['faresHoliday'] = faresHoliday[0:-1]
        return routeList

    loop = asyncio.get_event_loop()
    routeList = loop.run_until_complete(getRouteStopList())

    with open(ROUTE_LIST, 'w') as f:
        f.write(json.dumps(routeList, ensure_ascii=False))
    with open(STOP_LIST, 'w') as f:
        f.write(json.dumps(stopList, ensure_ascii=False))

getRouteStop('nlb')


#-*- coding:utf-8 –*-

# chinese.py

import sqlite3, sys

def insert(a, b, c, d, e ):
	conn = sqlite3.connect('sayHello.db')
	c = conn.cursor()
	c.execute("INSERT INTO COMPANY (姓名,学号,性别,年龄,学院) \
                 VALUES ('%s', '%s', '%s', '%s', '%s' )" % (a, b, c, d, e));
	conn.commit()
	c = conn.cursor()
	cursor = c.execute("SELECT 姓名,学号,性别,年龄,学院  from COMPANY")
	values= cursor.fetchall()
	for row in values:
		print ("姓名 = "+str(row[0]))
		print ("学号= "+str(row[1]))
		print ("性别= "+str(row[2]))
		print ("年龄= "+str(row[3]))
		print ("学院 = "+str(row[4])), "\n";
	return "Operation done successfully";

if '__main__' == __name__:
	if 6 == len(sys.argv):
		args = sys.argv
		insert(args[1], args[2], args[3], args[4], args[5])


"""Tokenizing, tagging and parsing text with UDPipe.

"""
import warnings

from ufal import udpipe

WORD_ATTRS = (
    "id",
    "form",
    "lemma",
    "xpostag",
    "upostag",
    "feats",
    "head",
    "deprel",
    "deps",
    "misc",
)
MULTIWORDTOKEN_ATTRS = ("idFirst", "idLast", "form", "misc")
EMPTYNODE_ATTRS = (
    "id",
    "index",
    "form",
    "lemma",
    "upostag",
    "xpostag",
    "feats",
    "deps",
    "misc",
)
SENT_ATTRS = ("comments", "words", "multiwordTokens", "emptyNodes")
PPRINT_DIGEST = True

class UdpipeError(Exception):
    """An error which occurred in the :mod:`ufal.udpipe` C extension."""

class Model:
    """A UDPipe model for tagging and parsing text.

    :param model_path: Path to the pre-compiled UDPipe model to load.
    :type model_path: str or pathlib.Path

    """

    def __init__(self, model_path):
        self._model = udpipe.Model.load(str(model_path))
        if self._model is None:
            raise RuntimeError(f"Unable to load model from {model_path!r}!")
        self._default = self._model.DEFAULT

    def process(self, text, *, tag=True, parse=True, in_format=None, out_format=None):
        """Process input text, yielding sentences one by one.

        The text is always at least tokenized, and optionally morphologically
        tagged and syntactically parsed, depending on the values of the ``tag``
        and ``parse`` arguments.

        :param text: Text to process.
        :type text: str
        :param tag: Perform morphological tagging.
        :type tag: bool
        :param parse: Perform syntactic parsing.
        :type parse: bool
        :param in_format: Input format (cf. below for possible values).
        :type in_format: None or str
        :param out_format: Output format (cf. below for possible values).
        :type out_format: None or str

        The input text is a string in one of the following formats (specified
        by ``in_format``):

        - ``None``: freeform text, which will be sentence split and tokenized
          by UDPipe
        - ``"conllu"``: the CoNLL-U_ format
        - ``"horizontal"``: one sentence per line, word forms separated by
          spaces
        - ``"vertical"``: one word per line, empty lines denote sentence ends

        .. _CoNLL-U: https://universaldependencies.org/docs/format.html

        The output format is specified by ``out_format``:

        - ``None``: native :mod:`ufal.udpipe` objects, suitable for further
          manipulation in Python
        - ``"conllu"``, ``"horizontal"`` or ``"vertical"``: cf. above
        - ``"epe"``: the EPE (Extrinsic Parser Evaluation 2017) interchange
          format
        - ``"matxin"``: the Matxin XML format
        - ``"plaintext"``: reconstruct text with original spaces, discarding
          annotations

        New input and output formats may be added with new releases of UDPipe;
        for an up-to-date list, consult the `UDPipe API reference
        <http://ufal.mff.cuni.cz/udpipe/api-reference>`__.

        """
        if in_format is None:
            in_format = self._model.newTokenizer(self._default)
        else:
            in_format = udpipe.InputFormat.newInputFormat(in_format)
            if in_format is None:
                raise RuntimeError(f"Cannot create input format {in_format!r}.")

        if out_format is not None:
            out_format = udpipe.OutputFormat.newOutputFormat(out_format)
            if out_format is None:
                raise RuntimeError(f"Cannot create output format {out_format!r}.")

        in_format.setText(text)
        error = udpipe.ProcessingError()
        sent = udpipe.Sentence()
        while in_format.nextSentence(sent, error):
            if tag:
                self.tag(sent)
            if parse:
                self.parse(sent)
            if out_format is None:
                yield sent
            else:
                yield out_format.writeSentence(sent)
            sent = udpipe.Sentence()
        if error.occurred():
            raise UdpipeError(error.message)
        if out_format is not None:
            end = out_format.finishDocument()
            if end != "":
                yield end

    def tag(self, sent):
        """Perform morphological tagging on sentence.

        Modifies ``sent`` in place.

        :param sent: Sentence to tag.
        :type sent: ufal.udpipe.Sentence

        """
        # NOTE: like InputFormat.nextSentence, Model.tag and Model.parse accept
        # a ProcessingError argument. However, the udpipe_model.py example in
        # the UDPipe repo only passes the error argument to nextSentence,
        # probably on the assumption that input format errors are the only ones
        # which can be caused by users (and therefore will also routinely have
        # to be resolved by them). Other errors are bugs which should be fixed
        # by UDPipe maintainers, so they're ignored for simplicity's sake. For
        # the time being, we follow the same rationale here.
        self._model.tag(sent, self._default)

    def parse(self, sent):
        """Perform syntactic parsing on sentence.

        Modifies ``sent`` in place.

        :param sent: Sentence to parse.
        :type sent: ufal.udpipe.Sentence

        """
        self._model.parse(sent, self._default)

def load(corpus, in_format="conllu"):
    """Load corpus in input format.

    :param corpus: The data to load.
    :type corpus: str
    :param in_format: Cf. the documentation of :meth:`Model.process`.
    :type in_format: str
    :return: A generator of sentences (:class:`ufal.udpipe.Sentence`).

    """
    in_format = udpipe.InputFormat.newInputFormat(in_format)
    if in_format is None:
        raise RuntimeError(f"Cannot create input format {in_format!r}.")
    in_format.setText(corpus)
    error = udpipe.ProcessingError()
    sent = udpipe.Sentence()
    while in_format.nextSentence(sent, error):
        yield sent
        sent = udpipe.Sentence()
    if error.occurred():
        raise UdpipeError(error.message)

def dump(sent_or_sents, out_format="conllu"):
    """Dump sentence or sentences in output format.

    :param sent_or_sents: The data to dump.
    :type corpus: :class:`ufal.udpipe.Sentence`, or iterable thereof
    :param out_format: Cf. the documentation of :meth:`Model.process`.
    :type out_format: str
    :return: A generator of strings, corresponding to the serialized sentences.
        One final additional string may contain any closing markup, if required
        by the output format.

    """
    out_format = udpipe.OutputFormat.newOutputFormat(out_format)
    if out_format is None:
        raise RuntimeError(f"Cannot create output format {out_format!r}.")

    if isinstance(sent_or_sents, udpipe.Sentence):
        yield out_format.writeSentence(sent_or_sents)
    else:
        for sent in sent_or_sents:
            yield out_format.writeSentence(sent)
    end = out_format.finishDocument()
    if end != "":
        yield end

def _pprint_token(token, printer, cycle):
    cls_name = type(token).__name__
    if cycle:
        return printer.text(f"{cls_name}(...)")
    elif PPRINT_DIGEST and token.form == "<root>":
        return printer.text(f"{cls_name}(id={token.id}, <root>)")
    indent = len(cls_name) + 1
    with printer.group(indent, f"{cls_name}(", ")"):
        i = 0
        for attr in globals()[cls_name.upper() + "_ATTRS"]:
            val = getattr(token, attr)
            if not PPRINT_DIGEST or val != "" and val != -1:
                if i:
                    printer.text(",")
                    printer.breakable()
                printer.text(f"{attr}={val!r}")
                i += 1

def _pprint_sent(sent, printer, cycle):
    if cycle:
        return printer.text("Sentence(...)")
    with printer.group(2, "Sentence(", ")"):
        for i, attr in enumerate(SENT_ATTRS):
            seq = getattr(sent, attr)
            if PPRINT_DIGEST and seq.size() == 0:
                continue
            if i:
                printer.text(",")
            printer.breakable("")
            with printer.group(2, f"{attr}=[", "]"):
                printer.breakable("")
                for j, elem in enumerate(seq):
                    if j:
                        printer.text(",")
                        printer.breakable()
                    printer.pretty(elem)

def _pprint_seq(seq, printer, cycle):
    if cycle:
        return printer.text("[...]")
    # NOTE: The following is basically the same code as at the end of
    # _pprint_sent, minus a call to printer.breakable("") just after the with,
    # the indent width and the starting delimiter string of the group.
    # Unfortunately, I haven't yet figured out a way to adjust this depending
    # on whether _pprint_seq is called from _pprint_sent or not, so it will
    # have to stay duplicated for the time being.
    with printer.group(1, "[", "]"):
        for j, elem in enumerate(seq):
            if j:
                printer.text(",")
                printer.breakable()
            printer.pretty(elem)

def pprint(obj):
    """Pretty-print object.

    This is a convenience wrapper over :func:`IPython.lib.pretty.pprint` for
    easier importing.

    """
    try:
        from IPython.lib import pretty

        pretty.pprint(obj)
    except ImportError:
        warnings.warn("Please install the IPython package for pretty-printing to work.")

def pprint_config(*, digest=True):
    """Configure pretty-printing of :mod:`ufal.udpipe` objects.

    :param digest: Show only attributes with interesting values (other than
        ``''`` or ``-1``)
    :type digest: bool

    """
    global PPRINT_DIGEST
    PPRINT_DIGEST = digest

def _register_pprinters(formatter):
    formatter.for_type(udpipe.Word, _pprint_token)
    formatter.for_type(udpipe.MultiwordToken, _pprint_token)
    formatter.for_type(udpipe.EmptyNode, _pprint_token)
    formatter.for_type(udpipe.Sentence, _pprint_sent)
    formatter.for_type(udpipe.Comments, _pprint_seq)
    formatter.for_type(udpipe.Words, _pprint_seq)
    formatter.for_type(udpipe.MultiwordTokens, _pprint_seq)
    formatter.for_type(udpipe.EmptyNodes, _pprint_seq)

try:
    from IPython import get_ipython
    from IPython.lib import pretty

    _register_pprinters(pretty)
    _ipython = get_ipython()  # pylint: disable=invalid-name
    if _ipython is not None:
        _plain_formatter = _ipython.display_formatter.formatters["text/plain"]
        _register_pprinters(_plain_formatter)
    else:
        warnings.warn(
            "IPython session not found! Processed text will not be automatically pretty-printed, "
            "but you may still do so explicitly with the corpy.udpipe.pprint function."
        )
except ImportError:
    warnings.warn(
        "IPython package not found! Processed text will not be automatically pretty-printed, and "
        "the corpy.udpipe.pprint function will not work."
    )


import numpy as np
import scipy.stats
import matplotlib.pyplot as plt
import matplotlib.colors
from sar_data import *

class Gamma(object):
    """
    Test statistic on equality of two Gamma parameters
    Use for change detection between two single channel SAR images X and Y
    n, m are Equivalent Number of Looks (ENL)
    """

    def __init__(self, X, Y, n, m, shape):
        self.X = X
        self.Y = Y
        self.n = n
        self.m = m
        self.shape = shape
        self.Q = Y/X # Test statistic

    def histogram(self, percentile):
        f = plt.figure(figsize=(8, 4))
        ax = f.add_subplot(111)
        ax.hist(self.Q.flatten(), bins=100, normed=True, range=(0,5), color='#3F5D7D')

        ax.spines["top"].set_visible(False)
        ax.spines["right"].set_visible(False)
        ax.get_xaxis().tick_bottom()
        ax.get_yaxis().tick_left()

        ax.set_xlabel('Test statistic')
        ax.set_ylabel('Frequency')

        ax.set_ylim([0, 1.1])

        # Fisher's F overlay
        F = scipy.stats.f(2*self.m, 2*self.n)
        x = np.linspace(0, 5, 500)
        ax.plot(x, F.pdf(x), color='black', linewidth=2)

        # Select threshold from distrib quantile
        t_inf, t_sup = F.ppf(percentile/2), F.ppf(1 - percentile/2)

        return f, ax

    def image_binary(self, percentile):
        F = scipy.stats.f(2*self.m, 2*self.n)
        t_inf, t_sup = F.ppf(percentile/2), F.ppf(1 - percentile/2)

        im = np.zeros_like(self.Q)
        im[self.Q < t_inf] = 1
        im[self.Q > t_sup] = 1

        return im.reshape(self.shape)

    def image_color2(self, percentile):
        """
        Change detection image with two colors indicating the change direction
        Black - Gray - White
        """
        F = scipy.stats.f(2*self.m, 2*self.n)
        t_inf, t_sup = F.ppf(percentile/2), F.ppf(1 - percentile/2)

        im = np.empty_like(self.Q)
        im[:] = 0.5
        im[self.Q < t_inf] = 0
        im[self.Q > t_sup] = 1

        return im.reshape(self.shape)

    def image_color3(self, percentile):
        """
        Change detection image with blue/red indicating the change direction
        """
        F = scipy.stats.f(2*self.m, 2*self.n)
        t_inf, t_sup = F.ppf(percentile/2), F.ppf(1 - percentile/2)

        im = np.empty((self.shape[0], self.shape[1], 3))
        im[:,:] = np.array([0, 0, 0])
        im[self.Q.reshape(self.shape) < t_inf] = np.array([170, 63, 57])
        im[self.Q.reshape(self.shape) > t_sup] = np.array([35, 100, 103])

        return im

    def image_linear(self, percentile):
        pass

def multiENL_gamma(april, may):
    gamma = Gamma(april, may, 13, 13, (1024, 1024))

    f = plt.figure(figsize=(8, 4))
    ax = f.add_subplot(111)
    ax.hist(gamma.Q.flatten(), bins=100, normed=True, range=(0,3), color='#3F5D7D')

    ax.spines["top"].set_visible(False)
    ax.spines["right"].set_visible(False)
    ax.get_xaxis().tick_bottom()
    ax.get_yaxis().tick_left()

    ax.set_xlabel('Test statistic')
    ax.set_ylabel('Frequency')

    ax.set_ylim([0, 1.3])
    ax.set_xticks([0, 1, 2, 3])

    # Fisher's F overlay
    def overlay(ENL, side="right"):
        F = scipy.stats.f(2*ENL, 2*ENL)
        x = np.linspace(0, 3, 500)
        ax.plot(x, F.pdf(x), color='black', linewidth=1)
        mode = (ENL - 1)/(ENL+1)
        xtext = 0.4 if side == "left" else 1.3
        ax.annotate('{}'.format(ENL), xy=(mode, F.pdf(mode)), xytext=(xtext, F.pdf(mode)),
            arrowprops=dict(facecolor='black', shrink=0.05, width=.5, headwidth=2),
            fontsize=11,
            horizontalalignment='right',
            verticalalignment='center'
            )

    # overlay(8)
    overlay(9, "left")
    # overlay(10)
    overlay(11, "left")
    # overlay(12)
    overlay(13, "left")
    # overlay(14)
    overlay(15, "left")
    # overlay(16)
    overlay(17, "left")

    return f, ax

def critical_region():
    "Critical region figure"

    percent = 0.10

    f = plt.figure(figsize=(8, 3))
    ax = f.add_subplot(111)

    ax.spines["top"].set_visible(False)
    ax.spines["right"].set_visible(False)
    ax.get_xaxis().tick_bottom()
    ax.get_yaxis().tick_left()

    ax.set_xlabel('Test statistic')
    ax.set_ylabel('Frequency')

    ax.set_ylim([0, 1.1])

    # Fisher's F pdf
    ENL = 13
    F = scipy.stats.f(2*ENL, 2*ENL)
    x = np.linspace(0, 3, 500)
    y = F.pdf(x)
    ax.plot(x, y, color='black', linewidth=1)

    # Thresholds
    t_inf, t_sup = F.ppf(percent/2), F.ppf(1 - percent/2)
    ax.fill_between(x, y, where=(x < t_sup) == (x > t_inf), color='#3F5D7D')

    ax.set_xticks([t_inf, t_sup])
    ax.set_xticklabels([r"$c_1$", r"$c_2$"], size=16)

    anotx = (ENL - 1)/(ENL+1) + 0.2
    ax.annotate(r'$F(2m, 2n)$', xy=(anotx, F.pdf(anotx)), xytext=(anotx + 0.6, F.pdf(anotx)),
        arrowprops=dict(facecolor='black', shrink=0.05, width=.3, headwidth=5),
        fontsize=16,
        horizontalalignment='right',
        verticalalignment='center'
        )

    ax.text(0.68, 0.5, "No change", color="white", size=16)
    ax.text(0.07, 0.5, "Change", color="black", size=16)
    ax.text(2.0, 0.5, "Change", color="black", size=16)

    ax.axvline(t_inf, color="black", linestyle="--")
    ax.axvline(t_sup, color="black", linestyle="--")

    return f, ax

if __name__ == "__main__":
    print("Gamma test...")

    def gamma_test(april, may, channel, ENL, percent):
        # Data
        X = april.__dict__[channel]
        Y = may.__dict__[channel]
        Xno = april.region(region_nochange).__dict__[channel]
        Yno = may.region(region_nochange).__dict__[channel]

        # Name variables
        short_channel = channel[:2].upper()
        hist_filename = "fig/gamma/gamma.hist.ENL{0}.{1}.{2}.pdf".format(ENL, short_channel, percent)

        # No change region histogram
        gno = Gamma(Xno, Yno, ENL, ENL, april.shape)
        f, ax = gno.histogram(percent)
        f.savefig(hist_filename, bbox_inches='tight')

        ## Images
        g = Gamma(X, Y, ENL, ENL, april.shape)

        # Binary image
        im = g.image_binary(percent)
        im_filename = "fig/gamma/gamma.im.ENL{0}.{1}.{2}.jpg".format(ENL, short_channel, percent)
        plt.imsave(im_filename, im, cmap='gray')

        # Two level image, grayscale
        im = g.image_color2(percent)
        im_filename = "fig/gamma/gamma.color2.ENL{0}.{1}.{2}.jpg".format(ENL, short_channel, percent)
        plt.imsave(im_filename, im, cmap="gray", vmin=0, vmax=1)

        # Two level image, color
        im = g.image_color3(percent)
        im_filename = "fig/gamma/gamma.color3.ENL{0}.{1}.{2}.jpg".format(ENL, short_channel, percent)
        plt.imsave(im_filename, im)

    gamma_test(april, may, "hhhh", 13, 0.10)
    gamma_test(april, may, "hvhv", 13, 0.10)
    gamma_test(april, may, "vvvv", 13, 0.10)

    gamma_test(april, may, "hhhh", 13, 0.05)
    gamma_test(april, may, "hvhv", 13, 0.05)
    gamma_test(april, may, "vvvv", 13, 0.05)

    gamma_test(april, may, "hhhh", 13, 0.01)
    gamma_test(april, may, "hvhv", 13, 0.01)
    gamma_test(april, may, "vvvv", 13, 0.01)

    gamma_test(april, may, "hhhh", 13, 0.001)
    gamma_test(april, may, "hvhv", 13, 0.001)
    gamma_test(april, may, "vvvv", 13, 0.001)

    gamma_test(april, may, "hhhh", 13, 0.0001)
    gamma_test(april, may, "hvhv", 13, 0.0001)
    gamma_test(april, may, "vvvv", 13, 0.0001)

    gamma_test(april, may, "hhhh", 13, 0.00001)
    gamma_test(april, may, "hvhv", 13, 0.00001)
    gamma_test(april, may, "vvvv", 13, 0.00001)

    # At lower ENL than normal
    gamma_test(april, may, "hhhh", 12, 0.01)
    gamma_test(april, may, "hvhv", 12, 0.01)
    gamma_test(april, may, "vvvv", 12, 0.01)

    # MultiENL plots
    f, ax = multiENL_gamma(april.region(region_nochange).hhhh, may.region(region_nochange).hhhh)
    f.savefig("fig/gamma/gamma.multiENL.HH.pdf", bbox_inches='tight')

    f, ax = multiENL_gamma(april.region(region_nochange).hvhv, may.region(region_nochange).hvhv)
    f.savefig("fig/gamma/gamma.multiENL.HV.pdf", bbox_inches='tight')

    f, ax = multiENL_gamma(april.region(region_nochange).vvvv, may.region(region_nochange).vvvv)
    f.savefig("fig/gamma/gamma.multiENL.VV.pdf", bbox_inches='tight')

    f, ax = critical_region()
    f.savefig("fig/gamma/gamma.critical-region.pdf", bbox_inches='tight')


# My modules
import json_manager

import os, sys, random
from typing import Optional
import discord
from discord import app_commands
import aiocron

settings = json_manager.ReadFile(os.getcwd() + '/settings.json')
adminIds = settings['adminIds']
online_presence = settings['online-presence']

class MyClient(discord.Client):
    def __init__(self, *, intents: discord.Intents):
        super().__init__(intents=intents)
        self.synced = False

    async def on_ready(self):
        if(not self.synced):
            await tree.sync()
            self.synced = True

            await changePresence()
            aiocron.crontab('0 */1 * * *', func=changePresence, start=True)
            print(f'Logged in as {client.user} (ID: {client.user.id}) \n------')

client = MyClient(intents=discord.Intents.default())
tree = app_commands.CommandTree(client)

#/- FUNCTIONS
async def changePresence():
    await client.change_presence(activity= discord.Game(online_presence[random.randint(0, len(online_presence) - 1)]));

@tree.command()
async def clear_all(interaction: discord.Interaction):
    """Clears all existing text from this channel"""
    await interaction.response.send_message(f'Clearing all chat...', ephemeral= True)
    await interaction.channel.purge()

@tree.command()
@app_commands.rename(amountToDelete = 'number')
@app_commands.describe(amountToDelete = 'Amount of messages to delete in this channel')
async def clear(interaction: discord.Interaction, amountToDelete: int):
    """Clears x amount of messages from this channel"""
    await interaction.response.send_message(f'Clearing {amountToDelete} message(s)...', ephemeral= True)

    msgs = []
    async for msg in interaction.channel.history(limit= amountToDelete):
        msgs.append(msg);

    await interaction.channel.delete_messages(msgs)

@tree.command()
@app_commands.rename(user = 'user')
@app_commands.describe(user = 'The selected user')
async def clear_user(interaction: discord.Interaction, user: discord.User):
    """Deletes all messages from a given user"""
    await interaction.response.send_message(f'Clearing all messages by {user}...', ephemeral= True)
    msgs = []
    async for msg in interaction.channel.history():
        if(msg.author.id != user.id): continue
        msgs.append(msg);
    await interaction.channel.delete_messages(msgs)

@tree.command(name="shutdown", description="Shuts the bot down")
async def self(interaction: discord.Interaction):
    if(not (interaction.user.id in adminIds)): # Stops anyone but the admins to turn shut off the bot.
        await interaction.response.send_message(f'You do not have permission to run that command!', ephemeral= True)
        return

    print(f'{interaction.user} has shutdown the bot!')
    await interaction.response.send_message(f'Shutting down...', ephemeral= True)
    sys.exit(0)

token = open('token.txt', 'r')
client.run(token.read())
token.close()


import tkinter as tk
import tkinter.ttk as ttk
from tkinter import messagebox
from datetime import date

# Variable para almacenar los datos de las ventas
datos_ventas = []

def guardar_venta():
    cliente = entry_cliente.get()
    producto = entry_producto.get()
    cantidad = entry_cantidad.get()

    if cliente == "" or producto == "" or cantidad == "":
        messagebox.showerror("Error", "Por favor, completa todos los campos.")
    else:
        # Aquí puedes agregar la lógica para guardar la venta en la base de datos
        messagebox.showinfo("Registro de Ventas", "Venta registrada correctamente.")
        entry_cliente.delete(0, tk.END)
        entry_producto.delete(0, tk.END)
        entry_cantidad.delete(0, tk.END)

        # Añadir los datos de la venta a la lista
        datos_venta = (producto, cantidad, "...", "...", "...")
        datos_ventas.append(datos_venta)

        # Actualizar el cuadro grande con los nuevos datos
        actualizar_cuadro_grande()

def actualizar_cuadro_grande():
    # Eliminar todas las etiquetas del cuadro grande
    for widget in cuadro_grande.winfo_children():
        widget.destroy()

    # Encabezados de la tabla
    encabezados = ["Producto", "Cantidad", "Precio", "Descuento", "Precio Total"]
    for col, encabezado in enumerate(encabezados):
        label_encabezado = tk.Label(cuadro_grande, text=encabezado, font=fuente_entry, anchor="w", width=15, bg="white", padx=5)
        label_encabezado.grid(row=0, column=col)
        if col > 0:
            separator = ttk.Separator(cuadro_grande, orient="vertical")
            separator.grid(row=0, column=col, sticky="ns")

    # Datos de las ventas
    for i, datos_venta in enumerate(datos_ventas):
        producto_valor = tk.Label(cuadro_grande, text=datos_venta[0], font=fuente_entry, anchor="w", width=20)
        producto_valor.grid(row=i+1, column=0)
        cantidad_valor = tk.Label(cuadro_grande, text=datos_venta[1], font=fuente_entry, anchor="w", width=10)
        cantidad_valor.grid(row=i+1, column=1)
        precio_valor = tk.Label(cuadro_grande, text=datos_venta[2], font=fuente_entry, anchor="w", width=10)
        precio_valor.grid(row=i+1, column=2)
        descuento_valor = tk.Label(cuadro_grande, text=datos_venta[3], font=fuente_entry, anchor="w", width=10)
        descuento_valor.grid(row=i+1, column=3)
        precio_total_valor = tk.Label(cuadro_grande, text=datos_venta[4], font=fuente_entry, anchor="w", width=10)
        precio_total_valor.grid(row=i+1, column=4)

# Crear la ventana de registro de ventas
ventana_registro_ventas = tk.Tk()
ventana_registro_ventas.title("Registro de Ventas")
ventana_registro_ventas.geometry("600x400")

# Configurar estilos
fuente_titulo = ("Arial", 24, "bold")
fuente_label = ("Arial", 14)
fuente_entry = ("Arial", 14)
fuente_boton = ("Arial", 14)

# Título del registro de ventas
titulo = tk.Label(ventana_registro_ventas, text="Registro de Ventas", font=fuente_titulo)
titulo.pack(pady=20)

# Contenedor para el formulario
contenedor_formulario = tk.Frame(ventana_registro_ventas)

# Label y Entry para el campo Cliente
label_cliente = tk.Label(contenedor_formulario, text="Cliente:", font=fuente_label)
label_cliente.grid(row=0, column=0, padx=10, pady=10, sticky="e")
entry_cliente = tk.Entry(contenedor_formulario, font=fuente_entry)
entry_cliente.grid(row=0, column=1, padx=10, pady=10)

# Label y Entry para el campo Producto
label_producto = tk.Label(contenedor_formulario, text="Producto:", font=fuente_label)
label_producto.grid(row=1, column=0, padx=10, pady=10, sticky="e")
entry_producto = tk.Entry(contenedor_formulario, font=fuente_entry)
entry_producto.grid(row=1, column=1, padx=10, pady=10)

# Label y Entry para el campo Cantidad
label_cantidad = tk.Label(contenedor_formulario, text="Cantidad:", font=fuente_label)
label_cantidad.grid(row=2, column=0, padx=10, pady=10, sticky="e")
entry_cantidad = tk.Entry(contenedor_formulario, font=fuente_entry)
entry_cantidad.grid(row=2, column=1, padx=10, pady=10)

# Label para la fecha
fecha_actual = date.today().strftime("%d/%m/%Y")
label_fecha = tk.Label(contenedor_formulario, text="Fecha:", font=fuente_label)
label_fecha.grid(row=3, column=0, padx=10, pady=10, sticky="e")
label_fecha_valor = tk.Label(contenedor_formulario, text=fecha_actual, font=fuente_entry)
label_fecha_valor.grid(row=3, column=1, padx=10, pady=10, sticky="w")

# Botón para guardar la venta
boton_registrar = tk.Button(contenedor_formulario, text="Registrar", font=fuente_boton, bg="#4CAF50", fg="white", command=guardar_venta)
boton_registrar.grid(row=4, column=0, padx=10, pady=10, sticky="w")

# Botón para cancelar
boton_cancelar = tk.Button(contenedor_formulario, text="Cancelar", font=fuente_boton, bg="#FF0000", fg="white", command=ventana_registro_ventas.quit)
boton_cancelar.grid(row=4, column=1, padx=10, pady=10, sticky="e")

# Agregar el contenedor del formulario a la ventana principal
contenedor_formulario.pack()

# Cuadro grande
cuadro_grande = tk.Frame(ventana_registro_ventas, bg="white", relief="solid", borderwidth=1)
cuadro_grande.pack(fill=tk.BOTH, expand=True, padx=20, pady=20)

# Encabezados de la tabla
encabezados = ["Producto", "Cantidad", "Precio", "Descuento", "Precio Total"]
for col, encabezado in enumerate(encabezados):
    label_encabezado = tk.Label(cuadro_grande, text=encabezado, font=fuente_entry, anchor="w", width=15, bg="white", padx=5)
    label_encabezado.grid(row=0, column=col)
    if col > 0:
        separator = ttk.Separator(cuadro_grande, orient="vertical")
        separator.grid(row=0, column=col, sticky="ns")

# Ejecutar la aplicación
ventana_registro_ventas.mainloop()


"""fire URL Configuration

The `urlpatterns` list routes URLs to views. For more information please see:
    https://docs.djangoproject.com/en/2.2/topics/http/urls/
Examples:
Function views
    1. Add an import:  from my_app import views
    2. Add a URL to urlpatterns:  path('', views.home, name='home')
Class-based views
    1. Add an import:  from other_app.views import Home
    2. Add a URL to urlpatterns:  path('', Home.as_view(), name='home')
Including another URLconf
    1. Import the include() function: from django.urls import include, path
    2. Add a URL to urlpatterns:  path('blog/', include('blog.urls'))
"""
from django.contrib import admin
from django.urls import path, include
from django.views.generic import TemplateView
from login import views
from login import user, messages, device, video

user_patterns = [
    path('login/', user.login_controller),
    path('check_login/', user.check_is_login_and_get_username_controller),
    path('info/', user.get_user_info_controller)
]
message_patterns = [
    path('', messages.messages),
    path('info/', messages.get_message_info_controller),
    path('approve', messages.approve_message_controller),
]

device_patterns = [
    path('', device.device_controller),
    path('all/', device.get_all_device_controller)
]

video_patterns = [
    path('', video.videos_controller)
]

api_patterns = [
    path('user/', include(user_patterns)),
    path('messages/', include(message_patterns)),
    path('devices/', include(device_patterns)),
    path('videos/', include(video_patterns)),
]
urlpatterns = [
    path('admin/', admin.site.urls),
    path('messages/', views.MessageAmount),
    path('warning/true/', views.dealTrue),
    path('warning/false/', views.dealFalse),
    path('warning/', views.warning),
    path('login/', views.login),
    path('monitor/', views.monitor),
    path('overview/', views.overview),
    path('logout/', views.logout),
    path('data', views.DealData),
    path('conf/', views.conf),
    path('wechat', views.wechat),
    path('user_config', views.getUserConf),
    path('', TemplateView.as_view(template_name='index.html')),
    path('api/', include(api_patterns))
]


import logging
import os
import sys
import time
from http import HTTPStatus

import requests
import telegram
from dotenv import load_dotenv

from exceptions import HttpResponseError, ParseError

load_dotenv()

TELEGRAM_TOKEN = os.getenv('TELEGRAM_TOKEN')
PRACTICUM_TOKEN = os.getenv('PRACTICUM_TOKEN')
TELEGRAM_CHAT_ID = os.getenv('TELEGRAM_CHAT_ID')

RETRY_PERIOD = 600
ENDPOINT = 'https://practicum.yandex.ru/api/user_api/homework_statuses/'
HEADERS = {'Authorization': f'OAuth {PRACTICUM_TOKEN}'}

HOMEWORK_VERDICTS = {
    'approved': 'Работа проверена: ревьюеру всё понравилось. Ура!',
    'reviewing': 'Работа взята на проверку ревьюером.',
    'rejected': 'Работа проверена: у ревьюера есть замечания.'
}

def check_tokens():
    """Проверка наличия переменных окружения."""
    return all([
        PRACTICUM_TOKEN,
        TELEGRAM_TOKEN,
        TELEGRAM_CHAT_ID
    ])

def get_api_answer(timestamp):
    """Создание get-запроса к API."""
    RESPONSE = {
        'url': ENDPOINT,
        'headers': HEADERS,
        'params': {"from_date": timestamp},
    }
    try:
        response = requests.get(**RESPONSE)
        if response.status_code != HTTPStatus.OK:
            message = (f'Параметры запроса: {response.url}',
                       f'Статус ответа API: {response.status_code}',
                       f'Контент ответа: {response.text}',)
            raise HttpResponseError(message)

    except Exception as error:
        message = f'Эндпоинт {ENDPOINT}, недоступен! Ошибка: {error}.'
        raise HttpResponseError(message)

    return response.json()

def check_response(response):
    """Проверка ответа API на наличие нужных ключей и типов данных."""
    logging.info('Проверка ответа API')

    if not isinstance(response, dict):
        message = 'Ответ API не являтеся словарем!'
        raise TypeError(message)

    if 'homeworks' not in response and 'current_date' not in response:
        message = 'Нет нужного ключа в ответе API!'
        raise KeyError(message)

    homeworks = response.get('homeworks')

    if not isinstance(homeworks, list):
        message = 'Формат данных по ключу "homeworks", не является списком!'
        raise TypeError(message)

    return homeworks

def parse_status(homework):
    """
    Парсим статус домашней работы.
    Содержащий один из вердиктов словаря HOMEWORK_VERDICTS.
    """
    homework_name = homework.get('homework_name')

    if 'homework_name' not in homework:
        message = 'В ответе API нет ключа "homework_name".'
        raise ParseError(message)

    status_work = homework.get('status')

    if 'status' not in homework:
        message = 'В ответе API отсутстует ключ "status".'
        raise ParseError(message)

    verdict = HOMEWORK_VERDICTS.get(status_work)

    if status_work not in HOMEWORK_VERDICTS:
        message = f'Неизвестный статус домашней работы: {status_work}'
        raise KeyError(message)

    return f'Изменился статус проверки работы "{homework_name}". {verdict}'

def send_message(bot, message):
    """Отправка сообщения в Telegram."""
    try:
        bot.send_message(
            chat_id=TELEGRAM_CHAT_ID,
            text=message,
        )
        logging.debug(f'Сообщение - "{message}", отправлено успешно')

    except telegram.error.TelegramError as error:
        message = f'Не удалось отправить сообщение из-за ошибки {error}'
        logging.error(message)
        raise AssertionError(message)

def main():
    """Основная логика работы бота."""
    if not check_tokens():
        logging.critical(
            'Отсутствуют переменные окружения',
            'Прогрмма принудительно остановлена!'
        )
        exit()

    bot = telegram.Bot(token=TELEGRAM_TOKEN)
    timestamp = int(time.time())
    old_status_homework = ''
    old_exception = ''

    while True:

        try:
            response_get_api = get_api_answer(timestamp)
            timestamp = response_get_api.get('current_date')
            homeworks = check_response(response_get_api)

            if not homeworks:
                message = 'Нет домашних работ'
                logging.debug(message)

            new_status_homework = parse_status(homeworks[0])

            if new_status_homework != old_status_homework:
                message = new_status_homework
                send_message(bot, message)
                old_status_homework = new_status_homework

        except Exception as error:
            message = f'Сбой в работе программы: {error}'
            logging.error(error.__context__)
            new_exception = message
            if new_exception != old_exception:
                send_message(bot, message)
                old_exception = new_exception

        finally:
            time.sleep(RETRY_PERIOD)

if __name__ == '__main__':
    logging.basicConfig(
        level=logging.DEBUG,
        format='%(asctime)s, %(levelname)s, %(message)s, %(name)s',
        stream=sys.stdout
    )
    main()


from django.core.management.base import BaseCommand, CommandError
from articles.queries import *
from articles.models import *

def is_unified(obj):
        exp_samples = obj.samples()
        has_empty_name = SampleAttribute.objects.filter(
          sample__in=exp_samples,
          unificated_name=None).exists()

        has_empty_value = SampleAttribute.objects.filter(
          sample__in=exp_samples,
          unificated_value=None).exists()
        if has_empty_name or has_empty_value:
            return False
        else:
            return True

class Command(BaseCommand):
    """
    """
    def handle(self, *args, **options):
        """
        command's hande method
        """

        exps = Experiment.objects.all()
        for exp in exps:
            if is_unified(exp):
                print(exp.data['accession'])