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

r"""
A tool for randomizing QA ordering in latex exams

Assumptions:
* Assumes all questions are of the form::

    \begin{problem}

        Text/etc to keep at top

        \begin{mchoice}
        Text/etc to keep at top

        \item (or \xtem) anwer choice text
        \item (or \xtem) anwer choice text
        .
        .
        .
        \item (or \xtem) anwer choice text
        \end{mchoice}
    \end{problem}

Usage
-----
If using a master file whose sections are fetched with `input{}`
statements, use the `-m` flag. E.g.::

    $ python randomize.py -m test/base.tex

To randomize the problems and answers in a file with no fixed sections,
omit the `-m` flag.  E.g.::

    $ python randomize.py test/section_*.tex

For more options/help::

    $ python randomize.py -h

License
-------
MIT licensed (Andy Port, October 2018)
"""

from __future__ import print_function, unicode_literals
import os
import re
from random import shuffle
from time import time
from copy import copy

def latex_environment_pattern(env):
    r"""Returns `re` pattern for latex begin-end `env` environment blocks.

    The returned pattern can be used to search for blocks that look like
    ``\begin{`env`}NOT_WHITESPACE (...)\end{`env`}NOT_WHITESPACE``
    where, upon searching with the pattern, (...) will be the returned
    `re.match` object's `self.group(1)`.
    """
    return re.compile(r"[^\s]*\\begin{%s}[^\s]*(.*?)[^\s]*\\end{%s}[^\s]*" % (env, env), re.DOTALL)

def get_problems(filename, debug=False):
    """Get list of problems/answers, and template the full TeX.

    Returns
    -------
    list of problems
        Each problem is represented as a dictionary containing the full
        latex problem block, a list of "answers", and the "beginning"-
        and "ending"-matter that the answers must be sandwiched between
        to reconstruct the original TeX.
    string
        The full contents of `filename` with the problems repaced by
        unique identifiers.
    function
        Given k, returns the unique identifier of the kth problem.
        """
    question_pattern = latex_environment_pattern('problem')
    answer_pattern = latex_environment_pattern('mchoice')

    with open(filename, 'r') as f:
        tex = f.read()

    t = time()
    marker = lambda n: r'##%s-%s' % (int(t), str(n).zfill(6))

    problems = []
    for k, m in enumerate(question_pattern.finditer(tex)):
        problem = m.group()  # full TeX block

        # get answer section (the `\item`s and `\xtem`s)
        answer_section_start = re.search(r'\\xtem|\\item', problem).start()
        answer_section_end = answer_pattern.search(problem).end(1)
        answer_section = problem[answer_section_start: answer_section_end]

        # split answer sections, one entry per `\item` or `\xtem`
        delimiter = '#!%s!#' % t
        answer_choices = answer_section.replace(r'\xtem', delimiter + r'\xtem')
        answer_choices = answer_choices.replace(r'\item', delimiter + r'\item')
        answer_choices = answer_choices.split(delimiter)

        problems.append({'full_tex': problem,
                          'beginning': problem[:answer_section_start],
                          'ending': problem[answer_section_end:],
                          'answers': answer_choices})

        # remove problem from `tex` and leave marker
        tex = tex.replace(problem, marker(k))

    if debug:
        for p in problems:
            print(p['beginning'])
            for a in p['answers']:
                print(a)
            print(p['ending'])
            print('\n\n---\n')
        print("Marked `tex`")
        print(tex)

    return problems, tex, marker

def randomize(problem_list, fix_questions=False, fix_answers=False):
    if not fix_questions:
        shuffle(problem_list)
    if not fix_answers:
        for p in problem_list:
            shuffle(p['answers'])
    return problem_list

def postfix_tag(k, num_versions):
    if num_versions <= 26:
        tags = 'abcdefghijklmnopqrstuvwxyz'
    else:
        tags = map(str, range(num_versions))
    return '_ver_' + tags[k]

def generate_randomized_versions(tex_file, num_versions=4,
                                 output_dir=os.getcwd(),
                                 fix_questions=False,
                                 fix_answers=False, debug=False):

    problems, tex, marker = get_problems(filename=tex_file, debug=debug)

    name, ext = os.path.splitext(os.path.basename(tex_file))
    for iv in range(num_versions):
        problems = randomize(problems, fix_questions, fix_answers)
        version_filename = \
            os.path.join(output_dir, name + postfix_tag(iv, num_versions) + ext)
        version_tex = copy(tex)

        for k, p in enumerate(problems):
            p_block = p['beginning'] + ''.join(p['answers']) + p['ending']
            version_tex = version_tex.replace(marker(k), p_block)
        with open(version_filename, 'w+') as f:
            f.write(version_tex)
        print('"%s" created' % version_filename)

    if debug:
        with open(os.path.join(output_dir, 'debug_marked.tex'), 'w') as f:
            f.write(tex)

def generate_randomized_versions_multi(tex_files, num_versions=4,
                                 output_dir=os.getcwd(), fix_questions=False,
                                 fix_answers=False, debug=False):
    for tex_file in tex_files:
        generate_randomized_versions(tex_file=tex_file,
                                     num_versions=num_versions,
                                     output_dir=output_dir,
                                     fix_questions=fix_questions,
                                     fix_answers=fix_answers,
                                     debug=debug)

def generate_new_masters(master_filename, num_versions=4,
                         output_dir=os.getcwd()):

    with open(master_filename, 'r') as f:
        tex = f.read()

    _cw = os.getcwd()
    os.chdir(os.path.dirname(os.path.abspath(master_filename)))
    input_files = [m.group(1) for m in re.finditer(r'\input\{(.*?)\}', tex)]
    input_files_abs = [os.path.abspath(fn) for fn in input_files]
    os.chdir(_cw)

    name, ext = os.path.splitext(os.path.basename(master_filename))
    for iv in range(num_versions):
        postfix = postfix_tag(iv, num_versions)
        version_tex = copy(tex)

        for fn in input_files:
            fn_base, fn_ext = os.path.splitext(os.path.basename(fn))
            version_tex = version_tex.replace(fn, fn_base + postfix + fn_ext)

        version_master_filename = os.path.join(output_dir, name + postfix + ext)
        with open(version_master_filename, 'w') as f:
            f.write(version_tex)
        print(output_dir)
        print('"%s" created' % version_master_filename)
    return input_files_abs

if __name__ == '__main__':
    import argparse
    args = argparse.ArgumentParser()
    args.add_argument('tex_files', nargs='+',
                      help="The TeX file(s) to randomize (wildcards allowed).")
    args.add_argument('-n', '--num_versions', default=4,
                      type=int, help="The number of versions to generate.")
    args.add_argument('-o', '--output_dir', default=os.getcwd(),
                      help="directory to store output.")
    args.add_argument('-q', '--fix_questions', default=False,
                      action='store_false',
                      help="Invoke to prevent randomization of questions.")
    args.add_argument('-a', '--fix_answers', default=False,
                      action='store_true',
                      help="Invoke to prevent randomization the answers.")
    args.add_argument('-m', '--master', default=False,
                      action='store_true',
                      help="The input document is assumed to be a master "
                           "document. Randomized versions of `\input{}` "
                           "statements will generated to be used by generated "
                           "versions of the master.")
    args.add_argument('-d', '--debug', default=False,
                      action='store_true',
                      help="Turn on debugging output.")
    args = vars(args.parse_args())

    if args['fix_answers'] and args['fix_questions']:
        raise ValueError(
            "Invoking `-qa` fixes both questions and answers -- meaning "
            "generated versions would be identical to originals.")

    if args.pop('master'):
        assert len(args['tex_files']) == 1, \
            "If '-m' is invoked, only one master file can be input"
        master_filename = args.pop('tex_files')[0]
        input_files = generate_new_masters(master_filename,
                                           num_versions=args['num_versions'],
                                           output_dir=args['output_dir'])

        print("Randomizing:", ', '.join(input_files))
        generate_randomized_versions_multi(input_files, **args)
    else:
        print("Randomizing:", ', '.join(args['tex_files']))
        generate_randomized_versions_multi(**args)


#!/usr/bin/python

import tweepy, sys

#Récupération des arguments de la commande
arguments = sys.argv
texte = arguments[1]
mediaAUpluoad = arguments[2]

#Identifiants API
API_KEY = ''
API_secret = ''
BAERER_TOKEN = ''
access_token = ''
access_token_secret = ''

#Connexion API
auth = tweepy.OAuthHandler(API_KEY, API_secret)
auth.set_access_token(access_token, access_token_secret)
api = tweepy.API(auth)

#Fonctions de Tweet
def post_tweet(text):
    response = api.update_status(text)
    return response

def upload_media(text, filename):
    media = api.media_upload(filename)
    response = api.update_status(text, media_ids=[media.media_id_string])
    return response

print(upload_media(texte, mediaAUpluoad))


from question_model import Question
from data import question_data
from quiz_brain import QuizBrain

question_bank = []

#Creando una lista de objetos
for elemento_lista in question_data:
    question_bank.append(Question(elemento_lista["question"], elemento_lista["correct_answer"]))

#Imprimiendo el objeto dentro de la lista con atributo text
# print(question_bank[1].text)

quiz = QuizBrain(question_bank)
while quiz.still_has_questions():
    quiz.next_question()

print("Terminaste el quiz")
print(f"Tu puntaje final es: {quiz.puntaje}/{quiz.question_number}")


# -*- coding: utf-8 -*-
"""
Load or train and then evaluates a ResNet on CIFAR10 like defined in the paper [1]
The training can be done with a grid search along learning rate (lr_lst) and epochs (nb_epochs_lst)
To train just a network do agrid search along 1 parameter in each

The ResNet structure and the pretrained models come from https://github.com/akamaster/pytorch_resnet_cifar10

Similar accuracy obtained w.r.t. the paper in this online version
Additionnaly, a resNet110 has been retrained from scratch and obtained similar performance than paper
However, the main difference is that here we train with 50k on train and 10 on test where as on the
paper they also used a validation dataset. See other small differences on the GitHub

Based on:
    [1] Kaiming He, Xiangyu Zhang, Shaoqing Ren, Jian Sun
        Deep Residual Learning for Image Recognition. arXiv:1512.03385
"""

# ----- Libraries ----- #
#Pytorch
import torch
import torch.nn as nn
from torchvision import datasets
import torchvision.transforms as transforms
import torch.optim as optim
#ResNet
import resnet
#Utils
import time
import numpy as np

# ----- Constants & Parameters ----- #
#Pretrain or train network
download_pretrained_net = True  #use pretrained model or start from scratch
skip_train = True               #skip the training (directly test the network)

#Network
resnet_size = 20                #select the size of the ResNet
NET_PATH = "pretrained_models/"
saved_net_name = {  '20': 'resnet20-12fca82f.th',
                    '32': 'resnet32-d509ac18.th',
                    '44': 'resnet44-014dd654.th',
                    '56': 'resnet56-4bfd9763.th',
                    '110': 'resnet110-1d1ed7c2.th',
                    '1202': 'resnet1202-f3b1deed.th'}

#Preprocessing
crop_values = [32, 4]           #crop: 4 pixels padded and then crop to 32x32 (from [1])

#Training infos
batch_size = 128                #batch size from [1]
lr_lst = [1e-1]                 #lr used in the [1] (for 20,32,44 !SPECIAL CARE FOR 110&1202)
nb_epochs_lst = [165]           #deduced nb of epochs from [1]
momentum = 0.9                  #SGD momentum from [1]
wd = 0.0001                     #weight decay from [1]
gamma = 0.1                     #lr decay [1]
lr_milestones = [80, 120]       #milestones for lr decay deduced from [1]
#Only for big networks
lr_decay_big_net = 0.1          #for big net the lr starts lower (from [1])
train_perf_lr_up_big_net = 0.8  #performance to reincrease the lr of big net (from [1])
lr_upgrade_done = False         #keep in track if the lr upgrade has been done (from [1])

#Datasets stats
cifar_mean = [0.485, 0.456, 0.406]
cifar_std = [0.229, 0.224, 0.225]

#GPU infos
use_cuda = torch.cuda.is_available()  # not no_cuda and
device = torch.device("cuda" if use_cuda else "cpu")
kwargs = {'num_workers': 1, 'pin_memory': True} if use_cuda else {}
torch.set_num_threads(1)

#Utils
loss_dsp_rate = 500
SAVE_PATH = "resNet"+str(resnet_size)+"/"

# ----- Functions ----- #
def nb_param_model(model):
    #Return the nb of trainable parameters of a model
    return sum(p.numel() for p in model.parameters() if p.requires_grad)

# ----- Loading and preprocessing the data ----- #
#Transformations
preprocess_train = transforms.Compose([
    transforms.RandomHorizontalFlip(),
    transforms.RandomCrop(crop_values[0], crop_values[1]),
    transforms.ToTensor(),
    transforms.Normalize(mean=cifar_mean, std=cifar_std)
])
preprocess_test = transforms.Compose([
    transforms.ToTensor(),
    transforms.Normalize(mean=cifar_mean, std=cifar_std)
])

#Load data
train_loader = torch.utils.data.DataLoader(datasets.CIFAR10('../data', train=True, download=True,
                                    transform=preprocess_train),
                                    batch_size=batch_size, shuffle=True, **kwargs)
test_loader = torch.utils.data.DataLoader(datasets.CIFAR10('../data', train=False,
                                    transform=preprocess_test),
                                    batch_size=batch_size, shuffle=False, **kwargs)

# ----- Grid search ----- #
print("Resnet size: "+str(resnet_size))
print("Pretrained: "+str(download_pretrained_net))
print("Will be trained: "+str(not skip_train))

#Create variables for saving
train_acc_lst = np.zeros((len(lr_lst),len(nb_epochs_lst)))
test_acc_lst = np.zeros((len(lr_lst),len(nb_epochs_lst)))
train_loss_lst = np.zeros((len(lr_lst),len(nb_epochs_lst)))
test_loss_lst = np.zeros((len(lr_lst),len(nb_epochs_lst)))
if len(lr_lst) == 1 and len(nb_epochs_lst) == 1:
    train_loss_evolv = np.zeros(int(nb_epochs_lst[0]))

for lr_i, lr in enumerate(lr_lst):
    for e_i, nb_epochs in enumerate(nb_epochs_lst):
        print("Learning rate at "+str(lr)+" and number of epochs at "+str(nb_epochs))
        # ----- Define the problem (model, optimiser, ...)
        #Create the model
        resNet = torch.nn.DataParallel(resnet.__dict__["resnet"+str(resnet_size)](),device_ids=[0])
        resNet.to(device)
        print("This ResNet has "+str(nb_param_model(resNet))+" parameters")

        #Load the pretrained model
        if download_pretrained_net:
            saved_data = torch.load(NET_PATH+saved_net_name[str(resnet_size)],
                                    map_location=torch.device(device))
            resNet.load_state_dict(saved_data['state_dict'])

        #Loss fct
        criterion = nn.CrossEntropyLoss().to(device)

        #Optimiser
        optimizer = optim.SGD(resNet.parameters(), lr=lr, momentum=momentum, weight_decay=wd)

        #LR modification
        lr_scheduler = torch.optim.lr_scheduler.MultiStepLR(optimizer, milestones=lr_milestones,gamma=gamma)

        #Big resnet have a different lr
        if resnet_size >=110:
            for param_group in optimizer.param_groups:
                param_group['lr'] = lr*lr_decay_big_net

        if not skip_train:
            # ----- Train the model ----- #
            print("\nProblem with "+str(nb_epochs)+" epochs and "+str(lr)+" as lr")
            print("TRAINING START")
            start_train = time.time()
            resNet.train()
            for epoch in range(int(nb_epochs)):
                for batch_idx, (data, target) in enumerate(train_loader):
                    data, target = data.requires_grad_().to(device), target.to(device)
                    optimizer.zero_grad()
                    output = resNet(data)
                    loss = criterion(output ,target)
                    loss.backward()
                    optimizer.step()

                    if(batch_idx%loss_dsp_rate)==0:
                        print("At epoch "+str(epoch)+" and batch_idx "+str(batch_idx)+" loss is "+str(loss.item()))

                #for big network if good performance has been obtained go to normal lr
                if resnet_size >=110 and not lr_upgrade_done:
                    correct = 0
                    with torch.no_grad():
                        for data, target in train_loader:
                            data, target = data.to(device), target.to(device)
                            output = resNet(data)
                            pred = output.argmax(dim=1, keepdim=True)
                            correct += pred.eq(target.view_as(pred)).sum().item()
                    train_acc = correct/len(train_loader.dataset)

                    if train_acc > train_perf_lr_up_big_net:
                        for param_group in optimizer.param_groups:
                            param_group['lr'] = lr
                        lr_upgrade_done = True
                        print("Upgrade of lr done")
                    else:
                        print("Upgrade of lr not done for now, acc is "+str(train_acc))

                lr_scheduler.step()

                #save value of the loss if not grid search
                if len(lr_lst) == 1 and len(nb_epochs_lst) == 1:
                    train_loss_evolv[epoch] = loss

            finish_train = time.time()
            print("The training lasted "+str(finish_train-start_train)+" s")

        # ----- Test the model ----- #
        print("TESTING START")
        #On the training dataset
        resNet.eval()
        train_loss = 0
        correct = 0
        with torch.no_grad():
            for data, target in train_loader:
                data, target = data.to(device), target.to(device)
                output = resNet(data)
                train_loss += criterion(output, target).item()  # sum up batch loss
                pred = output.argmax(dim=1, keepdim=True)  # get the index of the max log-probability
                correct += pred.eq(target.view_as(pred)).sum().item()
        train_loss /= len(train_loader.dataset)
        train_acc = correct/len(train_loader.dataset)

        #On the testing dataset
        resNet.eval()
        test_loss = 0
        correct = 0
        with torch.no_grad():
            for data, target in test_loader:
                data, target = data.to(device), target.to(device)
                output = resNet(data)
                test_loss += criterion(output, target).item()  # sum up batch loss
                pred = output.argmax(dim=1, keepdim=True)  # get the index of the max log-probability
                correct += pred.eq(target.view_as(pred)).sum().item()
        test_loss /= len(test_loader.dataset)
        test_acc = correct/len(test_loader.dataset)

        #Stock the results
        train_acc_lst[lr_i][e_i] = train_acc
        test_acc_lst[lr_i][e_i] = test_acc
        train_loss_lst[lr_i][e_i] = train_loss
        test_loss_lst[lr_i][e_i] = test_loss

        #Display the result
        print("Train accuracy is "+str(train_acc))
        print("Train loss is "+str(train_loss))
        print("Test accuracy is "+str(test_acc))
        print("Test loss is "+str(test_loss))

#Save results
np.save(SAVE_PATH+"nb_epochs_lst.npy", nb_epochs_lst)
np.save(SAVE_PATH+"lr_lst.npy", lr_lst)
np.save(SAVE_PATH+"train_loss.npy", train_loss_lst)
np.save(SAVE_PATH+"test_loss.npy", test_acc_lst)
np.save(SAVE_PATH+"train_acc.npy", train_acc_lst)
np.save(SAVE_PATH+"test_acc.npy", test_acc_lst)
if len(lr_lst) == 1 and len(nb_epochs_lst) == 1:
    np.save(SAVE_PATH+"train_loss_evolv.npy", train_loss_evolv)


#!/usr/bin/python
#
# Utility script to copy the pictures to the correct directory in the correct format
#
# Usage:
#    ./copy-pictures.py -s /tmp/pictures/ -t site/static/static/pictures/
import os
import sys
import re
import argparse
from shutil import copyfile

def _parse_args(argv):
    parser = argparse.ArgumentParser(description='Copy pictures and normalize file names')
    parser.add_argument('-s', '--source', required=True,
                        help='Source directory')
    parser.add_argument('-t', '--target', required=True,
                        help='Source directory')

    args = parser.parse_args()
    source_dir = args.source
    target_dir = args.target
    return source_dir, target_dir

def main(argv):
    # p = re.compile('A\. Confinamiento(\d*)\.png')
    p = re.compile('A\. Confinamiento movil(\d*)\.png')
    source_dir, target_dir = _parse_args(argv)
    for file in os.listdir(source_dir):
        match = p.match(file)
        if match:
            count = int(match.group(1) or 1)
            source_path = os.path.join(source_dir, file)
            target_file = 'picture-%s.png' % count
            target_path = os.path.join(target_dir, target_file)
            print("Copying '%s' to '%s'" % (source_path, target_path))
            copyfile(source_path, target_path)

if __name__ == "__main__":
    main(sys.argv[1:])


import traceback

from logging import WARNING as _WARNING
from logging import getLogger
from threading import Timer as _Timer

from gi.repository import Gdk, GLib, Gtk
from logitech_receiver.settings import KIND as _SETTING_KIND
from logitech_receiver.settings import SENSITIVITY_IGNORE as _SENSITIVITY_IGNORE
from solaar.i18n import _, ngettext
from solaar.ui import ui_async as _ui_async

_log = getLogger(__name__)
del getLogger

#
#
#

def _read_async(setting, force_read, sbox, device_is_online, sensitive):

    def _do_read(s, force, sb, online, sensitive):
        v = s.read(not force)
        GLib.idle_add(_update_setting_item, sb, v, online, sensitive, priority=99)

    _ui_async(_do_read, setting, force_read, sbox, device_is_online, sensitive)

def _write_async(setting, value, sbox, sensitive=True, key=None):

    def _do_write(s, v, sb, key):
        try:
            if key is None:
                v = setting.write(v)
            else:
                v = setting.write_key_value(key, v)
                v = {key: v}
        except Exception:
            traceback.print_exc()
            v = None
        if sb:
            GLib.idle_add(_update_setting_item, sb, v, True, sensitive, priority=99)

    if sbox:
        sbox._control.set_sensitive(False)
        sbox._failed.set_visible(False)
        sbox._spinner.set_visible(True)
        sbox._spinner.start()
    _ui_async(_do_write, setting, value, sbox, key)

#
#
#

class Control():

    def __init__(**kwargs):
        pass

    def init(self, sbox, delegate):
        self.sbox = sbox
        self.delegate = delegate if delegate else self

    def changed(self, *args):
        if self.get_sensitive():
            self.delegate.update()

    def update(self):
        _write_async(self.sbox.setting, self.get_value(), self.sbox)

    def layout(self, sbox, label, change, spinner, failed):
        sbox.pack_start(label, False, False, 0)
        sbox.pack_end(change, False, False, 0)
        sbox.pack_end(self, sbox.setting.kind == _SETTING_KIND.range, sbox.setting.kind == _SETTING_KIND.range, 0)
        sbox.pack_end(spinner, False, False, 0)
        sbox.pack_end(failed, False, False, 0)
        return self

class ToggleControl(Gtk.Switch, Control):

    def __init__(self, sbox, delegate=None):
        super().__init__(halign=Gtk.Align.CENTER, valign=Gtk.Align.CENTER)
        self.init(sbox, delegate)
        self.connect('notify::active', self.changed)

    def set_value(self, value):
        self.set_state(value)

    def get_value(self):
        return self.get_state()

class SliderControl(Gtk.Scale, Control):

    def __init__(self, sbox, delegate=None):
        super().__init__(halign=Gtk.Align.FILL)
        self.init(sbox, delegate)
        self.timer = None
        self.set_range(*self.sbox.setting.range)
        self.set_round_digits(0)
        self.set_digits(0)
        self.set_increments(1, 5)
        self.connect('value-changed', self.changed)

    def get_value(self):
        return int(super().get_value())

    def changed(self, *args):
        if self.get_sensitive():
            if self.timer:
                self.timer.cancel()
            self.timer = _Timer(0.5, lambda: GLib.idle_add(self.do_change))
            self.timer.start()

    def do_change(self):
        self.timer.cancel()
        self.update()

def _create_choice_control(sbox, delegate=None, choices=None):
    if 50 > len(choices if choices else sbox.setting.choices):
        return ChoiceControlLittle(sbox, choices=choices, delegate=delegate)
    else:
        return ChoiceControlBig(sbox, choices=choices, delegate=delegate)

# GTK boxes have property lists, but the keys must be strings
class ChoiceControlLittle(Gtk.ComboBoxText, Control):

    def __init__(self, sbox, delegate=None, choices=None):
        super().__init__(halign=Gtk.Align.FILL)
        self.init(sbox, delegate)
        self.choices = choices if choices is not None else sbox.setting.choices
        for entry in self.choices:
            self.append(str(int(entry)), str(entry))
        self.connect('changed', self.changed)

    def get_value(self):
        return int(self.get_active_id()) if self.get_active_id() is not None else None

    def set_value(self, value):
        self.set_active_id(str(int(value)))

    def get_choice(self):
        id = self.get_value()
        return next((x for x in self.choices if x == id), None)

    def set_choices(self, choices):
        self.remove_all()
        for choice in choices:
            self.append(str(int(choice)), _(str(choice)))

class ChoiceControlBig(Gtk.Entry, Control):

    def __init__(self, sbox, delegate=None, choices=None):
        super().__init__(halign=Gtk.Align.FILL)
        self.init(sbox, delegate)
        self.choices = choices if choices is not None else sbox.setting.choices
        self.value = None
        self.set_width_chars(max([len(str(x)) for x in self.choices]) + 5)
        liststore = Gtk.ListStore(int, str)
        for v in self.choices:
            liststore.append((int(v), str(v)))
        completion = Gtk.EntryCompletion()
        completion.set_model(liststore)
        norm = lambda s: s.replace('_', '').replace(' ', '').lower()
        completion.set_match_func(lambda completion, key, it: norm(key) in norm(completion.get_model()[it][1]))
        completion.set_text_column(1)
        self.set_completion(completion)
        self.connect('changed', self.changed)
        self.connect('activate', self.activate)
        completion.connect('match_selected', self.select)

    def get_value(self):
        choice = self.get_choice()
        return int(choice) if choice is not None else None

    def set_value(self, value):
        self.set_text(str(next((x for x in self.choices if x == value), None)))

    def get_choice(self):
        key = self.get_text()
        return next((x for x in self.choices if x == key), None)

    def changed(self, *args):
        self.value = self.get_choice()
        icon = 'dialog-warning' if self.value is None else 'dialog-question' if self.get_sensitive() else ''
        self.set_icon_from_icon_name(Gtk.EntryIconPosition.SECONDARY, icon)
        tooltip = _('Incomplete') if self.value is None else _('Complete - ENTER to change')
        self.set_icon_tooltip_text(Gtk.EntryIconPosition.SECONDARY, tooltip)

    def activate(self, *args):
        if self.value is not None and self.get_sensitive():
            self.set_icon_from_icon_name(Gtk.EntryIconPosition.SECONDARY, '')
            self.delegate.update()

    def select(self, completion, model, iter):
        self.set_value(model.get(iter, 0)[0])
        if self.value and self.get_sensitive():
            self.set_icon_from_icon_name(Gtk.EntryIconPosition.SECONDARY, '')
            self.delegate.update()

class MapChoiceControl(Gtk.HBox, Control):

    def __init__(self, sbox, delegate=None):
        super().__init__(homogeneous=False, spacing=6)
        self.init(sbox, delegate)
        self.keyBox = Gtk.ComboBoxText()
        for entry in sbox.setting.choices:
            self.keyBox.append(str(int(entry)), _(str(entry)))
        self.keyBox.set_active(0)
        key_choice = int(self.keyBox.get_active_id())
        self.value_choices = self.sbox.setting.choices[key_choice]
        self.valueBox = _create_choice_control(sbox.setting, choices=self.value_choices, delegate=self)
        self.pack_start(self.keyBox, False, False, 0)
        self.pack_end(self.valueBox, False, False, 0)
        self.keyBox.connect('changed', self.map_value_notify_key)

    def get_value(self):
        key_choice = int(self.keyBox.get_active_id())
        if key_choice is not None and self.valueBox.get_value() is not None:
            return self.valueBox.get_value()

    def set_value(self, value):
        self.valueBox.set_sensitive(self.get_sensitive())
        key = int(self.keyBox.get_active_id())
        if value.get(key) is not None:
            self.valueBox.set_value(value.get(key))
        self.valueBox.set_sensitive(True)

    def map_populate_value_box(self, key_choice):
        choices = self.sbox.setting.choices[key_choice]
        if choices != self.value_choices:
            self.value_choices = choices
            self.valueBox.remove_all()
            self.valueBox.set_choices(choices)
        current = self.sbox.setting._value.get(key_choice) if self.sbox.setting._value else None
        if current is not None:
            self.valueBox.set_value(current)

    def map_value_notify_key(self, *args):
        key_choice = int(self.keyBox.get_active_id())
        if self.keyBox.get_sensitive():
            self.map_populate_value_box(key_choice)

    def update(self):
        key_choice = int(self.keyBox.get_active_id())
        value = self.get_value()
        if value is not None and self.valueBox.get_sensitive() and self.sbox.setting._value.get(key_choice) != value:
            self.sbox.setting._value[int(key_choice)] = value
            _write_async(self.sbox.setting, value, self.sbox, key=int(key_choice))

class MultipleControl(Gtk.ListBox, Control):

    def __init__(self, sbox, change, button_label='...', delegate=None):
        super().__init__()
        self.init(sbox, delegate)
        self.set_selection_mode(Gtk.SelectionMode.NONE)
        self.set_no_show_all(True)
        self._showing = True
        self.setup(sbox.setting)  # set up the data and boxes for the sub-controls
        btn = Gtk.Button(button_label)
        btn.set_alignment(1.0, 0.5)
        btn.connect('clicked', self.toggle_display)
        self._button = btn
        hbox = Gtk.HBox(homogeneous=False, spacing=6)
        hbox.pack_end(change, False, False, 0)
        hbox.pack_end(btn, False, False, 0)
        self._header = hbox
        vbox = Gtk.VBox(homogeneous=False, spacing=6)
        vbox.pack_start(hbox, True, True, 0)
        vbox.pack_end(self, True, True, 0)
        self.vbox = vbox
        self.toggle_display()
        _disable_listbox_highlight_bg(self)

    def layout(self, sbox, label, change, spinner, failed):
        self._header.pack_start(label, False, False, 0)
        self._header.pack_end(spinner, False, False, 0)
        self._header.pack_end(failed, False, False, 0)
        sbox.pack_start(self.vbox, True, True, 0)
        sbox._button = self._button
        return True

    def toggle_display(self, *args):
        self._showing = not self._showing
        if not self._showing:
            for c in self.get_children():
                c.hide()
            self.hide()
        else:
            self.show()
            for c in self.get_children():
                c.show_all()

class MultipleToggleControl(MultipleControl):

    def setup(self, setting):
        self._label_control_pairs = []
        for k in setting._validator.get_options():
            h = Gtk.HBox(homogeneous=False, spacing=0)
            lbl_text = str(k)
            lbl_tooltip = None
            if hasattr(setting, '_labels'):
                l1, l2 = setting._labels.get(k, (None, None))
                lbl_text = l1 if l1 else lbl_text
                lbl_tooltip = l2 if l2 else lbl_tooltip
            lbl = Gtk.Label(lbl_text)
            h.set_tooltip_text(lbl_tooltip or ' ')
            control = Gtk.Switch()
            control._setting_key = int(k)
            control.connect('notify::active', self.toggle_notify)
            h.pack_start(lbl, False, False, 0)
            h.pack_end(control, False, False, 0)
            lbl.set_alignment(0.0, 0.5)
            lbl.set_margin_left(30)
            self.add(h)
            self._label_control_pairs.append((lbl, control))

    def toggle_notify(self, switch, active):
        if switch.get_sensitive():
            key = switch._setting_key
            new_state = switch.get_state()
            if self.sbox.setting._value[key] != new_state:
                self.sbox.setting._value[key] = new_state
                _write_async(self.sbox.setting, new_state, self.sbox, key=int(key))

    def set_value(self, value):
        active = 0
        total = len(self._label_control_pairs)
        to_join = []
        for lbl, elem in self._label_control_pairs:
            v = value.get(elem._setting_key, None)
            if v is not None:
                elem.set_state(v)
            if elem.get_state():
                active += 1
            to_join.append(lbl.get_text() + ': ' + str(elem.get_state()))
        b = ', '.join(to_join)
        self._button.set_label(f'{active} / {total}')
        self._button.set_tooltip_text(b)

class MultipleRangeControl(MultipleControl):

    def setup(self, setting):
        self._items = []
        for item in setting._validator.items:
            lbl_text = str(item)
            lbl_tooltip = None
            if hasattr(setting, '_labels'):
                l1, l2 = setting._labels.get(int(item), (None, None))
                lbl_text = l1 if l1 else lbl_text
                lbl_tooltip = l2 if l2 else lbl_tooltip
            item_lbl = Gtk.Label(lbl_text)
            self.add(item_lbl)
            self.set_tooltip_text(lbl_tooltip or ' ')
            item_lb = Gtk.ListBox()
            item_lb.set_selection_mode(Gtk.SelectionMode.NONE)
            item_lb._sub_items = []
            for sub_item in setting._validator.sub_items[item]:
                h = Gtk.HBox(homogeneous=False, spacing=20)
                lbl_text = str(sub_item)
                lbl_tooltip = None
                if hasattr(setting, '_labels_sub'):
                    l1, l2 = setting._labels_sub.get(str(sub_item), (None, None))
                    lbl_text = l1 if l1 else lbl_text
                    lbl_tooltip = l2 if l2 else lbl_tooltip
                sub_item_lbl = Gtk.Label(lbl_text)
                h.set_tooltip_text(lbl_tooltip or ' ')
                h.pack_start(sub_item_lbl, False, False, 0)
                sub_item_lbl.set_margin_left(30)
                sub_item_lbl.set_alignment(0.0, 0.5)
                if sub_item.widget == 'Scale':
                    control = Gtk.Scale.new_with_range(Gtk.Orientation.HORIZONTAL, sub_item.minimum, sub_item.maximum, 1)
                    control.set_round_digits(0)
                    control.set_digits(0)
                    h.pack_end(control, True, True, 0)
                elif sub_item.widget == 'SpinButton':
                    control = Gtk.SpinButton.new_with_range(sub_item.minimum, sub_item.maximum, 1)
                    control.set_digits(0)
                    h.pack_end(control, False, False, 0)
                else:
                    raise NotImplementedError
                control.connect('value-changed', self.changed, item, sub_item)
                item_lb.add(h)
                h._setting_sub_item = sub_item
                h._label, h._control = sub_item_lbl, control
                item_lb._sub_items.append(h)
            item_lb._setting_item = item
            _disable_listbox_highlight_bg(item_lb)
            self.add(item_lb)
            self._items.append(item_lb)

    def changed(self, control, item, sub_item):
        if control.get_sensitive():
            if hasattr(control, '_timer'):
                control._timer.cancel()
            control._timer = _Timer(0.5, lambda: GLib.idle_add(self._write, control, item, sub_item))
            control._timer.start()

    def _write(self, control, item, sub_item):
        control._timer.cancel()
        delattr(control, '_timer')
        new_state = int(control.get_value())
        if self.sbox.setting._value[int(item)][str(sub_item)] != new_state:
            self.sbox.setting._value[int(item)][str(sub_item)] = new_state
            _write_async(self.sbox.setting, self.sbox.setting._value[int(item)], self.sbox, key=int(item))

    def set_value(self, value):
        b = ''
        n = 0
        for ch in self._items:
            item = ch._setting_item
            v = value.get(int(item), None)
            if v is not None:
                b += str(item) + ': ('
                to_join = []
                for c in ch._sub_items:
                    sub_item = c._setting_sub_item
                    try:
                        sub_item_value = v[str(sub_item)]
                    except KeyError:
                        sub_item_value = c._control.get_value()
                    c._control.set_value(sub_item_value)
                    n += 1
                    to_join.append(str(sub_item) + f'={sub_item_value}')
                b += ', '.join(to_join) + ') '
        lbl_text = ngettext('%d value', '%d values', n) % n
        self._button.set_label(lbl_text)
        self._button.set_tooltip_text(b)

class PackedRangeControl(MultipleRangeControl):

    def setup(self, setting):
        validator = setting._validator
        self._items = []
        for item in range(validator.count):
            h = Gtk.HBox(homogeneous=False, spacing=0)
            lbl = Gtk.Label(str(validator.keys[item]))
            control = Gtk.Scale.new_with_range(Gtk.Orientation.HORIZONTAL, validator.min_value, validator.max_value, 1)
            control.set_round_digits(0)
            control.set_digits(0)
            control.connect('value-changed', self.changed, validator.keys[item])
            h.pack_start(lbl, False, False, 0)
            h.pack_end(control, True, True, 0)
            h._setting_item = validator.keys[item]
            h.control = control
            lbl.set_alignment(0.0, 0.5)
            lbl.set_margin_left(30)
            self.add(h)
            self._items.append(h)

    def changed(self, control, item):
        if control.get_sensitive():
            if hasattr(control, '_timer'):
                control._timer.cancel()
            control._timer = _Timer(0.5, lambda: GLib.idle_add(self._write, control, item))
            control._timer.start()

    def _write(self, control, item):
        control._timer.cancel()
        delattr(control, '_timer')
        new_state = int(control.get_value())
        if self.sbox.setting._value[int(item)] != new_state:
            self.sbox.setting._value[int(item)] = new_state
            _write_async(self.sbox.setting, self.sbox.setting._value[int(item)], self.sbox, key=int(item))

    def set_value(self, value):
        b = ''
        n = len(self._items)
        for h in self._items:
            item = h._setting_item
            v = value.get(int(item), None)
            if v is not None:
                h.control.set_value(v)
            else:
                v = self.sbox.setting._value[int(item)]
            b += str(item) + ': (' + str(v) + ') '
        lbl_text = ngettext('%d value', '%d values', n) % n
        self._button.set_label(lbl_text)
        self._button.set_tooltip_text(b)

#
#
#

_allowables_icons = {True: 'changes-allow', False: 'changes-prevent', _SENSITIVITY_IGNORE: 'dialog-error'}
_allowables_tooltips = {
    True: _('Changes allowed'),
    False: _('No changes allowed'),
    _SENSITIVITY_IGNORE: _('Ignore this setting')
}
_next_allowable = {True: False, False: _SENSITIVITY_IGNORE, _SENSITIVITY_IGNORE: True}
_icons_allowables = {v: k for k, v in _allowables_icons.items()}

# clicking on the lock icon changes from changeable to unchangeable to ignore
def _change_click(button, sbox):
    icon = button.get_children()[0]
    icon_name, _ = icon.get_icon_name()
    allowed = _icons_allowables.get(icon_name, True)
    new_allowed = _next_allowable[allowed]
    sbox._control.set_sensitive(new_allowed is True)
    _change_icon(new_allowed, icon)
    if sbox.setting._device.persister:  # remember the new setting sensitivity
        sbox.setting._device.persister.set_sensitivity(sbox.setting.name, new_allowed)
    if allowed == _SENSITIVITY_IGNORE:  # update setting if it was being ignored
        setting = next((s for s in sbox.setting._device.settings if s.name == sbox.setting.name), None)
        if setting:
            persisted = sbox.setting._device.persister.get(setting.name) if sbox.setting._device.persister else None
            if setting.persist and persisted is not None:
                _write_async(setting, persisted, sbox)
            else:
                _read_async(setting, True, sbox, bool(sbox.setting._device.online), sbox._control.get_sensitive())
    return True

def _change_icon(allowed, icon):
    if allowed in _allowables_icons:
        icon._allowed = allowed
        icon.set_from_icon_name(_allowables_icons[allowed], Gtk.IconSize.LARGE_TOOLBAR)
        icon.set_tooltip_text(_allowables_tooltips[allowed])

def _create_sbox(s, device):
    sbox = Gtk.HBox(homogeneous=False, spacing=6)
    sbox.setting = s
    sbox.kind = s.kind
    if s.description:
        sbox.set_tooltip_text(s.description)
    lbl = Gtk.Label(s.label)
    lbl.set_alignment(0.0, 0.5)
    label = Gtk.EventBox()
    label.add(lbl)
    spinner = Gtk.Spinner()
    spinner.set_tooltip_text(_('Working') + '...')
    sbox._spinner = spinner
    failed = Gtk.Image.new_from_icon_name('dialog-warning', Gtk.IconSize.SMALL_TOOLBAR)
    failed.set_tooltip_text(_('Read/write operation failed.'))
    sbox._failed = failed
    change_icon = Gtk.Image.new_from_icon_name('changes-prevent', Gtk.IconSize.LARGE_TOOLBAR)
    sbox._change_icon = change_icon
    _change_icon(False, change_icon)
    change = Gtk.Button()
    change.set_relief(Gtk.ReliefStyle.NONE)
    change.add(change_icon)
    change.set_sensitive(True)
    change.connect('clicked', _change_click, sbox)

    if s.kind == _SETTING_KIND.toggle:
        control = ToggleControl(sbox)
    elif s.kind == _SETTING_KIND.range:
        control = SliderControl(sbox)
    elif s.kind == _SETTING_KIND.choice:
        control = _create_choice_control(sbox)
    elif s.kind == _SETTING_KIND.map_choice:
        control = MapChoiceControl(sbox)
    elif s.kind == _SETTING_KIND.multiple_toggle:
        control = MultipleToggleControl(sbox, change)
    elif s.kind == _SETTING_KIND.multiple_range:
        control = MultipleRangeControl(sbox, change)
    elif s.kind == _SETTING_KIND.packed_range:
        control = PackedRangeControl(sbox, change)
    else:
        if _log.isEnabledFor(_WARNING):
            _log.warn('setting %s display not implemented', s.label)
        return None

    control.set_sensitive(False)  # the first read will enable it
    control.layout(sbox, label, change, spinner, failed)
    sbox._control = control
    sbox.show_all()
    spinner.start()  # the first read will stop it
    failed.set_visible(False)
    return sbox

def _update_setting_item(sbox, value, is_online=True, sensitive=True):
    #    sbox._spinner.set_visible(False)   # don't repack item box
    sbox._spinner.stop()
    if value is None:
        sbox._control.set_sensitive(False)
        _change_icon(False, sbox._change_icon)
        sbox._failed.set_visible(is_online)
        return
    sbox._failed.set_visible(False)
    sbox._control.set_sensitive(False)
    sbox._control.set_value(value)
    sensitive = sbox._change_icon._allowed if sensitive is None else sensitive
    sbox._control.set_sensitive(sensitive is True)
    _change_icon(sensitive, sbox._change_icon)

def _disable_listbox_highlight_bg(lb):
    colour = Gdk.RGBA()
    colour.parse('rgba(0,0,0,0)')
    for child in lb.get_children():
        child.override_background_color(Gtk.StateFlags.PRELIGHT, colour)

#
#
#

# config panel
_box = None
_items = {}

def create():
    global _box
    assert _box is None
    _box = Gtk.VBox(homogeneous=False, spacing=8)
    _box._last_device = None

    config_scroll = Gtk.ScrolledWindow()
    config_scroll.add(_box)
    config_scroll.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC)
    config_scroll.set_shadow_type(Gtk.ShadowType.IN)
    config_scroll.set_size_request(0, 350)  # ask for enough vertical space for about eight settings

    return config_scroll

def update(device, is_online=None):
    assert _box is not None
    assert device
    device_id = (device.receiver.path if device.receiver else device.path, device.number)
    if is_online is None:
        is_online = bool(device.online)

    # if the device changed since last update, clear the box first
    if device_id != _box._last_device:
        _box.set_visible(False)
        _box._last_device = device_id

    # hide controls belonging to other devices
    for k, sbox in _items.items():
        sbox = _items[k]
        sbox.set_visible(k[0:2] == device_id)

    for s in device.settings:
        k = (device_id[0], device_id[1], s.name)
        if k in _items:
            sbox = _items[k]
        else:
            sbox = _create_sbox(s, device)
            if sbox is None:
                continue
            _items[k] = sbox
            _box.pack_start(sbox, False, False, 0)
        sensitive = device.persister.get_sensitivity(s.name) if device.persister else True
        _read_async(s, False, sbox, is_online, sensitive)

    _box.set_visible(True)

def clean(device):
    """Remove the controls for a given device serial.
    Needed after the device has been unpaired.
    """
    assert _box is not None
    device_id = (device.receiver.path if device.receiver else device.path, device.number)
    for k in list(_items.keys()):
        if k[0:2] == device_id:
            _box.remove(_items[k])
            del _items[k]

def destroy():
    global _box
    _box = None
    _items.clear()

def change_setting(device, setting, values):
    """External interface to change a setting and have the GUI show the change"""
    assert device == setting._device
    GLib.idle_add(_change_setting, device, setting, values, priority=99)

def _change_setting(device, setting, values):
    device_path = device.receiver.path if device.receiver else device.path
    if (device_path, device.number, setting.name) in _items:
        sbox = _items[(device_path, device.number, setting.name)]
    else:
        sbox = None
    _write_async(setting, values[-1], sbox, None, key=values[0] if len(values) > 1 else None)

def record_setting(device, setting, values):
    """External interface to record a setting that has changed on the device and have the GUI show the change"""
    assert device == setting._device
    GLib.idle_add(_record_setting, device, setting, values, priority=99)

def _record_setting(device, setting, values):
    if len(values) > 1:
        setting.update_key_value(values[0], values[-1])
        value = {values[0]: values[-1]}
    else:
        setting.update(values[-1])
        value = values[-1]
    device_path = device.receiver.path if device.receiver else device.path
    if (device_path, device.number, setting.name) in _items:
        sbox = _items[(device_path, device.number, setting.name)]
        if sbox:
            _update_setting_item(sbox, value)


from .database import DataBase

keyname = 'EC'
alternative_keynames = []

class EC(DataBase):

    def __init__(self, id=None):

        self.database = keyname
        self.name = 'EC'
        self.id = id
        self.web = 'https://iubmb.qmul.ac.uk/enzyme/'
        self.webid = 'https://enzyme.expasy.org/EC/{self.id}'
        self.info = 'Enzyme Commission number of the Nomenclature Committee of the International Union of Biochemistry and Molecular Biology (IUBMB) Database of Interacting Proteins'


import os
import re

import requests
from lxml import html
from selenium import webdriver

os.environ["webdriver.chrome.driver"] = "d:/py/chromedriver.exe"

from selenium.webdriver.common.desired_capabilities import DesiredCapabilities

dcap = dict(DesiredCapabilities.PHANTOMJS)
dcap["phantomjs.page.settings.userAgent"] = (
    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:25.0) Gecko/20100101 Firefox/25.0 "
)

dcap["phantomjs.page.settings.webSecurityEnabled"] = False
dcap["phantomjs.page.settings.loadImages"] = False
dcap["phantomjs.page.settings.diskCache"] = True
driver = webdriver.PhantomJS(executable_path="D:/py/phantomjs-2.1.1-windows/bin/phantomjs.exe",
                             desired_capabilities=dcap)

class Tool:
    def __init__(self, url, headers={}):
        resp = requests.get(url, headers)
        resp.encoding = 'utf8'
        text = resp.text.lower()
        text = re.sub(re.compile(' '), '', text)
        text = re.sub(re.compile('

|
|
'), '', text)
        self.page = html.fromstring(text)
        self.text = text

    def xpath(self, path):
        return self.page.xpath(path)

    def xpathOne(self, path):
        doms = self.page.xpath(path)
        if len(doms) > 0:
            return doms[0]
        else:
            return None

class PhantomJSTool:
    def __init__(self, url):
        driver.get(url)
        self.text = driver.page_source
        self.driver = driver
        text = re.sub(re.compile(' '), '', self.text)
        text = re.sub(re.compile('

|
|
'), '', text)
        self.page = html.fromstring(text)

    def getDriver(self):
        return self.driver

    def xpath(self, path):
        return self.page.xpath(path)

    def xpathOne(self, path):
        doms = self.page.xpath(path)
        if len(doms) > 0:
            return doms[0]
        else:
            return None

    def __str__(self):
        return self.text

class PicTool:
    def __init__(self, url, postdata, headers={}):
        s = requests.Session()
        r = s.post('http://m.1kkk.com/userdata.ashx', data=postdata)
        _cookies = r.cookies
        rs = s.get(url, headers=headers, cookies=_cookies)
        self.content = rs.content


def my_len(data):
    """
    求字符串长度
    :param data: 求出字符串的长度
    :return: 空的值
    """
    count = 0
    for i in data:
        count += 1

    print(f"字符串{data},的长度为:{count}")
    return None
# None 表示c 语言的void

str1 = "python"

my_len(str1)


import siliconcompiler
import os

from siliconcompiler.pdks import freepdk45
from siliconcompiler.flows import dvflow

def test_write_flowgraph_serial():

    ################################################
    # Serial
    ################################################

    chip = siliconcompiler.Chip('test')
    chip.load_target("freepdk45_demo")
    chip.write_flowgraph('serial.png')

    assert os.path.isfile('serial.png')

def test_write_flowgraph_forkjoin():

    ################################################
    # Fork-Join
    ################################################

    chip = siliconcompiler.Chip('test')
    chip.load_target("freepdk45_demo", syn_np=4, place_np=4, route_np=4)
    chip.write_flowgraph('forkjoin.png')

    assert os.path.isfile('forkjoin.png')

def test_write_flowgraph_pipes():

    ################################################
    # Pipes
    ################################################

    chip = siliconcompiler.Chip('test')
    chip.use(freepdk45)
    chip.use(dvflow, np=10)
    chip.set('option', 'flow', 'dvflow')
    chip.write_flowgraph('pipes.png')

    assert os.path.isfile('pipes.png')


import random

class Point:
    def __init__(self, x: int, y: int):
        self.x: int = x
        self.y: int = y
    def __eq__(self, other):
        return self.x == other.x and self.y == other.y

class Ship:
    def __init__(self, length: int, prow, direction: bool, lives: int):
        self.length: int = length
        self.prow = prow # Point() class, self.prow.x|y
        self.direction: bool = direction # True - vertical, False - horizontal
        self.lives: int = lives

    def get_points(self):
        points = []
        if self.direction:
            for i in range(self.length):
                points.append(Point(self.prow.x, self.prow.y + i))
        else:
            for i in range(self.length):
                points.append(Point(self.prow.x + i, self.prow.y))
        return points

class Field:
    def __init__(self, status: list, ships: list, hid: bool, alive_ships: int):
        self.status: list = status
        self.ships: list = ships
        self.hid: bool = hid
        self.alive_ships: int = alive_ships

    def show_field(self):
        print("    ", end = "")
        for i in range(6):
            print(i + 1, "| ", end = "")
        print()
        for i in range(6):
            print(i + 1, '| ', end = '')
            for j in range(6):
                if self.hid and self.status[j][i] == 'O':
                    print(' ', '| ', end = '')
                else:
                    print(self.status[j][i], '| ', end = '')
            print()

    def out(self, point):
        return point.x < 0 or point.x > 5 or point.y < 0 or point.y > 5

    def get_contour(self, ship):
        contour = []
        # ship.get_points()
        for point in ship.get_points():
            point_contour = [Point(point.x, point.y + 1),
                             Point(point.x, point.y - 1),
                             Point(point.x + 1, point.y),
                             Point(point.x - 1, point.y),
                             Point(point.x + 1, point.y + 1),
                             Point(point.x - 1, point.y + 1),
                             Point(point.x + 1, point.y - 1),
                             Point(point.x - 1, point.y - 1)]
            for each_point in point_contour:
                if not each_point in contour and not each_point in ship.get_points():
                    contour.append(each_point)
        return contour

    def used(self, point):
        try:
            return self.status[point.x][point.y] == 'O'
        except IndexError:
            pass

    def add_ship(self, ship):
        contour = self.get_contour(ship)
        for point in ship.get_points():
            try:
                if self.out(point) or self.used(point):
                    raise PointError()
                for contour_point in contour:
                    if self.used(contour_point):
                        raise PointError()
            except PointError:
                return False
        for point in ship.get_points():
            self.status[point.x][point.y] = 'O'
        return True

    def shot(self, point):
        try:
            char = self.status[point.x][point.y]
            if char in ['.', 'X'] or self.out(point):
                raise ShotError
        except ShotError:
            return False
        else:
            return True

class Player:
    def __init__(self, user_field, ai_field):
        self.user_field = user_field
        self.ai_field = ai_field

    def ask(self):
        pass

    def move(self, field):
        while True:
            point = self.ask()
            if field.shot(point):
                break
        if field.status[point.x][point.y] == 'O':
            field.status[point.x][point.y] = 'X'
            return True
        else:
            field.status[point.x][point.y] = '.'
            return False

class Ai(Player):
    def ask(self):
       return Point(random.randint(0, 5), random.randint(0, 5))

class User(Player):
    def ask(self):
        while True:
            try:
                x = int(input('Enter x:'))
                y = int(input('Enter y:'))
                return Point(x - 1, y - 1)
            except:
                continue

class Game:
    def get_random_ship(self, size, points):
        prow = random.choice(points)
        self.ship = Ship(size, prow, bool(random.randint(0, 1)), size)
        return self.ship

    def random_field(self):
        field = Field(status=[[' ' for _ in range(6)] for _ in range(6)], ships = [], hid = False, alive_ships = 11)
        field_points = []
        for i in range(6):
            for j in range(6):
                field_points.append(Point(j, i))
        lengths = [3, 2, 2, 1, 1, 1, 1]
        i = 0
        for length in lengths:
            while True:
                i += 1
                if i > 5000:
                    return None
                ship = self.get_random_ship(size = length, points = field_points)
                add_ship = field.add_ship(ship)
                if add_ship:
                    break
        return field

    def get_field(self):
        field = None
        while field is None:
            field = self.random_field()
        return field

    def greet(self):
        print('Hello!')
        print('Enter x and y to shot')

    def loop(self):
        ai_field = self.get_field()
        ai_field.hid = True
        print('ai field:')
        ai_field.show_field()
        print('---')
        user_field = self.get_field()
        print('user field:')
        user_field.show_field()
        print('---')
        ai = Ai(user_field = ai_field, ai_field = user_field)
        user = User(user_field = user_field, ai_field = ai_field)
        move_label = bool(random.randint(0, 1))
        shot_result = None
        while True:
            if move_label:
                while True:
                    if ai_field.alive_ships == 0:
                        return 'You win!'
                    shot_result = user.move(ai_field)
                    print('ai field:')
                    user_field.show_field()
                    print('---')
                    ai_field.show_field()
                    print('---')
                    if shot_result:
                        ai_field.alive_ships -= 1
                        continue
                    else:
                        break
            else:
                while True:
                    if ai_field.alive_ships == 0:
                        return 'AI win!'
                    shot_result = ai.move(user_field)
                    print('user field:')
                    user_field.show_field()
                    print('---')
                    ai_field.show_field()
                    print('---')
                    if shot_result:
                        user_field.alive_ships -= 1
                        continue
                    else:
                        break

            move_label = not move_label

    def start(self):
        self.greet()
        print(self.loop())

class Error(Exception):
    pass
class PointError(Error):
    pass
class ShotError(Error):
    pass


# test_IM_GetNewsTopicList     查询专题下的资讯     /as_stock_information/api/news/v1/topic_list
import json
import logging
import random

import allure
import pytest

from Common.getConsoleLogin import getConsoleLogin_token
from Common.get_time_stamp import stampToTime

from Common.sign import get_sign

from Common.requests_library import Requests
from Common.tools.read_write_json import get_json

from glo import BASE_DIR, HTTP, JSON

# @pytest.mark.skip(reason="调试中 ")
@allure.feature('资讯app_查询专题下的资讯')
class TestIMNewsList():
    @classmethod
    def setup_class(cls) -> None:
        cls.session = Requests().get_session()

    def tearDown(self) -> None:
        Requests(self.session).close_session()

    # @pytest.mark.skip(reason="调试中 ")
    @pytest.mark.parametrize('info',
                             get_json(BASE_DIR + r"/TestData/testIMData/test_IM_NewsList.json"))
    def test_IM_NewsList(self, info):
        url = HTTP + "/as_stock_information/api/news/v1/topic_list"
        header = {}
        header.update(JSON)

        paylo = info
        # print(paylo)
        sign1 = {"sign": get_sign(paylo)}  # 把参数签名后通过sign1传出来
        payload1 = {}
        payload1.update(paylo)
        payload1.update(sign1)
        headers = {}
        headers.update(header)

        token = {"token": getConsoleLogin_token()}
        headers.update(token)  # 将token更新到headers

        payload = json.dumps(dict(payload1))

        r = Requests(self.session).post(
            url=url, headers=headers, data=payload, title="查询专题下的资讯"
        )

        j = r.json()
        # print(j)
        assert r.status_code == 200
        assert j.get("code") == "000000"
        assert j.get("msg") == "ok"


import dearpygui.dearpygui as dpg
import numpy as np

import random

from dropFunc import _axis_drop

class PlotManager:
    def __init__(self) -> None:
        pass

    def __init__(self):
        self.plot_id = []
        self.yaxis_id = []

    def generate_random_dataset(self, num_points):
        x_values = np.linspace(0, 0.001, num_points)  # Generate x values evenly spaced between 0 and 10
        random_frequency = random.uniform(1000, 100000)  # Generate a random frequency between 1 and 10
        y_values = np.sin(2 * np.pi * random_frequency * x_values)
        # Calculate y values using a sine wave with the random frequency and add some random noise

        return x_values, y_values

    def add_line_series(self):
        if self.yaxis_id:
            x, y = self.generate_random_dataset(10000)

            # dpg.push_container_stack(dpg.add_line_series(x, y, label=f"{random.uniform(1,100)}", parent=self.yaxis_id[-1]))
            # dpg.pop_container_stack()
            dpg.add_line_series(x, y, label=f"{random.uniform(1,100)}", parent=self.yaxis_id[-1])

    def delete_plot(self):
        if self.plot_id:
            dpg.delete_item(self.plot_id[-1])
            self.plot_id.pop()
            self.yaxis_id.pop()

    def add_plot(self):
        yaxis_id = dpg.generate_uuid()
        plot_id = dpg.generate_uuid()

        self.plot_id.append(plot_id)
        self.yaxis_id.append(yaxis_id)

        x, y = self.generate_random_dataset(10000)

        dpg.push_container_stack(dpg.add_plot(label="Line Series", height=400, width=-1, parent="PlotWin", anti_aliased=True, tag=plot_id))
        dpg.add_plot_legend()
        dpg.add_plot_axis(dpg.mvXAxis, label="x")
        dpg.add_plot_axis(dpg.mvYAxis, label="y1", tag=yaxis_id, payload_type="plotting", drop_callback=_axis_drop)
        dpg.add_plot_axis(dpg.mvYAxis, label="y2", tag=dpg.generate_uuid(), payload_type="plotting", drop_callback=_axis_drop)
        dpg.add_line_series(x, y, label="Random Freq", parent=yaxis_id, tag=dpg.generate_uuid())
        us = dpg.last_item()
        dpg.add_button(label="drag", user_data = us, parent=us)

        with dpg.drag_payload(parent=dpg.last_item(), drag_data=(x,y , "fag"), payload_type="plotting"):
            dpg.add_text(dpg.get_item_label(us))
            dpg.add_simple_plot(label="", default_value=y)

        dpg.pop_container_stack()


# -*- coding: utf-8 -*-
"""
Created on Fri Mar  3 13:07:40 2023

@author: suraj

{1: {"id": 1, "name": "Suraj", "blood_type": "O+", "tests": []}}
"""
import flask

from flask import Flask, jsonify, request

app = Flask(__name__)

db = {}

def add_patient_to_db(id, name, blood_type):
    new_patient = {"id": id,
                   "name": name,
                   "blood_type": blood_type,
                   "tests": []}
    db[id] = new_patient
    print(db)

def new_patient_driver(in_data):
    validation = validate(in_data)
    if validation is not True:
        return validation, 400
    add_patient_to_db(in_data['id'], in_data['name'], in_data['blood_type'])
    return "Patient added", 200

def validate(in_data):
    if type(in_data) is not dict:
        return "input is not a dictionary"
    expected_keys = ["name", "id", "blood_type"]
    expected_types = [str, int, str]
    for key, vale_type in zip(expected_keys, expected_types):
        if key not in in_data:
            return "key {} is missing from input".format(key)
        if type(in_data[key]) is not vale_type:
            return "{} incorrect type".format(key)
    return True

def add_new_test(id, test, test_re):
    db[id]['tests'].append((test, test_re))
    print(db)

def new_test_driver(in_data):
    validation = validate_tests(in_data)
    if validation is not True:
        return validation, 400
    add_new_test(in_data["id"], in_data["test_name"], in_data["test_result"])
    return "Test added", 200

def id_in_db(id):
    if id in db:
        return True
    else:
        return False

def validate_tests(in_data):

    if type(in_data) is not dict:
        return "input is not a dictionary"
    expected_keys = ["id", "test_name", "test_result"]
    expected_types = [int, str, int]
    for key, vale_type in zip(expected_keys, expected_types):
        if key not in in_data:
            return "key {} is missing from input".format(key)
        if type(in_data[key]) is not vale_type:
            return "{} incorrect type".format(key)
    if not id_in_db(in_data['id']):
        return "No patient with {} in db".format(in_data['id']), 400
    return True

def results_find(id):
    if not id_in_db(id):
        return "no {} here".format(id), 400
    return db[id]['tests'], 200

@app.route("/new_patient", methods = ["POST"])
def post_new_patient():
    in_data = request.get_json()
    answer, stat_code = new_patient_driver(in_data)
    return jsonify(answer), stat_code

@app.route("/add_test", methods = ["POST"])
def post_new_test():
    in_data = request.get_json()
    answer, stat_code = new_test_driver(in_data)
    return jsonify(answer), stat_code

@app.route("/get_results/<patient_id>", methods = ["GET"])
def get_results(patient_id):
    id = int(patient_id)
    results, stat_code = results_find(id)
    return jsonify(results), stat_code

if __name__ == "__main__":
    app.run()


import random
import sqlite3
import sys
from datetime import datetime
from win10toast import ToastNotifier

from PyQt5 import QtCore, QtMultimedia, QtGui
from PyQt5.QtCore import QTimer
from PyQt5.QtWidgets import QApplication, QMainWindow, QInputDialog, QTableWidgetItem

from DataBaseWork import DataBaseWork
from Edit_note_form import EditNoteForm
from Edit_reminder_form import EditReminderForm
from Edit_task_form import EditTaskForm
from Play_Sounds import PlaySounds
from Record_type import RecordType
from View_note_form import ViewNoteForm
from View_reminder_form import ViewReminderForm
from View_task_form import ViewTaskForm
from Формы.Ui_OrganizerForm import Ui_OrganizerForm

class OrganizerForm(QMainWindow, Ui_OrganizerForm):
    def __init__(self):
        super().__init__()
        self.setupUi(self)

        self.pictures = ['6-4.ico', 'biohazard.ico', 'cheetah.ico', 'food.ico', 'marvin.ico',
                         'parrot.ico', 'space.ico', 'space_cat.ico', 'unicorn.ico', 'viper.ico']
        self.record_types = ['Заметка', 'Напоминание', 'Задача']
        self.timers = {'Reminders': {}, 'Tasks': {}}
        self.filter = False
        self.database = DataBaseWork()
        self.form = EditNoteForm()
        self.sounds = PlaySounds()

        self.update_records()

        self.init_ui()

    def init_ui(self):
        self.setWindowIcon(QtGui.QIcon('значки окон/organizer.png'))

        self.pb_create.clicked.connect(self.create_record)

        self.tw_records.doubleClicked.connect(self.open_record)

        self.filter_all.triggered.connect(self.change_filter)
        self.filter_notes.triggered.connect(self.change_filter)
        self.filter_reminders.triggered.connect(self.change_filter)
        self.filter_tasks.triggered.connect(self.change_filter)

    def open_record(self):
        self.form.close()

        id = self.tw_records.currentItem().row()
        record_type = self.tw_records.item(id, 0).text()
        title = self.tw_records.item(id, 1).text()

        if record_type == self.record_types[0]:
            record_type = RecordType.NOTE.value
            self.form = ViewNoteForm()
        elif record_type == self.record_types[1]:
            record_type = RecordType.REMINDER.value
            self.form = ViewReminderForm()
        elif record_type == self.record_types[2]:
            record_type = RecordType.TASK.value
            self.form = ViewTaskForm()

        id = self.database.get_id(record_type, title)

        self.show_record(id, record_type)

    def create_record(self):
        record_type, btn_pressed = QInputDialog.getItem(self, " ", 'Выберите тип записи', self.record_types, 1, False)

        if btn_pressed:
            if not self.record.isEmpty():
                self.form.close()

            if record_type == self.record_types[0]:
                self.form = EditNoteForm()
            elif record_type == self.record_types[1]:
                self.form = EditReminderForm()
            elif record_type == self.record_types[2]:
                self.form = EditTaskForm()

            self.form.closed.connect(self.show_record)
            self.record.addWidget(self.form, 0, 0)

    def edit_record(self, id, record_type):
        if record_type == RecordType.NOTE:
            self.form = EditNoteForm()
        elif record_type == RecordType.REMINDER:
            self.form = EditReminderForm()
        elif record_type == RecordType.TASK:
            self.form = EditTaskForm()

        self.form.closed.connect(self.show_record)
        self.record.addWidget(self.form, 0, 0)
        self.form.load_record(id, record_type.value)

    def delete_record(self, id, record_type):
        self.database.delete_record(id, record_type)

        if record_type != RecordType.NOTE.value and id in self.timers[record_type]:
            self.timers[record_type][id].stop()
            self.timers[record_type][id].deleteLater()

        self.update_records()

    def update_records(self):
        self.form.close()
        con = sqlite3.connect("Records.db")
        cur = con.cursor()

        notes = []
        reminders = []
        tasks = []

        if not self.filter or self.filter == RecordType.NOTE.value:
            notes = self.database.get_records_by_type(RecordType.NOTE.value)

        if not self.filter or self.filter == RecordType.REMINDER.value:
            reminders = self.database.get_records_by_type(RecordType.REMINDER.value)

        if not self.filter or self.filter == RecordType.TASK.value:
            tasks = self.database.get_records_by_type(RecordType.TASK.value)

        records = notes + reminders + tasks

        self.tw_records.setRowCount(0)
        self.tw_records.setColumnCount(3)

        for i in range(len(records)):
            if records[i] in notes:
                record_type = self.record_types[0]
            elif records[i] in reminders:
                record_type = self.record_types[1]
                self.create_update_timer(records[i], RecordType.REMINDER.value)
            elif records[i] in tasks:
                record_type = self.record_types[2]
                self.create_update_timer(records[i], RecordType.TASK.value)

            if records[i] != []:
                self.tw_records.insertRow(i)
                self.tw_records.setItem(i, 0, QTableWidgetItem(record_type))
                self.tw_records.setItem(i, 1, QTableWidgetItem(str(records[i][1])))
                self.tw_records.setItem(i, 2, QTableWidgetItem(str(records[i][2])))

    def change_filter(self):
        if self.sender() == self.filter_all:
            self.filter = False
        elif self.sender() == self.filter_notes:
            self.filter = RecordType.NOTE.value
        elif self.sender() == self.filter_reminders:
            self.filter = RecordType.REMINDER.value
        elif self.sender() == self.filter_tasks:
            self.filter = RecordType.TASK.value

        self.update_records()

    def create_update_timer(self, record, record_type):
        set_date_time = datetime.strptime(record[5], '%Y-%m-%d %H:%M:%S')

        if int((set_date_time - datetime.now()).total_seconds()) >= 0:

            add_date_time = datetime.now()
            seconds = int(str(int((set_date_time - add_date_time).total_seconds())) + '000')

            if record[0] in self.timers[record_type]:
                timer = self.timers[record_type][record[0]]
                timer.stop()

            timer = QTimer()
            timer.timeout.connect(lambda: self.send_notification(record_type, record[1], record[2]))
            timer.setSingleShot(True)
            timer.start(seconds)
            self.timers[record_type].update({record[0]: timer})

    def show_record(self, id, record_type):
        self.update_records()

        if record_type == RecordType.NOTE.value:
            self.form = ViewNoteForm()
        elif record_type == RecordType.REMINDER.value:
            self.form = ViewReminderForm()
        elif record_type == RecordType.TASK.value:
            self.form = ViewTaskForm()

        self.record.addWidget(self.form, 0, 0)
        self.form.load_record(id, record_type)

        self.form.delete_record.connect(self.delete_record)
        self.form.edit_record.connect(self.edit_record)

    def send_notification(self, record_type, title, topic):
        toaster = ToastNotifier()

        icon = 'картинки ico/' + random.choice(self.pictures)

        if record_type == RecordType.REMINDER.value:
            self.sounds.remind.play()

            toaster.show_toast(topic, title, threaded=True,
                               icon_path=icon, duration=5)

        elif record_type == RecordType.TASK.value:
            self.sounds.fail.play()

            toaster.show_toast('Внимание', f'Время на выполнение задния {title} истекло', threaded=True,
                               icon_path=icon, duration=5)

if __name__ == '__main__':
    app = QApplication(sys.argv)
    wnd = OrganizerForm()
    wnd.show()
    sys.exit(app.exec())


import inspect
import logging

class cust_LoggerDemo:
    @staticmethod
    def cust_logger(logLevel=logging.DEBUG):
        # Set Class/method name from where its called
        logger_name = inspect.stack()[1][3]

        # Step 1. create logger
        logger = logging.getLogger(logger_name)
        logger.setLevel(logLevel)

        # Step 2. create console handler (ch) or file handler (ch) and set the log level
        fh = logging.FileHandler(r"C:\Users\HP\Desktop\Python\Python_Logging\logs\Automation.log", mode="a")

        # Step 3. Create formatter  - how you want your logs to be formatted
        formatter = logging.Formatter('%(asctime)s - %(name)s:%(filename)s - %(levelname)s | %(message)s',
                                      datefmt='%d-%B-%y | %A | %H:%M:%S %p')

        # Step 4. Add formatter to console or file handler
        fh.setFormatter(formatter)

        # Step 5. Add console handler(ch) to logger

        logger.addHandler(fh)

        # Step 6. 'application' code - log messages
        logger.debug(f"This is debug")
        logger.info(f"This is info")
        logger.warning(f"This is warning")
        logger.error(f"This is error")
        logger.critical(f"This is critical")
        # return logger

ld = cust_LoggerDemo()
ld.cust_logger()


# Function to calculate monthly mortgage payment
def calculate_mortgage():
    loan_amount = float(input("Enter the loan amount: "))  # get loan amount from user
    annual_interest_rate_input = input(
        "Enter the annual interest rate (as a decimal or percentage): "
    )
    # get annual interest rate from user as decimal or percentage
    annual_interest_rate = (
        float(annual_interest_rate_input.strip("%")) / 100
        if "%" in annual_interest_rate_input
        else float(annual_interest_rate_input) / 100
    )
    # convert percentage to decimal if necessary
    loan_term_years = float(
        input("Enter the loan term in years: ")
    )  # get loan term from user
    number_of_payments = (
        loan_term_years * 12
    )  # calculate number of payments based on loan term
    monthly_interest_rate = annual_interest_rate / 12  # calculate monthly interest rate
    payment = (
        loan_amount
        * (monthly_interest_rate * (1 + monthly_interest_rate) ** number_of_payments)
        / ((1 + monthly_interest_rate) ** number_of_payments - 1)
    )
    # calculate monthly payment based on loan amount, interest rate, and number of payments
    payment = round(payment, 2)  # round payment to 2 decimal places
    print(f"The monthly mortgage payment is: ${payment:.2f}")  # print payment result

# Function to calculate compound interest
def calculate_compound_interest():
    principal = float(
        input("Enter the principal amount: ")
    )  # get principal amount from user
    interest_rate_input = input(
        "Enter the annual interest rate (as a decimal or percentage): "
    )
    # get annual interest rate from user as decimal or percentage
    interest_rate = (
        float(interest_rate_input.strip("%")) / 100
        if "%" in interest_rate_input
        else float(interest_rate_input)
    )
    # convert percentage to decimal if necessary
    compound_frequency = float(
        input("Enter the number of times the interest is compounded per year: ")
    )  # get compound frequency from user
    time_period = float(
        input("Enter the time period in years: ")
    )  # get time period from user
    amount = principal * (
        (1 + (interest_rate / compound_frequency)) ** (compound_frequency * time_period)
    )
    # calculate amount based on principal, interest rate, compound frequency, and time period
    amount = round(amount, 2)  # round amount to 2 decimal places
    print(
        f"The amount after {time_period:.2f} years is: ${amount:.2f}"
    )  # print amount result

# Main function to run program
def main():
    print("Welcome to the Loan Calculator!")
    while True:
        print("1. Calculate Monthly Mortgage Payment")
        print("2. Calculate Compound Interest")
        choice = input("Enter your choice (1 or 2): ")  # get user choice
        if choice == "1":
            calculate_mortgage()  # run monthly mortgage payment calculation function
            break
        elif choice == "2":
            calculate_compound_interest()  # run compound interest calculation function
            break
        else:
            print(
                "Invalid choice. Please select either 1 or 2."
            )  # prompt user for valid choice

if __name__ == "__main__":
    main()  # run main function


import os
import time

class Move:
    def __init__(self, row, col):
        self.row = row
        self.col = col

player = 'x'
ai = 'o'

def is_move_left(board):
    for i in range(3):
        for j in range(3):
            if board[i][j] == "_":
                return True
    return False

def check_position(board, row, col):
    if board[row][col] == '_':
        return True
    return False

def evaluate(board):
    # checking for row if someone has won
    for row in range(3):
        if board[row][0] == board[row][1] and board[row][1] == board[row][2]:
            if board[row][0] == ai:
                return +10
            elif board[row][0] == player:
                return -10

    # checking for column if someone has won
    for col in range(3):
        if board[0][col] == board[1][col] and board[1][col] == board[2][col]:
            if board[0][col] == ai:
                return +10
            elif board[0][col] == player:
                return -10
    # checking for diagonal if someone has won
    if board[0][0] == board[1][1] and board[1][1] == board[2][2]:
        if board[0][0] == ai:
            return +10
        elif board[0][0] == player:
            return -10

    if board[0][2] == board[1][1] and board[1][1] == board[2][0]:
        if board[0][2] == ai:
            return +10
        elif board[0][2] == player:
            return -10

def mini_max(board, depth, is_max):
    score = evaluate(board)

    if score == 10:
        return score
    if score == -10:
        return score

    if not is_move_left(board):
        return 0

    if is_max:
        best = -1000
        for i in range(3):
            for j in range(3):
                if board[i][j] == '_':
                    board[i][j] = ai
                    best = max(best, mini_max(board, depth + 1, not is_max))
                    board[i][j] = '_'
        return best
    else:
        best = 1000
        for i in range(3):
            for j in range(3):
                if board[i][j] == '_':
                    board[i][j] = player
                    best = min(best, mini_max(board, depth + 1, not is_max))
                    board[i][j] = '_'
        return best

def find_best_move(board):
    best_value = -1000
    best_move = Move(-1, -1)
    for i in range(3):
        for j in range(3):
            # Check if cell is empty
            if board[i][j] == '_':
                # Make the move
                board[i][j] = ai
                # compute evaluation function for this move.
                move_val = mini_max(board, 0, False);
                # Undo the move
                board[i][j] = '_';
                if move_val > best_value:
                    best_move.row = i
                    best_move.col = j
                    best_value = move_val
    return best_move

def draw_board(board):
    print(" %c | %c | %c " % (board[0][0], board[0][1], board[0][2]))
    print("___|___|___")
    print(" %c | %c | %c " % (board[1][0], board[1][1], board[1][2]))
    print("___|___|___")
    print(" %c | %c | %c " % (board[2][0], board[2][1], board[2][2]))
    print("   |   |   ")

if __name__ == "__main__":
    tic_toc_board = [
        ['_', '_', '_'],
        ['_', '_', '_'],
        ['_', '_', '_']
    ]

    while True:
        draw_board(tic_toc_board)
        val = evaluate(tic_toc_board)
        if val == 10:
            print("====== Ai win ======")
            break
        elif val == -10:
            print("====== You win ======")
            break
        elif (val is not 10 or -10) and is_move_left(tic_toc_board) is False:
            print("====== Draw ======")
            break
        choice = int(input("Enter the position between [1-9]"))
        if choice == 1:
            if check_position(tic_toc_board, 0, 0):
                tic_toc_board[0][0] = player
            else:
                os.system('clear')
                print("sorry the choice is already filled up. try again!")
                continue
        if choice == 2:
            if check_position(tic_toc_board, 0, 1):
                tic_toc_board[0][1] = player
            else:
                os.system('clear')
                print("sorry the choice is already filled up. try again!")
                continue
        if choice == 3:
            if check_position(tic_toc_board, 0, 2):
                tic_toc_board[0][2] = player
            else:
                os.system('clear')
                print("sorry the choice is already filled up. try again!")
                continue
        if choice == 4:
            if check_position(tic_toc_board, 1, 0):
                tic_toc_board[1][0] = player
            else:
                os.system('clear')
                print("sorry the choice is already filled up. try again!")
                continue
        if choice == 5:
            if check_position(tic_toc_board, 1, 1):
                tic_toc_board[1][1] = player
            else:
                os.system('clear')
                print("sorry the choice is already filled up. try again!")
                continue
        if choice == 6:
            if check_position(tic_toc_board, 1, 2):
                tic_toc_board[1][2] = player
            else:
                os.system('clear')
                print("sorry the choice is already filled up. try again!")
                continue
        if choice == 7:
            if check_position(tic_toc_board, 2, 0):
                tic_toc_board[2][0] = player
            else:
                os.system('clear')
                print("sorry the choice is already filled up. try again!")
                continue
        if choice == 8:
            if check_position(tic_toc_board, 2, 1):
                tic_toc_board[2][1] = player
            else:
                os.system('clear')
                print("sorry the choice is already filled up. try again!")
                continue
        if choice == 9:
            if check_position(tic_toc_board, 2, 2):
                print("-------")
                tic_toc_board[2][2] = player
            else:
                os.system('clear')
                print("sorry the choice is already filled up. try again!")
                continue
        os.system('clear')
        draw_board(tic_toc_board)
        if is_move_left(tic_toc_board):
            os.system('clear')
            print("waiting for the ai's move")
            time.sleep(3)
            move = find_best_move(board=tic_toc_board)
            tic_toc_board[move.row][move.col] = ai
        os.system('clear')


import tweepy
from textblob import TextBlob
import json
import sys

from tokens import consumer_key, consumer_secret, access_token, access_token_secret

auth = tweepy.OAuthHandler(consumer_key, consumer_secret)
auth.set_access_token(access_token, access_token_secret)

api = tweepy.API(auth)

public_tweets = api.search(sys.argv[1]+" -filter:retweets", lang='en', tweet_mode='extended', count=10)
total_list = []
tweets_for_topics = {}
my_dict = {}

for tweet in public_tweets:
	# print(tweet.full_text)
	analysis = TextBlob(tweet.full_text)
	# print(analysis.sentiment)
	# print(analysis.words)
	# print(analysis.noun_phrases)
	total_list += analysis.noun_phrases

	for word in total_list:
		if word in my_dict:
			my_dict[word][0] += 1
			my_dict[word][1].append([tweet.id,tweet.full_text])
		else:
			my_dict[word] = [1, []]
			my_dict[word][1].append([tweet.id,tweet.full_text])

sorted_dict = {k: v for k, v in sorted(my_dict.items(), key=lambda item: item[1], reverse=True)}

json.dump(sorted_dict, open("tweets.json", "w"))
print(sorted_dict)


import hoshino
from hoshino import Service, aiorequests, priv
from hoshino.util import FreqLimiter, DailyNumberLimiter
from .request import *
from .config import DAILY_MAX_NUM, FREQ_LIMIT

sv = Service('setu_acggov', bundle='pcr娱乐', enable_on_default=False, manage_priv = priv.SUPERUSER, help_='随机涩图/setu [n]\n本日涩图排行榜 [page]\n看涩图 [n] 或 [start end]')

#设置limiter
tlmt = DailyNumberLimiter(DAILY_MAX_NUM)
flmt = FreqLimiter(FREQ_LIMIT)

def check_lmt(uid, num):
    if uid in hoshino.config.SUPERUSERS:
        return 0, ''
    if not tlmt.check(uid):
        return 1, f'您今天已经冲过{DAILY_MAX_NUM}次了,请明天再来!'
    if num > 1 and (DAILY_MAX_NUM - tlmt.get_num(uid)) < num:
            return 1, f'您今天的剩余次数为{DAILY_MAX_NUM - tlmt.get_num(uid)}次,已不足{num}次,请少冲一点!'
    if not flmt.check(uid):
        return 1, f'您冲的太快了,请等待{round(flmt.left_time(uid))}秒!'
    tlmt.increase(uid,num)
    flmt.start_cd(uid)
    return 0, ''

@sv.on_prefix(['随机涩图', 'setu'])
async def send_setu(bot, ev):
    num = ev.message.extract_plain_text()
    if not num.isdigit():
        num = 1
    num = int(num)
    uid = ev['user_id']
    result, msg = check_lmt(uid, num)
    if result != 0:
        await bot.send(ev, msg)
        return
    await bot.send(ev, '正在下载图片...')
    for _ in range(num):
        _, msg = await get_setu()
        await bot.send(ev, msg)

@sv.on_prefix('本日涩图排行榜')
async def send_ranking(bot, ev):
    page = ev.message.extract_plain_text()
    if not page.isdigit():
        page = 1
    page = int(page)
    page -= 1
    if page < 0:
        page = 0
    _, msg = await get_ranking(page)
    await bot.send(ev, msg)

@sv.on_prefix('看涩图')
async def send_ranking_setu(bot, ev):
    uid = ev['user_id']
    start = 0
    end = 0
    args = ev.message.extract_plain_text().split()
    if len(args) > 0 and args[0].isdigit():
        start = int(args[0])
        start -= 1
        if start < 0:
            start = 0
        end = start + 1
    if len(args) > 1 and args[1].isdigit():
        end = int(args[1])
    result, msg = check_lmt(uid, end - start)
    if result != 0:
        await bot.send(ev, msg)
        return
    await bot.send(ev, '正在下载图片...')
    for i in range(start, end):
        _, msg = await get_ranking_setu(i)
        await bot.send(ev, msg)


from barcodeutil.license_fields import driver_license_fields

def decode_barcode(data: str):
    sub_data = data
    splitted = sub_data.split('\n')
    fields = driver_license_fields

    for datum in splitted:

        for field in fields:
            abb = field.get('abbreviation')

            if datum.find(abb) == 0:
                field['in_license'] = True
                field['value'] = datum[len(abb):]

# gender, address, organ donor(ddk, dbh), anything INDICATOR, weight, height
# Mentioned values must be modified

    for field in fields:
        if field.get('abbreviation') == ('DAG' or 'DAH' or 'DAL' or 'DAM'):
            pass

        if field.get('abbreviation') == 'DBC':
            field['value'] = 'Female' if field.get('value') == '2' else 'Male'

        if field.get('abbreviation') == ('DDK' or 'DBH'):
            field['value'] = 'Yes' if field.get('value') == ('1' or 'Y') else 'No'

    license_result = ''

    for field in fields:
        if field.get('in_license'):
            license_result \
                = license_result \
                  + ('\n%s: %s' % (field.get('description'), field.get('value')))

    return license_result


import matplotlib
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np

df = pd.read_csv('./vehicles.csv')

old = df['Current fleet'].tolist()
new = df['New Fleet'].tolist()

new = [x for x in new if x !='nan']

plt.scatter(np.arange(len(old)),old, c='b')
plt.scatter(np.arange(len(new)),new, c='r')
plt.legend(labels = ['Old Fleet', 'New Fleet'])
plt.title('Fleet Size')
plt.xlabel('Number')
plt.ylabel('size')
plt.savefig("Scatterplot.png", bbox_inches='tight')
plt.show()

plt.hist(old)
plt.savefig("HistogramNew.png", bbox_inches='tight')
plt.show()

plt.hist(df['New Fleet'].dropna())
plt.savefig("HistogramOld.png", bbox_inches='tight')
plt.show()


import pandas as pd
from optparse import OptionParser
import config
from collections import defaultdict
from utils import pkl_utils
import os

def path_count(types):
    cnt = 0
    for a in types:
        flag = 1
        for b in types:
            if len(a) >= len(b):
                continue
            if (a == b[:len(a)]) and (b[len(a)] == "/"):
                flag = 0
        cnt += flag
    return cnt

def create_type_dict(infile, outfile, full_path):
    df = pd.read_csv(infile, sep="\t", names=["p1", "p2", "text", "type", "f"])
    size = df.shape[0]
    typeSet = set()
    freq = defaultdict(int)
    for i in range(size):
        types = df["type"][i].split()
        out_type = []
        for a in types:
            flag = True
            for b in types:
                if len(a) >= len(b):
                    continue
                if (a == b[:len(a)]) and (b[len(a)] == "/"):
                    flag = False
            if flag:
                out_type.append(a)
        if full_path:
            typeSet.update(types)
        else:
            typeSet.update(out_type)
        for t in types:
            freq[t] += 1

    type2id = {y: x for x, y in enumerate(typeSet)}
    typeDict = defaultdict(list)
    for a in type2id.keys():
        for b in type2id.keys():
            if len(a) >= len(b):
                continue
            if (a == b[:len(a)]) and (b[len(a)] == "/"):
                typeDict[a].append(b)
    pkl_utils._save(outfile, (type2id, typeDict))

def clear_text(text):
    text = text.replace("-LRB-", "``")
    text = text.replace("-RRB-", "''")
    text = text.replace("-LSB-", "[")
    text = text.replace("-RSB-", "]")
    text = text.replace("-LCB-", "{")
    text = text.replace("-RCB-", "}")

    return text.strip()

def preprocess(data_name, if_clean=False, full_path=False):
    if data_name == "wiki":
        raw_all_file = config.WIKI_ALL
        raw_train_file = config.WIKI_TRAIN
        raw_valid_file = config.WIKI_VALID
        raw_test_file = config.WIKI_TEST
        clean_train_file = config.WIKI_TRAIN_CLEAN
        clean_test_file = config.WIKI_TEST_CLEAN
        type_file = config.WIKI_TYPE
    elif data_name == "wikim":
        raw_all_file = config.WIKIM_ALL
        raw_train_file = config.WIKIM_TRAIN
        raw_valid_file = config.WIKIM_VALID
        raw_test_file = config.WIKIM_TEST
        clean_train_file = config.WIKIM_TRAIN_CLEAN
        clean_test_file = config.WIKIM_TEST_CLEAN
        type_file = config.WIKIM_TYPE
    elif data_name == "ontonotes":
        raw_all_file = config.ONTONOTES_ALL
        raw_train_file = config.ONTONOTES_TRAIN
        raw_valid_file = config.ONTONOTES_VALID
        raw_test_file = config.ONTONOTES_TEST
        clean_train_file = config.ONTONOTES_TRAIN_CLEAN
        clean_test_file = config.ONTONOTES_TEST_CLEAN
        type_file = config.ONTONOTES_TYPE
    else:
        raise AttributeError("Invalid data name!")

    if not os.path.exists(type_file):
        create_type_dict(raw_all_file, type_file, full_path)
    type2id, typeDict = pkl_utils._load(type_file)

    df_train = pd.read_csv(raw_train_file, sep="\t", names=["p1", "p2", "text", "type", "f"])
    df_valid = pd.read_csv(raw_valid_file, sep="\t", names=["p1", "p2", "text", "type", "f"])
    df = pd.concat((df_train, df_valid), ignore_index=True)
    size = df.shape[0]
    outfile = open(clean_train_file, "w")
    for i in range(size):
        p1 = df["p1"][i]
        p2 = df["p2"][i]
        text = df["text"][i]
        types = df["type"][i].split()
        if (not path_count(types) == 1) and if_clean:
            continue

        text = clear_text(text)
        tokens = text.split()
        if p1 >= len(tokens):
            continue
        mention = " ".join(tokens[p1:p2])

        if p1 == 0:
            mention = "<PAD> " + mention
        else:
            mention = tokens[p1 - 1] + " " + mention
        if p2 >= len(tokens):
            mention = mention + " <PAD>"
        else:
            mention = mention + " " + tokens[p2]

        offset = max(0, p1 - config.WINDOW_SIZE)
        text = " ".join(tokens[offset:min(len(tokens), p2 + config.WINDOW_SIZE - 1)])
        p1 -= offset
        p2 -= offset

        out_type = []
        for a in types:
            flag = True
            for b in types:
                if len(a) >= len(b):
                    continue
                if (a == b[:len(a)]) and (b[len(a)] == "/"):
                    flag = False
            if flag:
                out_type.append(a)

        if len(out_type) > 0:
            if full_path:
                outfile.write("%d\t%d\t%s\t%s\t%s\n" % (p1, p2, text, mention, " ".join(types)))
            else:
                outfile.write("%d\t%d\t%s\t%s\t%s\n" % (p1, p2, text, mention, " ".join(out_type)))
    outfile.close()

    df = pd.read_csv(raw_test_file, sep="\t", names=["p1", "p2", "text", "type", "f"])
    size = df.shape[0]
    outfile = open(clean_test_file, "w")
    for i in range(size):
        p1 = df["p1"][i]
        p2 = df["p2"][i]
        text = df["text"][i]
        types = df["type"][i].split()

        text = clear_text(text)
        tokens = text.split()
        if p1 >= len(tokens):
            continue
        mention = " ".join(tokens[p1:p2])

        if p1 == 0:
            mention = "<PAD> " + mention
        else:
            mention = tokens[p1 - 1] + " " + mention
        if p2 >= len(tokens):
            mention = mention + " <PAD>"
        else:
            mention = mention + " " + tokens[p2]

        offset = max(0, p1 - config.WINDOW_SIZE)
        text = " ".join(tokens[offset:min(len(tokens), p2 + config.WINDOW_SIZE - 1)])
        p1 -= offset
        p2 -= offset

        out_type = []
        for a in types:
            flag = True
            for b in types:
                if len(a) >= len(b):
                    continue
                if (a == b[:len(a)]) and (b[len(a)] == "/"):
                    flag = False
            if flag:
                out_type.append(a)

        if full_path:
            outfile.write("%d\t%d\t%s\t%s\t%s\n" % (p1, p2, text, mention, " ".join(types)))
        else:
            outfile.write("%d\t%d\t%s\t%s\t%s\n" % (p1, p2, text, mention, " ".join(out_type)))
    outfile.close()

def parse_args(parser):
    parser.add_option("-d", "--data_name", type="string", dest="data_name")
    parser.add_option("-c", default=False, action="store_true", dest="if_clean")
    parser.add_option("-f", default=False, action="store_true", dest="full_path")

    (options, args) = parser.parse_args()
    return options, args

def main(options):
    preprocess(options.data_name, options.if_clean, options.full_path)

if __name__ == "__main__":
    parser = OptionParser()
    options, args = parse_args(parser)
    main(options)