import discord
from discord.ext import commands, tasks
import datetime

try:
    from utilities import webcam_photo, picam_photo
except:
    print("could not import picam module")

class CamCog(commands.Cog):
    def __init__(self, bot):
        self.bot = bot

    @commands.command(name="plant", hidden=False)
    async def webcam_image(self, ctx):
        async with ctx.channel.typing():
            # await ctx.reply("Sorry, the plants are away for winter! But don't worry, we'll be back next year"
            #                 " :slight_smile:")
            image_path = await picam_photo.take_image()
            img = discord.File(image_path)
        await ctx.reply("", file=img)

    @tasks.loop(time=[datetime.time(13, 0, 0)])
    async def auto_image(self):
        _ = await picam_photo.take_image()
        return


import os
import configparser as config

class ProjectManager:
    FILE_LOG_DATA = []
    CONSTANT = {}

    def __init__(self, fname):
        self.fname = fname

        # load file if exist
        if os.path.isfile(fname+".gai"):
            with open(fname+".gai", "r") as fbj:
                fdt = fbj.readlines()

        # load .ini file
        cfg = config.ConfigParser()  # load config parser
        cfg.optionxform = str
        cfg.read("meta.ini")
        for sect in cfg.sections():
            ProjectManager.CONSTANT[sect] = {}
            for key, val in cfg.items(sect):  # test out each type; default is string
                if val.isdigit(): ProjectManager.CONSTANT[sect][key] = int(val)
                elif val == "true": ProjectManager.CONSTANT[sect][key] = True
                elif val == "false": ProjectManager.CONSTANT[sect][key] = False
                else: ProjectManager.CONSTANT[sect][key] = val

    @classmethod
    def insert_node(cls, pos, fx):
        cls.FILE_LOG_DATA.append(["%NODE", pos, fx])

    @classmethod
    def insert_bias(cls, nodes, weight):
        cls.FILE_LOG_DATA.append(["%BIAS", nodes[0], nodes[1], weight])

    def flush(self):  # write files from the log data
        with open(self.fname+".gai", "a") as fbj:
            pass

    class Mouse:
        @staticmethod
        def OnTrigger(first, last): return True if first != last and last is False else False  # useless

"""
flushed-based file
.gai File system:

%world posx posy
$var %node posx posy fx
$nodes %node posx posy fx
$var1 %bias node1 node2 weight

"""


import sys
from itertools import permutations
input = sys.stdin.readline

numOfsign = int(input())
sign = input().split()
num_list = list(permutations([i for i in range(0,10)], numOfsign+1))
able_num = []
for permu in num_list:
    flag = 0
    for signal in range(len(sign)):
        if sign[signal] == '<' and not permu[signal] < permu[signal+1]:
            flag = 1
            break
        elif sign[signal] == '>' and not permu[signal] > permu[signal+1]:
            flag = 1
            break
    if flag:
            continue
    able_num.append(permu)
max_num = ''
min_num = ''
for i in able_num[-1]:
    max_num+=str(i)
for i in able_num[0]:
    min_num+=str(i)
print(max_num)
print(min_num)


import argparse
import time
import math
import numpy as np
import pickle
import random

import torch
import torch.nn as nn
import torch.optim as optim
import torch.nn.functional as F
import torch.autograd as autograd
from torch.autograd import Variable

from utils import to_gpu, LoadEmbeddingsFromText, Corpus, batchify, truncate
from models import LanguageModel, RNNDiscriminator

parser = argparse.ArgumentParser(description='PyTorch Sequence GAN for Text')
parser.add_argument('--data', type=str, default='./snli_lm',
                    help='location of the data corpus')
parser.add_argument('--rnn_type', type=str, default='LSTM',
                    help='type of recurrent net (LSTM, GRU)')
parser.add_argument('--embedding_file', type=str, default='',
                    help='path to pretrained embedding file')
parser.add_argument('--emsize', type=int, default=50,
                    help='size of word embeddings')
parser.add_argument('--nhidden', type=int, default=50,
                    help='number of hidden units per layer')
parser.add_argument('--nlayers', type=int, default=1,
                    help='number of layers')
parser.add_argument('--lowercase', type=bool,  default=True,
                    help='whether to lowercase')
parser.add_argument('--k', type=int, default=1,
                    help='number of layers')
parser.add_argument('--pretrain-lr', type=float, default=20,
                    help='initial learning rate')
parser.add_argument('--lr', type=float, default=0.01,
                    help='initial learning rate')
parser.add_argument('--beta1', type=float, default=0.5,
                    help='beta1 for adam. default=0.5')
parser.add_argument('--clip', type=float, default=0.25,
                    help='gradient clipping')
parser.add_argument('--pretrain-epochs', type=int, default=1,
                    help='pretraining epochs limit')
parser.add_argument('--epochs', type=int, default=2,
                    help='upper epoch limit')
parser.add_argument('--pretrain-batch_size', type=int, default=80, metavar='N',
                    help='batch size')
parser.add_argument('--batch_size', type=int, default=100, metavar='N',
                    help='batch size')
parser.add_argument('--bidirectional', action='store_true',
                    help='bidirectional discriminator')
parser.add_argument('--dropout', type=float, default=0.2,
                    help='dropout applied to layers (0 = no dropout)')
parser.add_argument('--tied', action='store_true',
                    help='tie the word embedding and softmax weights')
parser.add_argument('--seed', type=int, default=111,
                    help='random seed')
parser.add_argument('--pretrain', action='store_true',
                    help='pretrains the generator on a language model objective')
parser.add_argument('--reinforce', action='store_true',
                    help='use REINFORCE log-likelihood reward instead of Maximum Likelihood augmented reward')
parser.add_argument('--cuda', action='store_true',
                    help='use CUDA')
parser.add_argument('--log-interval', type=int, default=200, metavar='N',
                    help='report interval')
parser.add_argument('--save', type=str,  default='netG.pt',
                    help='path to save the final model')
parser.add_argument('--outf', type=str, default='.')
parser.add_argument('--netG', default='', help="path to netG (to continue training)")
parser.add_argument('--netD', default='', help="path to netD (to continue training)")
parser.add_argument('--sample', action='store_true',\
                    help='will sample for generation')
parser.add_argument('--temp', type=float, default=1.0,\
                    help='softmax temperaturen')
args = parser.parse_args()

with open(args.outf+'/args.txt', 'w') as f:
    f.write(str(args))

# Set the random seed manually for reproducibility.
torch.manual_seed(args.seed)
if torch.cuda.is_available():
    if not args.cuda:
        print("WARNING: You have a CUDA device, so you should probably run with --cuda")
    else:
        torch.cuda.manual_seed(args.seed)

###############################################################################
# Load data
###############################################################################

corpus = Corpus(args.data, lowercase=args.lowercase)

eval_batch_size = 10
val_data = batchify(corpus.valid, eval_batch_size, max_len=150)
test_data = batchify(corpus.test, eval_batch_size, max_len=150)

print("Loaded data!")

###############################################################################
# Build the generator
###############################################################################

ntokens = len(corpus.dictionary.word2idx)

if args.embedding_file == "":
    vocab = None
else:
    # Load pretrained word embeddings
    vocab = LoadEmbeddingsFromText(corpus.word2idx, embedding_dim=args.emsize, path=args.embedding_file)

netG = LanguageModel(rnn_type=args.rnn_type,
                     emsize=args.emsize,
                     nhidden=args.nhidden,
                     ntokens=ntokens,
                     nlayers=args.nlayers,
                     dropout=args.dropout,
                     tied=args.tied,
                     max_unroll=50,
                     initial_vocab=vocab,
                     gpu=args.cuda)
if args.netG != "":
    print('Loading generator from '+args.netG)
    netG.load_state_dict(torch.load(args.netG))

print(netG.max_unroll)

if args.cuda:
    netG.cuda()

lm_criterion = nn.CrossEntropyLoss()

###############################################################################
# Pretraining code
###############################################################################

def lm_train():
    # Turn on training mode which enables dropout.
    netG.train()
    total_loss = 0
    start_time = time.time()
    ntokens = len(corpus.dictionary.word2idx)
    vocab = corpus.dictionary.idx2word

    for i, batch in enumerate(train_data):
        source, target, lengths = batch
        source = to_gpu(args.cuda, Variable(source))
        target = to_gpu(args.cuda, Variable(target))

        # Create sentence length mask over padding
        mask = target.gt(0)
        masked_target = target.masked_select(mask)
        flat_mask = mask.view(-1, 1)
        output_mask = flat_mask.view(-1, 1).expand(flat_mask.size(0), ntokens) # examples x ntokens

        netG.zero_grad()
        output = netG(teacher_forcing=True, input_=source) # output: batch x seq_len x ntokens
        flattened_output = output.view(-1, ntokens)

        masked_output = flattened_output.masked_select(output_mask).view(-1, ntokens)
        loss = lm_criterion(masked_output, masked_target)
        loss.backward()

        # `clip_grad_norm` helps prevent the exploding gradient problem in RNNs / LSTMs.
        torch.nn.utils.clip_grad_norm(netG.parameters(), args.clip)
        for p in netG.parameters():
            p.data.add_(-lr, p.grad.data)

        total_loss += loss.data

        if i % args.log_interval == 0 and i > 0:
            cur_loss = total_loss[0] / args.log_interval
            elapsed = time.time() - start_time
            print('| epoch {:3d} | {:5d}/{:5d} batches | lr {:02.2f} | ms/batch {:5.2f} | '
                    'loss {:5.2f} | ppl {:8.2f}'.format(
                epoch, i, len(train_data), lr,
                elapsed * 1000 / args.log_interval, cur_loss, math.exp(cur_loss)))
            total_loss = 0
            start_time = time.time()

    return total_loss

def lm_evaluate(data_source):
    # Turn on evaluation mode which disables dropout.
    netG.eval()
    total_loss = 0
    ntokens = len(corpus.dictionary.word2idx)
    vocab = corpus.dictionary.idx2word
    for i, batch in enumerate(data_source):
        source, target, lengths = batch
        source = to_gpu(args.cuda, Variable(source, volatile=True))
        target = to_gpu(args.cuda, Variable(target, volatile=True))

        mask = target.gt(0)
        masked_target = target.masked_select(mask)
        flat_mask = mask.view(-1, 1)
        output_mask = flat_mask.view(-1, 1).expand(flat_mask.size(0), ntokens) # examples x ntokens

        netG.zero_grad()
        output = netG(teacher_forcing=True, input_=source) # output: batch x seq_len x ntokens
        flattened_output = output.view(-1, ntokens)

        masked_output = flattened_output.masked_select(output_mask).view(-1, ntokens)

        total_loss += lm_criterion(masked_output, masked_target).data

    return total_loss[0] / len(data_source)

# Loop over epochs.
lr = args.pretrain_lr
best_val_loss = None
stats = []

if args.pretrain:
    print("Pretraining generator with language model objective...")
    # At any point you can hit Ctrl + C to break out of training early.
    try:
        for epoch in range(1, args.pretrain_epochs+1):
            train_data = batchify(corpus.train, args.pretrain_batch_size, shuffle=True, max_len=120)
            epoch_start_time = time.time()
            train_loss = lm_train()
            val_loss = lm_evaluate(val_data)
            print('-' * 89)
            print('| end of epoch {:3d} | time: {:5.2f}s | valid loss {:5.2f} | '
                    'valid ppl {:8.2f}'.format(epoch, (time.time() - epoch_start_time),
                                            val_loss, math.exp(val_loss)))
            print('-' * 89)
            stats.append((epoch, train_loss, val_loss, math.exp(val_loss)))
            # Save the model if the validation loss is the best we've seen so far.
            if not best_val_loss or val_loss < best_val_loss:
                print("Saving with best val loss", val_loss)
                with open(args.save, 'wb') as f:
                    torch.save(netG.state_dict(), f)
                best_val_loss = val_loss
            else:
                # Anneal the learning rate if no improvement has been seen in the validation dataset.
                lr *= 0.25
            pickle.dump(stats, open("stats_"+args.save[:-3]+".p", "wb"))

    except KeyboardInterrupt:
        print('-' * 89)
        print('Exiting from training early')

        # Load the best saved model.
        with open(args.save, 'rb') as f:
            netG.load_state_dict(torch.load(f))
        # Run on test data.
        test_loss = lm_evaluate(test_data)
        print('=' * 89)
        print('| End of training | test loss {:5.2f} | test ppl {:8.2f}'.format(
            test_loss, math.exp(test_loss)))
        print('=' * 89)
else:
    print("Not pretraining generator with language model objective")

###############################################################################
# Build the discriminator
###############################################################################

netD = RNNDiscriminator(rnn_type=args.rnn_type,
                        emsize=args.emsize,
                        nhidden=args.nhidden,
                        ntokens=ntokens,
                        nlayers=args.nlayers,
                        bidirectional=args.bidirectional,
                        dropout=args.dropout,
                        initial_vocab=vocab,
                        gpu=args.cuda)
if args.netD != "":
    print('Loading discriminator from '+args.netD)
    netD.load_state_dict(torch.load(args.netD))

if args.cuda:
    netD.cuda()

###############################################################################
# Training setup code
###############################################################################

# Setup Optimizers
optimizerD = optim.SGD(netD.parameters(), lr=args.lr)
# optimizerD = optim.Adam(netD.parameters(), lr=args.lr, betas=(args.beta1, 0.999))
optimizerG = optim.SGD(netG.parameters(), lr=args.lr)
# optimizerG = optim.Adam(netG.parameters(), lr=args.lr, betas=(args.beta1, 0.999))

# input image, noise, fixed noise for comparing learning improvement over epochs, label (real/fake)
input_ = torch.FloatTensor(args.batch_size, 9, args.emsize)
noise = torch.FloatTensor(args.nlayers, args.batch_size, args.nhidden)
fixed_noise = torch.FloatTensor(args.nlayers, args.batch_size, args.nhidden).normal_(0, 1)
label = torch.FloatTensor(args.batch_size)
ones = torch.FloatTensor(args.batch_size)
real_label = 1
fake_label = 0

input_ = to_gpu(args.cuda, Variable(input_))
label = to_gpu(args.cuda, Variable(label))
noise = to_gpu(args.cuda, Variable(noise))
fixed_noise = to_gpu(args.cuda, Variable(fixed_noise))
ones = to_gpu(args.cuda, Variable(ones))

# Binary cross entropy loss
criterion = nn.BCELoss()

if args.cuda:
    netD.cuda()
    netG.cuda()
    criterion.cuda()
    input_, label = input_.cuda(), label.cuda()
    noise, fixed_noise = noise.cuda(), fixed_noise.cuda()

# Main Training Loop
g_losses = []
d_losses = []

# Discriminator and Generator share embedding weights
netD.embedding._parameters['weight'] = netG.embedding._parameters['weight']

# do checkpointing
torch.save(netG.state_dict(), '%s/netG_epoch_%d.pth' % (args.outf, 0))
torch.save(netD.state_dict(), '%s/netD_epoch_%d.pth' % (args.outf, 0))
last_D_x = 0.5
last_D_z = None
best_test_loss = None

train_data = batchify(corpus.train, args.batch_size, shuffle=True, max_len=50)

best_G = '%s/netG_epoch_%d.pth' % (args.outf, 0)

###############################################################################
# Language Model Generation
###############################################################################

print("\nLanguage Model Generation")
# Generate fake sentences
fake_probs, list_indices = netG(teacher_forcing=False, input_=fixed_noise,
                                sample=args.sample, temp=args.temp)
indices = torch.cat(list_indices, 1)

with open("%s/language_model.txt" % args.outf, "w") as f:
    fake, fake_lengths = truncate(indices, args.cuda, sort=False)
    for ex in fake.data:
        chars = " ".join([corpus.dictionary.idx2word[x] for x in ex])
        f.write(chars)
        f.write("\n")

###############################################################################
# Training loop
###############################################################################

# At any point you can hit Ctrl + C to break out of training early.
try:
    print("\nTraining...")
    # Loop through epochs
    for epoch in range(1, args.epochs+1):

        # Loop through batches
        for i, (data, target, lengths) in enumerate(train_data):
            ############################
            # (1) Update D network: maximize log(D(x)) + log(1 - D(G(z)))
            ###########################
            data = data[:, 1:]
            netD.zero_grad()
            batch_size = data.size(0)

            # Train with Real Examples ----------------------------
            label.data.resize_(batch_size).fill_(real_label)
            data = to_gpu(args.cuda, Variable(data))

            output = netD(data, lengths)
            errD_real = criterion(output, label)
            errD_real.backward()
            D_x = output.data.mean()

            # Train with Generated Examples ----------------------------

            # Resample noise for generator
            noise.data.resize_(args.nlayers, batch_size, args.nhidden)
            noise.data.normal_(0, 1)

            # Generate fake text
            fake_probs, list_indices = netG(teacher_forcing=False, input_=noise, sample=True, temp=args.temp)
            indices = torch.cat(list_indices, 1)

            fake, fake_lengths = truncate(indices, args.cuda)
            label.data.resize_(len(fake_lengths)).fill_(fake_label)

            # detach b/c discriminator does NOT backpropagate into the generator (adversarial objective)
            output = netD(fake.detach(), fake_lengths)
            errD_fake = criterion(output, label)
            errD_fake.backward(retain_graph=True)
            D_G_z1 = output.data.mean()

            errD = errD_real + errD_fake

            if last_D_z is None:
                last_D_z = D_G_z1

            if D_x < 0.9:
                # Sum losses from training on real and fake examples
                optimizerD.step()
                last_D_x = D_x
                last_D_z = D_G_z1

            netG.embedding._parameters['weight'] = netD.embedding._parameters['weight']
            d_losses.append((epoch, i, errD.data.cpu()[0]))

            if epoch != 1 or i > args.k:
                ############################
                # (2) Update G network: maximize log(D(G(z)))
                ###########################
                netG.zero_grad()
                label.data.fill_(real_label)  # fake labels are real for generator cost
                # generator gets signal from discriminator, don't detach output
                prob_real = netD(fake, fake_lengths)
                generated_lengths = to_gpu(args.cuda, Variable(torch.from_numpy(np.array(fake_lengths))))

                # Regular REINFORCE: reward is log probability of objective (tricking discriminator)
                #log_prob = prob_real.log()

                # Maximum-Likelihood Augmented
                ones.data.resize_(len(fake_lengths)).fill_(1)
                weight = torch.div(prob_real, ones - prob_real)
                total = torch.sum(weight)
                mlreward = torch.div(weight, total.data[0])

                if mlreward.size(0) < batch_size:
                    ones.data.resize_(batch_size-mlreward.size(0)).fill_(0)
                    mlreward = torch.cat([mlreward, ones], 0)

                # Policy gradient reward
                total_reward = 0
                for j, action in enumerate(list_indices):
                    # Create sentence length mask over padding
                    mask = generated_lengths.gt(j).float()
                    if mask.size(0) < batch_size:
                        mask = torch.cat([mask, ones], 0)
                    if args.reinforce:
                        reward = log_prob * mask
                    else:
                        reward = mlreward * mask
                    reward = reward.unsqueeze(1)
                    action.reinforce(reward.data)
                    total_reward += torch.sum(reward)

                optimizerG.zero_grad()
                autograd.backward(list_indices, [None for _ in list_indices], retain_graph=True)
                optimizerG.step()

                total_reward = total_reward.data.cpu()[0] / batch_size
                g_losses.append((epoch, i, total_reward))
                netD.embedding._parameters['weight'] = netG.embedding._parameters['weight']

                if i % 25 == 0:
                    print('[%d/%d][%d/%d] Loss_D: %.4f Loss_G: %.4f D(x): %.4f D(G(z)): %.4f'
                        % (epoch, args.epochs, i, len(train_data),
                            errD.data[0], total_reward, D_x, D_G_z1))

                    with open("%s/%d-%d-epoch_real.txt" % (args.outf, i, epoch), "w") as f:
                        indices = data.data.cpu().numpy()
                        for ex in indices:
                            chars = " ".join([corpus.dictionary.idx2word[x] for x in ex])
                            f.write(chars)
                            f.write("\n")

                    with open("%s/%d-%d-epoch_fake.txt" % (args.outf, i, epoch), "w") as f:
                        fake_embeddings, list_indices = netG(teacher_forcing=False,
                                                             input_=fixed_noise,
                                                             sample=args.sample,
                                                             temp=args.temp)
                        indices = torch.cat(list_indices, 1)
                        fake, fake_lengths = truncate(indices, args.cuda, sort=False)
                        for ex in fake.data:
                            chars = " ".join([corpus.dictionary.idx2word[x] for x in ex])
                            f.write(chars)
                            f.write("\n")

            if i % 100 == 0:
                # Run on test data.
                test_loss = lm_evaluate(test_data)
                print('=' * 89)
                print('| test loss {:5.2f} | test ppl {:8.2f}'.format(
                    test_loss, math.exp(test_loss)))
                print('=' * 89)

                if best_test_loss is None or best_test_loss > test_loss:
                    print("saving with new best loss", test_loss)
                    # do checkpointing
                    best_G = '%s/netG_epoch_%d_best.pth' % (args.outf, epoch)
                    torch.save(netG.state_dict(), '%s/netG_epoch_%d_best.pth' % (args.outf, epoch))
                    torch.save(netD.state_dict(), '%s/netD_epoch_%d_best.pth' % (args.outf, epoch))
                    pickle.dump(g_losses, open("%s/netG_stats_epoch_%d_best.p" % (args.outf, epoch), "wb"))
                    pickle.dump(d_losses, open("%s/netD_stats_epoch_%d_best.p" % (args.outf, epoch), "wb"))
                    best_test_loss = test_loss

        # do checkpointing
        torch.save(netG.state_dict(), '%s/netG_epoch_%d.pth' % (args.outf, epoch))
        torch.save(netD.state_dict(), '%s/netD_epoch_%d.pth' % (args.outf, epoch))
        pickle.dump(g_losses, open("%s/netG_stats_epoch_%d.p" % (args.outf, epoch), "wb"))
        pickle.dump(d_losses, open("%s/netD_stats_epoch_%d.p" % (args.outf, epoch), "wb"))

except KeyboardInterrupt:
    print('-' * 89)
    print('Exiting from training early')

    # # Load the best saved model.
    with open(best_G, 'rb') as f:
        netG.load_state_dict(torch.load(f))

    # Run on test data.
    test_loss = lm_evaluate(test_data)
    print('=' * 89)
    print('| End of training | test loss {:5.2f} | test ppl {:8.2f}'.format(
        test_loss, math.exp(test_loss)))
    print('=' * 89)
    exit(0)

print('-' * 89)
print('Exiting from training early')

# Load the best saved model.
with open(best_G, 'rb') as f:
    netG.load_state_dict(torch.load(f))

# Run on test data.
test_loss = lm_evaluate(test_data)
print('=' * 89)
print('| End of training | test loss {:5.2f} | test ppl {:8.2f}'.format(
    test_loss, math.exp(test_loss)))
print('=' * 89)


# This is a simple web server showing
# temperature, pressure and humidity data

import machine
import network
import socket
import time
from machine import Pin, I2C
from BME280.BME280 import BME280

# The web page template
html = """<!DOCTYPE html>

        <title>Pico W</title>
        <meta http-equiv="refresh" content="30">

Pico W with BME280 Sensor

            Temperature: %s,
            Pressure: %s,
            Humidity: %s

"""

# show we are alive
led = Pin("LED", machine.Pin.OUT)
led.on()
# start up the wifi connection
wlan = network.WLAN(network.STA_IF)
wlan.active(True)
wlan.connect('router-name-here', 'connection-password-here')

# try to connect
while True:
    if wlan.status() < 0 or wlan.status() >= 3:
        break
    print('Waiting for connection...')
    time.sleep(5)

if wlan.status() != 3:
    print('Cannot connect to the wifi')
    time.sleep(5)
    machine.reset()
else:
    status = wlan.ifconfig()
    print('WLAN established on: ' + status[0]) # you need this address to connect on

# connect to the BME280 sensor on the i2c bus
i2c = I2C(0, sda=Pin(0), scl=Pin(1))
bme = BME280(i2c=i2c)

# create a socket and start listening
try:
    addr = socket.getaddrinfo('0.0.0.0', 80)[0][-1] # port 80
    skt = socket.socket()
    skt.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    skt.bind(addr)
    skt.listen(1)
    print('Web server is now listening on address: ', addr[1])
except Exception as e:
    print('Get connection failed: ', e)
    machine.reset()

#
# flash the led to let the user know we have a connection
for _ in range (5):
    led.off()
    time.sleep(0.5)
    led.on()
    time.sleep(0.5)
led.off()

# listen for connections, respond and loop back for the next one
conn = None
while True:
    try:
        conn, addr = skt.accept()
        led.on() # flash every time we service a request
        print('Request from: ', addr)
        request = conn.recv(1024) # not used, just interesting to see what was sent
        print(request)

        response = html % bme.values

        conn.send('HTTP/1.0 200 OK\nContent-type: text/html\n\n')
        conn.send(response)
        conn.close()
        led.off()

    except Exception as e:
        print('Something broke while serving the page: ', e)
        if conn != None:
            conn.close()
        if skt != None:
            skt.close()
        print('Connection closed')
        break

# restart if something bad happened
machine.reset()


n = int(input())
data = list(map(int, input().split()))

count = 0
data.sort()

while True:
    n = n - data[-1]
    count += 1
    data.pop()

    if data[-1] <= n:
        count += 1
        break

print(count)

"""
# 2023/04/01 풀이
import sys

n = int(input())

people = list(map(int, sys.stdin.readline().split()))

people.sort()       # 맨 마지막 사람이 가장 무서움을 많이 느끼는 사람

cnt = 0
while people:
    k = people.pop()
    cnt += 1
    for i in range(k-1):
        if not people:
            break
        people.pop()

print(cnt)

"""

"""
# 책 정답 풀이

n = int(input())
data = list(map(int, input().split()))
data.sort()

result = 0
count = 0

for i in data:
    count += 1
    if count >= i:
        result += 1
        count = 0

print(result)
"""

이것이코딩테스트다/Greedy/모험가길드.py


from datetime import date, datetime, timedelta
from time import daylight, sleep

def getNumberOfWeeksTillNow(year,month,day):

    d1=date(year,month,day)
    d2=date.today()

    monday1 = (d1 - timedelta(days=d1.weekday()))
    monday2 = (d2 - timedelta(days=d2.weekday()))
    return (monday2 - monday1).days / 7


# 중복조합풀이! 난 조합으로 풀려고 했기에, 안되었던 것
cards = list(input())

path = ['']*4
cnt_odd = 0
cnt_even = 0
used = [0]*len(cards)
answer = []
def abc(level, start):
    if level == 4:
        if path[0] !=0:
            number = path[0]+path[1]+path[2]+path[3]
            answer.append(number)
        return

    for i in range(start, len(cards)):
        path[level] = cards[i]
        abc(level+1, i) # 중복조합이니까, i+1대신에 i..... ㅜ

abc(0, 0)

answer = [int(i) for i in answer]
for i in range(len(answer)):
    if answer[i] % 2 == 1:
        cnt_odd += 1
    else:
        cnt_even += 1

print(len(answer),end = ' ')
print(cnt_even, end=' ')
print(cnt_odd, end= ' ')


from django.shortcuts import render
from app.helper import save_to_cache
from django.http.response import JsonResponse
from django.conf import settings
from requests.exceptions import RequestException
from django.conf import settings
from django.core.cache import cache
import requests
import json

class Api():

	def __init__(self):
		self.API_URL = 'https://currencydatafeed.com/api/data.php'
		self.MAIN_CURRENCIES = ('EUR', 'USD', 'CSK', 'PLN')

	def get_currency(self, currency: str):
		"""Get currencies.

		currency -- string in format 'EUR/USD'
		"""
		try:
			response = requests.get(f'{self.API_URL}?token={settings.CURRENCY_TOKEN}&currency={currency}')
			return response.json()
		except RequestException as re:
			return {'error': f'RequestException: {re}'}
		except ValueError as ve:
			return {'error': f'JsonException: {ve}'}

	@staticmethod
	def read_codes():
		"""Read currency codes from json"""
		codes_file = open(f'{settings.BASE_DIR}/resources/fixtures/codes.json')
		codes = json.load(codes_file)
		codes_file.close()
		return codes

	def get_all_currencies(self):
		"""Get currencies for all main codes"""
		currencies = {}
		codes = self.read_codes()
		for currency in self.MAIN_CURRENCIES:
			currency_param = ''
			for code in codes:
				if currency != code["code"]:
					currency_param += f'{currency}/{code["code"]}+'
			result = self.get_currency(currency_param[0:-1])
			if 'error' not in result:
				currencies[currency] = result['currency']
			else:
				currencies[currency] = result
		return currencies

	def show_currency(self, request, from_code:str, to_code:str):
		result = {}
		currencies = self.__from_cache_or_request()
		for item in currencies[from_code]:
			if item['currency'] == f'{from_code}/{to_code}':
				result = item
				break
		return JsonResponse(result, safe=False)

	def show_all_currencies(self, request):
		"""
		Show all currencies in json.

		request -- request object
		"""
		currencies = self.__from_cache_or_request()
		return JsonResponse(currencies, safe=False)

	def show_codes(self, request):
		"""
		Show countries and codes and currencies in json"""
		return JsonResponse(self.read_codes(), safe=False)

	def __from_cache_or_request(self):
		"""Get currencies fron cache or make request"""
		currencies = cache.get('currencies')
		if currencies is None or len(currencies) == 0:
			currencies = self.get_all_currencies()
			save_to_cache(currencies)
		return currencies


from collections import Counter

def simulate(fishes, days):
    counter = Counter(fishes)

    for _ in range(days):
        born = counter[0]

        for i in range(8):
            counter[i] = counter[i + 1]

        counter[6] += born
        counter[8] = born

    return sum(counter.values())

#with open('test-input.txt', 'r') as f:
with open('input.txt', 'r') as f:
    fishes = [int(x) for x in f.read().split(',')]

solution1 = simulate(fishes, 80)
solution2 = simulate(fishes, 256)
print(solution1, solution2)


import unittest

import bitstamp.client
import mock
import requests
import hmac
import hashlib

from .fake_response import FakeResponse

class TradingTests(unittest.TestCase):

    def setUp(self):
        self.username = 'USERNAME'
        self.key = 'KEY'
        self.secret = 'SECRET'
        self.client = bitstamp.client.Trading(
            self.username, self.key, self.secret)

    def test_bad_response(self):
        response = FakeResponse(b'''{"error": "something went wrong"}''')
        with mock.patch('requests.post', return_value=response):
            self.assertRaises(
                bitstamp.client.BitstampError, self.client.account_balance)

    def test_nonjson_response(self):
        response = FakeResponse(b'''Hey wait, this isn't JSON!''')
        with mock.patch('requests.post', return_value=response):
            self.assertRaises(
                bitstamp.client.BitstampError, self.client.account_balance)

    def test_404_response(self):
        response = FakeResponse(status_code=404)
        with mock.patch('requests.post', return_value=response):
            self.assertRaises(requests.HTTPError, self.client.account_balance)

    def test_nonce(self):
        # Each call to .nonce increases it.
        with mock.patch('time.time', return_value=1):
            self.assertEqual(self.client.get_nonce(), 1)
            self.assertEqual(self.client.get_nonce(), 2)
            self.assertEqual(self.client.get_nonce(), 3)
        # But if the unix time is greater, use that instead.
        with mock.patch('time.time', return_value=10):
            self.assertEqual(self.client.get_nonce(), 10)

    def test_500_response(self):
        response = FakeResponse(status_code=500)
        with mock.patch('requests.post', return_value=response):
            self.assertRaises(requests.HTTPError, self.client.account_balance)

    def test_signing(self):
        response = FakeResponse(b'[]')
        with mock.patch('requests.post', return_value=response) as mocker:
            self.client._post('test')
        kwargs = mocker.call_args[1]
        self.assertIn('data', kwargs)
        self.assertIn('nonce', kwargs['data'])
        self.assertIn('signature', kwargs['data'])
        self.assertEqual(kwargs['data'].get('key'), 'KEY')

    def test_account_balance(self):
        response = FakeResponse(b'''{
            "usd_balance": "100.00",
            "btc_balance": "2.001",
            "usd_reserved": "40",
            "btc_reserved": "1",
            "usd_available": "60.00",
            "btc_available": "1.001"}''')
        with mock.patch('requests.post', return_value=response):
            result = self.client.account_balance()
        self.assertIsInstance(result, dict)

    def test_user_transactions(self):
        response = FakeResponse(b'[]')
        with mock.patch('requests.post', return_value=response):
            result = self.client.user_transactions()
        self.assertIsInstance(result, list)

    def test_open_orders(self):
        response = FakeResponse(b'[]')
        with mock.patch('requests.post', return_value=response):
            result = self.client.open_orders()
        self.assertIsInstance(result, list)

    def test_all_open_orders(self):
        response = FakeResponse(b'[]')
        with mock.patch('requests.post', return_value=response):
            result = self.client.all_open_orders()
        self.assertIsInstance(result, list)

    def test_order_status(self):
        response = FakeResponse(b'''{"status": "Open", "transactions": []}''')
        with mock.patch('requests.post', return_value=response):
            result = self.client.order_status(0000000000)
        self.assertIsInstance(result, dict)

    def test_bitcoin_deposit_address(self):
        response = FakeResponse(b'"1ARfAEqUzAtbnuJLUxm5KKfDJqrGi27hwA"')
        with mock.patch('requests.post', return_value=response):
            result = self.client.bitcoin_deposit_address()
        self.assertEqual(result, '1ARfAEqUzAtbnuJLUxm5KKfDJqrGi27hwA')

    def test_litecoin_deposit_address(self):
        response = FakeResponse(b'"MVYt6Mw6XHp7UE1gDn6pa8ZbsdtWqWiZUp"')
        with mock.patch('requests.post', return_value=response):
            result = self.client.litecoin_deposit_address()
        self.assertEqual(result, 'MVYt6Mw6XHp7UE1gDn6pa8ZbsdtWqWiZUp')

    def test_ethereum_deposit_address(self):
        response = FakeResponse(b'"0xbd8c4ffcb30c1fed0facf716bc9fd5849539e1c2"')
        with mock.patch('requests.post', return_value=response):
            result = self.client.ethereum_deposit_address()
        self.assertEqual(result, '0xbd8c4ffcb30c1fed0facf716bc9fd5849539e1c2')

    def test_xrp_deposit_address(self):
        response = FakeResponse(b'{"destination_tag": 53965834, "address":"rDsbeamaa4FFwbQTJp9Rs84Q56vCiWCaBx"}')
        with mock.patch('requests.post', return_value=response):
            result = self.client.xrp_deposit_address()
        self.assertDictEqual(result, {u'destination_tag': 53965834, u'address': u'rDsbeamaa4FFwbQTJp9Rs84Q56vCiWCaBx'})

    def test_buy_limit_order(self):
        response = FakeResponse(b'''
            {"amount": "0.1",
             "datetime": "2014-01-22 01:20:23.226788",
             "id": 55507211,
             "price": "90",
             "type": 0}''')
        with mock.patch('requests.post', return_value=response):
            result = self.client.buy_limit_order('0.1', '90')
        self.assertIsInstance(result, dict)

    def test_sell_limit_order(self):
        response = FakeResponse(b'''
            {"amount": "1",
             "datetime": "2014-01-22 02:20:23.226788",
             "id": 55507212,
             "price": "9000",
             "type": 1}''')
        with mock.patch('requests.post', return_value=response):
            result = self.client.sell_limit_order('1', '9000')
        self.assertIsInstance(result, dict)

    def test_buy_market_order(self):
        response = FakeResponse(b'''
            {"amount": "0.1",
             "datetime": "2014-01-22 01:20:23.226788",
             "id": 55507211,
             "price": "90",
             "type": 0}''')
        with mock.patch('requests.post', return_value=response):
            result = self.client.buy_market_order('0.1')
        self.assertIsInstance(result, dict)

    def test_sell_market_order(self):
        response = FakeResponse(b'''
            {"amount": "1",
             "datetime": "2014-01-22 02:20:23.226788",
             "id": 55507212,
             "price": "9000",
             "type": 1}''')
        with mock.patch('requests.post', return_value=response):
            result = self.client.sell_market_order('1')
        self.assertIsInstance(result, dict)

    def test_cancel_order(self):
        response = FakeResponse(b'true')
        with mock.patch('requests.post', return_value=response):
            result = self.client.cancel_order('15807214')
        self.assertTrue(result)

    def test_cancel_order_v2(self):
        response = FakeResponse(b'{}')
        with mock.patch('requests.post', return_value=response):
            result = self.client.cancel_order('15807214', version=2)
        self.assertIsInstance(result, dict)

    def test_cancel_all_orders(self):
        response = FakeResponse(b'true')
        with mock.patch('requests.post', return_value=response):
            result = self.client.cancel_all_orders()
        self.assertTrue(result)

    def test_withdrawal_requests(self):
        response = FakeResponse(b'[]')
        with mock.patch('requests.post', return_value=response):
            result = self.client.withdrawal_requests()
        self.assertIsInstance(result, list)

    def test_unconfirmed_bitcoin_deposits(self):
        response = FakeResponse(b'[]')
        with mock.patch('requests.post', return_value=response):
            result = self.client.unconfirmed_bitcoin_deposits()
        self.assertIsInstance(result, list)

    def test_default_data(self):
        """
        GitHub Issue #9
        """
        ret_data = self.client._default_data()
        msg = str(ret_data['nonce']) + self.username + self.key
        signature = hmac.new(
            self.secret.encode('utf-8'), msg=msg.encode('utf-8'),
            digestmod=hashlib.sha256).hexdigest().upper()
        self.assertEqual(signature, ret_data['signature'])

    def test_bitcoin_withdrawal(self):
        response = FakeResponse(b'''{"id": "1"}''')
        with mock.patch('requests.post', return_value=response):
            result = self.client.bitcoin_withdrawal(1, '3J98a1Wpaf73CNmQviecrnyiWrnqRhWNLy')
        self.assertIsInstance(result, dict)

    def test_bch_withdrawal(self):
        response = FakeResponse(b'''{"id": "1"}''')
        with mock.patch('requests.post', return_value=response):
            result = self.client.bch_withdrawal(1, '17xu2tUdikA2grgqnVoxQxAKRuDuwmPDjU')
        self.assertIsInstance(result, dict)

    def test_xrp_withdrawal(self):
        response = FakeResponse(b'''{"id": "1"}''')
        with mock.patch('requests.post', return_value=response):
            result = self.client.xrp_withdrawal(1, "rDsbeamaa4FFwbQTJp9Rs84Q56vCiWCaBx")
        self.assertEqual(result, '1')

    def test_transfer_to_main(self):
        response = FakeResponse(b'{"status": "ok"}')
        with mock.patch('requests.post', return_value=response):
            result = self.client.transfer_to_main(1, "btc")
        self.assertIsInstance(result, dict)
        self.assertEqual(result["status"], "ok")

    def test_transfer_from_main(self):
        response = FakeResponse(b'{"status": "ok"}')
        with mock.patch('requests.post', return_value=response):
            result = self.client.transfer_from_main(1, "btc", "")
        self.assertIsInstance(result, dict)
        self.assertEqual(result["status"], "ok")

if __name__ == '__main__':
    unittest.main()


# coding: utf-8

# # Amazon and Rotten Tomatoes Entity Resolution
# ### Adam Coviensky (ac4092), Ian Johnson (icj2103)
# ### Instabase submission: icj2103
# ### GitHub repo: https://github.com/adamianaml/aml-entity-resolution

# Our entity resolution technique involved joining the Amazon and Rotten Tomatoes databases for the ID’s listed in the training set. We then matched the schemas for the features contained in both of the datasets and created new features from these. These features included the absolute value of the difference in time. Boolean features indicating whether or not the directors of the two movies are the same, the runtimes are the same, and whether or not the runtimes are the same within some range (we used 3 minutes). We then created features for the number of matching actors and for the percentage of matching actors. Finally, we performed cross-validation with a customized gridsearch using the training set to determine which features we should be keeping in our final model and which classifier to use between a decision tree, a random forest, and the gradient boosting classifier.
#
# Our model had a precision, recall, and F1-scores of 0.97, 0.97 and 0.96 respectively for the training set. We obtained these scores by using train_test_split on our training set and fitting the model to the training portion and testing it on the testing portion.
#
#
# The most important features were determined to be ‘time_same_2’ which is a binary variable indicating whether the two runtimes are equivalent within a range of 3 minutes. Also, ‘directors_same’, indicated whether the two directors are the same.  ‘num_match_stars’ and ‘percent_match_stars’ indicated the number of matching stars and the percentage of the stars matched from the Amazon dataset respectively. These were the features we used to train our final model.
#
# We avoided pairwise comparison of all movies across both datasets by simply joining the id’s listed in the training set to create a model. We trained a random forest classifier on this training data with our newly created features. This allowed us to predict whether two new movies matched using our trained random forest on a new combination of two movies.

# In[18]:

import re
import pandas as pd
import numpy as np

from sklearn.cross_validation import train_test_split
from sklearn.ensemble import RandomForestClassifier

np.random.seed(42)

ama = pd.read_csv('./data/amazon.csv')
rt = pd.read_csv('./data/rotten_tomatoes.csv')

holdout = pd.read_csv('./holdout.csv')
test = pd.read_csv('./test.csv')
train = pd.read_csv('./train.csv')

# ### Define Columns

# In[19]:

ama.columns = [
    'id_left',
    'time_left',
    'director_left',
    'star_left',
    'cost_left'
]

rt.columns = [
    'id_right',
    'time_right',
    'director_right',
    'year_right',
    'star1_right',
    'star2_right',
    'star3_right',
    'star4_right',
    'star5_right',
    'star6_right',
    'rotten_tomatoes_right',
    'audience_rating_right',
    'review1_right',
    'review2_right',
    'review3_right',
    'review4_right',
    'review5_right'
]

# ### Feature Creation Function

# In[20]:

def create_features(dataset):
    new_data = pd.DataFrame(dtype=str)

    for index, row in dataset.iterrows():
        amarow = ama[ama['id_left'] == row['id1']]
        rtrow = rt[rt['id_right'] == row['id 2']]

        amarow.reset_index(drop=True, inplace=True)
        rtrow.reset_index(drop=True, inplace=True)

        new_row = pd.concat([amarow, rtrow], axis=1)
        new_data = pd.concat([new_data, new_row])

    new_data.fillna('0', inplace = True)
    new_data.dropna()

    # Compute directors match column
    new_data['directors_same'] = (new_data['director_left'] == new_data['director_right']).astype(int)

    # Compute time columns
    new_data['time_left'] = new_data['time_left'].astype(str)
    new_data['time_right'] = new_data['time_right'].astype(str)
    new_data['time_norm_left'] = new_data['time_left'].apply(compute_time_norm)
    new_data['time_norm_right'] = new_data['time_right'].apply(compute_time_norm)
    new_data['time_same'] = (new_data['time_norm_left'].astype(int) == new_data['time_norm_right'].astype(int)).astype(int)
    new_data['time_same_2'] = (abs((new_data['time_norm_left'].astype(int) - new_data['time_norm_right'].astype(int)).astype(int)) <= 3).astype(int)
    new_data['time_diff'] = (new_data['time_norm_left'].astype(int) - new_data['time_norm_right'].astype(int)).astype(int)
    new_data['time_diff_abs'] = abs(new_data['time_diff']).astype(int)

    # Compute actors columns
    actors_split = new_data['star_left'].str.split(', ', expand=True)
    for i in range(6 - actors_split.shape[1]):
        actors_split[str(i)] = ""
    actors_split.columns = ['star_' + str(i) for i in range(6)]
    new_data = pd.concat([new_data, actors_split], axis=1)

    # Number actors match
    cols = list(new_data.loc[:,'star_0':'star_4']) + list(new_data.loc[:,'star1_right':'star6_right'])
    new_data['num_match_stars'] = new_data[cols].apply(compute_number_stars_match, axis = 1)

    # Percent actors match
    new_data['percent_match_stars'] = new_data[cols].apply(compute_percent_stars_match, axis = 1)

    return new_data

# ### Helper Feature Creation Functions

# In[21]:

def compute_number_stars_match(row):
    actors_left = ['star_0', 'star_1', 'star_2', 'star_3', 'star_4']
    actors_right = ['star1_right', 'star2_right', 'star3_right', 'star4_right', 'star5_right', 'star6_right']
    list_left = row.loc[actors_left].tolist()
    list_right = row.loc[actors_right].tolist()

    # Avoid matching nulls
    list_left = filter(None, list_left)
    list_right = filter(None, list_right)

    return len(np.intersect1d(list_left, list_right))

def compute_percent_stars_match(row):
    actors_left = ['star_0', 'star_1', 'star_2', 'star_3', 'star_4']
    actors_right = ['star1_right', 'star2_right', 'star3_right', 'star4_right', 'star5_right', 'star6_right']
    list_left = row.loc[actors_left].tolist()
    list_left = filter(None, list_left)
    list_right = row.loc[actors_right].tolist()
    x = float(len(np.intersect1d(list_left, list_right)))
    ama_num = len(list_left)
    return x / ama_num

regex = re.compile(r'[0-9]*')

def compute_time_norm(row):
    row = str(row)

    if '/' in row:
        # Invalid time entry
        print(row)
        return 0

    match = regex.findall(row)
    temp = filter(None, match)
    if len(temp) == 2:
        return 60*int(temp[0]) + int(temp[1])
    if len(temp) == 1:
        return temp[0]

def remove_bad_samples(data):

    train.reset_index(drop=True, inplace=True)
    data.reset_index(drop=True, inplace=True)
    data = pd.concat([data, train], axis=1)

    # Remove bad training rows
    data = data[data['id_left'] != 199]
    data = data[data['id_left'] != 680]
    data = data[data['id_left'] != 487]
    data = data[data['id_left'] != 756]
    data = data[data['id_left'] != 770]
    data = data[data['id_left'] != 1701]

    return data

# ### Predict With Training Data

# In[23]:

features_cols = [
    'time_same_2',
    'directors_same',
    'num_match_stars',
    'percent_match_stars',
]

train_data = create_features(train)
train_data = remove_bad_samples(train_data)

x_train, x_test, y_train, y_test = train_test_split(train_data[features_cols], train_data['gold'], random_state=10)

clf = RandomForestClassifier(random_state=42)
clf.fit(x_train, y_train)
scores = clf.score(x_test, y_test)

preds = clf.predict(x_test)

# F1 score:
from sklearn.metrics import classification_report
print(classification_report(y_test, preds))

# ### Final Predictions

# In[24]:

features_cols = [
    'time_same_2',
    'directors_same',
    'num_match_stars',
    'percent_match_stars',
]

# Test Predictions
train_data = create_features(train)
train_data = remove_bad_samples(train_data)
test_data = create_features(test)

clf = RandomForestClassifier()
clf.fit(train_data[features_cols], train_data['gold'])
test_preds = clf.predict(test_data[features_cols])

test_preds = pd.DataFrame(test_preds)
test_preds.columns = ['gold']
test_preds.to_csv('test_gold.csv', index=False)

# Holdout Predictions
train_data = create_features(train)
train_data = remove_bad_samples(train_data)
holdout_data = create_features(holdout)

clf = RandomForestClassifier()
clf.fit(train_data[features_cols], train_data['gold'])
holdout_preds = clf.predict(holdout_data[features_cols])

holdout_preds = pd.DataFrame(holdout_preds)
holdout_preds.columns = ['gold']
holdout_preds.to_csv('holdout_gold.csv', index=False)

# In[ ]:


from torch.utils import data
from PIL import Image
import numpy as np
import torch
from torchvision.transforms.functional import to_tensor
from torchvision import transforms
class dataset_base(data.Dataset):#需要继承data.Dataset
    def __init__(self,data_x,data_y):
        self.raw_data_x=data_x
        self.raw_data_y=data_y
        self.new_size=224

    def __getitem__(self, index):
        data_x=self.raw_data_x[index]
        data_y=self.raw_data_y[index]
        if isinstance(data_x, str):
            data_x=np.array(Image.open(data_x).convert("RGB").resize((self.new_size, self.new_size)))
        data_x=to_tensor(data_x)
        if data_x.shape[0] == 1:
            data_x=data_x.repeat(3,1,1)
        return (data_x,data_y)

    def __len__(self):
        return len(self.raw_data_x)

normalize4caltech = transforms.Normalize((0.485, 0.456, 0.406),
                                        (0.229, 0.224, 0.225))
normalize4caltech_new = transforms.Normalize((0.5477,0.5305,0.5034),
                                         (0.3151,0.3095,0.3225))
normalize4cifar10 = transforms.Normalize((0.4914,0.4822,0.4465),
                                         (0.2470,0.2435,0.2615))
normalize4food = transforms.Normalize((0.5450, 0.4435, 0.3436),
                                      (0.2709, 0.2735, 0.2781))
normalize4clip = transforms.Normalize((0.48145466, 0.4578275, 0.40821073),
                                      (0.26862954, 0.26130258, 0.27577711))
# normalize4food = transforms.Normalize()
def get_mean_std(dataset, method="woclip"):
    if method in ["fedclip","cliptqn"]:
        return normalize4clip
    if dataset == "cifar10":
        return normalize4cifar10
    elif dataset == "caltech101":
        return normalize4caltech
    elif dataset == "food101":
        return normalize4food

def get_num_classes(dataset):
    if dataset == "cifar10":
        return 10
    elif dataset == "caltech101":
        return 101
    elif dataset == "food101":
        return 101


import sys
from sqlalchemy import MetaData, Table, Column, Integer, String, create_engine

meta = MetaData()
engine = create_engine(f"postgresql+psycopg2://{sys.argv[1]}:{sys.argv[2]}@localhost/arbk")

business = Table(
    'Businesses', meta,
    Column('ID', Integer, primary_key=True),
    Column('Name', String, nullable=False),
    Column('Trade_Name', String),
    Column('Business_ID', Integer),
    Column('Region', String),
    Column('Business_Type', String),
    Column('Status', String),
    Column('Link', String)
)

business_data = Table(  # Data are stored in Key-Value pairs
    'BusinessInfo', meta,
    Column('ID', Integer, primary_key=True),
    Column('Business_ID', Integer),
    Column('Key', String),
    Column('Value', String)
)

activity = Table(
    'Activities', meta,
    Column('ID', Integer, primary_key=True),
    Column('Business_ID', Integer),
    Column('Description', String),
    Column('Type', String)
)

def create_tables():
    meta.create_all(engine)


#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time    : 2020/11/13 21:33
# @Author  : huni
# @File    : CSDN上的彼岸图.py
# @Software: PyCharm

from urllib.request import urlretrieve
from bs4 import BeautifulSoup
import os
import requests
from urllib.error import HTTPError
from urllib.error import URLError
url="http://www.netbian.com/"
tempList=[]

#避开URL错误
def get_page_(imageLink,fileName):
    try:
        urlretrieve(imageLink, filename=fileName)
    except URLError as e:
        return None
#解析网页
def openhtml(label,attrs,end,url,sortUrl,urlList,):
    html = url + sortUrl + end
    page = requests.get(html)
    bso = BeautifulSoup(page.content, "html.parser")
    #找到要获取的标签
    for item in bso.findAll(label):
        if attrs in item.attrs:
            urlList.append(item.attrs[attrs])
#获取图片链接，并创建文件夹
def downimage(imageUrl,imageName,filepath):
    try:
        for index in range(0, len(imageUrl)):
            #去掉图片链接中.htm方便自定义链接
            imageUrl[index] = imageUrl[index].replace(".htm", "")
            #获取图片名称
            openhtml("img", "title", f"{imageUrl[index]}.htm", url=url, sortUrl="", urlList=imageName)
            #拼接链接
            image = requests.get(url + imageUrl[index] + "-1920x1080.htm")
            #解析图片链接获取.JPG链接
            page = BeautifulSoup(image.content, "html.parser")
            imageLink=(page.find("td").find("img").get("src"))
            #拼接下载时保存的文件名
            fileName="{}{}{}".format(filepath,imageName[index],".jpg")
            #下载到本地
            get_page_(imageLink=imageLink, fileName=fileName)
            print(imageName[index])
    except:
        print("图片异常，爬取失败")
#主体函数，整体流程在这
def wallpaperDown(sortname,sorturl,page,type):
    #新建保存到本地的文件夹
    filepath = f"E:\\1080p壁纸\\{sortname}\\"
    if not os.path.exists(filepath):
        os.makedirs(filepath)
    urlList=[]
    #打开壁纸分类地址
    openhtml("a","href",".htm",urlList=urlList,url=url,sortUrl=sorturl)
    #筛选出需要网页的连接
    urlList=[list for list in urlList if list is not None and f"{sorturl}" in list ]
    linkLength=len(sorturl)
    #获取网站页数用于循环
    if urlList==[]:
        end=""
    else:
        end = urlList[-2][2+linkLength:-4]
    #循环N页，获取下载链接

    for i in range(page,int(end)+1):
        # 下载第一页，上面的循环只能从第二页开始下载。
        if i>=int(end):
            print("正在下载第1页")
            homeImageUrl = []
            homeImageName = []
            #打开第一页
            openhtml("a", "href", ".htm", url=url, sortUrl=sorturl, urlList=homeImageUrl)
            #筛选出图片链接
            homeImageUrl=[list for list in homeImageUrl if list is not None and "/desk/" in list]
            #下载图片
            downimage(imageUrl=homeImageUrl, imageName=homeImageName, filepath=filepath)

        #判断下载类型，单类别下载则下载完尾页之后结束，多类别则继续下载其他类别
        if i >= int(end):
            if type==0:
                print(f"正在下载第{i}页",i,end)
                print(f"{sortname}壁纸已下载完毕")
                exit()
        else:
            print(f"正在下载第{i}页")
            imageUrl = []
            imageName = []
            # 找到包含下载链接的标签，并获取内容
            openhtml("a", "href", f"_{i}.htm", url=url, sortUrl=sorturl, urlList=imageUrl)
            # 筛选出需要的图片链接
            imageUrl = [list for list in imageUrl if list is not None and "/desk/" in list]
            # 下载图片
            downimage(imageUrl=imageUrl, imageName=imageName, filepath=filepath)

数据解析/CSDN上的彼岸图.py


import pygame
from pygame.sprite import Sprite
import random

class Bullet(Sprite):
    """A class to manage bullets fired from the ship"""

    def __init__(self, ai_game):
        """Create a bullet object at the ship's current position."""
        super().__init__()
        self.screen = ai_game.screen
        self.settings = ai_game.settings
        self.bullet_type = random.choice(["normal", "fast", "large"])
        self.set_bullet_properties()

        # Create a bullet rect at (0, 0) and then set correct position.
        self.rect = pygame.Rect(0, 0, self.width, self.height)
        self.rect.midtop = ai_game.ship.rect.midtop

        # Store the bullet's position as decimal values.
        self.y = float(self.rect.y)
        self.x = float(self.rect.x)

        # Make bullets curve left or right randomly
        self.curve_direction = random.choice([-1, 1])
        self.curve_speed = random.uniform(0.2, 0.8)

    def set_bullet_properties(self):
        """Set properties for different bullet types."""
        if self.bullet_type == "normal":
            self.color = self.settings.bullet_color
            self.speed = self.settings.bullet_speed
            self.width = self.settings.bullet_width
            self.height = self.settings.bullet_height
        elif self.bullet_type == "fast":
            self.color = (0, 255, 0)
            self.speed = self.settings.bullet_speed * 1.5
            self.width = self.settings.bullet_width
            self.height = self.settings.bullet_height
        elif self.bullet_type == "large":
            self.color = (255, 0, 0)
            self.speed = self.settings.bullet_speed * 0.8
            self.width = self.settings.bullet_width * 2
            self.height = self.settings.bullet_height * 2

    def update(self):
        """Move the bullet up the screen and curve left or right."""
        # Update the decimal position of the bullet.
        self.y -= self.speed
        self.x += self.curve_direction * self.curve_speed

        # Update the rect position.
        self.rect.y = self.y
        self.rect.x = self.x

    def draw_bullet(self):
        """Draw the bullet to the screen."""
        pygame.draw.rect(self.screen, self.color, self.rect)


#!/usr/local/bin/python
# -*- coding: utf-8 -*-
##
# Georeference distance calculator
# @author: rafael magalhaes

# import math functions
from math import *

# Getting the latitute and longitude points from user
print("\nWelcome to Earth distance calculator! (degrees only)\n")
lat_1 = float(input("Inform the Latitude of the origin point: "))
lon_1 = float(input("Inform the Longitude of the origin point: "))
lat_2 = float(input("\nInform the Latitude of the destination point: "))
lon_2 = float(input("Inform the Longitude of the destination point: "))

# converting degrees to radians
lat_1 = radians(lat_1)
lon_1 = radians(lon_1)
lat_2 = radians(lat_2)
lon_2 = radians(lon_2)

# distance calculation
distance = 6371.01 * acos(sin(lat_1)*sin(lat_2) + cos(lat_1)*cos(lat_2) *
                          cos(lon_1 - lon_2))
# Displey the results
print("\nThe distance between points is: {:.2f} kilometers".format(distance))
print("\n")


import xml.etree.ElementTree as ET

class ESLReader:
    """
    Class to read ESL (Energy System Language) files.

    Attributes:
        tree (ElementTree): The parsed XML tree.
        root (Element): The root of the XML tree.
    """

    def __init__(self, filename):
        """
        Initialize the ESLReader class.

        Args:
            filename (str): The path of the ESL file to read.
        """
        self.tree = ET.parse(filename)
        self.root = self.tree.getroot()

    def get_interval(self):
        """
        Get the time interval of the ESL data.

        Returns:
            str: The start and end time of the data in the ESL file.
        """
        data = self.root.findall('.//TimePeriod')

        start_times = []

        for item in data:
            start_times.append(item.attrib["end"])

        return start_times[::-1]

    def get_values(self):
        """
        Get specific values from the ESL file based on OBIS codes.

        Returns:
            tuple: A tuple containing four values corresponding to OBIS codes 1-1:1.8.1,
            1-1:1.8.2, 1-1:2.8.1 and 1-1:2.8.2.
        """
        values = []
        dates = []
        bunch = self.root.findall('.//TimePeriod')

        for item in bunch:
            dates.append(item.attrib["end"])
            for child in item:
                if child.attrib["obis"] == "1-1:1.8.1":
                    values.append(child.attrib["value"])
                elif child.attrib["obis"] == "1-1:1.8.2":
                    values.append(child.attrib["value"])
                elif child.attrib["obis"] == "1-1:2.8.1":
                    values.append(child.attrib["value"])
                elif child.attrib["obis"] == "1-1:2.8.2":
                    values.append(child.attrib["value"])

        return values

    def get_usage(self):
        """
        Get total electricity usage from the ESL file.

        Returns:
            tuple: A tuple containing four values corresponding to OBIS codes 1-1:1.8.1,
            1-1:1.8.2, 1-1:2.8.1 and 1-1:2.8.2.
        """
        bunch = self.root.findall('.//TimePeriod')
        bunch = bunch[::-1]
        usage = []

        for item in bunch:
            subtotal = 0
            for child in item:
                if child.attrib["obis"] == "1-1:1.8.1":
                    subtotal += float(child.attrib["value"])
                elif child.attrib["obis"] == "1-1:1.8.2":
                    subtotal += float(child.attrib["value"])

            usage.append((item.attrib["end"], round(subtotal, 4))) if subtotal > 0 else None

        return usage

    def get_production(self):
        """
        Get total electricity production from the ESL file.

        Returns:
            tuple: A tuple containing four values corresponding to OBIS codes 1-1:1.8.1,
            1-1:1.8.2, 1-1:2.8.1 and 1-1:2.8.2.
        """
        bunch = self.root.findall('.//TimePeriod')
        bunch = bunch[::-1]
        prod = []

        for item in bunch:
            subtotal = 0
            for child in item:
                if child.attrib["obis"] == "1-1:2.8.1":
                    subtotal += float(child.attrib["value"])
                elif child.attrib["obis"] == "1-1:2.8.2":
                    subtotal += float(child.attrib["value"])

            prod.append((item.attrib["end"], round(subtotal, 4))) if subtotal > 0 else None

        return prod

    def get_values(self):
        """
        Get specific electricity usage and production values from the ESL file based on OBIS codes.

        Returns:
            list: A list of tuples, where each tuple contains the end time, electricity usage and
                electricity production values for that time period.
        """
        used = self.get_usage()
        produced = self.get_production()
        result = []

        for i in used:
            for j in produced:
                if i[0] == j[0]:
                    result.append((i[0], i[1], j[1]))
        return result

if __name__ == "__main__":
    esl = ESLReader('././data\ESL-Files\EdmRegisterWertExport_20201003_eslevu_20201003051024.xml')

    print(esl.get_usage())
    print(esl.get_production())
    print(esl.get_values())


"""
Primary function of recipe here
"""

import mbuild as mb

class BeadSpring(mb.Compound):
    """
    Example class that would go in your recipe.

    Parameters
    ----------
    your_argument: int
        This is an example argument

    """
    def __init__(self, n_beads=10, build='linear', bead_name='bead', spring_distance=1):
        super(BeadSpring, self).__init__()
        prev_bead = mb.Particle(pos=[0.0, 0.0, 0.0], name=bead_name)
        self.add(prev_bead)
        for n in range(1, n_beads):
            current_bead = mb.Particle(pos=[0.0, 0.0, n*spring_distance], name=bead_name)
            self.add(current_bead)
            self.add_bond((prev_bead, current_bead))
            prev_bead = current_bead


from PyQt5 import QtCore, QtGui, QtWidgets, QtMultimedia, QtMultimediaWidgets
#from PyQt5.QtWidgets import (QFileDialog, QWidget, QTableWidget, QHBoxLayout, QApplication, QDesktopWidget, QTableWidgetItem, QHeaderView, QMessageBox, QListWidgetItem)
from PyQt5.QtWidgets import *
#from PyQt5.QtCore import qDebug, QModelIndex
from PyQt5.QtCore import *
import sys,os
from ui_login import *
from ui_chat import *
import threading, time
from socket import *
from time import ctime,sleep
import random
from sys import argv, exit, stdout
#from Crypto.Random import get_random_bytes
import json
from extra import *
import random
#count = 0

translate = QCoreApplication.translate

class Main_Window(QThread):
    sig_refresh_msg_show = pyqtSignal(str)
    #sig_refresh_msg_show.connect(self.refresh_msg_show)
    sig_handle_msg = pyqtSignal(str)
    #sig_handle_msg.connect(self.handle_msg)
    sig_connect_to = pyqtSignal(str)
    #sig_connect_to.connect(self.connect_to)
    sig_update_add_pri = pyqtSignal(str)
    #sig_update_add_pri.connect(self.update_add_pri)
    sig_update_add_pub = pyqtSignal(str)
    #sig_update_add_pub.connect(self.update_add_pub)
    sig_update_rm_pri = pyqtSignal(str)
    #sig_update_rm_pri.connect(self.update_rm_pri)
    sig_update_rm_pub = pyqtSignal(str)
    #sig_update_rm_pub.connect(self.update_rm_pub)
    sig_test = pyqtSignal(str)

    def __init__(self, parent=None):
        super().__init__(parent)
        self.users_record = {}
        self.username = ""
        self.cur_user = "public"
        self.server_ip = ""
        self.server_port = 0
        self.ui_login = Ui_Login()
        self.ui_chat = Ui_Chat()
        self.wl = QtWidgets.QMainWindow()
        self.ui_login.setupUi(self.wl)
        self.wc = QtWidgets.QMainWindow()
        self.ui_chat.setupUi(self.wc)
        self.set_connect()
        self.init_para()
        self.center(1)
        self.Sessions = {}
        self.online_users = {}
        self.threads = {}
        self.status = False
        self.lock = threading.Lock()
        #self.msg_show_lock = threading.Lock()
        self.msg_stack = stack()
        self.register_signals()
        self.sig_test.connect(self.test_sig)
        self.sig_test.emit("hahaha")
        self.init_media()
        self.wl.show()

    def init_conn(self):
        key_pair = load_keys(self.username)
        self.private_key = key_pair[0]
        self.public_key = key_pair[1]
        self.server_addr = (self.server_ip, self.server_port)
        self.server_addr_a = (self.server_ip, self.server_port+1)
        self.clientSocket = socket(AF_INET, SOCK_DGRAM)
        self.Sessions["public"] = Session(self.server_addr, get_random_bytes(16))
        self.Sessions["public_a"] = Session(self.server_addr_a, get_random_bytes(16))

    def test_sig(self, test_msg):
        qDebug("test signal "+test_msg)

    def register_signals(self):
        #self.sig_refresh_msg_show = QtCore.pyqtSignal(str)
        self.sig_refresh_msg_show.connect(self.refresh_msg_show)
        #self.sig_handle_msg = QtCore.pyqtSignal(str)
        self.sig_handle_msg.connect(self.handle_msg)
        #self.sig_connect_to = QtCore.pyqtSignal(str)
        self.sig_connect_to.connect(self.connect_to)
        #self.sig_update_add_pri = QtCore.pyqtSignal(str)
        self.sig_update_add_pri.connect(self.update_add_pri)
        #self.sig_update_add_pub = QtCore.pyqtSignal(str)
        self.sig_update_add_pub.connect(self.update_add_pub)
        #self.sig_update_rm_pri = QtCore.pyqtSignal(str)
        self.sig_update_rm_pri.connect(self.update_rm_pri)
        #self.sig_update_rm_pub = QtCore.pyqtSignal(str)
        self.sig_update_rm_pub.connect(self.update_rm_pub)

    def init_para(self):
        self.ui_login.server_ip.setText("127.0.0.1")
        self.ui_login.server_port.setText("20000")
        self.ui_login.user_name.setText("sustc")

    def init_chat(self):
        #init_users = ["public", "zt", "sustc", "su"]
        init_users = self.online_users.keys()
        self.ui_chat.pri_users.addItem(QListWidgetItem("public"))
        for user in init_users:
            self.ui_chat.pub_users.addItem(QListWidgetItem(user))
            self.users_record[user] = []

        #self.users_record["public"] = [chat_record("public","hello"), chat_record("public","world")]
        #self.users_record["zt"] = [chat_record("zt","hey"), chat_record("zt","zt")]

    def init_media(self):
        qDebug("init media resources")
        media_root="./music"
        self.play_list = QtMultimedia.QMediaPlaylist()
        self.play_list.setPlaybackMode(QtMultimedia.QMediaPlaylist.Random)
        qDebug("????")
        self.player = QtMultimedia.QMediaPlayer()
        qDebug("???")
        self.player.setPlaylist(self.play_list)
        self.play_names = []
        file_list = do_dir(media_root, "mp3")
        qDebug(json.dumps(file_list))
        for fpath in file_list:
            qDebug(fpath)
            media_content = QtMultimedia.QMediaContent(QUrl.fromLocalFile(fpath))
            self.play_list.addMedia(media_content)
            fname = fpath.split("/").pop()
            self.play_names.append(fname)

        play_num = self.play_list.mediaCount()
        rand_index = random.randint(0,play_num-1)
        self.play_list.setCurrentIndex(rand_index)

        #self.player.play()
    def switch_play(self):
        self.player.stop()
        play_num = self.play_list.mediaCount()
        rand_index = random.randint(0,play_num-1)
        self.play_list.setCurrentIndex(rand_index)
        self.player.play()

    def set_connect(self):
        self.ui_login.login_btu.clicked.connect(self.clicked_login)
        self.ui_chat.logout_btu.clicked.connect(self.clicked_logout)
        self.ui_chat.add_pri_user.clicked.connect(self.clicked_add_pri)
        self.ui_chat.rm_pri_user.clicked.connect(self.clicked_rm_pri)
        self.ui_chat.pri_users.clicked.connect(self.clicked_reciever)
        self.ui_chat.send_btu.clicked.connect(self.clicked_send)
        self.ui_chat.msg_input.returnPressed.connect(self.ui_chat.send_btu.clicked.emit)
        self.ui_chat.switch_btu.clicked.connect(self.switch_play)
    '''
    def cliecked_login(self):
        #self.init_chat()
        if self.login():
            qDebug("Login successful")
            self.wl.hide()
            self.center(0)
            self.wc.show()
        else:
            qDebug("Login failure")
    '''

    def clicked_login(self):
        try:
            #_translate = QtCore.QCoreApplication.translate
            self.server_ip = self.ui_login.server_ip.text()
            self.server_port = int(self.ui_login.server_port.text())
            self.username = self.ui_login.user_name.text()
            if self.username == 'public':
                #raise(Exception e)
                qDebug("Login failure")
                qDebug("Can't be public")
                return False

            #初始化和服务器连接
            self.init_conn()
            #初始化聊天界面
            self.ui_chat.menuStatus.setTitle(translate("MainWindow", "Hey, "+self.username))
            self.ui_chat.welcome_label.setText(translate("MainWindow", "Hey " + self.username +", Welcome to  chat!"))
            self.ui_chat.welcome_label.adjustSize()
            qDebug(self.server_ip + ":" + str(self.server_port) + "  " + self.username)
            #self.myclient = client.Client((self.server_ip, self.server_port), self.username)
            #打开登录线程并最多阻塞三秒
            t = threading.Thread(target=self.back_login, args=())
            t.setDaemon(True)
            t.start()
            '''
            t = 3
            dt = t/50
            for i in range(50):
                time.sleep(dt)
                if self.status and len(self.online_users.keys())>0:
                    self.cur_user = "public"
                    self.init_chat()
                    self.refresh_msg_show(self.cur_user)
                    return True
            '''
            t.join(3)
            #根据status以及获取online_users列表来判断是否登录成功
            if self.status and len(self.online_users.keys())>0:
                self.cur_user = "public"
                self.init_chat()
                qDebug("Login successful")
                self.wl.hide()
                self.center(0)
                self.wc.show()
                #self.init_media()
                self.player.play()
                self.refresh_msg_show(self.cur_user)
                qDebug(self.cur_user)
                #t = threading.Thread(target=self.init_media,args=())
                #t.setDaemon(True)
                #t.start()
                #self.sig_refresh_msg_show.emit(self.cur_user)
                return True

            qDebug("status " + str(self.status))
            qDebug("Login failure")
            #self.myclient.run()
            return False

        except Exception as e:
            qDebug(str(e))
            qDebug("Please input all info")
            return False

    def clicked_logout(self):
        '''
        logout按钮触发事件
        '''
        #打开注销线程并最多阻塞两秒
        t = threading.Thread(target=self.back_logout, args=())
        t.setDaemon(True)
        t.start()
        t.join(2)
        qDebug("Logout successful")
        #清空用户相关参数
        self.users_record = {}
        self.ui_chat.pri_users.clear()
        self.ui_chat.pub_users.clear()

        #隐藏聊天窗口，显示登录窗口
        self.wc.hide()
        self.player.stop()
        self.center(1)
        self.wl.show()

    def clicked_send(self):
        '''
        消息发送按钮触发事件
        获取输入框内容并生存记录以及消息，将消息msg发送给当前聊天用户
        '''
        input_msg = self.ui_chat.msg_input.text()
        #gen_msg = "msg:"+self.cur_user + ":"+input_msg
        #self.myclient.deal_input(gen_msg)
        new_record = chat_record("me", input_msg)
        self.users_record[self.cur_user].append(new_record)
        #if self.cur_user == "public":
        #    self.ui_chat.msg_show.append("me(pub): " + input_msg)
        #else:
        self.ui_chat.msg_show.append("me: " + input_msg)
        self.ui_chat.msg_input.clear()

        msg = Message(("msg", self.username, input_msg.encode(encoding='utf_8')))
        qDebug(self.username +  "->" + self.cur_user + ": " + msg.body.decode(encoding='utf_8'))
        self.send(self.cur_user, msg)
        #count+=1
        #qDebug(str(count))
        return

    @pyqtSlot()
    def refresh_msg_show(self, who="public"):
        '''
        根据传入用户名刷新msg_show窗口为和该用户的聊天记录
        '''
        qDebug("1")
        #self.msg_show_lock.acquire()
        self.ui_chat.msg_show.clear()
        qDebug("2")
        if who in self.users_record.keys():
            qDebug("3")
            for record in self.users_record[who]:
                qDebug("4")
                self.ui_chat.msg_show.append(record.__str__())
        #else:
            #self.users_record[who] = []
        #self.msg_show_lock.release()
        qDebug("5")

    def refresh_tip(self):
        '''
        刷新提示栏为提示栈的栈顶提示
        '''
        if self.msg_stack.len >0 :
            top_tip = self.msg_stack.pop()
            self.ui_chat.label_tip.setText(translate("MainWindow", top_tip))
        else:
            self.ui_chat.label_tip.setText(translate("MainWindow", ""))

    def add_record(self, new_record, isPublic=False):
        '''
        添加一条消息记录，如果消息记录来源为自己或者当前聊天用户则同时添加到msg_show窗口中
        '''
        qDebug("add record")
        if isPublic:
            self.users_record["public"].append(new_record)
            if "public" == self.cur_user:
                self.ui_chat.msg_show.append(new_record.__str__())
            else:
                tip = "recieved (pub)msg from " + new_record.who
                self.msg_stack.push(tip)
                self.refresh_tip()
        else:
            self.users_record[new_record.who].append(new_record)
            if new_record.who == self.cur_user:
                self.ui_chat.msg_show.append(new_record.__str__())
            else:
                tip = "recieved msg from " + new_record.who
                #self.ui_chat.label_tip.setText(translate("MainWindow", tip))
                self.msg_stack.push(tip)
                self.refresh_tip()

    def contain_item(self, user_list, name):
        '''
        用于判断在一个QListWidgets里面时候包含文本值为name的Item,包含的话返回索引，否则-1
        '''
        users_N = user_list.count()
        qDebug(str(users_N))
        for i in range(users_N):
            item = user_list.item(i)
            if name == item.text():
                return i
        return -1

    @pyqtSlot()
    def update_add_pub(self, new_user):
        '''
        往在线客户端列表中新加一个客户端，在有客户端登录时接受到服务器的更新列表消息后会调用本函数
        '''
        qDebug("add_pub_user")
        #try:
        if self.contain_item(self.ui_chat.pub_users, new_user)<0:
            self.ui_chat.pub_users.addItem(new_user)
            tip = new_user + " is online now!"
            self.msg_stack.push(tip)
            self.refresh_tip()

        else:
            qDebug("Already added")

    @pyqtSlot()
    def update_rm_pub(self, rm_user):
        '''
        从在线客户端列表中删除一个客户端，在有客户端注销是收到服务器的更新列表消息后会调用本函数
        '''
        qDebug("rm_pub_user")
        #try:
        '''
        if (not rm_user in ("public", self.username)) and (self.contain_item(self.ui_chat.pub_users, rm_user)>=0):
            pub_users_N = self.ui_chat.pub_users.count()
            for i in range(pub_users_N):
                item = self.ui_chat.pub_users.item(i)
                if rm_user == item.text():
                    self.ui_chat.pub_users.takeItem(i)
                    self.msg_stack.remove_by_name(rm_user)
                    tip = rm_user + " logout!"
                    self.msg_stack.push(tip)
                    self.refresh_tip()
                    return
        '''
        #判断删除客户端不是public或者自己，并且在当前的在线客户端列表中
        index = self.contain_item(self.ui_chat.pub_users, rm_user)
        not_in = (not rm_user in ("public", self.username))
        if not_in and index >=0:
            item = self.ui_chat.pub_users.item(index)
            #qDebug(rm_user + " =? " + item.text())
            if rm_user == item.text():
                self.ui_chat.pub_users.takeItem(index)
                #qDebug("befor remove")
                self.msg_stack.remove_by_name(rm_user)
                tip = rm_user + " logout!"
                self.msg_stack.push(tip)
                #qDebug("add tip")
                self.refresh_tip()
                #qDebug("refreshed logout tip")
                return
        else:
            qDebug("Can't find pub_user "+rm_user)

    @pyqtSlot()
    def update_rm_pri(self, rm_user, need_send=False):
        '''
        从私密客户端列表中删除一个客户端，在收到客户端的断开连接消息或服务器发来的删除已注销客户端消息时会调用。
        '''
        qDebug("rm_pri_user")
        '''
        判断删除客户端不是public并且与自己建立了私密连接
        '''
        qDebug("1")
        if rm_user == self.cur_user:
            qDebug("a")
            self.cur_user = "public"
            self.reset_who()
            qDebug("b")
            #self.refresh_msg_show(self.cur_user)
            self.sig_refresh_msg_show.emit(self.cur_user)

        qDebug("2")
        if rm_user in self.Sessions.keys():
            self.delete_session(rm_user, need_send)

        if rm_user in self.users_record.keys():
            del self.users_record[rm_user]

        qDebug("3")
        index = self.contain_item(self.ui_chat.pri_users, rm_user)
        not_pub = rm_user != "public"
        qDebug(str(index))
        qDebug(str(not_pub))
        if not_pub and index >=0:
            item = self.ui_chat.pri_users.item(index)
            qDebug(rm_user + " =? " + item.text())
            if rm_user == item.text():
                self.ui_chat.pri_users.takeItem(index)
                qDebug("4")
                self.msg_stack.remove_by_name(rm_user)
                qDebug("5")
                tip = "disconnected to " + rm_user
                self.msg_stack.push(tip)
                qDebug("6")
                self.refresh_tip()
                qDebug("7")
                return
        else:
            qDebug("Can't find pri_user " + rm_user)

    @pyqtSlot()
    def update_add_pri(self, new_pri, send_request=True):
        '''
        新建一个与其他客户端的私密会话并加到私密客户端列表中，在发起或收到连接请求时会调用本函数。
        '''
        if (self.contain_item(self.ui_chat.pri_users, new_pri)==-1) and new_pri != self.username:
                    qDebug("send conn request to " + new_pri)
                    #self.connect_to(new_pri)
                    if send_request:

                        t = threading.Thread(target=self.connect_to, args=([new_pri]))
                        t.setDaemon(True)
                        t.start()
                        t.join(3)
                        '''
                        self.sig_connect_to.emit(new_pri)
                        '''
                    i = 0
                    while i<30:
                        sleep(0.01)
                        if new_pri in self.Sessions.keys() and self.Sessions[new_pri].client_addr != self.server_addr:
                            break
                        i+=1

                    if new_pri in self.Sessions.keys() and self.Sessions[new_pri].client_addr != self.server_addr:
                        self.ui_chat.pri_users.addItem(new_pri)
                        if not (new_pri in self.users_record.keys()):
                            self.users_record[new_pri] = []
                        tip = "connected to " + new_pri + " successful!"
                        self.msg_stack.push(tip)
                        self.refresh_tip()
                        return
                    else:
                        tip = "connected to " + new_pri + " failed!"
                        self.msg_stack.push(tip)
                        self.refresh_tip()
                        return
        else:
            qDebug("Already added")

    def clicked_add_pri(self):
        '''
        新建私密连接按钮触发事件，向在线客户端列表中被选择的用户发起连接请求
        '''
        qDebug("hahahah")
        #try:
        items = self.ui_chat.pub_users.selectedItems()
        if len(items) > 0:
            for item in items:
                #qDebug(item.text())
                #qDebug(str(self.contain_item(self.ui_chat.pri_users, item.text())))
                threading.Thread(target=self.update_add_pri, args=([item.text()])).start()
                #self.sig_update_add_pri.emit(item.text())
        #except Exception as e:
        #    qDebug("Nothing selected")

    def clicked_rm_pri(self):
        '''
        删除私密连接按钮触发事件，向私密客户端列表中被选择的用户发起断开连接请求
        '''
        qDebug("hahahah")
        indexs = self.ui_chat.pri_users.selectedIndexes()
        if len(indexs) > 0:
            for index in indexs:
                qDebug(str(index.row()))
                item = self.ui_chat.pri_users.item(index.row())
                if item.text() != "public":
                    #self.delete_session(item.text(), True)
                    '''
                    self.ui_chat.pri_users.takeItem(index.row())
                    #self.send(item.text(), Message(("disconnect",self.username, b'')))
                    tip = "disconnected to " + item.text()
                    self.msg_stack.push(tip)
                    self.refresh_tip()
                    if item.text() == self.cur_user:
                        self.cur_user = "public"
                        self.reset_who()
                        self.refresh_msg_show(self.cur_user)
                    '''
                    self.update_rm_pri(item.text(), True)
                    return
                else:
                    qDebug("Can't remove public")

    def reset_who(self):
        self.ui_chat.label_user.setText(translate("MainWindow", self.cur_user + ":"))

    def clicked_reciever(self):
        '''
        私密客户端列表被点击时获取被选中项，将消息窗口切换成与该客户端的聊天记录
        '''
        items = self.ui_chat.pri_users.selectedItems()
        if len(items) > 0:
            to_who = items[0].text()
            #self.ui_chat.label_user.setText(translate("MainWindow", to_who + ":"))
            self.cur_user = to_who
            self.reset_who()
            qDebug(to_who)
            self.refresh_msg_show(self.cur_user)
            #self.sig_refresh_msg_show.emit(self.cur_user)
            tip = "chat with " + self.cur_user + " now"
            self.msg_stack.push(tip)
            self.refresh_tip()
            return

    def center(self, i):
        '''
        将窗口移动到屏幕中央
        '''
        #qDebug("????")
        #qr = self.ui_login.frameGeometry()
        cp = QDesktopWidget().availableGeometry().center()
        #self.ui_login.move(cp.x(),cp.y())
        if i==1:
            qr = self.ui_login.frameGeometry()
            qr.moveCenter(cp)
            self.wl.move(qr.topLeft())

        else:
            qr = self.ui_login.frameGeometry()
            qr.moveCenter(cp)
            self.wc.move(qr.topLeft())

    def back_login(self):
        '''
        back_login:
            客户端登陆，先从客户端获取公钥，用公钥加密与服务端的会话密钥并放入msg.body中，
            服务器返回一个数组[status all_users_name],登陆成功后打开和服务器会话线程
        '''
        msg = Message(("get_pub", self.username, b"public"))
        qDebug((msg.body.decode()))
        self.send("public", msg)
        qDebug("want key")
        qDebug(str(self.server_addr))
        pub_msg = self.Sessions["public"].recieve()
        qDebug("No pub key")
        server_pub_key = rsa.PublicKey.load_pkcs1(pub_msg.body)
        '''
        qDebug(server_pub_key)
        qDebug(self.Sessions["public"].get_key())
        '''
        qDebug("***********")

        #[session_key pub_key] -> dump -> rsa
        rsa_session_key = rsa_encode(server_pub_key, self.Sessions["public"].get_key())

        body =  self.public_key.save_pkcs1() + rsa_session_key

        self.Sessions["public"].send(Message(("login", self.username, body)))
        qDebug("***********")
        msg = self.Sessions["public"].recieve()
        qDebug("***********")
        info = json.loads(msg.body.decode(encoding='utf_8'))
        status = info[0]
        if status == 1:
            qDebug("login in sucessful")
            self.online_users["public"] = server_pub_key
            for cn in info[1:]:
                self.online_users[cn] = ""
                qDebug(cn)
            #self.locks["public"] = threading.Lock()
            self.threads["public"] = threading.Thread(target=self.handle_msg, args=(["public"]))
            self.threads["public"].start()
            #self.threads["public"].join()
            #self.sig_handle_msg.emit("public")
            self.lock.acquire()
            self.status = True
            self.lock.release()
            return True
        else:
            qDebug("login failure!")
            return False

    def get_status(self):
        return self.status

    def back_logout(self):
        '''
        logout:
            注销登陆，断开所有连接并清空
        '''
        #msg = Message(("logout",self.username, ""))
        ##self.locks[client_username].acquire()
        #self.Sessions["public"].send(msg.__bytes__())
        ##self.locks[client_username].release()
        #ts = []
        #for client_username in list(self.Sessions.keys()):
        t = threading.Thread(target=self.delete_session,args=(["public", True]))
        t.start()
        t.join(3)
        #    ts.append(t)

        #for t in ts:
        #    t.join()

        self.Sessions = {}
        self.clientSocket.close()
        self.online_users = {}
        return 0

    @pyqtSlot()
    def connect_to(self, client_username):
        '''
        connect_to:
            连接到另一个客户端，先生成会话密钥， 检测已连接，然后检测时候有该客户端公钥，
            没有的话先向服务器查询，接着建立会话， 构建消息包:
            msg:
                type: connect
                username: current_username
                body: json.dumps([to rsa_encode(to_pub_key,session_key)])
            发送出去后等待目标客户端响应，得到目标客户端会话地址，更新会话地址
        '''
        #input()
        session_key = get_random_bytes(16)
        qDebug(session_key)
        if client_username in self.Sessions.keys():
            qDebug("Already connected!")
            return
        #input()
        if self.online_users[client_username] == "":
            self.Sessions["public"].send(Message(('get_pub',self.username, client_username.encode(encoding='utf_8'))))
        #input()
            #pub_key = rsa_decode(self.private_key, encry_pub_key)

        while self.online_users[client_username] == "":
            sleep(0.01)

        #input()
        qDebug("get pub key")
        self.Sessions[client_username] = Session(self.server_addr_a, session_key)
        #input()
        #self.locks[client_username] = threading.Lock()
        #将client_username补齐20位
        qDebug("padding msg head")
        body = client_username.encode(encoding='utf_8')
        lb = len(body)
        l = 20 - len(body)
        for i in range(l):
            body+= bytes([l])

        #print("origin body " + body[:lb].decode(encoding='utf_8'))
        msg = Message(('connect',self.username, body+rsa_encode(self.online_users[client_username], session_key)))
        #input()
        self.send(client_username, msg)
        #input()
        qDebug("send connect request")
        msg, client_addr = self.Sessions[client_username].recieve(True)
        #input()
        qDebug("aim IP: " + str(client_addr))
        qDebug("connected successful")
        self.Sessions[client_username].update_client(client_addr)
        self.threads[client_username] = threading.Thread(target=self.handle_msg, args=([client_username]))
        self.threads[client_username].start()
        #self.sig_handle_msg.emit(client_username)
        #self.threads[client_username].join()

    def add_connect(self, msg):
        '''
        add_connect:
            响应其他客户端的连接请求
            msg:
                type: connect
                username: from_name
                body: bytes[from_addr rsa_encode(self_pub_key,session_key)])
            新建会话，并返回一个数据包告诉对方自己的会话地址
        '''
        #json_msg = bytes_msg.decode(encoding='utf_8')
        #msg = loads_msg(bytes_msg)
        qDebug("recieve connect request")
        client_username = msg.username
        #body中前30字节为目标客户端名字
        #print(msg.body)
        bytes_addr = msg.body[:(30-msg.body[29])]
        client_addr = tuple(json.loads(bytes_addr.decode(encoding='utf_8')))
        session_key = rsa_decode(self.private_key, msg.body[30:])
        #self.locks[client_username] = threading.Lock()
        self.Sessions[client_username] = Session(client_addr, session_key)
        self.threads[client_username] = threading.Thread(target=self.handle_msg, args=([client_username]))
        self.threads[client_username].start()
        #self.sig_handle_msg.emit(client_username)

        self.send(client_username, Message(("msg", self.username, b"")))
        qDebug("connected by " + msg.username)
        self.update_add_pri(msg.username, False)
        #self.threads[client_username].join()

    def delete_session(self, client_username, need_send=False):
        '''
        delete_session:
            删除一个会话，先告诉对方自己即将断开连接
            并把对应的线程，锁清除
            不复杂UI列表刷新
        '''
        #lock = threading.Lock()
        #lock.acquire()
        qDebug("disconnected to "+client_username)
        qDebug(json.dumps(list(self.Sessions.keys())))
        if client_username in self.Sessions.keys():
            #self.locks[client_username].acquire()
            if need_send:
                if client_username == "public":
                    msg = Message(("logout", self.username, b""))
                    self.send(client_username, msg)
                else:
                    msg = Message(("disconnect", self.username, b""))
                    self.send(client_username, msg)

            #self.locks[client_username].release()
            #time.sleep(0.01)
            self.Sessions[client_username].close()
            #if self.threads[client_username].isAlive():
            #    self.threads[client_username].cancel()
            lock = threading.Lock()
            lock.acquire()
            del self.threads[client_username]
            del self.Sessions[client_username]
            lock.release()
            #del self.locks[client_username]
        #lock.release()

    def send(self, to_who, msg):
        '''
        send:
            封装发送过程，客户端发送消息
        参数:
            client_username: 接收机名字
            msg: Message对象
        '''
        if to_who in list(self.Sessions.keys()):
            #msg = Message(("msg", self.username, ))
            #self.locks[to_who].acquire()
            rs = self.Sessions[to_who].send(msg)
            #self.locks[to_who].release()
            qDebug("send msg to " + to_who + ": " + msg.__str__())

            '''
            if msg.type == "msg":
                qDebug(msg.body)
                qDebug("to " + to_who + " : " + msg.body.decode(encoding='utf_8'))
            '''

    @pyqtSlot()
    def handle_msg(self, client_username):
        '''
        handle_msg:
            接收和client_username的会话中的返回内容
        '''
        while 1:
            ##self.locks[client_username].acquire()
            #接收到的Message对象除了msg和broadmsg类型的消息外，其他类型消息的body都保持了bytes可是，msg类型的body已用会话密钥解密
            msg = self.Sessions[client_username].recieve()
            qDebug("From " + client_username + " recieved " + msg.__str__())
            ##self.locks[client_username].release()
            if msg.type == "msg":

                if client_username == "public":
                    qDebug(("from (pub)" + msg.username + " : " + msg.body.decode(encoding='utf_8')))
                    #self.add_record(chat_record(msg.username, msg.body.decode(encoding='utf_8')))
                    new_record = chat_record(msg.username, msg.body.decode(encoding='utf_8'))
                    self.add_record(new_record, True)

                else:
                    qDebug((" " + client_username + " : " + msg.body.decode(encoding='utf_8')))
                    new_record = chat_record(msg.username, msg.body.decode(encoding='utf_8'))
                    #self.users_record[client_username].append(new_record)
                    #if client_username == self.cur_user:
                    #    self.ui_chat.msg_show.append(new_record.__str__())
                    self.add_record(new_record)
                    #self.add_record(chat_record(client_username, msg.body.decode(encoding='utf_8')))

                #qDebug(("from " + client_username + " : " + msg.body.decode(encoding='utf_8')))
                #self.add_record(chat_record(client_username, msg.body.decode(encoding='utf_8')))
                continue
            '''
            if msg.type == "broadmsg":
                msg.body = aes_decode(msg.body, self.Sessions["public"].get_key())
                qDebug("(pub) from ")
            '''
            if msg.type == "connect":
                self.add_connect(msg)
                continue

            if msg.type == "get_pub":
                pub_key = rsa.PublicKey.load_pkcs1(msg.body)
                self.online_users[msg.username] = pub_key
                continue

            if msg.type == "disconnect":
                '''
                self.delete_session(msg.username)
                index = self.contain_item(self.ui_chat.pri_users, client_username)
                if index != -1:
                    self.ui_chat.pri_users.takeItem(index)
                    tip = "disconnected from " + msg.username + "!"
                    self.msg_stack.push(tip)
                    self.refresh_tip()
                '''
                self.update_rm_pri(msg.username)
                #self.sig_update_rm_pri.emit(msg.user_name)
                break

            if msg.type == "update":
                self.update_online_users(msg)
                continue

    def update_online_users(self, msg):
        '''
        处理服务器发来的更新用户消息，新用户登录以及用户注销
        '''
        client_name = msg.username
        op = msg.body.decode(encoding='utf_8')
        if op == "add":
            self.online_users[client_name] = b''
            #self.ui_chat.pub_users.addItem(client_name)
            self.update_add_pub(client_name)
            #self.sig_update_add_pub.emit(client_name)
            qDebug("Update online users")
            qDebug(json.dumps(list(self.online_users.keys())))
            return

        if op == "rm":
            #self.delete_session(client_name)
            self.update_rm_pri(client_name)
            #self.sig_update_rm_pri.emit(client_name)
            self.update_rm_pub(client_name)
            #self.sig_update_rm_pub.emit(client_name)
            #print(json.dumps(list(self.online_users.keys())))
            #print(json.dumps(list(self.Sessions.keys())))
            return

    '''
    def deal_input(self, input_msg):

        （在非GUI版本中用于处理命令行输入)
        deal_input:
            处理输入内容，一般为: 类型:接收者：消息内容(默认为空)
        构建Message对象并发送

        #global count
        #input_msg = line[0]
        inputs = input_msg.split(":", -1)
        if len(inputs) == 2:
            inputs.append("")

        msg_type = inputs[0]
        username = inputs[1]
        body = inputs[2]

        if msg_type == "logout":
            self.logout()
            return
        if msg_type == "login":
            self.username = username
            self.login()
            return

        if msg_type == "connect":
            self.connect_to(username)
            return

        if msg_type == "disconnect":
            index = self.contain_item(self.ui_chat.pri_users, username)
            if index != -1:
                self.ui_chat.pri_users.takeItem(index)

            self.delete_session(username)
            return
        if inputs[0] == "show":
            if inputs[1]=="pub_users":
                qDebug(json.dumps(list(self.online_users.keys())))
                return
            if inputs[1]=="pri_users":
                qDebug(json.dumps(list(self.Sessions.keys())))
                return
            if inputs[1] == "pub_key":
                qDebug(self.Sessions["public"].get_key())
                return
            return

        inputs[2] = inputs[2].encode(encoding='utf_8')
        #print("input->>" + inputs[2].decode('utf_8'))
        msg = Message(inputs)
        msg.username = self.username

        if msg.type == "msg":
            qDebug(self.username +  "->" + username + ": " + msg.body.decode(encoding='utf_8'))
            self.send(username, msg)
            #+=1
            #qDebug(str(count))
            return

        qDebug("invalied msg format:\n type:who:body\n")
    '''