from typing import List, Union, Dict, Tuple, Any

from type import Type
from tokenizer import TK, Token
from utils import debug, warning

from parser.parseutils import *
from parser.tokenparser import TokenParser
from parser.subexpressionparser import SubExpressionParser

class ExpressionParser(TokenParser, SubExpressionParser):
    # expression

    def primary_expression(self) -> Node:
        try:
            return self.constant()
        except ParseError:
            pass
        if self.consume('('):
            expression = self.expression()
            self.consume_must(')')
            return expression
        raise ParseError

    def postfix_expression(self) -> Node:
        postfix = self.primary_expression()

        while True:

            if self.consume('['):
                exp = self.expression()
                self.consume_must(']')
                if not postfix.type.is_ptr and not exp.type.is_ptr:
                    TypeError('ポインタ以外を配列参照しています')
                node = self.sub_add(postfix, exp)
                postfix = Node(ND.REF, type=node.type.ptr_to, lhs=node)
                continue
            if self.consume('('):
                if postfix.type.ty == '.unknown':
                    warning(postfix.val, '関数の暗黙的宣言(返り値をlongにします)')
                    postfix.type = Type('.func', func_call_to=Type('long', signed=True))
                args = self.sep_repeat(self.assignment_expression, ',', True)
                self.consume_must(')')
                if not postfix.type.is_func:
                    raise TypeError('関数以外を呼び出そうとしています')
                postfix = Node(ND.CALL, type=postfix.type.func_call_to, call=postfix, call_args=args)
                continue

            if self.consume('++'):
                if not postfix.type.is_real_num():
                    raise TypeError('後置++に実数型以外が指定されています')
                if postfix.type.const:
                    raise TypeError('後置++にconst変数が指定されています')
                postfix = Node('++', type=postfix.type, lhs=postfix)
                continue
            if self.consume('--'):
                if not postfix.type.is_real_num():
                    raise TypeError('後置--に実数型以外が指定されています')
                if postfix.type.const:
                    raise TypeError('後置--にconst変数が指定されています')
                postfix = Node('--', type=postfix.type, lhs=postfix)
                continue

            break

        if postfix.type.ty == '.unknown':
            raise TypeError('変数が宣言されていません')

        return postfix

    def unary_expression(self) -> Node:
        unary = None

        while True:
            if self.consume('++'):
                node = self.unary_expression()
                if not node.type.is_real_num():
                    raise TypeError('前置++に実数型以外が指定されています')
                if node.type.const:
                    raise TypeError('前置++にconst変数が指定されています')
                unary = Node('+', lhs=node, rhs=n_signed_int_plus1, type=node.type)
                continue
            if self.consume('--'):
                node = self.unary_expression()
                if not node.type.is_real_num():
                    raise TypeError('前置--に実数型以外が指定されています')
                if node.type.const:
                    raise TypeError('前置--にconst変数が指定されています')
                unary = Node('-', lhs=node, rhs=n_signed_int_plus1, type=node.type)
                continue

            if self.consume('&'):
                node = self.cast_expression()
                if node.ty == ND.INT:
                    raise TypeError('定数の参照を作成しようとしています')
                unary = Node(ND.LEA, type=Type('.ptr', ptr_to=node.type), lhs=node)
                continue
            if self.consume('*'):
                node = self.cast_expression()
                if not node.type.is_ptr:
                    raise TypeError('ポインタ以外を参照解決しています')
                unary = Node(ND.REF, type=node.type.ptr_to, lhs=node)
                continue
            if self.consume('+'):
                unary = self.cast_expression()
                if not unary.type.is_arithmetic():
                    raise TypeError('単行+に非算術型が指定されています')
                continue
            if self.consume('-'):
                node = self.cast_expression()
                if not node.type.is_arithmetic():
                    raise TypeError('単行-に非算術型が指定されています')
                unary = Node('*', type=node.type, lhs=node, rhs=n_signed_int_minus1)
                continue
            if self.consume('!'):
                node = self.cast_expression()
                unary = Node('==', type=t_signed_int, lhs=node, rhs=n_signed_int_0)
                continue

            if self.consume('sizeof'):
                node = self.unary_expression()
                return Node(ND.INT, type=t_signed_int, val=node.type.size)
            break

        if unary is None:
            unary = self.postfix_expression()
        return unary

    def cast_expression(self) -> Node:
        cast = self.unary_expression()

        while True:
            break

        return cast

    def multiple_expression(self) -> Node:
        mul = self.cast_expression()

        while True:
            if self.consume('*'):
                rhs = self.cast_expression()
                mul = self.sub_mul(mul, rhs)
                continue
            if self.consume('/'):
                rhs = self.cast_expression()
                mul = self.sub_div(mul, rhs)
                continue
            if self.consume('%'):
                rhs = self.cast_expression()
                mul = self.sub_sur(mul, rhs)
                continue
            break

        return mul

    def additive_expression(self) -> Node:
        add = self.multiple_expression()

        while True:
            if self.consume('+'):
                rhs = self.multiple_expression()
                add = self.sub_add(add, rhs)
                continue
            if self.consume('-'):
                rhs = self.multiple_expression()
                add = self.sub_sub(add, rhs)
                continue
            break
        return add

    def shift_expression(self) -> Node:
        shift = self.additive_expression()

        while True:
            if self.consume('>>'):
                rhs = self.additive_expression()
                if not Type.both_integer(shift.type, rhs.type):
                    raise TypeError('右シフト演算子>>に整数型以外が指定されています')
                shift = Node('>>', type=shift.type, lhs=shift, rhs=rhs)
                continue
            if self.consume('<<'):
                rhs = self.additive_expression()
                if not Type.both_integer(shift.type, rhs.type):
                    raise TypeError('左シフト演算子<<に整数型以外が指定されています')
                shift = Node('<<', type=shift.type, lhs=shift, rhs=rhs)
                continue
            break

        return shift

    def relational_expression(self) -> Node:
        relational = self.shift_expression()

        while True:  # todo: http://port70.net/~nsz/c/c11/n1570.html#6.5.8p2  2番目の制約
            if self.consume('<'):
                rhs = self.shift_expression()
                if not Type.both_real_num(relational.type, rhs.type):
                    raise TypeError('比較演算子<に実数型以外が指定されています')
                relational = Node('<', type=t_signed_int, lhs=relational, rhs=rhs)
                continue
            if self.consume('>'):
                rhs = self.shift_expression()
                if not Type.both_real_num(relational.type, rhs.type):
                    raise TypeError('比較演算子>に実数型以外が指定されています')
                relational = Node('<', type=t_signed_int, rhs=relational, lhs=rhs)
                continue
            if self.consume('<='):
                rhs = self.shift_expression()
                if not Type.both_real_num(relational.type, rhs.type):
                    raise TypeError('比較演算子<=に実数型以外が指定されています')
                relational = Node('<=', type=t_signed_int, lhs=relational, rhs=rhs)
                continue
            if self.consume('>='):
                rhs = self.shift_expression()
                if not Type.both_real_num(relational.type, rhs.type):
                    raise TypeError('比較演算子>=に実数型以外が指定されています')
                relational = Node('<=', type=t_signed_int, rhs=relational, lhs=rhs)
                continue
            break

        return relational

    def equality_expression(self) -> Node:
        equality = self.relational_expression()

        while True:
            if self.consume('=='):
                rhs = self.relational_expression()
                if not Type.both_arithmetic(equality.type, rhs.type):
                    raise TypeError('比較演算子==に算術型以外が指定されています')
                equality = Node('==', type=t_signed_int, lhs=equality, rhs=rhs)
                continue
            if self.consume('!='):
                rhs = self.relational_expression()
                if not Type.both_arithmetic(equality.type, rhs.type):
                    raise TypeError('比較演算子!=に算術型以外が指定されています')
                equality = Node('!=', type=t_signed_int, lhs=equality, rhs=rhs)
                continue
            break

        return equality

    def and_expression(self) -> Node:
        and_ = self.equality_expression()

        while True:
            if self.consume('&'):
                rhs = self.equality_expression()
                if not Type.both_integer(and_.type, rhs.type):
                    raise TypeError('&演算子に整数型以外が指定されています')
                and_ = Node('&', type=and_.type, lhs=and_, rhs=rhs)
                continue
            break

        return and_

    def exclusive_or_expression(self) -> Node:
        xor = self.and_expression()

        while True:
            if self.consume('^'):
                rhs = self.and_expression()
                if not Type.both_integer(xor.type, rhs.type):
                    raise TypeError('^演算子に整数型以外が指定されています')
                xor = Node('^', type=xor.type, lhs=xor, rhs=rhs)
                continue
            break

        return xor

    def or_expression(self) -> Node:
        or_ = self.exclusive_or_expression()

        while True:
            if self.consume('|'):
                rhs = self.exclusive_or_expression()
                if not Type.both_integer(or_.type, rhs.type):
                    raise TypeError('|演算子に整数型以外が指定されています')
                or_ = Node('|', type=or_.type, lhs=or_, rhs=rhs)
                continue
            break

        return or_

    def logical_and_expression(self) -> Node:
        land = self.or_expression()

        while True:
            if self.consume('&&'):
                rhs = self.or_expression()
                if not Type.both_integer(land.type, rhs.type):  # TODO: integerじゃなくてscala...
                    raise TypeError('&&演算子に整数型以外が指定されています')
                land = Node('&&', type=land.type, lhs=land, rhs=rhs)
                continue
            break

        return land

    def logical_or_expression(self) -> Node:
        lor = self.logical_and_expression()

        while True:
            if self.consume('||'):
                rhs = self.logical_and_expression()
                if not Type.both_integer(lor.type, rhs.type):
                    raise TypeError('||演算子に整数型以外が指定されています')
                lor = Node('||', type=lor.type, lhs=lor, rhs=rhs)
                continue
            break

        return lor

    def conditional_expression(self) -> Node:
        condition = self.logical_or_expression()

        while True:
            break

        return condition

    def assignment_expression(self) -> Node:
        assign = self.conditional_expression()

        while True:
            if self.consume('='):
                if assign.type.const:
                    raise TypeError('const変数に代入しています')
                assign = Node('=', type=assign.type, lhs=assign, rhs=self.assignment_expression())
                continue

            if self.consume('*='):
                if assign.type.const:
                    raise TypeError('const変数に代入しています')
                assign = Node('=', lhs=assign,
                              rhs=Node('*', lhs=assign, rhs=self.assignment_expression(), type=assign.type),
                              type=assign.type
                              )
                continue

            if self.consume('/='):
                if assign.type.const:
                    raise TypeError('const変数に代入しています')
                assign = Node('=', lhs=assign,
                              rhs=Node('/', lhs=assign, rhs=self.assignment_expression(), type=assign.type),
                              type=assign.type
                              )
                continue

            if self.consume('%='):
                if assign.type.const:
                    raise TypeError('const変数に代入しています')
                assign = Node('=', lhs=assign,
                              rhs=Node('%', lhs=assign, rhs=self.assignment_expression(), type=assign.type),
                              type=assign.type
                              )
                continue

            if self.consume('+='):
                if assign.type.const:
                    raise TypeError('const変数に代入しています')
                assign = Node('=', lhs=assign,
                              rhs=Node('+', lhs=assign, rhs=self.assignment_expression(), type=assign.type),
                              type=assign.type
                              )
                continue

            if self.consume('-='):
                if assign.type.const:
                    raise TypeError('const変数に代入しています')
                assign = Node('=', lhs=assign,
                              rhs=Node('-', lhs=assign, rhs=self.assignment_expression(), type=assign.type),
                              type=assign.type
                              )
                continue

            if self.consume('<<='):
                if assign.type.const:
                    raise TypeError('const変数に代入しています')
                assign = Node('=', lhs=assign,
                              rhs=Node('<<', lhs=assign, rhs=self.assignment_expression(), type=assign.type),
                              type=assign.type
                              )
                continue

            if self.consume('>>='):
                if assign.type.const:
                    raise TypeError('const変数に代入しています')
                assign = Node('=', lhs=assign,
                              rhs=Node('>>', lhs=assign, rhs=self.assignment_expression(), type=assign.type),
                              type=assign.type
                              )
                continue

            if self.consume('&='):
                if assign.type.const:
                    raise TypeError('const変数に代入しています')
                assign = Node('=', lhs=assign,
                              rhs=Node('&', lhs=assign, rhs=self.assignment_expression(), type=assign.type),
                              type=assign.type
                              )
                continue

            if self.consume('^='):
                if assign.type.const:
                    raise TypeError('const変数に代入しています')
                assign = Node('=', lhs=assign,
                              rhs=Node('^', lhs=assign, rhs=self.assignment_expression(), type=assign.type),
                              type=assign.type
                              )
                continue

            if self.consume('|='):
                if assign.type.const:
                    raise TypeError('const変数に代入しています')
                assign = Node('=', lhs=assign,
                              rhs=Node('|', lhs=assign, rhs=self.assignment_expression(), type=assign.type),
                              type=assign.type
                              )
                continue

            break

        return assign

    def expression(self) -> Node:
        exp = self.assignment_expression()

        while True:
            if self.consume(','):
                rhs = self.assignment_expression()
                exp = Node(',', type=rhs.type, lhs=exp, rhs=rhs)
                continue
            break

        return exp

    def constant_expression(self) -> Node:  # TODO: http://port70.net/~nsz/c/c11/n1570.html#6.6
        constant = self.conditional_expression()

        def gen_constant(node):
            if node.ty == ND.INT:
                return node.val
            if node.ty == '*':
                return gen_constant(node.lhs) * gen_constant(node.rhs)
            if node.ty == '/':
                return gen_constant(node.lhs) // gen_constant(node.rhs)
            if node.ty == '%':
                return gen_constant(node.lhs) % gen_constant(node.rhs)
            if node.ty == '+':
                return gen_constant(node.lhs) + gen_constant(node.rhs)
            if node.ty == '-':
                return gen_constant(node.lhs) - gen_constant(node.rhs)
            if node.ty == '<<':
                return gen_constant(node.lhs) << gen_constant(node.rhs)
            if node.ty == '>>':
                return gen_constant(node.lhs) >> gen_constant(node.rhs)
            if node.ty == '<':
                return int(gen_constant(node.lhs) < gen_constant(node.rhs))
            if node.ty == '>':
                return int(gen_constant(node.lhs) > gen_constant(node.rhs))
            if node.ty == '<=':
                return int(gen_constant(node.lhs) <= gen_constant(node.rhs))
            if node.ty == '>=':
                return int(gen_constant(node.lhs) >= gen_constant(node.rhs))
            if node.ty == '==':
                return int(gen_constant(node.lhs) == gen_constant(node.rhs))
            if node.ty == '!=':
                return int(gen_constant(node.lhs) != gen_constant(node.rhs))
            if node.ty == '&':
                return int(gen_constant(node.lhs) & gen_constant(node.rhs))
            if node.ty == '|':
                return int(gen_constant(node.lhs) | gen_constant(node.rhs))
            if node.ty == '&&':
                return 1 if gen_constant(node.lhs) and gen_constant(node.rhs) else 0
            if node.ty == '|':
                return 1 if gen_constant(node.lhs) or gen_constant(node.rhs) else 0

        res = gen_constant(constant)
        return Node(ND.INT, type=t_signed_int, val=res)


#Тема 2. Встроенные типы и операции с ними
#1: Даны два произвольные списка. Удалите из первого списка элементы присутствующие во втором списке.
#    Примечание. Списки создайте вручную, например так:
#my_list_1 = [2, 5, 8, 2, 12, 12, 4]
#my_list_2 = [2, 7, 12, 3]
print('----- Задача 1 -----')
my_list_1 = [2, 5, 8, 2, 12, 12, 4]
my_list_2 = [2, 7, 12, 3]
print('Первый список: {}'.format(my_list_1))
print('Второй список: {}'.format(my_list_2))

#перебираем второй список
for list_2_element in my_list_2:
    #используем не if, а while, поскольку элементы
    #второго списка могут несколько раз встречаться в первом списке
    while list_2_element in  my_list_1:
        my_list_1.remove(list_2_element)
#вывод результата
print('Исключаем второй список из первого')
print('Результат: {}'.format(my_list_1))
print()

#2: Дана дата в формате dd.mm.yyyy, например: 02.11.2013.
#Ваша задача — вывести дату в текстовом виде, например: второе ноября 2013 года.
#Склонением пренебречь (2000 года, 2010 года)
print('----- Задача 2 -----')
my_date = input('Введите дату в формате dd.mm.yyyy: ').split('.')
day = int(my_date[0])
month = int(my_date[1])
year = int(my_date[2])
#Проверим правильность ввода даты
month_31 = [1,3,5,7,8,10,12]    #список месяцев с 31 днем
month_30 = [4,6,9,11]           #список месяцев с 30 днями
month_28 = [2]                  #список месяцев с 28 днями
month_29 = [2]                  #список месяцев с 29 днями
year_right = False              #переменная - правильный ли год
month_right = False             #переменная - правильный ли месяц
day_right = False               #переменная - правильная ли дата
#если в году 4 цифры, то он введен верно
if len(my_date[2])== 4:
    year_right = True
#если месяц от 1 до 12, то он введен верно
if 0<month<=12:
    month_right = True
#определяем, високосный ли год
if (year%400==0 or year%4==0) and year%100!=0:
    #високосный год, определяем корректность даты
    if month in month_31:
        if 0<day<=31:
            day_right = True
    elif month in month_30:
        if 0<day<=30:
            day_right = True
    elif month in month_29:
         if 0<day<=29:
             day_right = True
else:
    #не високосный год, определяем корректность даты
    if month in month_31:
        if 0 < day <= 31:
            day_right = True
    elif month in month_30:
        if 0 < day <= 30:
            day_right = True
    elif month in month_28:
        if 0 < day <= 28:
            day_right = True
if day_right & month_right & year_right:
    print('Дата введена корректно: {}.{}.{}'.format(day,month,year))
    days_dict = {1: 'первое', 2: 'второе', 3: 'третье', 4: 'четвертое', 5: 'пятое',
                 6: 'шестое', 7: 'седьмое', 8: 'восьмое', 9: 'девятое', 10: 'десятое',
                 11: 'одиннадцатое', 12: 'двенадцатое', 13: 'тринадцатое', 14: 'четырнадцатое', 15: 'пятнадцатое',
                 16: 'шестнадцатое', 17: 'семнадцатое', 18: 'восемнадцатое', 19: 'девятнадцатое', 20: 'двадцатое',
                 21: 'двадцать первое', 22: 'двадцать второе', 23: 'двадцать третье', 24: 'двадцать четвертое',
                 25: 'двадцать пятое',
                 26: 'двадцать шестое', 27: 'двадцать седьмое', 28: 'двадцать восьмое', 29: 'двадцать девятое',
                 30: 'тридцатое', 31: 'тридцать перове'}
    months_dict = {1: 'января', 2: 'февраля', 3: 'марта', 4: 'апреля', 5: 'мая', 6: 'июня', 7: 'июля', 8: 'августа',
                   9: 'сентября', 10: 'октября', 11: 'ноября', 12: 'декабря'}
    print('Текстовый вариант вашей даты:')
    print('{} {} {} года'.format(days_dict[day],months_dict[month],year))
    print()
else:
    print('Дата введена некорректно. Вывод текстового варианта не будет производиться!')
    print()

#3: Дан список заполненный произвольными целыми числами.
#Получите новый список, элементами которого будут только уникальные элементы исходного.
#    Примечание. Списки создайте вручную, например так:
#my_list_1 = [2, 2, 5, 12, 8, 2, 12]
#В этом случае ответ будет:
#[5, 8]
print('----- Задача 3 -----')
my_list_1 = [2, 2, 5, 12, 8, 2, 12]
my_list_2 = []
my_list_3 = []
print('Первый список: {}'.format(my_list_1))
print('Получаем список уникальных элементов первого списка:')
print('1 вариант, через set:')
set_temp = set(my_list_1)
for set_element in set_temp:
    index = 0                               #счетчик количества элементов в первом списке
    for list_element in my_list_1:
        if set_element == list_element:
            index +=1
    if index==1:
        my_list_2.append(set_element)       #добавляем элемент во второй список
print('Список уникальных элементов: {}'.format(my_list_2))
print('2 вариант, через count:')
for list_element in my_list_1:
    if my_list_1.count(list_element)==1:
        my_list_3.append(list_element)      #добавляем элемент во второй список
print('Список уникальных элементов: {}'.format(my_list_3))


# 5LSL0 Final Assignment main code for mfcc based model

## Import arbitrary libraries
import numpy as np
import matplotlib.pyplot as plt
import os
import openpyxl
import sys

## Import tensorflow and keras
import tensorflow as tf
from tensorflow import keras
from tensorflow.keras.layers import Input, Dense, Conv1D, Conv2D, MaxPooling1D, LeakyReLU, AvgPool2D, UpSampling2D, ReLU, MaxPooling2D, Reshape, Flatten, Activation
from tensorflow.keras.losses import MSE, categorical_crossentropy
from tensorflow.keras.models import Model, Sequential
from tensorflow.keras.optimizers import Adam
from sklearn.metrics import accuracy_score
from keras.models import load_model
import bisect

## Import selfmade modules
from generator_mfcc import DataGenerator
from model_mfcc import deep_cnn
sys.path.insert(0, 'Data')
import createNoise
from datasplitter import datasplitter

def getDivisors(x):
    divisors = []
    i = 1
    for i in range(1,x):
        if(x%i == 0):
            divisors.append(i)
        else:
            continue
        i+=1
    return divisors

def find_le(a, x):
    'Find rightmost value less than or equal to x'
    i = bisect.bisect_right(a, x)
    if i:
        return a[i-1]
    raise ValueError

## Labels
labels=("yes", "no", "up", "down", "left", "right", "on", "off", "stop", "go", "silence", "unknown")
num_classes = len(labels)
training_batch_size = 128
# test_batch_size = 28
final_test_batch_size = 6

## normalization options
normalization = {"subtract_mean": True,
                 "epsilon": 1e-8,           # prevent division by 0
                 "normalize": "95",        # "none", "var", "std", "95", "97"
                 "type": "sample"}          # "sample", "class"

## evaluation metrics
metrics=['acc']

## create silence
USE_SILENCE = True
N_SILENCE = 2000
if USE_SILENCE:
    createNoise.create(N_SILENCE)

## create lists
datasplitter()

## paths
data_path = 'Data/train/audio/'
data_lists = 'Data/train/lists/'
final_test_path = 'Data/test/audio/'

## Create generator
traingen1 = DataGenerator(data_path=data_path,
                         data_listing=data_lists+'train_set.txt',
                         batch_size=training_batch_size,
                         dims_in=(16000,1),
                         dims_out=(13,32),
                         labels=labels)

validgen1 = DataGenerator(data_path=data_path,
                         data_listing=data_lists+'validation_set.txt',
                         batch_size=training_batch_size,
                         dims_in=(16000,1),
                         dims_out=(13,32),
                         labels=labels)

## Create test model
shape = (13,32,1)
model = deep_cnn(shape, num_classes)

#optimizer = Adam(lr = 0.0001)
model.compile(optimizer='Adam', loss = categorical_crossentropy, metrics = metrics)

# Train model on dataset
num_lines_train = sum(1 for line in open(data_lists+'train_set.txt'))
num_lines_valid = sum(1 for line in open(data_lists+'validation_set.txt'))

history = model.fit_generator(generator=traingen1,
                              epochs = 15,
                              verbose = 1,
                              validation_data=validgen1)

# summarize history for acc
plt.plot(history.history['acc'])
plt.plot(history.history['val_acc'])
plt.title('model accuracy')
plt.ylabel('accuracy')
plt.xlabel('epoch')
plt.legend(['train', 'valid'], loc='upper left')
plt.savefig('results/mfcc/model_spectrum_norm_acc.pdf')
plt.close()

# summarize history for loss
plt.plot(history.history['loss'])
plt.plot(history.history['val_loss'])
plt.title('model loss')
plt.ylabel('loss')
plt.xlabel('epoch')
plt.legend(['train', 'valid'], loc='upper left')
plt.savefig('results/mfcc/model_spectrum_norm_loss.pdf')

# save model
model.save('results/mfcc/model_spectrum_norm.h5')

## test data
from generator_mfcc_test import DataGenerator

with open(data_lists+'test_set.txt') as f:
    content = f.readlines()

divisors_test = getDivisors(len(content))
test_batch_size = find_le(divisors_test, 100)

testgen = DataGenerator(data_path=data_path,
                         data_listing=data_lists+'test_set.txt',
                         batch_size=test_batch_size,
                         dims_in=(16000,1),
                         dims_out=(13,32),
                         labels=labels)

y_pred_proba = model.predict_generator(generator=testgen,
                                     verbose=1)

y_pred = np.argmax(y_pred_proba, axis=1)

y_true = []
# Added modulo to test batch size to make sure len(y_true) == len(y_pred)
for lbl in range(len(content)):
    label = content[lbl].split('/')[0]
    if label in labels:
        y_true.append(labels.index(label))
    else:
        y_true.append(labels.index('unknown'))

acc_score = accuracy_score(y_true, y_pred)
print(acc_score)

## test final data for submission
from generator_mfcc_finaltest import DataGenerator

y_files = os.listdir(final_test_path)

finaltestgen = DataGenerator(data_path=final_test_path,
                             dataset = y_files,
                             batch_size=final_test_batch_size,
                             dims_in=(16000,1),
                             dims_out=(13,32),
                             labels=labels)

y_pred_proba = model.predict_generator(generator = finaltestgen,
                                     verbose=1)
y_pred = np.argmax(y_pred_proba, axis=1)

# Save computed probabilities so that they can be used with the other models
np.savetxt('results/mfcc/probabilities_spectrum_norm.csv', y_pred_proba, delimiter=',')

# Save the final outcome
wb = openpyxl.Workbook()
sheet = wb.active
sheet.cell(row=1, column=1).value='fname,label'
for y in range(len(y_pred)):
    sheet.cell(row=y+2, column=1).value=y_files[y]+','+labels[y_pred[y]]

wb.save('results/mfcc/submission_spectrum_norm.xlsx')


"""
Test cases for the metadata reading/writing of pyslim.
"""
import os

import numpy as np
import pytest
import msprime
import tskit
import pyslim

import tests
from .recipe_specs import recipe_eq

class TestMetadataSchemas(tests.PyslimTestCase):

    def validate_table_metadata(self, table):
        ms = table.metadata_schema
        for j, row in enumerate(table):
            a = table.metadata_offset[j]
            b = table.metadata_offset[j+1]
            raw_md = table.metadata[a:b]
            # this checks to make sure metadata follows the schema
            enc_md = ms.validate_and_encode_row(row.metadata)
            assert bytes(raw_md) == enc_md

    def test_slim_metadata(self, recipe):
        tables = recipe["ts"].dump_tables()
        for t in (tables.populations, tables.individuals, tables.nodes, tables.edges,
                  tables.sites, tables.mutations, tables.migrations):
            self.validate_table_metadata(t)

    def test_default_metadata(self):
        for k in pyslim.slim_metadata_schemas:
            schema = pyslim.slim_metadata_schemas[k]
            entry = pyslim.default_slim_metadata(k)
            encoded = schema.validate_and_encode_row(entry)
            decoded = schema.decode_row(encoded)
            if entry is None:
                assert decoded is None
            else:
                assert entry == decoded

    def test_slim_metadata_schema_equality(self, recipe):
        t = recipe["ts"].dump_tables()
        assert t.metadata_schema == pyslim.slim_metadata_schemas['tree_sequence']
        assert t.edges.metadata_schema == pyslim.slim_metadata_schemas['edge']
        assert t.sites.metadata_schema == pyslim.slim_metadata_schemas['site']
        assert t.mutations.metadata_schema == pyslim.slim_metadata_schemas['mutation']
        assert t.nodes.metadata_schema == pyslim.slim_metadata_schemas['node']
        assert t.individuals.metadata_schema == pyslim.slim_metadata_schemas['individual']
        assert t.populations.metadata_schema == pyslim.slim_metadata_schemas['population']

class TestTreeSequenceMetadata(tests.PyslimTestCase):
    arbitrary_recipe = [next(recipe_eq())]  # for testing any one recipe

    def validate_slim_metadata(self, t):
        # t could be tables or a tree sequence
        schema = t.metadata_schema.schema
        assert 'SLiM' in schema['properties']
        assert 'SLiM' in t.metadata
        for k in pyslim.default_slim_metadata('tree_sequence')['SLiM']:
            assert k in schema['properties']['SLiM']['properties']
            assert k in t.metadata['SLiM']

    def validate_model_type(self, ts, model_type):
        assert ts.metadata['SLiM']['file_version'] == pyslim.slim_file_version
        assert ts.metadata['SLiM']['model_type'] == model_type
        assert ts.metadata['SLiM']['generation'] > 0
        assert ts.metadata['SLiM']['generation'] >= np.max(ts.tables.nodes.time)

    @pytest.mark.parametrize('recipe', arbitrary_recipe, indirect=True)
    def test_set_tree_sequence_metadata_errors(self, recipe):
        tables = recipe["ts"].dump_tables()
        tables.metadata_schema = tskit.MetadataSchema(None)
        assert len(tables.metadata) > 0
        with pytest.raises(ValueError):
            pyslim.set_tree_sequence_metadata(tables, "nonWF", 0)

    @pytest.mark.parametrize('recipe', arbitrary_recipe, indirect=True)
    def test_set_tree_sequence_metadata_keeps(self, recipe):
        # make sure doesn't overwrite other stuff
        dummy_schema = tskit.MetadataSchema({
                'codec': 'json',
                'type': 'object',
                'properties': { 'abc': { 'type': 'string' } }
                })
        dummy_metadata = { 'abc': 'foo' }
        tables = recipe["ts"].dump_tables()
        tables.metadata_schema = dummy_schema
        tables.metadata = dummy_metadata
        pyslim.set_tree_sequence_metadata(tables, "nonWF", 0)
        schema = tables.metadata_schema.schema
        for k in dummy_metadata:
            assert k in schema['properties']
            assert k in tables.metadata
            assert tables.metadata[k] == dummy_metadata[k]
        self.validate_slim_metadata(tables)
        assert tables.metadata['SLiM']['model_type'] == "nonWF"
        assert tables.metadata['SLiM']['generation'] == 0

    @pytest.mark.parametrize('recipe', arbitrary_recipe, indirect=True)
    def test_set_tree_sequence_metadata(self, recipe):
        tables = recipe["ts"].dump_tables()
        pyslim.set_tree_sequence_metadata(
                tables, "WF", 99,
                spatial_dimensionality='xy',
                spatial_periodicity='y',
                separate_sexes=False,
                nucleotide_based=True)
        self.validate_slim_metadata(tables)
        assert tables.metadata['SLiM']['model_type'] == "WF"
        assert tables.metadata['SLiM']['generation'] == 99
        assert tables.metadata['SLiM']['spatial_dimensionality'] == 'xy'
        assert tables.metadata['SLiM']['spatial_periodicity'] == 'y'
        assert tables.metadata['SLiM']['separate_sexes'] == False
        assert tables.metadata['SLiM']['nucleotide_based'] == True

    @pytest.mark.parametrize('recipe', recipe_eq("WF"), indirect=True)
    def test_WF_model_type(self, recipe):
        self.validate_model_type(recipe["ts"], "WF")

    @pytest.mark.parametrize('recipe', recipe_eq("nonWF"), indirect=True)
    def test_nonWF_model_type(self, recipe):
        self.validate_model_type(recipe["ts"], "nonWF")

    @pytest.mark.parametrize(
        'recipe', recipe_eq(exclude="user_metadata"), indirect=True)
    def test_recover_metadata(self, recipe):
        # msprime <=0.7.5 discards metadata, but we can recover it from provenance
        ts = recipe["ts"]
        tables = ts.dump_tables()
        tables.metadata_schema = tskit.MetadataSchema(None)
        tables.metadata = b''
        new_ts = pyslim.load_tables(tables)
        assert new_ts.metadata == ts.metadata

    @pytest.mark.parametrize('recipe', recipe_eq("user_metadata"), indirect=True)
    def test_user_metadata(self, recipe):
        ts = recipe["ts"]
        md = ts.metadata["SLiM"]
        #print(md)
        assert "user_metadata" in md
        assert md['user_metadata'] == {
                "hello" : ["world"],
                "pi" : [3, 1, 4, 1, 5, 9]
                }

class TestDumpLoad(tests.PyslimTestCase):
    '''
    Test reading and writing.
    '''

    def verify_times(self, ts, slim_ts):
        gen = slim_ts.slim_generation
        assert ts.num_nodes == slim_ts.num_nodes
        # verify internal consistency
        for j in range(slim_ts.num_nodes):
            assert slim_ts.node(j).time == slim_ts.tables.nodes.time[j]
        # verify consistency between tree sequences
        for n1, n2 in zip(ts.nodes(), slim_ts.nodes()):
            assert n1.time == n2.time

    def test_load_tables(self, recipe):
        ts = recipe["ts"]
        assert isinstance(ts, pyslim.SlimTreeSequence)
        tables = ts.dump_tables()
        new_ts = pyslim.load_tables(tables)
        assert isinstance(new_ts, pyslim.SlimTreeSequence)
        new_tables = new_ts.dump_tables()
        assert tables == new_tables

    def test_load(self, recipe):
        fn = recipe["path"]["ts"]
        # load in msprime then switch
        msp_ts = tskit.load(fn)
        assert isinstance(msp_ts, tskit.TreeSequence)
        # transfer tables
        msp_tables = msp_ts.dump_tables()
        new_ts = pyslim.load_tables(msp_tables)
        assert isinstance(new_ts, pyslim.SlimTreeSequence)
        self.verify_times(msp_ts, new_ts)
        new_tables = new_ts.dump_tables()
        self.assertTableCollectionsEqual(msp_tables, new_tables)
        # convert directly
        new_ts = pyslim.SlimTreeSequence(msp_ts)
        assert isinstance(new_ts, pyslim.SlimTreeSequence)
        self.verify_times(msp_ts, new_ts)
        new_tables = new_ts.dump_tables()
        self.assertTableCollectionsEqual(msp_tables, new_tables)
        # load to pyslim from file
        slim_ts = pyslim.load(fn)
        assert isinstance(slim_ts, pyslim.SlimTreeSequence)
        slim_tables = slim_ts.dump_tables()
        self.assertTableCollectionsEqual(msp_tables, slim_tables)
        assert slim_ts.slim_generation == new_ts.slim_generation

    def test_dump_equality(self, recipe, tmp_path):
        """
        Test that we can dump a copy of the specified tree sequence
        to the specified file, and load an identical copy.
        """
        tmp_file = os.path.join(tmp_path, "test_dump.trees")
        ts = recipe["ts"]
        ts.dump(tmp_file)
        ts2 = pyslim.load(tmp_file)
        assert ts.num_samples == ts2.num_samples
        assert ts.sequence_length == ts2.sequence_length
        assert ts.tables == ts2.dump_tables()
        assert ts.reference_sequence == ts2.reference_sequence

class TestAlleles(tests.PyslimTestCase):
    '''
    Test nothing got messed up with haplotypes.
    '''

    def test_haplotypes(self, recipe):
        slim_ts = recipe["ts"]
        tables = slim_ts.dump_tables()
        ts = tables.tree_sequence()
        self.verify_haplotype_equality(ts, slim_ts)

class TestNucleotides(tests.PyslimTestCase):
    '''
    Test nucleotide support
    '''

    def test_nucleotides(self, recipe):
        '''
        Check that nucleotides are all valid, i.e.,
        -1, 0, 1, 2, or 3.
        '''
        ts = recipe["ts"]
        for mut in ts.mutations():
            # print(mut)
            for u in mut.metadata['mutation_list']:
                assert u["nucleotide"] >= -1
                assert u["nucleotide"] <= 3

class TestDecoding(tests.PyslimTestCase):
    '''
    Test by comparing decoding to our previous direct implementation of struct decoding.
    '''

    def verify_decoding(self, t, decoder):
        ms = tskit.MetadataSchema(None)
        nt = t.copy()
        nt.metadata_schema = ms
        for a, b in zip(t, nt):
            md = a.metadata
            with pytest.warns(FutureWarning):
                omd = decoder(b.metadata)
            if md is None:
                assert omd is None
            else:
                assert md == omd.asdict()

    def verify_mutation_decoding(self, t):
        ms = tskit.MetadataSchema(None)
        nt = t.copy()
        nt.metadata_schema = ms
        for a, b in zip(t, nt):
            md = a.metadata
            with pytest.warns(FutureWarning):
                omd = pyslim.decode_mutation(b.metadata)
            assert md == {"mutation_list": [u.asdict() for u in omd]}

    def test_decoding(self, recipe):
        tables = recipe["ts"].dump_tables()
        self.verify_decoding(tables.populations, pyslim.decode_population)
        self.verify_decoding(tables.individuals, pyslim.decode_individual)
        self.verify_decoding(tables.nodes, pyslim.decode_node)
        self.verify_mutation_decoding(tables.mutations)

@pytest.mark.parametrize('recipe', [next(recipe_eq())], indirect=True)
class TestMetadataAttributeError(tests.PyslimTestCase):
    """
    These are all only tested on a single recipe, the first grabbed from recipe
    """

    def test_population_error(self, recipe):
        ts = recipe["ts"]
        for x in ts.populations():
            if x.metadata is not None:
                with pytest.raises(AttributeError) as exec_info:
                    _ = x.metadata.slim_id
                assert 'legacy' in str(exec_info)
                with pytest.raises(AttributeError) as exec_info:
                    _ = x.metadata.selfing_fraction
                assert 'legacy' in str(exec_info)
                with pytest.raises(AttributeError) as exec_info:
                    _ = x.metadata.sex_ratio
                assert 'legacy' in str(exec_info)
            with pytest.raises(AttributeError) as exec_info:
                _ = x.metadata.ping
            assert "has no attribute 'ping'" in str(exec_info)
            break

    def test_individual_error(self, recipe):
        ts = recipe["ts"]
        for x in ts.individuals():
            with pytest.raises(AttributeError) as exec_info:
                _ = x.metadata.pedigree_id
            assert 'legacy' in str(exec_info)
            with pytest.raises(AttributeError) as exec_info:
                _ = x.metadata.age
            assert 'legacy' in str(exec_info)
            with pytest.raises(AttributeError) as exec_info:
                _ = x.metadata.subpopulation
            assert 'legacy' in str(exec_info)
            with pytest.raises(AttributeError) as exec_info:
                _ = x.metadata.sex
            assert 'legacy' in str(exec_info)
            with pytest.raises(AttributeError) as exec_info:
                _ = x.metadata.flags
            assert 'legacy' in str(exec_info)
            with pytest.raises(AttributeError) as exec_info:
                _ = x.metadata.pong
            assert "has no attribute 'pong'" in str(exec_info)
            break

    def test_node_error(self, recipe):
        ts = recipe["ts"]
        for x in ts.nodes():
            if x.metadata is not None:
                with pytest.raises(AttributeError) as exec_info:
                    _ = x.metadata.slim_id
                assert 'legacy' in str(exec_info)
                with pytest.raises(AttributeError) as exec_info:
                    _ = x.metadata.is_null
                assert 'legacy' in str(exec_info)
                with pytest.raises(AttributeError) as exec_info:
                    _ = x.metadata.genome_type
                assert 'legacy' in str(exec_info)
            with pytest.raises(AttributeError) as exec_info:
                _ = x.metadata.pang
            assert "has no attribute 'pang'" in str(exec_info)
            break

    def test_mutation_error(self, recipe):
        ts = recipe["ts"]
        for x in ts.mutations():
            with pytest.raises(KeyError) as exec_info:
                _ = x.metadata[0]
            assert 'legacy' in str(exec_info)
            with pytest.raises(KeyError) as exec_info:
                _ = x.metadata[999]
            assert 'legacy' in str(exec_info)
            with pytest.raises(KeyError):
                _ = x.metadata['ping']
            break


# -- coding: UTF-8 --
# Name: MyTest.py
# Date: 2018.05.18
# Author: Lniper
# Aim:  构建如下图所示识别模型：该模型由两个相同的网络G(x)组成。两个网络共享相同的参数W.
#       例如，输入  负样本对：X1=6的图片 ， X2=9的图片 输出：1
#       输入  正样本对：X1=3的图片 ， X2=3的图片 输出：0
#       G(x)是一个一般的全连接网络（两边的网络结构是一样的！共享参数W、b等），由结构可以自己设计。
#       比如建议两层网络：hidden1：784(28x28)->500; hidden2: 500->10，使用relu。也可以尝试其他节点数组合，和其他非线性变换函数。
#
import tensorflow as tf
from tensorflow.examples.tutorials.mnist import input_data
import MNISTInference as mnInferece
import MNISTTrain as mnTrain
import numpy as np

batch_size = 64
learning_rate = 0.005

def evaluate():
    iter = 100
    itera = 0
    for itera in range(iter):
        mnist = input_data.read_data_sets('MNIST_data/', one_hot=True)
        x_1, y_1 = mnist.train.next_batch(batch_size)
        # print("x_1 = ", x_1)

        x_2, y_2 = mnist.train.next_batch(batch_size)
        # print("x_2 = ", x_2)

        with tf.Graph().as_default() as g:
            # x1数据
            x = tf.placeholder(tf.float32, [None, mnInferece.INPUT_NODE], name='x-input')
            y_ = tf.placeholder(tf.float32, [None, mnInferece.OUTPUT_NODE], name='y-input')

            # x2数据
            x2 = tf.placeholder(tf.float32, [None, mnInferece.INPUT_NODE], name='x-input2')
            y2_ = tf.placeholder(tf.float32, [None, mnInferece.OUTPUT_NODE], name='y-input2')

            y1 = mnInferece.inference(x, None)
            # tf.argmax(y1, 1)可以得到输入样例中的预测类别
            correct_prediction1 = tf.equal(tf.argmax(y1, 1), tf.argmax(y_, 1))

            y2 = mnInferece.inference(x2, None, True)
            # tf.argmax(y1, 1)可以得到输入样例中的预测类别
            correct_prediction2 = tf.equal(tf.argmax(y2, 1), tf.argmax(y_2, 1))

            accuracy1 = tf.reduce_mean(tf.cast(correct_prediction1, tf.float32))
            accuracy2 = tf.reduce_mean(tf.cast(correct_prediction2, tf.float32))

            variable_averages = tf.train.ExponentialMovingAverage(mnTrain.MOVING_AVERAGE_DECAY)
            variables_to_restore = variable_averages.variables_to_restore()
            saver = tf.train.Saver(variables_to_restore)

            # 计算损失函数
            y_s = np.array(correct_prediction2 != correct_prediction1, dtype = np.float32)
            Q = 5
            # E_w = tf.sqrt(tf.reduce_sum(tf.square(o1-o2),1))，  tf.exp()等请自查
            E_w = tf.sqrt(tf.reduce_sum(tf.square((y1 - y2)), 1))
            L = (1 - y_s) * (2 / Q) * tf.square(E_w) + y_s * 2 * Q * tf.exp(-2.77 / Q)

            OptimLoss = tf.train.GradientDescentOptimizer(learning_rate).minimize(L)

            accuracy3 = tf.reduce_mean(tf.cast(L, tf.float32))

            with tf.Session() as sess:
                ckpt = tf.train.get_checkpoint_state(mnTrain.MODEL_SAVE_PATH)

                if ckpt and ckpt.model_checkpoint_path:
                    saver.restore(sess, ckpt.model_checkpoint_path)
                    global_step = ckpt.model_checkpoint_path.split('/')[-1].split('-')[-1]

                    validate_feed1 = {x: x_1, y_: y_1}
                    Predict1 = sess.run(correct_prediction1, feed_dict=validate_feed1)
                    accuracy_score1 = sess.run(accuracy1, feed_dict=validate_feed1)

                    validate_feed2 = {x2: x_2, y2_: y_2}
                    Predict2 = sess.run(correct_prediction2, feed_dict=validate_feed2)
                    accuracy_score2 = sess.run(accuracy2, feed_dict=validate_feed2)

                    # 例如，输入  负样本对：X1=6的图片 ， X2=9的图片 输出：1
                    #       输入  正样本对：X1=3的图片 ， X2=3的图片 输出：0
                    y_sOut = np.array(Predict1 != Predict2, dtype=np.float32)
                    # y_sOut = sess.run(y_s, {x: x_1, x2: x_2, y_: y_1, y2_: y_2})
                    print("y_sOut = ", y_sOut)

                    L_OutPut = sess.run(OptimLoss, {x: x_1, x2: x_2, y_: y_1, y2_: y_2})
                    print("L_OutPut = ", L_OutPut)

                    accuracy_score3 = sess.run(accuracy3, {x: x_1, x2: x_2, y_: y_1, y2_: y_2})

                    print("After %s training step(s), validation accuracy = %g" % (global_step, accuracy_score1))
                    print("After %s training step(s), validation accuracy = %g" % (global_step, accuracy_score2))
                    print("After %s training step(s), validation accuracy = %g" % (global_step, accuracy_score3))

                else:
                    print('No checkpoint file found')
                    return

def main(argv=None):
    evaluate()

if __name__ == '__main__':
    main()


# -*- coding: utf-8 -*-
# ░░░░░░░░░░░░░░░░░░░░░░░░▄░░
# ░░░░░░░░░▐█░░░░░░░░░░░▄▀▒▌░
# ░░░░░░░░▐▀▒█░░░░░░░░▄▀▒▒▒▐
# ░░░░░░░▐▄▀▒▒▀▀▀▀▄▄▄▀▒▒▒▒▒▐
# ░░░░░▄▄▀▒░▒▒▒▒▒▒▒▒▒█▒▒▄█▒▐
# ░░░▄▀▒▒▒░░░▒▒▒░░░▒▒▒▀██▀▒▌
# ░░▐▒▒▒▄▄▒▒▒▒░░░▒▒▒▒▒▒▒▀▄▒▒
# ░░▌░░▌█▀▒▒▒▒▒▄▀█▄▒▒▒▒▒▒▒█▒▐
# ░▐░░░▒▒▒▒▒▒▒▒▌██▀▒▒░░░▒▒▒▀▄
# ░▌░▒▄██▄▒▒▒▒▒▒▒▒▒░░░░░░▒▒▒▒
# ▀▒▀▐▄█▄█▌▄░▀▒▒░░░░░░░░░░▒▒▒
# @Author : 雾江南

def reserved_fields_list(lists, need_fields_list):
    """
    数据根据字段条件进行筛选重组
    :param lists: 数组
    :param need_fields_list: 条件
    :return:
    """
    result_data = []
    for r in lists:
        result_data.append(reserved_fields(r, need_fields_list))
    return result_data

def reserved_fields(dicts, need_fields_list):
    res = {}
    for field in need_fields_list:
        if field in dicts.keys():
            res.update({field: dicts[field]})
    return res

def filter_dict_without_none(filter_dict):
    """
    去除字段中为空字段
    :param filter_dict: 字典
    :return:
    """
    for key, value in filter_dict.items():
        if not value:
            filter_dict.__delitem__(key)

    return filter_dict

def filter_list_status(lists, status=1):
    """
    去除数组中不符合条件的字段
    :param lists:  数组
    :param status: 条件（字符串）
    :return:
    """
    new_detail = []
    for res in lists:
        if res.status == status:
            new_detail.append(res)

    lists = new_detail
    return lists

def update_relationship_method(data, check_id, update_date=None):
    """
    处理层级关系（前端需要）
    :param data: 元数据
    :param check_id: 目标
    :param update_date: 新数据
    :return:
    """
    for res in data:
        if res['key'] == check_id:
            res['children'].append(update_date)
            return data
        if res['children'] is not None:
            update_relationship_method(res['children'], check_id, update_date)
        continue
    return False


import multiprocessing
import os
from argparse import ArgumentParser

import gensim
import tensorflow as tf
from tqdm import tqdm

import constants as const
import models
import preprocess

def parse_args():
    parser = ArgumentParser()
    parser.add_argument("input_path", help="The path of the input file")
    parser.add_argument("output_path", help="The path of the output file")
    parser.add_argument(
        "resources_path", help="The path of the resources needed to load your model"
    )

    return parser.parse_args()

def predict(input_path, output_path, resources_path):
    """
    This is the skeleton of the prediction function.
    The predict function will build your model, load the weights from the checkpoint and write a new file (output_path)
    with your predictions in the BIES format.

    The resources folder should contain everything you need to make the predictions. It is the "resources" folder in
    your submission.

    N.B. DO NOT HARD CODE PATHS IN HERE. Use resource_path instead, otherwise we will not be able to run the code.

    :param input_path: the path of the input file to predict.
    :param output_path: the path of the output file (where you save your predictions)
    :param resources_path: the path of the resources folder containing your model and stuff you might need.
    :return: None
    """

    # tf configurations
    config = tf.ConfigProto()
    config.intra_op_parallelism_threads = multiprocessing.cpu_count()
    config.inter_op_parallelism_threads = multiprocessing.cpu_count()
    tf.Session(config=config)

    # resources
    weights_path = os.path.join(resources_path, "model_weights.h5")
    embedding = os.path.join(resources_path, "bigram_unigram300.txt")

    # Load the vocab
    print("Computing vocab...")
    w2v = gensim.models.KeyedVectors.load_word2vec_format(embedding)
    vocab = preprocess.vocab_from_w2v(w2v)

    # Build the model
    print("loading model...")
    model = models.build_model(
        n_classes=4,
        dropout=0.45,
        recurrent_dropout=0.2,
        learning_rate=0.0025,
        word2vec=w2v,
        word2vec_bi=w2v,
    )
    # Load the weights
    model.load_weights(weights_path)

    # Load test txt
    features_test = preprocess.read_dataset(input_path)
    with open(output_path, mode="w", encoding="utf8") as out_file:
        for line in tqdm(features_test):
            line = line.strip()

            to_predict_uni = preprocess.compute_X([line], vocab, pad=False)
            to_predict_bi = preprocess.compute_X(
                [preprocess.compute_bigrams(line)], vocab, pad=False
            )

            prediction = model.predict(
                [to_predict_uni, to_predict_bi], workers=multiprocessing.cpu_count()
            )

            id_prediction = prediction.argmax(-1)[0]
            bies_prediction = [const.INVERSE_LABELS[p] for p in id_prediction]
            out_file.write("".join(bies_prediction) + "\n")

    return

if __name__ == "__main__":
    args = parse_args()
    predict(args.input_path, args.output_path, args.resources_path)


# uncompyle6 version 3.7.4
# Python bytecode 2.7 (62211)
# Decompiled from: Python 3.6.9 (default, Apr 18 2020, 01:56:04)
# [GCC 8.4.0]
# Embedded file name: /tmp/pip-install-n_sfyb/Django/django/core/cache/backends/memcached.py
# Compiled at: 2019-02-14 00:35:17
"""Memcached cache backend"""
import pickle, re, time, warnings
from django.core.cache.backends.base import DEFAULT_TIMEOUT, BaseCache
from django.utils import six
from django.utils.deprecation import RemovedInDjango21Warning
from django.utils.encoding import force_str
from django.utils.functional import cached_property

class BaseMemcachedCache(BaseCache):

    def __init__(self, server, params, library, value_not_found_exception):
        super(BaseMemcachedCache, self).__init__(params)
        if isinstance(server, six.string_types):
            self._servers = re.split('[;,]', server)
        else:
            self._servers = server
        self.LibraryValueNotFoundException = value_not_found_exception
        self._lib = library
        self._options = params.get('OPTIONS') or {}

    @property
    def _cache(self):
        """
        Implements transparent thread-safe access to a memcached client.
        """
        if getattr(self, '_client', None) is None:
            self._client = self._lib.Client(self._servers, **self._options)
        return self._client

    def get_backend_timeout(self, timeout=DEFAULT_TIMEOUT):
        """
        Memcached deals with long (> 30 days) timeouts in a special
        way. Call this function to obtain a safe value for your timeout.
        """
        if timeout == DEFAULT_TIMEOUT:
            timeout = self.default_timeout
        if timeout is None:
            return 0
        else:
            if int(timeout) == 0:
                timeout = -1
            if timeout > 2592000:
                timeout += int(time.time())
            return int(timeout)

    def make_key(self, key, version=None):
        return force_str(super(BaseMemcachedCache, self).make_key(key, version))

    def add(self, key, value, timeout=DEFAULT_TIMEOUT, version=None):
        key = self.make_key(key, version=version)
        return self._cache.add(key, value, self.get_backend_timeout(timeout))

    def get(self, key, default=None, version=None):
        key = self.make_key(key, version=version)
        val = self._cache.get(key)
        if val is None:
            return default
        else:
            return val

    def set(self, key, value, timeout=DEFAULT_TIMEOUT, version=None):
        key = self.make_key(key, version=version)
        if not self._cache.set(key, value, self.get_backend_timeout(timeout)):
            self._cache.delete(key)

    def delete(self, key, version=None):
        key = self.make_key(key, version=version)
        self._cache.delete(key)

    def get_many(self, keys, version=None):
        new_keys = [ self.make_key(x, version=version) for x in keys ]
        ret = self._cache.get_multi(new_keys)
        if ret:
            _ = {}
            m = dict(zip(new_keys, keys))
            for k, v in ret.items():
                _[m[k]] = v

            ret = _
        return ret

    def close(self, **kwargs):
        self._cache.disconnect_all()

    def incr(self, key, delta=1, version=None):
        key = self.make_key(key, version=version)
        if delta < 0:
            return self._cache.decr(key, -delta)
        else:
            try:
                val = self._cache.incr(key, delta)
            except self.LibraryValueNotFoundException:
                val = None

            if val is None:
                raise ValueError("Key '%s' not found" % key)
            return val

    def decr(self, key, delta=1, version=None):
        key = self.make_key(key, version=version)
        if delta < 0:
            return self._cache.incr(key, -delta)
        else:
            try:
                val = self._cache.decr(key, delta)
            except self.LibraryValueNotFoundException:
                val = None

            if val is None:
                raise ValueError("Key '%s' not found" % key)
            return val

    def set_many(self, data, timeout=DEFAULT_TIMEOUT, version=None):
        safe_data = {}
        for key, value in data.items():
            key = self.make_key(key, version=version)
            safe_data[key] = value

        self._cache.set_multi(safe_data, self.get_backend_timeout(timeout))

    def delete_many(self, keys, version=None):
        self._cache.delete_multi(self.make_key(key, version=version) for key in keys)

    def clear(self):
        self._cache.flush_all()

class MemcachedCache(BaseMemcachedCache):
    """An implementation of a cache binding using python-memcached"""

    def __init__(self, server, params):
        import memcache
        super(MemcachedCache, self).__init__(server, params, library=memcache, value_not_found_exception=ValueError)

    @property
    def _cache(self):
        if getattr(self, '_client', None) is None:
            client_kwargs = dict(pickleProtocol=pickle.HIGHEST_PROTOCOL)
            client_kwargs.update(self._options)
            self._client = self._lib.Client(self._servers, **client_kwargs)
        return self._client

class PyLibMCCache(BaseMemcachedCache):
    """An implementation of a cache binding using pylibmc"""

    def __init__(self, server, params):
        import pylibmc
        super(PyLibMCCache, self).__init__(server, params, library=pylibmc, value_not_found_exception=pylibmc.NotFound)
        legacy_behaviors = {}
        for option in list(self._options):
            if option not in ('behaviors', 'binary', 'username', 'password'):
                warnings.warn('Specifying pylibmc cache behaviors as a top-level property within `OPTIONS` is deprecated. Move `%s` into a dict named `behaviors` inside `OPTIONS` instead.' % option, RemovedInDjango21Warning, stacklevel=2)
                legacy_behaviors[option] = self._options.pop(option)

        if legacy_behaviors:
            self._options.setdefault('behaviors', {}).update(legacy_behaviors)

    @cached_property
    def _cache(self):
        return self._lib.Client(self._servers, **self._options)

    def close(self, **kwargs):
        pass


# https://www.jiuzhang.com/solutions/longest-increasing-subsequence
# https://leetcode.com/articles/longest-increasing-subsequence/
class Solution:
    def lengthOfLIS(self, nums: List[int]) -> int:
        # x = self.dp_search(nums)
        return self.dp_search_optimized(nums)

    # DP TBD
    def dp_find_all_sequence(self, nums):
        pass

    def dp_search_optimized(self, nums):
        # O(NlogN), O(N)
        if not nums:
            return 0

        n = len(nums)
        # Record the count of numbers smaller than the current number in sequence
        dp = [0] * n
        # Map the count to the smallest number in subsequence
        lis = [0] * (n + 1)

        # Initialize dp

        for i in range(1, n):
            if nums[i] > lis[j]:
                # Current number larger than previous number
                dp[i] = j
                j += 1
                lis[j] = nums[i]
            else:
                # Current number smaller than previous number. N
                # eed to find the lis index of the number smaller than the current one.
                start, end = 1, j
                """
                # Method 1
                while start != end:
                    mid = (start + end) // 2
                    if lis[mid] < nums[i]:
                        start = mid + 1
                    else:
                        end = mid
                prev = start
                """
                # Method 2
                while start + 1 < end:
                    mid = (start + end) // 2
                    if lis[mid] < nums[i]:
                        start = mid
                    else:
                        end = mid
                prev = 1
                if lis[start] == nums[i]:
                    prev = start
                elif lis[end] == nums[i]:
                    prev = end
                elif lis[start] < nums[i]:
                    prev = start + 1
                elif lis[end] < nums[i]:
                    prev = end + 1

                dp[i], lis[prev] = prev, min(lis[prev], nums[i])
        print(nums)
        print(dp)
        print(lis)
        return j

    def dp_search(self, nums):
        # O(N^2), O(N)
        n = len(nums)
        # Record the number of numbers smaller than the current number in the previous sequence
        dp = [1] * n
        for i in range(n):
            # See if there are other previous numbers smaller than the cuurent number
            for prev in range(i):
                if nums[prev] < nums[i]:
                    dp[i] = max(dp[i], dp[prev] + 1)
        print(nums)
        print(dp)
        return max(dp)


"""
xkcd module by @Protoh
"""
from telegram import Bot, Update
from urllib.parse import quote
import requests

import core
PLUGINVERSION = 2
# Always name this variable as `plugin`
# If you dont, module loader will fail to load the plugin!
plugin = core.Plugin(name="xkcd")

TEXT = """
*title:* %(safe_title)s
*number:* %(num)s
*date*`(yyyy-mm-dd for christ's sake)`*:* %(year)s-%(month)s-%(day)s
*alt:* _%(alt)s_
*link:* xkcd.com/%(num)s
"""

@plugin.command(command="/xkcd",
                description="Sends xkcd comics in the chat! usage: '/xkcd', '/xkcd <number>', or '/xkcd <query>'",
                inline_supported=True,
                hidden=False)
def xkcd(bot: Bot, update: Update, user, args): # pylint: disable=W0613
    """
    Example usage:
    User:
    /xkcd 1

    OctoBot:
    title: Barrel - Part 1
    number: 1
    date(yyyy-mm-dd for christ's sake): 2006-01-01
    alt: Don't we all.
    link: xkcd.com/1
    """
    argument = " ".join(args)
    id = ""
    if not argument:
        id = -1
    else:
        if argument.isdigit():
            id = argument
        else:
            queryresult = requests.get('https://relevantxkcd.appspot.com/process?',params={"action":"xkcd","query":quote(argument)}).text
            id = queryresult.split(" ")[2].lstrip("\n")
    data = ""
    if id == -1:
        data = requests.get("https://xkcd.com/info.0.json").json()
    else:
        r = requests.get("https://xkcd.com/{}/info.0.json".format(id))
        if r.ok:
            data = r.json()
        else:
            return core.message("xkcd n.{} not found!".format(id), failed=True)
    #msg.reply_photo(photo = data['img']) Cause telegram makes preview of comic, we dont need it anymore
    data['month'] = data['month'].zfill(2)
    data['day'] = data['day'].zfill(2)
    return core.message(TEXT % data, parse_mode="MARKDOWN")


"""
### BEGIN NODE INFO
[info]
name = visa
version = 1
description =
instancename = %LABRADNODE%_visa

[startup]
cmdline = %PYTHON% %FILE%
timeout = 20

[shutdown]
message = 987654321
timeout = 20
### END NODE INFO
"""
import os

from labrad.server import setting
import visa

from hardware_interface_server.server import HardwareInterfaceServer
from hardware_interface_server.exceptions import InterfaceNotAvailable

class VISAServer(HardwareInterfaceServer):
    """Provides direct access to VISA-enabled hardware via pyvisa"""
    name = '%LABRADNODE%_visa'

    def _get_rm(self):
        if os.name == 'nt':
            return visa.ResourceManager()
        else:
            return visa.ResourceManager('@py')

    def _get_available_interfaces(self):
        rm = self._get_rm()
        available_interfaces = list(rm.list_resources())
        return available_interfaces

    def _get_open_interfaces(self):
        available_interfaces = self._get_available_interfaces()
        for interface_id in self.interfaces:
            if interface_id not in available_interfaces:
                del self.interfaces[interface_id]
        return self.interfaces.keys()

    def _open_interface(self, interface_id):
        rm = self._get_rm()
        if interface_id in self.interfaces:
            return
#            raise InterfaceAlreadyOpen(interface_id)
        try:
            inst = rm.open_resource(interface_id)
        except:
            raise InterfaceNotAvailable(interface_id)
        self.interfaces[interface_id] = inst

    def _close_interface(self, interface_id):
        inst = self._get_interface(interface_id)
        inst.close()
        del self.interfaces[interface_id]

    @setting(10)
    def go_to_local(self, c, interface_id):
        interface = self._get_interface(interface_id)
        interface.control_ren(6)

    @setting(11)
    def query(self, c, interface_id, command):
        interface = self._get_interface(interface_id)
        response = interface.query(command)
        return response.strip()

    @setting(12)
    def read(self, c, interface_id):
        interface = self._get_interface(interface_id)
        response = interface.read(command)
        return response.strip()

    @setting(13, interface_id='s', timeout='v')
    def timeout(self, c, interface_id, timeout=None):
        interface = self._get_interface(interface_id)
        if timeout is not None:
            interface.timeout = timeout
        return interface.timeout

    @setting(14)
    def write(self, c, interface_id, command):
        interface = self._get_interface(interface_id)
        interface.write(command)

Server = VISAServer

if __name__ == '__main__':
    from labrad import util
    util.runServer(Server())


def update_shortcuts(custom_keys):
        # Configure actions.
        action = QtWidgets.QAction('Print', None)
        action.setEnabled(True)
        printkey = QtGui.QKeySequence(QtGui.QKeySequence.Print)
        if 'print' in custom_keys.keys():
            printkey = custom_keys['print']
        elif printkey.matches("Ctrl+P") and sys.platform != 'darwin':
            # Only override the default if there is a collision.
            # Qt ctrl = cmd on OSX, so the match gets a false positive on OSX.
            printkey = "Ctrl+Shift+P"

        action.setShortcut(printkey)
        action.setShortcutContext(QtCore.Qt.WidgetWithChildrenShortcut)
        action.triggered.connect(self.print_)
        self.addAction(action)
        self.print_action = action

        action = QtWidgets.QAction('Save as HTML/XML', None)
        action.setShortcut(QtGui.QKeySequence.Save)
        action.setShortcutContext(QtCore.Qt.WidgetWithChildrenShortcut)
        action.triggered.connect(self.export_html)
        self.addAction(action)
        self.export_action = action

        action = QtWidgets.QAction('Select All', None)
        action.setEnabled(True)
        selectall = QtGui.QKeySequence(QtGui.QKeySequence.SelectAll)
        if selectall.matches("Ctrl+A") and sys.platform != 'darwin':
            # Only override the default if there is a collision.
            # Qt ctrl = cmd on OSX, so the match gets a false positive on OSX.
            selectall = "Ctrl+Shift+A"
        action.setShortcut(selectall)
        action.setShortcutContext(QtCore.Qt.WidgetWithChildrenShortcut)
        action.triggered.connect(self.select_all_smart)
        self.addAction(action)
        self.select_all_action = action

        self.increase_font_size = QtWidgets.QAction("Bigger Font",
                self,
                shortcut=QtGui.QKeySequence.ZoomIn,
                shortcutContext=QtCore.Qt.WidgetWithChildrenShortcut,
                statusTip="Increase the font size by one point",
                triggered=self._increase_font_size)
        self.addAction(self.increase_font_size)

        self.decrease_font_size = QtWidgets.QAction("Smaller Font",
                self,
                shortcut=QtGui.QKeySequence.ZoomOut,
                shortcutContext=QtCore.Qt.WidgetWithChildrenShortcut,
                statusTip="Decrease the font size by one point",
                triggered=self._decrease_font_size)
        self.addAction(self.decrease_font_size)

        self.reset_font_size = QtWidgets.QAction("Normal Font",
                self,
                shortcut="Ctrl+0",
                shortcutContext=QtCore.Qt.WidgetWithChildrenShortcut,
                statusTip="Restore the Normal font size",
                triggered=self.reset_font)
        self.addAction(self.reset_font_size)


import requests
import json
import pandas as pd
import yaml
from datetime import datetime

with open('G:\WEBSCRAP\REAL_ESTATE\SgpRealEstateSecrets.yaml','r') as masked_data:
    secrets = yaml.load(masked_data, Loader=yaml.FullLoader)

myAccessKey=secrets['AccessKey']
URL_token = "https://www.ura.gov.sg/uraDataService/insertNewToken.action"
tokenResponse = requests.get(URL_token, headers={'AccessKey':myAccessKey})
mytoken= (tokenResponse.text.split(":"))[3].split('}')[0].replace('"','')

outputDir = 'I:\\REAL_ESTATE_DATA\\DATA_TO_PROCESS'

for i in range(1,5) :
    transactionFileName = 'TransactionData_' + datetime.today().strftime('%d_%m_%Y') + '_' + str(i) + '.csv'
    condoFileName = 'CondoData_' + datetime.today().strftime('%d_%m_%Y') + '_' + str(i) + '.csv'
    df_CondoDetails = pd.DataFrame()
    df_Transactions = pd.DataFrame()
    URL_privateResidenceTransaction = 'https://www.ura.gov.sg/uraDataService/invokeUraDS?service=PMI_Resi_Transaction&batch=' + str(i)
    Response_transaction = requests.get(URL_privateResidenceTransaction, headers={'AccessKey':myAccessKey, 'token':mytoken})
    Response_transaction = Response_transaction.text
    transactions = json.loads(Response_transaction)
    transactions = transactions['Result']

    for transaction_rec in transactions :
        CondoName = transaction_rec['project']
        Street = transaction_rec['street']
        MarketSegment = transaction_rec['marketSegment']
        District = transaction_rec['transaction'][0]['district']
        Tenure = transaction_rec['transaction'][0]['tenure']
        PropertyType = transaction_rec['transaction'][0]['propertyType']
        condoDict = {'CondoName': [CondoName],
                     'Street': [Street],
                     'MarketSegment': [MarketSegment],
                     'District': [District],
                     'PropertyType': [PropertyType]
                    }
        tempdf_CondoDetails = pd.DataFrame.from_dict(condoDict )

        trans = transaction_rec['transaction']
        tempdf_Transactions = pd.DataFrame(trans)
        tempdf_Transactions['CondoName'] = CondoName
        if df_CondoDetails.empty == True:
            df_CondoDetails = tempdf_CondoDetails.copy()
        df_CondoDetails = df_CondoDetails.append(tempdf_CondoDetails)

        if df_Transactions.empty == True:
            df_Transactions = tempdf_Transactions.copy()
        df_Transactions = df_Transactions.append(tempdf_Transactions)

    df_Transactions['contractDate_mm'] = df_Transactions['contractDate'].str[:2]
    df_Transactions['contractDate_yy'] = df_Transactions['contractDate'].str[2:]
    if 'nettPrice' in df_Transactions :
        df_Transactions = df_Transactions.drop(columns=['nettPrice'])
    df_CondoDetails = df_CondoDetails.set_index('CondoName')
    df_Transactions = df_Transactions.set_index('CondoName')

    df_Transactions.to_csv(outputDir + '\\' + transactionFileName )
    df_CondoDetails.to_csv(outputDir + '\\' + condoFileName )


import datetime
import pickle
from os import path

import numpy as np
import tensorflow as tf
from keras import Model
from keras.callbacks import EarlyStopping, ModelCheckpoint, CSVLogger
from sklearn.metrics import confusion_matrix

from constants import EMOTIONS, WEEK, PKL_ROOT

def train(model: Model, x: [], y: [], EPOCHS: int, batch_size=4, early_stopping=True,
          save_history=True, TIME=datetime.datetime.now().strftime("%Y%m%d-%H%M%S")):
    print("Start Training")

    log_dir = "logs/week_{}/fit_{}_class/{}_{}_{}".format(WEEK, len(EMOTIONS), model.name,
                                                          type(model.optimizer).__name__,
                                                          TIME)
    tensorboard_callback = tf.keras.callbacks.TensorBoard(log_dir=log_dir)

    callback_list = [
        ModelCheckpoint(
            filepath=model.name + '.h5',
            monitor='val_acc',
            save_best_only='True',
            verbose=1,
            mode='max'
        ), tensorboard_callback]

    if early_stopping:
        callback_list.append(
            EarlyStopping(
                monitor='val_loss',
                patience=10,
                verbose=1,
                mode='min'
            )
        )

    if save_history:
        history_file = "history/week_{}/{}_{}_{}.csv".format(WEEK, model.name, type(model.optimizer).__name__,
                                                             TIME)
        callback_list.append(
            CSVLogger(filename=history_file)
        )

    tic = datetime.datetime.now()
    history = model.fit(x, y,
                        batch_size=batch_size, epochs=EPOCHS,
                        validation_split=0.2,
                        verbose=True,
                        callbacks=callback_list)
    toc = datetime.datetime.now()

    diff = toc - tic
    print("Finished Training: Took : {} Seconds".format(diff.total_seconds()))

    return history, model, diff.total_seconds()

def test(model: Model, x: [], y: []):
    matrices = model.evaluate(x, y)

    test_results = {}
    for i in range(len(model.metrics_names)):
        print("{} : \t {}".format(model.metrics_names[i], matrices[i]))
        test_results[model.metrics_names[i]] = matrices[i]

    return test_results

def randomize_split(data, split_ratio=0.8):
    # shuffle the dataset
    np.random.shuffle(data)

    # divide training and testing dataset
    training_count = int(len(data) * split_ratio)

    training_data = data[:training_count]
    testing_data = data[training_count:]
    return training_data, testing_data

def plot_model(model, filename):
    filename = 'model_plots/{}.png'.format(filename)
    print("Plotting the model. Saving at: {}".format(filename))
    tf.keras.utils.plot_model(
        model,
        to_file=filename,
        show_shapes=True,
        show_layer_names=True
    )

def plot_confusion_matrix(cm,
                          target_names,
                          filename,
                          title='Confusion matrix',
                          cmap=None,
                          normalize=True):
    """
    given a sklearn confusion matrix (cm), make a nice plot

    Arguments
    ---------
    cm:           confusion matrix from sklearn.metrics.confusion_matrix

    target_names: given classification classes such as [0, 1, 2]
                  the class names, for example: ['high', 'medium', 'low']

    title:        the text to display at the top of the matrix

    cmap:         the gradient of the values displayed from matplotlib.pyplot.cm
                  see http://matplotlib.org/examples/color/colormaps_reference.html
                  plt.get_cmap('jet') or plt.cm.Blues

    normalize:    If False, plot the raw numbers
                  If True, plot the proportions

    Usage
    -----
    plot_confusion_matrix(cm           = cm,                  # confusion matrix created by
                                                              # sklearn.metrics.confusion_matrix
                          normalize    = True,                # show proportions
                          target_names = y_labels_vals,       # list of names of the classes
                          title        = best_estimator_name) # title of graph

    Citiation
    ---------
    http://scikit-learn.org/stable/auto_examples/model_selection/plot_confusion_matrix.html

    """
    import matplotlib.pyplot as plt
    import numpy as np
    import itertools

    accuracy = np.trace(cm) / float(np.sum(cm))
    misclass = 1 - accuracy

    if cmap is None:
        cmap = plt.get_cmap('Blues')

    plt.figure()
    plt.imshow(cm, interpolation='nearest', cmap=cmap)
    plt.title(title, pad=6)
    plt.colorbar()

    if target_names is not None:
        tick_marks = np.arange(len(target_names))
        plt.xticks(tick_marks, target_names, rotation=45)
        plt.yticks(tick_marks, target_names)

    if normalize:
        cm = cm.astype('float') / cm.sum(axis=1)[:, np.newaxis]

    thresh = cm.max() / 1.5 if normalize else cm.max() / 2
    for i, j in itertools.product(range(cm.shape[0]), range(cm.shape[1])):
        if normalize:
            plt.text(j, i, "{:0.4f}".format(cm[i, j]),
                     horizontalalignment="center",
                     color="white" if cm[i, j] > thresh else "black")
        else:
            plt.text(j, i, "{:,}".format(cm[i, j]),
                     horizontalalignment="center",
                     color="white" if cm[i, j] > thresh else "black")

    # plt.tight_layout()
    plt.ylabel('True label')
    plt.xlabel('Predicted label\naccuracy={:0.4f}; misclass={:0.4f}'.format(accuracy, misclass))
    plt.savefig(filename)
    print("Saved Confusion Matrix to: {}".format(filename))

def get_confusion_matrix(model: Model, x_test, y_test, prediction_index=None):
    predictions = model.predict(x_test)
    if prediction_index is None:
        prediction_classes = np.argmax(predictions[0], axis=1)
    else:
        prediction_classes = np.argmax(predictions[prediction_index], axis=1)

    return confusion_matrix(np.argmax(y_test, axis=1), prediction_classes)

def get_dataset(filename='signal-dataset.pkl'):
    if not path.exists(PKL_ROOT + filename):
        download(filename)

    with open(PKL_ROOT + filename, 'rb') as f:
        data = pickle.load(f)
        return data

def download(filename, base_url='https://s3-ap-southeast-1.amazonaws.com/usq.iothealth/iemocap/'):
    import urllib.request

    url = base_url + filename

    print('Beginning file download {}'.format(url))

    store_file = PKL_ROOT + filename
    urllib.request.urlretrieve(url, store_file)

    print("Downloaded and saved to file: {}".format(store_file))


# 调用函数的时候 传入 名字 年龄
# 例如: 老王 30
# 通过函数内部进行数据处理
# 你的名字叫做老王
# 你的年龄为30岁
# 把新的数据返回给函数调用者
def deal_info(name, age):
    new_name = "你的名字叫做" + name
    new_age = "你的年龄为%d岁" % age
    # 如果一个函数返回多个数据的方式
    # 只需要把多个数据使用逗号隔开即可 就是一个元组类型
    return new_name, new_age

ret = deal_info("老王", 30)
print(type(ret))
print(ret[0])
print(ret[1])

08-一个函数返回多个数据的方式.py


# uncompyle6 version 3.7.4
# Python bytecode 2.6 (62161)
# Decompiled from: Python 3.6.9 (default, Apr 18 2020, 01:56:04)
# [GCC 8.4.0]
# Embedded file name: build/bdist.linux-i686/egg/mortar/tests/test_convertors.py
# Compiled at: 2008-12-19 12:41:15
import datetime, unittest
from fixtures import identity, check
from mortar import types
from mortar.interfaces import IFieldType, empty

class TestConvertors(unittest.TestCase):
    mapping = {types.datetime: [
                      (
                       '2008/02/01', datetime.datetime(2008, 2, 1, 0, 0)),
                      (
                       identity, TypeError('Could not adapt', identity, types.datetime)),
                      (
                       datetime.datetime(2008, 2, 1, 0, 0), identity),
                      (
                       'junk', TypeError('Could not adapt', 'junk', types.datetime))],
       types.datetimes: [], types.date: [
                  (
                   '2008/02/01', datetime.date(2008, 2, 1)),
                  (
                   'junk', TypeError('Could not adapt', 'junk', types.date))],
       types.dates: [], types.time: [], types.times: [], types.number: [
                    (
                     1.0, identity)],
       types.numbers: [], types.text: [
                  ('some text', 'some text'),
                  (
                   'a unicode', identity),
                  (1, '1'),
                  (1.0, '1.0'),
                  (
                   datetime.datetime(2008, 1, 2, 0, 0), '2008/01/02 00:00:00'),
                  (
                   datetime.date(2008, 1, 2), '2008/01/02'),
                  (None, '')],
       types.texts: [
                   (
                    datetime.datetime(2008, 1, 2, 0, 0), ('2008/01/02 00:00:00', )),
                   (
                    datetime.date(2008, 1, 2), ('2008/01/02', )),
                   (
                    [
                     datetime.datetime(2008, 1, 2, 0, 0)], ['2008/01/02 00:00:00']),
                   (
                    (
                     datetime.date(2008, 1, 2),), ['2008/01/02']),
                   (
                    'text', TypeError('Could not adapt', 'text', types.texts)),
                   (
                    'text', ('text', )),
                   (
                    1, ('1', )),
                   (
                    1.0, ('1.0', )),
                   (
                    None, [])],
       types.reference: [], types.references: [], types.binary: [], types.binaries: []}

    def test_convertors(self):
        errors = []
        for (t, s2e) in self.mapping.items():
            for (s, e) in s2e:
                check(t, s, e, errors)

        if errors:
            self.fail('Conversion not as expected:\n' + ('\n').join(errors))

class TestConversion(unittest.TestCase):
    mapping = [
     ('some text', 'some text'),
     (
      'some text', identity),
     (
      1.0, identity),
     (
      [
       'some text'], ['some text']),
     (
      ('some text', ), ('some text', )),
     (
      (), empty), ([], empty),
     (
      [
       'some text'], identity),
     (
      ('some text', ), identity),
     (
      (1, 'x'), TypeError("Sequences must be of one type, could not convert 'x' to <InterfaceClass mortar.types.number>")),
     (
      [
       1, 'x'], TypeError("Sequences must be of one type, could not convert 'x' to <InterfaceClass mortar.types.number>")),
     (
      datetime.datetime(2008, 1, 2, 0, 0), identity),
     (
      datetime.date(2008, 1, 2), identity),
     (
      [
       datetime.datetime(2008, 1, 2, 0, 0)], [datetime.datetime(2008, 1, 2, 0, 0)]),
     (
      (
       datetime.datetime(2008, 1, 2, 0, 0),), (datetime.datetime(2008, 1, 2, 0, 0),)),
     (
      [
       datetime.date(2008, 1, 2)], [datetime.date(2008, 1, 2)]),
     (
      (
       datetime.date(2008, 1, 2),), (datetime.date(2008, 1, 2),))]

    def test_conversion(self):
        errors = []
        for (s, e) in self.mapping:
            check(IFieldType, s, e, errors)

        if errors:
            self.fail('Conversion not as expected:\n' + ('\n').join(errors))

def test_suite():
    return unittest.TestSuite((
     unittest.makeSuite(TestConvertors),
     unittest.makeSuite(TestConversion)))


import os
import traceback
import discord
from discord.ext import commands
from urllib import parse, request
import re
import datetime
import pytz
from bs4 import BeautifulSoup

bot = commands.Bot(command_prefix = '/' , description="This is a Helper Bot" )
token = os.environ['DISCORD_BOT_TOKEN']
TEST_ID = 737270360277254164

@bot.command()
async def ping(ctx):
    await ctx.send('pong')

@bot.command()
async def dii(ctx):
    await ctx.send('バカ')

@bot.command()
async def pict(ctx):
    await ctx.send('http://www.no1game.net/games/escapemen/game0056.html')

@bot.command()
async def clear(ctx, number = 1):
    mgs = []
    number = int(number) #Converting the amount of messages to delete to an integer
    counter = 0

    async for x in ctx.message.channel.history(limit = number+1):
         if counter < number+1:
             print(x.content)
             mgs.append(x)
             counter += 1
    await x.channel.delete_messages(mgs)
    delmsg = await ctx.send(str(counter-1) + "件削除しました")
    print(delmsg.content)
    await delmsg.delete(delay=2)

@bot.command()
async def youtube(ctx, *, search):
    query_string = parse.urlencode({'search_query': search})
    html_content = request.urlopen('http://www.youtube.com/results?' + query_string)
    OBJ = BeautifulSoup(html_content,"html.parser")
    html_content.close()
    search_results = re.findall('"videoId":"(.{11})"' , OBJ.decode())
    if search_results :
        pass
    else:
        print('nasi')
    # I will put just the first result, you can loop the response to show more results
    await ctx.send('https://www.youtube.com/watch?v='+ search_results[0])
    await ctx.send('https://www.youtube.com/watch?v='+ search_results[4])

@bot.event
async def on_ready():
   channel1 = bot.get_channel(TEST_ID)
   await channel1.send("起動")

@bot.event
async def on_voice_state_update(member, before, after):
    if before.channel == after.channel:
        print('STATS変更')
        return
    if after.channel is None:
        print('退出')
        return
    if  after.channel is not None:
        TIME = datetime.datetime.now(pytz.timezone('Asia/Tokyo'))
        STR_TIME = TIME.strftime('%Y/%m/%d %H:%M')
        print(member.display_name + ' ' + after.channel.name)
        channel2 = bot.get_channel(TEST_ID)
        await channel2.send("[" + STR_TIME +  "]" + member.display_name + "が" + after.channel.name + "にきたぞ")

bot.run(token)


class SplitHelper(object):

    @classmethod
    def split_with_delimiter(cls, text: str, delimiter: str, qtd: int):
        elements = [e + delimiter*qtd for e in text.split(delimiter*qtd) if e]

        # remove o ultimo espaço
        elements[-1] = elements[-1][0:-qtd]

        return elements


#https://projecteuler.net/problem=3
import pandas as pd
import numpy as np

def find_largest_prime_factor():
    num = 600851475143
    df = pd.DataFrame(sieve_of_erat(), columns=['primes'])
    df['nummodprime'] = num / df['primes']
    df['factors'] = df['nummodprime'] % 1
    df = df[df['factors'] == 0]
    return(df['primes'].max())

def sieve_of_erat():
    lst = [i for i in range(2, 10000)]
    for i in lst:
        for val in lst:
            if i == val:
                continue
            elif val % i == 0:
                lst.remove(val)
    return lst
print(find_largest_prime_factor())


#!/usr/bin/env python3

# Given a string, write a function to check if it is a permutation of a
# palindrome. A palindrome is a word or phrase that is the same forwards and
# backwards. A permutation is a rearrangement of letters. The palindrome does not
# need to be limited to just dictionary words.

# This solution is case and white-space sensitive.

def palindromePermutation(str):
    isPalPerm = False               # Innocent until prov-- False until proven True

    counts = {}                     # {Character[number of occurances],...}
    for char in str:
        if char not in counts:
            counts[char] = 1
        else:
            counts[char] += 1

    oddCounts = 0                   # Only need to consider odd valued counts
    for key in counts:
        if (counts[key] % 2 != 0):
            oddCounts += 1

    if oddCounts <= 1:              # PalPerm is False with > 1 odd count
        isPalPerm = True

    return isPalPerm

print(palindromePermutation('tacocat'))
print(palindromePermutation('not a palperm'))


import pygame
import random
import math

pygame.font.init()
pygame.mixer.init()

WIDTH, HEIGHT = 450, 800
WIN = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("Jelly Game")

WHITE = (255, 255, 255)
BLACK = (0, 0, 0)

RED = (255, 0, 0)
YELLOW = (255, 255, 0)
GREEN = (0, 255, 0)
BLUE = (0, 0, 255)

BORDER = pygame.Rect(0, 0, WIDTH, HEIGHT)

STANDARD_FONT = pygame.font.SysFont('comicsans', 40)

FPS = 60

def draw_window(board, score):

    # clear screen
    pygame.draw.rect(WIN, BLACK, BORDER)

    # Draw score
    score_text = STANDARD_FONT.render("Score: " + str(score), 1, WHITE)
    WIN.blit(score_text, (10, 760))

    # Draw game board with cubes

    draw_board(board)

    pygame.display.update()

def draw_board(board):
    game_block = pygame.Rect(0, 0, 50, 50)
    pygame.draw.rect(WIN, YELLOW, game_block)

    temp_height = 0
    temp_width = 0
    for row in board:
        temp_width = 0
        for block in row:

            game_block = pygame.Rect(temp_width, temp_height, 50, 50)

            if (block == 1):
                color = YELLOW
            elif (block == 2):
                color = BLUE
            elif (block == 3):
                color = RED
            elif (block == 4):
                color = GREEN
            else:
                color = BLACK
            pygame.draw.rect(WIN, color, game_block)

            temp_width = temp_width + 50
        temp_height = temp_height + 50
        #pygame.draw.rect(WIN, YELLOW, bullet)

def end_game(text):
    draw_text = STANDARD_FONT.render(text, 1, WHITE)
    WIN.blit(draw_text, (WIDTH/2 - draw_text.get_width() / 2, HEIGHT/2 - draw_text.get_height()/2))
    pygame.display.update()
    pygame.time.delay(5000)

def generate_board():

    board = []
    for x in range(15):
        row = []
        for y in range(9):
            row.append(random.randint(1, 4))
        board.append(row)

    return board

def nearby_same_color(color_number, up_color, down_color, left_color, right_color):
    if color_number == up_color or color_number == down_color or color_number == left_color or color_number == right_color:
        return True
    return False

def get_valid_moves(board):
    valid_moves = []

    row = 0

    for rows in board:
        column = 0
        for block in rows:

            if(block == 0):
                column = column + 1
                continue

            up_color = 0
            if(row > 0):
                up_color = board[row - 1][column]

            down_color = 0
            if(row < 14):
                down_color = board[row + 1][column]

            left_color = 0
            if(column > 0):
                left_color = board[row][column-1]

            right_color = 0
            if(column < 8):
                right_color = board[row][column+1]

            if nearby_same_color(block, up_color, down_color, left_color, right_color):

                valid_moves.append([row, column])

            column = column + 1

        row = row + 1

    return valid_moves

def clear_all_nearby(deleting_color, row, column, board, number_of_clears):

    if(row == -1):
        return board, number_of_clears

    if(row == 15):
        return board, number_of_clears

    if(column == -1):
        return board, number_of_clears

    if(column == 9):
        return board, number_of_clears

    if deleting_color == board[row][column]:
        board[row][column] = 0
        number_of_clears = number_of_clears + 1
        board, number_of_clears = clear_all_nearby(deleting_color, row+1, column, board, number_of_clears)
        board, number_of_clears = clear_all_nearby(deleting_color, row-1, column, board, number_of_clears)
        board, number_of_clears = clear_all_nearby(deleting_color, row, column-1, board, number_of_clears)
        board, number_of_clears = clear_all_nearby(deleting_color, row, column+1, board, number_of_clears)
    return board, number_of_clears

def add_score(number_of_clears):
    if(number_of_clears==2):
        return 2
    elif(number_of_clears==3):
        return 5
    elif(number_of_clears==4):
        return 8
    elif(number_of_clears==5):
        return 13
    elif(number_of_clears==6):
        return 18
    elif(number_of_clears==7):
        return 25
    elif(number_of_clears==8):
        return 32
    elif(number_of_clears==9):
        return 41
    elif(number_of_clears==10):
        return 50        # THIS IS FAKED
    elif(number_of_clears==11):
        return 61
    elif(number_of_clears==12):
        return 70        # THIS IS FAKED
    elif(number_of_clears==13):
        return 85
    elif(number_of_clears==14):
        return 90        # THIS IS FAKED
    elif(number_of_clears==15):
        return 100        # THIS IS FAKED
    elif(number_of_clears==16):
        return 110        # THIS IS FAKED
    else:
        return 999999     # THIS IS FAKED

def are_there_colors_above(colors, row, column, board):
    if(row == 0):
        return colors

    if (board[row][column] == 0):
        return colors

    if (board[row][column] != 0):
        colors.append([row, column])
        colors = are_there_colors_above(colors, row-1, column, board)
    return colors

def fill_board(board):

    row = 0
    for rows in board:
        column = 0
        for block in rows:
            if board[14][column] == 0:
                break

            if(block == 0):
                board[row][column] = random.randint(1, 4)

            column = column + 1
        row = row + 1
    return board

def remove_column(column, board):
    del board[0][column]
    del board[1][column]
    del board[2][column]
    del board[3][column]
    del board[4][column]
    del board[5][column]
    del board[6][column]
    del board[7][column]
    del board[8][column]
    del board[9][column]
    del board[10][column]
    del board[11][column]
    del board[12][column]
    del board[13][column]
    del board[14][column]
    return board

def add_column(board):
    board[0].append(0)
    board[1].append(0)
    board[2].append(0)
    board[3].append(0)
    board[4].append(0)
    board[5].append(0)
    board[6].append(0)
    board[7].append(0)
    board[8].append(0)
    board[9].append(0)
    board[10].append(0)
    board[11].append(0)
    board[12].append(0)
    board[13].append(0)
    board[14].append(0)
    return board

def execute_column_break(board, active_columns):

    should_board_be_filled = False
    columns_to_remove = []
    for column in range(active_columns):
        if(board[14][column] == 0):
            columns_to_remove.append(column)
            active_columns = active_columns -1

    if(len(columns_to_remove)>0):
        should_board_be_filled = True
        reversed_list = columns_to_remove[::-1]
        for reversed in reversed_list:
            board = add_column(board)
            board = remove_column(reversed, board)

    return board, active_columns, should_board_be_filled

def execute_gravity(board):

    row = 0
    for rows in board:
        column = 0
        for block in rows:

            if(block == 0):
                column = column + 1
                continue

            if(row > 13):
                break

            # Can block move down?
            if(board[row + 1][column] == 0):
                board[row + 1][column] = board[row][column]
                board[row][column] = 0
                # Run it again
                execute_gravity(board)

            column = column + 1

        row = row + 1

    return board

def main():

    score = 0

    board = generate_board()
    active_columns = 9
    clock = pygame.time.Clock()
    run = True
    while run:
        clock.tick(FPS)

        valid_moves = get_valid_moves(board)

        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                run = False
                pygame.quit()

            if event.type == pygame.MOUSEBUTTONDOWN and event.button == 1:

                print(len(valid_moves))

                x, y = pygame.mouse.get_pos()
                column = math.floor(x/50)
                row = math.floor(y/50)
                print(row,column, board[row][column])
                if ([row, column] in valid_moves and board[row][column] != 0):
                    board, number_of_clears = clear_all_nearby(board[row][column], row, column, board, 0)
                    score = score + add_score(number_of_clears)
                    board = execute_gravity(board)
                    board, active_columns, should_board_be_filled = execute_column_break(board, active_columns)
                    if (should_board_be_filled):
                        board = fill_board(board)

        if len(valid_moves) == 0:
            end_game('You lost')
            break

        keys_pressed = pygame.key.get_pressed()

        if keys_pressed[pygame.K_b]:
            print("\n\r")
            for row in board:
                print(row)

        if keys_pressed[pygame.K_c]:
            print(valid_moves)

        if keys_pressed[pygame.K_a]:
            score = score + 10
            print('A is pressed')

        draw_window(board, score)

    main()

if __name__ == "__main__":
    main()