# coding=utf-8
# Python 3.5.3

# import urllib
import urllib.request
import json
import urllib.parse
# import base64
import os
# import wave
# import pyaudio
# import struct

import codecs

from tkinter import *
from tkinter import filedialog

def callback():
    filename =  filedialog.askopenfilename(initialdir = os.getcwd(),title = "Select file",filetypes = (("text files","*.txt"),("all files","*.*")))
    # print (root.filename)

    f = codecs.open(filename, 'r')
    text = f.read()
    f.close()

    # text="hello world"
    # text=u'\u4f60\u597d'

    # text = u'我是欲动，我住在密歇根。我喜欢打篮球。我有一个iphone。'
    # text = text.encode('utf-8')

    Api_Key='your_api_key'
    Secret_Key='your_secret_key'
    url = 'https://openapi.baidu.com/oauth/2.0/token?grant_type=client_credentials&client_id='+Api_Key+'&client_secret='+Secret_Key
    ServerUrl='http://tsn.baidu.com/text2audio'
    res = urllib.request.urlopen(url).read().decode('utf8')

    data1 = json.loads(res)
    token = data1['access_token']    #got token
    # print('token get success:',token)

    lan='zh'
    cuid='YourCUID'
    per='0' # per: reader selection. 0 is boy, 1 is girl. 3 is boy with emotion. 4 is girl with emotion. default is 1. 1 and 3 is used in this project.
    data2={'tex':text,'lan':lan,'cuid':cuid,'ctp':1,'tok':token,'per':per}
    data2_urlencode=urllib.parse.urlencode(data2)
    # print(type(data2_urlencode)) ##check data_urlencodede data2 type
    r=urllib.request.urlopen(ServerUrl,str.encode(data2_urlencode))
    # print(r.getcode())
    result=r.read()
    file=open(r"voice.mp3","wb")
    file.write(result)
    file.close()

    os.startfile('voice.mp3')

# Define a main() function.
def main():

  root = Tk()
  root.withdraw()
  mybutton = Button(root, text='select text file', command=callback())
  mybutton.pack()

# This is the standard boilerplate that calls the main() function.
if __name__ == '__main__':
  main()


import configparser
import os
from Listen.savefile.zipmanager import ZipManager
from scrapy.crawler import CrawlerProcess
from scrapy.settings import Settings
from scrapy.utils import project
from Listen.spiders.listen_spider import ListenSpider
from Dmzj.dmzj_spider import DmzjSpider
from ting89search.ting89s_spider import Ting89sSpider
import re

def GetSpiderList(cfgname):
    conf = configparser.ConfigParser()
    conf.read(os.path.join(os.path.dirname(os.path.realpath(__file__)), cfgname))
    spider_path = conf.items('settings')
    spider_module = [x[0] for x in spider_path]
    return spider_module

    # 本想从spider中获取name，结果遍历失败
    from scrapy.utils.misc import walk_modules
    from scrapy.utils.spider import iter_spider_classes

    spider_name = []
    for module in spider_module:
        for module1 in walk_modules(module):
            for spcls in iter_spider_classes(module1):
                spider_name.append(spcls.name)
    return spider_name

def main():
    spider_factory = GetSpiderList('scrapy.cfg')

    ## init
    conf = configparser.ConfigParser()
    conf.read(os.path.join(os.path.dirname(os.path.realpath(__file__)),'./config.ini'), encoding='utf-8')

    # 通过url，解析爬虫名字 ( 取 //和/之间的域名，用'.'分割，之后取倒数第二个作为爬虫名字)
    url = conf.get('Network', 'url')
    spider_name = re.search('\/\/.*?\/', url).group().split('.')[-2]
    if spider_name not in spider_factory:
        print("url not support!!!", url)
        exit(0)

    os.environ['SCRAPY_PROJECT'] = spider_name
    setting = project.get_project_settings()
    process = CrawlerProcess(setting)
    r1 = process.crawl(spider_name, url)
    r2 = process.start()

	# if conf.getint('Zip', 'enable') == 1:
	#     setting = project.get_project_settings()
	#     spider = list(process.spiders._spiders.values())[0]
	#     file_path = '{}/{}/{}'.format(setting.get('BOOK_FULL_PATH'), spider.name, spider.book_name)
	#     ## zipfile
	#     # zipmanager.AddDir(r'E:\Scrapy\Listen\ting89Catch\本次下载的小说的名字')
	#     zipmanager = ZipManager(prefix='第一序列',sectionsize=conf.getint('Zip','sectionsize'))
	#     zipmanager.AddDir(setting.get('BOOK_FULL_PATH'))
	#     zipmanager.ZipAll()

if __name__ == "__main__":
	main()


# Author: Hubert Kario (c) 2014
# see LICENCE file for legal information regarding use of this file

# compatibility with Python 2.6, for that we need unittest2 package,
# which is not available on 3.3 or 3.4
try:
    import unittest2 as unittest
except ImportError:
    import unittest
try:
    import mock
except ImportError:
    import unittest.mock as mock

from tlslite.handshakesettings import HandshakeSettings, Keypair, VirtualHost

class TestHandshakeSettings(unittest.TestCase):
    def test___init__(self):
        hs = HandshakeSettings()

        self.assertIsNotNone(hs)

    def test_validate(self):
        hs = HandshakeSettings()
        newHS = hs.validate()

        self.assertIsNotNone(newHS)
        self.assertIsNot(hs, newHS)

    def test_minKeySize_too_small(self):
        hs = HandshakeSettings()
        hs.minKeySize = 511

        with self.assertRaises(ValueError):
            hs.validate()

    def test_minKeySize_too_large(self):
        hs = HandshakeSettings()
        hs.minKeySize = 16385

        with self.assertRaises(ValueError):
            hs.validate()

    def test_maxKeySize_too_small(self):
        hs = HandshakeSettings()
        hs.maxKeySize = 511

        with self.assertRaises(ValueError):
            hs.validate()

    def test_maxKeySize_too_large(self):
        hs = HandshakeSettings()
        hs.maxKeySize = 16385

        with self.assertRaises(ValueError):
            hs.validate()

    def test_maxKeySize_smaller_than_minKeySize(self):
        hs = HandshakeSettings()
        hs.maxKeySize = 1024
        hs.minKeySize = 2048

        with self.assertRaises(ValueError):
            hs.validate()

    def test_cipherNames_with_unknown_name(self):
        hs = HandshakeSettings()
        hs.cipherNames = ["aes256"]

        newHs = hs.validate()

        self.assertEqual(["aes256"], newHs.cipherNames)

    def test_cipherNames_with_unknown_name(self):
        hs = HandshakeSettings()
        hs.cipherNames = ["camellia256gcm", "aes256"]

        with self.assertRaises(ValueError):
            hs.validate()

    def test_cipherNames_empty(self):
        hs = HandshakeSettings()
        hs.cipherNames = []

        with self.assertRaises(ValueError):
            hs.validate()

    def test_certificateTypes_empty(self):
        hs = HandshakeSettings()
        hs.certificateTypes = []

        with self.assertRaises(ValueError):
            hs.validate()

    def test_certificateTypes_with_unknown_type(self):
        hs = HandshakeSettings()
        hs.certificateTypes = [0, 42]

        with self.assertRaises(ValueError):
            hs.validate()

    def test_cipherImplementations_empty(self):
        hs = HandshakeSettings()
        hs.cipherImplementations = []

        with self.assertRaises(ValueError):
            hs.validate()

    def test_cipherImplementations_with_unknown_implementations(self):
        hs = HandshakeSettings()
        hs.cipherImplementations = ["openssl", "NSS"]

        with self.assertRaises(ValueError):
            hs.validate()

    def test_minVersion_higher_than_maxVersion(self):
        hs = HandshakeSettings()
        hs.minVersion = (3, 3)
        hs.maxVersion = (3, 0)

        with self.assertRaises(ValueError):
            hs.validate()

    def test_minVersion_with_unknown_version(self):
        hs = HandshakeSettings()
        hs.minVersion = (2, 0)

        with self.assertRaises(ValueError):
            hs.validate()

    def test_maxVersion_with_unknown_version(self):
        hs = HandshakeSettings()
        hs.maxVersion = (3, 5)

        with self.assertRaises(ValueError):
            hs.validate()

    def test_maxVersion_without_TLSv1_2(self):
        hs = HandshakeSettings()
        hs.maxVersion = (3, 2)

        self.assertTrue('sha256' in hs.macNames)

        new_hs = hs.validate()

        self.assertFalse("sha256" in new_hs.macNames)

    def test_getCertificateTypes(self):
        hs = HandshakeSettings()

        self.assertEqual([0], hs.getCertificateTypes())

    def test_getCertificateTypes_with_unsupported_type(self):
        hs = HandshakeSettings()
        hs.certificateTypes = ["x509", "openpgp"]

        with self.assertRaises(AssertionError):
            hs.getCertificateTypes()

    def test_useEncryptThenMAC(self):
        hs = HandshakeSettings()
        self.assertTrue(hs.useEncryptThenMAC)

        hs.useEncryptThenMAC = False

        n_hs = hs.validate()

        self.assertFalse(n_hs.useEncryptThenMAC)

    def test_useEncryptThenMAC_with_wrong_value(self):
        hs = HandshakeSettings()
        hs.useEncryptThenMAC = None

        with self.assertRaises(ValueError):
            hs.validate()

    def test_useExtendedMasterSecret(self):
        hs = HandshakeSettings()
        self.assertTrue(hs.useExtendedMasterSecret)

        hs.useExtendedMasterSecret = False

        n_hs = hs.validate()

        self.assertFalse(n_hs.useExtendedMasterSecret)

    def test_useExtendedMasterSecret_with_wrong_value(self):
        hs = HandshakeSettings()
        hs.useExtendedMasterSecret = None

        with self.assertRaises(ValueError):
            hs.validate()

    def test_requireExtendedMasterSecret(self):
        hs = HandshakeSettings()
        self.assertFalse(hs.requireExtendedMasterSecret)

        hs.requireExtendedMasterSecret = True

        n_hs = hs.validate()

        self.assertTrue(n_hs.requireExtendedMasterSecret)

    def test_requireExtendedMasterSecret_with_wrong_value(self):
        hs = HandshakeSettings()
        hs.requireExtendedMasterSecret = None

        with self.assertRaises(ValueError):
            hs.validate()

    def test_requireExtendedMasterSecret_with_incompatible_use_EMS(self):
        hs = HandshakeSettings()
        hs.useExtendedMasterSecret = False
        hs.requireExtendedMasterSecret = True

        with self.assertRaises(ValueError):
            hs.validate()

    def test_invalid_MAC(self):
        hs = HandshakeSettings()
        hs.macNames = ['sha1', 'whirpool']

        with self.assertRaises(ValueError):
            hs.validate()

    def test_invalid_KEX(self):
        hs = HandshakeSettings()
        hs.keyExchangeNames = ['rsa', 'ecdhe_rsa', 'gost']

        with self.assertRaises(ValueError):
            hs.validate()

    def test_invalid_signature_algorithm(self):
        hs = HandshakeSettings()
        hs.rsaSigHashes += ['md2']
        with self.assertRaises(ValueError):
            hs.validate()

    def test_no_signature_hashes_set_with_TLS1_2(self):
        hs = HandshakeSettings()
        hs.rsaSigHashes = []
        hs.dsaSigHashes = []
        hs.ecdsaSigHashes = []
        hs.more_sig_schemes = []
        with self.assertRaises(ValueError):
            hs.validate()

    def test_no_signature_hashes_set_with_TLS1_1(self):
        hs = HandshakeSettings()
        hs.rsaSigHashes = []
        hs.dsaSigHashes = []
        hs.ecdsaSigHashes = []
        hs.maxVersion = (3, 2)
        self.assertIsNotNone(hs.validate())

    def test_invalid_signature_ecdsa_algorithm(self):
        hs = HandshakeSettings()
        hs.ecdsaSigHashes += ['md5']
        with self.assertRaises(ValueError):
            hs.validate()

    def test_invalid_curve_name(self):
        hs = HandshakeSettings()
        hs.eccCurves = ['P-256']
        with self.assertRaises(ValueError):
            hs.validate()

    def test_invalid_additional_signature(self):
        hs = HandshakeSettings()
        hs.more_sig_schemes = ["rsa_pkcs1_sha1"]
        with self.assertRaises(ValueError):
            hs.validate()

    def test_usePaddingExtension(self):
        hs = HandshakeSettings()
        self.assertTrue(hs.usePaddingExtension)

    def test_invalid_usePaddingExtension(self):
        hs = HandshakeSettings()
        hs.usePaddingExtension = -1
        with self.assertRaises(ValueError):
            hs.validate()

    def test_invalid_dhParams(self):
        hs = HandshakeSettings()
        hs.dhParams = (2, 'bd')
        with self.assertRaises(ValueError):
            hs.validate()

    def test_invalid_dhGroups(self):
        hs = HandshakeSettings()
        hs.dhGroups = ["ffdhe2048", "ffdhe1024"]
        with self.assertRaises(ValueError):
            hs.validate()

    def test_invalid_rsaScheme(self):
        hs = HandshakeSettings()
        hs.rsaSchemes += ["rsassa-pkcs1-1_5"]
        with self.assertRaises(ValueError):
            hs.validate()

    def test_invalid_defaultCurve_name(self):
        hs = HandshakeSettings()
        hs.defaultCurve = "ffdhe2048"
        with self.assertRaises(ValueError):
            hs.validate()

    def test_invalid_keyShares_name(self):
        hs = HandshakeSettings()
        hs.keyShares = ["ffdhe1024"]
        with self.assertRaises(ValueError):
            hs.validate()

    def test_not_matching_keyShares(self):
        hs = HandshakeSettings()
        hs.keyShares = ["x25519"]
        hs.eccCurves = ["x448"]
        with self.assertRaises(ValueError) as e:
            hs.validate()

        self.assertIn("x25519", str(e.exception))

    def test_not_matching_ffdhe_keyShares(self):
        hs = HandshakeSettings()
        hs.keyShares = ["ffdhe2048", "x25519"]
        hs.dhGroups = ["ffdhe4096"]
        with self.assertRaises(ValueError) as e:
            hs.validate()

        self.assertIn("ffdhe2048", str(e.exception))

    def test_versions_and_maxVersion_mismatch(self):
        hs = HandshakeSettings()
        hs.maxVersion = (3, 3)
        hs = hs.validate()

        self.assertNotIn((3, 4), hs.versions)
        self.assertNotIn((0x7f, 21), hs.versions)

    def test_pskConfigs(self):
        hs = HandshakeSettings()
        hs.pskConfigs = [(b'test', b'sicritz', 'sha384')]

        hs = hs.validate()

        self.assertEqual(hs.pskConfigs, [(b'test', b'sicritz', 'sha384')])

    def test_pskConfigs_invalid_tuple(self):
        hs = HandshakeSettings()
        hs.pskConfigs = [(b'test', b'sicrits'), tuple([b'invalid'])]

        with self.assertRaises(ValueError) as e:
            hs.validate()

        self.assertIn("pskConfigs", str(e.exception))

    def test_pskConfig_invalid_hash(self):
        hs = HandshakeSettings()
        hs.pskConfigs = [(b'test', b'sicrits', 'wrong-hash')]

        with self.assertRaises(ValueError) as e:
            hs.validate()

        self.assertIn("wrong-hash", str(e.exception))

    def test_ticketCipher_invalid(self):
        hs = HandshakeSettings()
        hs.ticketCipher = "aes-128-cbc"

        with self.assertRaises(ValueError) as e:
            hs.validate()

        self.assertIn("Invalid cipher", str(e.exception))

    def test_ticketKeys_wrong_size(self):
        hs = HandshakeSettings()
        hs.ticketKeys = [bytearray(8)]

        with self.assertRaises(ValueError) as e:
            hs.validate()

        self.assertIn("encryption keys", str(e.exception))

    def test_ticketLifetime_wrong(self):
        hs = HandshakeSettings()
        hs.ticketLifetime = 2**32

        with self.assertRaises(ValueError) as e:
            hs.validate()

        self.assertIn("Ticket lifetime", str(e.exception))

    def test_invalid_psk_mode(self):
        hs = HandshakeSettings()
        hs.psk_modes = ["psk_pqe_ke"]

        with self.assertRaises(ValueError) as e:
            hs.validate()

        self.assertIn("psk_pqe_ke", str(e.exception))

    def test_invalid_max_early_data(self):
        hs = HandshakeSettings()
        hs.max_early_data = -1

        with self.assertRaises(ValueError) as e:
            hs.validate()

        self.assertIn("max_early_data", str(e.exception))

    def test_invalid_use_heartbeat_extension(self):
        hs = HandshakeSettings()
        hs.use_heartbeat_extension = None

        with self.assertRaises(ValueError) as e:
            hs.validate()

        self.assertIn("use_heartbeat_extension", str(e.exception))

    def test_invalid_heartbeat_extension_combination(self):
        hs = HandshakeSettings()
        def heartbeatResponseCallback(message):
            return message
        hs.heartbeat_response_callback = heartbeatResponseCallback
        hs.use_heartbeat_extension = False

        with self.assertRaises(ValueError) as e:
            hs.validate()

        self.assertIn("heartbeat_response_callback", str(e.exception))

    def test_too_small_record_size_limit(self):
        hs = HandshakeSettings()
        hs.record_size_limit = 63

        with self.assertRaises(ValueError) as e:
            hs.validate()

        self.assertIn("record_size_limit", str(e.exception))

    def test_too_big_record_size_limit(self):
        hs = HandshakeSettings()
        hs.record_size_limit = 2**14+2

        with self.assertRaises(ValueError) as e:
            hs.validate()

        self.assertIn("record_size_limit", str(e.exception))

    def test_none_as_record_size_limit(self):
        hs = HandshakeSettings()
        self.assertIsNotNone(hs.record_size_limit)

        hs.record_size_limit = None

        hs = hs.validate()

        self.assertIsNone(hs.record_size_limit)

    def test_ticket_count_zero(self):
        hs = HandshakeSettings()
        hs.ticket_count = 0

        hs = hs.validate()

        self.assertIsNotNone(hs.ticket_count, 0)

    def test_ticket_count_200(self):
        hs = HandshakeSettings()
        hs.ticket_count = 200

        hs = hs.validate()

        self.assertIsNotNone(hs.ticket_count, 200)

    def test_ticket_count_negative(self):
        hs = HandshakeSettings()
        hs.ticket_count = -1

        with self.assertRaises(ValueError) as e:
            hs.validate()

        self.assertIn("new session tickets", str(e.exception))

class TestKeypair(unittest.TestCase):
    def test___init___(self):
        k_p = Keypair()

        self.assertIsInstance(k_p, Keypair)
        self.assertIsNone(k_p.key)
        self.assertIsInstance(k_p.certificates, tuple)

    def test_validate_with_missing_keys(self):
        k_p = Keypair()

        with self.assertRaises(ValueError):
            k_p.validate()

    def test_validate_with_missing_certificates(self):
        k_p = Keypair()
        k_p.key = mock.MagicMock()

        with self.assertRaises(ValueError):
            k_p.validate()

class TestVirtualHost(unittest.TestCase):
    def test___init__(self):
        v_h = VirtualHost()

        self.assertIsInstance(v_h, VirtualHost)
        self.assertEqual(v_h.keys, [])
        self.assertEqual(v_h.hostnames, set())
        self.assertEqual(v_h.trust_anchors, [])
        self.assertEqual(v_h.app_protocols, [])

    def test_matches_hostname_with_non_matching_name(self):
        v_h = VirtualHost()
        v_h.hostnames = set([b'example.com'])

        self.assertFalse(v_h.matches_hostname(b'example.org'))

    def test_matches_hostname_with_matching_name(self):
        v_h = VirtualHost()
        v_h.hostnames = set([b'example.com'])

        self.assertTrue(v_h.matches_hostname(b'example.com'))

    def test_validate_without_keys(self):
        v_h = VirtualHost()

        with self.assertRaises(ValueError):
            v_h.validate()

    def test_validate_with_keys(self):
        v_h = VirtualHost()
        v_h.keys = [mock.MagicMock()]

        v_h.validate()

        v_h.keys[0].validate.assert_called_once_with()

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


filename = "resources/day1.txt"

changes = [int(x) for x in open("resources/day1.txt").readlines()]

#Solution first star
print("Final frequency: " + str(sum(changes)))

#solution second star
frequency = 0
frequencies = set([0])
inFrequencies = False

while inFrequencies == False:
    for line in changes:
        frequency += line
        if frequency in frequencies:
            print("First double value: " + str(frequency))
            inFrequencies = True
            break
        frequencies.add(frequency)

#Lessons learned:
# set is way faster then List
# cleaner to read in the changes into variable and convert to int


""" read keyboard command
Ref: https://github.com/ros-teleop/teleop_twist_keyboard/blob/master/teleop_twist_keyboard.py
"""

import sys
from select import select

if sys.platform == 'win32':
    import msvcrt
else:
    import termios
    import tty

def get_key(settings, timeout=0.5):
    if sys.platform == 'win32':
        # getwch() returns a string on Windows
        key = msvcrt.getwch()
    else:
        tty.setraw(sys.stdin.fileno())
        # sys.stdin.read() returns a string on Linux
        rlist, _, _ = select([sys.stdin], [], [], timeout)
        if rlist:
            key = sys.stdin.read(1)
        else:
            key = ''
        termios.tcsetattr(sys.stdin, termios.TCSADRAIN, settings)
    return key

def save_terminal_settings():
    if sys.platform == 'win32':
        return None
    return termios.tcgetattr(sys.stdin)

def restore_terminal_settings(old_settings):
    if sys.platform == 'win32':
        return
    termios.tcsetattr(sys.stdin, termios.TCSADRAIN, old_settings)


d = {}
limite = int(input())
for i in range(limite):
              s = int(input())
              try:
                     d[s]+=1
              except KeyError:
                     d[s]=1
d = dict(sorted(d.items(),key=lambda x: x[0]))
for i in d:
       print(f'{i} aparece {d[i]} vez(es)',end='\n')


from django.shortcuts import render, redirect
from school.forms import Form1AForm
from school.models import Form1A

def school(request):
    if request.method == "POST":
        form = Form1AForm(request.POST)
        if form.is_valid():
            try:
                form.save()
                return redirect('/show')
            except:
                pass
        else:
            print(form.errors)
    else:
        form = Form1AForm()
    return render(request,'index.html',{'form':form})

def show(request):
    form1As= Form1A.objects.all()
    print(form1As)
    return render(request,"show.html",{'form1As':form1As})

# def edit(request, id):
#     form1A = Form1A.objects.get(id=id)
#     return render(request,'edit.html', {'form1A':form1A})

def edit(request, id):
    instance = Form1A.objects.get(id=id)

    form = Form1AForm(request.POST, instance=instance)
    if request.method == 'POST':
        print(form.is_valid())
        if form.is_valid():
            form.save()
            print('form edited')
            return redirect('show')
        else:
            for field in form:
                if field.errors:
                    print("Error in field '{}': {}".format(field.name, field.errors))

    else:
        form = Form1AForm(instance=instance)

    context = {'form': form}
    return render(request, 'edit.html', context)

def update(request, id):
    form1A= Form1A.objects.get(id=id)
    form = Form1A(request.POST, instance = school)
    if form.is_valid():
        form.save()
        return redirect("/show")
    return render(request, 'edit.html', {'form1A': form1A})

def destroy(request, id):
    form1A = Form1A.objects.get(id=id)
    form1A.delete()
    return redirect("/show")


def solution(n, times):
    answer = 0
    end = min(times)
    start = max(times)*n
    while start <= end:
        mid = (start + end) // 2
        checked = 0
        for time in times:
            checked += mid // time
            if checked >= n:
                break

        if checked >= n:
            answer = mid
            end = mid - 1
        elif checked < n:
            start = mid + 1

    return answer


"""
1476. 날짜 계산
https://www.acmicpc.net/problem/1476
"""

def year_determinator(e, s, m):
    year = e
    s_false = True
    m_false = True

    year -= 15
    while s_false or m_false:
        year += 15
        s_false = False if (year-1)%28+1 == s else True
        if s_false:
            continue
        m_false = False if (year-1)%19+1 == m else True

    return year

if __name__ == '__main__':
    e, s, m = map(int, input().split())
    # print(e,s,m)
    print(year_determinator(e, s, m))


import random
import asyncio
import datetime
from copy import deepcopy
from typing import List, Optional

from gsuid_core.gss import gss
from gsuid_core.logger import logger
from gsuid_core.utils.database.models import GsUser
from gsuid_core.utils.api.mys.models import RoleCalendar, RolesCalendar

from .get_draw import post_my_draw
from ..utils.mys_api import mys_api

private_msg_list = {}
group_msg_list = {}
calendar: Optional[RolesCalendar] = None
is_got: Optional[bool] = None
today = datetime.datetime.now().day

async def check_today(uid: str) -> bool:
    global calendar
    global is_got
    global today
    if calendar is None:
        _calendar = await mys_api.get_draw_calendar(uid)
        if not isinstance(_calendar, int):
            calendar = _calendar
        else:
            return False

    now = datetime.datetime.now()

    if today == now.day and is_got is not None:
        return is_got
    else:
        today = now.day

    month = now.month
    calendar_role: List[RoleCalendar] = calendar['calendar_role_infos'][
        str(month)
    ]['calendar_role']

    assert isinstance(calendar_role, List)

    for char in calendar_role:
        char_day = char['role_birthday']
        day = now.day
        if char_day == f'{month}/{day}':
            is_got = True
            logger.info('[自动留影叙佳期] 今日有可获取角色，开启任务...')
            break
    else:
        is_got = False
        logger.info('[自动留影叙佳期] 今日无可获取角色，自动取消任务...')

    return is_got

async def single_get_draw(bot_id: str, uid: str, gid: str, qid: str):
    if is_got is not None and not is_got:
        return
    elif not await check_today(uid):
        return

    im = await post_my_draw(uid)

    if isinstance(im, (bytes, bytearray, memoryview)):
        return

    if '没有需要获取' in im:
        return

    if gid == 'on':
        if qid not in private_msg_list:
            private_msg_list[qid] = []
        private_msg_list[qid].append({'bot_id': bot_id, 'uid': uid, 'msg': im})
    else:
        # 向群消息推送列表添加这个群
        if gid not in group_msg_list:
            group_msg_list[gid] = {
                'bot_id': bot_id,
                'success': 0,
                'failed': 0,
            }

        # 如果失败, 则添加到推送列表
        if isinstance(im, bytes):
            group_msg_list[gid]['failed'] += 1
        else:
            group_msg_list[gid]['success'] += 1

async def daily_get_draw():
    tasks = []
    for bot_id in gss.active_bot:
        user_list = await GsUser.get_all_user()
        for user in user_list:
            if user.draw_switch != 'off':
                tasks.append(
                    single_get_draw(
                        user.bot_id, user.uid, user.sign_switch, user.user_id
                    )
                )
            if len(tasks) >= 1:
                await asyncio.gather(*tasks)
                delay = 50 + random.randint(3, 45)
                logger.info(f'[自动留影叙佳期] 已完成{len(tasks)}个用户, 等待{delay}秒进行下一次获取')
                tasks.clear()
                await asyncio.sleep(delay)

    await asyncio.gather(*tasks)
    tasks.clear()
    result = {
        'private_msg_list': deepcopy(private_msg_list),
        'group_msg_list': deepcopy(group_msg_list),
    }
    private_msg_list.clear()
    group_msg_list.clear()
    logger.info(result)
    logger.info('[自动留影叙佳期] 已结束')
    return result


import argparse
import copy
import glob
import json
import logging
import os
import random

import numpy as np
import torch
from data import (FewRelDataset, MAVENDataset, MAVENTestDataset,
                  RETACREDDataset, TACREDDataset, UFETDataset)
from eval_metric import macro, macro_fewshot, tacred_f1
from model import UniSTModel
from sklearn.metrics import (accuracy_score, f1_score, precision_score,
                             recall_score)
from torch.cuda.amp import GradScaler
from torch.utils.data import (ConcatDataset, DataLoader, RandomSampler,
                              SequentialSampler)
from torch.utils.data.distributed import DistributedSampler
from tqdm import tqdm, trange
from transformers import (WEIGHTS_NAME, AdamW, AutoTokenizer, RobertaConfig,
                          get_linear_schedule_with_warmup)

logger = logging.getLogger(__name__)

def set_seed(seed):
    random.seed(seed)
    np.random.seed(seed)
    torch.manual_seed(seed)
    torch.cuda.manual_seed_all(seed)
    # if args.n_gpu > 0:
        # print(f"let's us {args.n_gpu} gpus.")
        # torch.cuda.manual_seed_all(args.seed)

def train(args, train_dataset, eval_datasets, model, tokenizer):
    """train the model"""
    # prepare dataloader
    args.train_batch_size = args.per_gpu_train_batch_size * max(1, args.n_gpu)
    train_sampler = RandomSampler(train_dataset) if args.local_rank == -1 else DistributedSampler(train_dataset)

    def collate_fn(batch, mode='train'):
        # 不使用伪数据
        # batch: [(sent, pos, neg)]
        # batch[0]: sent
        # batch[1]: pos
        # batch[2]: neg
        if mode != 'train':
            return list(map(list, zip(*batch)))
        else: # 使用伪数据
            batch1 = [d[0] for d in batch] # 原始数据
            batch2 = [d[1] for d in batch] # 伪数据
            batch = batch1 + batch2
            return list(map(list, zip(*batch)))

    # 训练模型的阶段
    train_dataloader = DataLoader(train_dataset, sampler=train_sampler, batch_size=args.train_batch_size, collate_fn=collate_fn)

    total_steps = int(len(train_dataloader) * args.num_train_epochs // args.gradient_accumulation_steps)
    warmup_steps = int(total_steps * args.warmup_ratio)

    # Prepare optimizer and schedule (linear warmup and decay)
    no_decay = ["bias", "LayerNorm.weight"]
    optimizer_grouped_parameters = [
        {"params": [p for n, p in model.named_parameters() if not any(nd in n for nd in no_decay)], "weight_decay": args.weight_decay},
        {"params": [p for n, p in model.named_parameters() if any(nd in n for nd in no_decay)], "weight_decay": 0.0},
    ]
    scaler = GradScaler()
    optimizer = AdamW(optimizer_grouped_parameters, lr=args.learning_rate)
    scheduler = get_linear_schedule_with_warmup(optimizer, num_warmup_steps=warmup_steps, num_training_steps=total_steps)

    # Distributed training
    if args.local_rank != -1:
        model = torch.nn.parallel.DistributedDataParallel(model, device_ids=[args.local_rank],
                                                          output_device=args.local_rank)

    logger.info("***** Running training *****")
    logger.info("  Num examples = %d", len(train_dataset))
    logger.info("  Num Epochs = %d", args.num_train_epochs)
    logger.info("  Instantaneous batch size per GPU = %d", args.per_gpu_train_batch_size)
    logger.info("  Total train batch size (w. parallel, distributed & accumulation) = %d",
                args.train_batch_size * args.gradient_accumulation_steps * (torch.distributed.get_world_size() if args.local_rank != -1 else 1))
    logger.info("  Gradient Accumulation steps = %d", args.gradient_accumulation_steps)
    logger.info("  Total optimization steps = %d", total_steps)

    num_steps = 0
    model.zero_grad()
    train_iterator = trange(int(args.num_train_epochs), desc="Epoch", disable=args.local_rank not in [-1, 0])
    set_seed(args.seed)  # Added here for reproductibility

    for epoch in train_iterator:
        # 从dataloader中读取一个batch的数据，直接编码
        epoch_iterator = tqdm(train_dataloader, desc="Iteration", disable=args.local_rank not in [-1, 0])
        for step, batch in enumerate(epoch_iterator):
            # 句子，正样本，负样本
            sent, pos, neg, ent_ss, ent_se, ent_os, ent_oe = batch[0], batch[1], batch[2], batch[3], batch[4], batch[5], batch[6]
            batch_size = len(sent)
            model.train()
            # 编码成为tensor
            sent_inputs = tokenizer(sent, padding=True, truncation=True, max_length=args.max_sent_length, return_tensors="pt", is_split_into_words=True).to(args.device)
            ent_ss = torch.tensor([sent_inputs.word_to_tokens(idx, ent_ss[idx])[0] for idx in range(batch_size)], dtype=torch.long).to(args.device)
            ent_se = torch.tensor([sent_inputs.word_to_tokens(idx, ent_se[idx])[1]-1 for idx in range(batch_size)], dtype=torch.long).to(args.device)
            ent_os = torch.tensor([sent_inputs.word_to_tokens(idx, ent_os[idx])[0] for idx in range(batch_size)], dtype=torch.long).to(args.device)
            ent_oe = torch.tensor([sent_inputs.word_to_tokens(idx, ent_oe[idx])[1]-1 for idx in range(batch_size)], dtype=torch.long).to(args.device)
            pos_inputs = tokenizer(pos, padding=True, truncation=True, max_length=args.max_label_length, return_tensors="pt").to(args.device)
            neg_inputs = tokenizer(neg, padding=True, truncation=True, max_length=args.max_label_length, return_tensors="pt").to(args.device)

            desc_ss, desc_se, desc_os, desc_oe = batch[7], batch[8], batch[9], batch[10]
            if not args.no_task_desc:
                # 超过范围可能为None，替换为0
                desc_ss = torch.tensor([sent_inputs.word_to_tokens(idx, desc_ss[idx])[0] if sent_inputs.word_to_tokens(idx, desc_ss[idx]) is not None else 0 for idx in range(batch_size)], dtype=torch.long).to(args.device)
                desc_se = torch.tensor([sent_inputs.word_to_tokens(idx, desc_se[idx])[1]-1 if sent_inputs.word_to_tokens(idx, desc_se[idx]) is not None else 0 for idx in range(batch_size)], dtype=torch.long).to(args.device)
                desc_os = torch.tensor([sent_inputs.word_to_tokens(idx, desc_os[idx])[0] if sent_inputs.word_to_tokens(idx, desc_os[idx]) is not None else 0 for idx in range(batch_size)], dtype=torch.long).to(args.device)
                desc_oe = torch.tensor([sent_inputs.word_to_tokens(idx, desc_oe[idx])[1]-1 if sent_inputs.word_to_tokens(idx, desc_oe[idx]) is not None else 0 for idx in range(batch_size)], dtype=torch.long).to(args.device)

            inputs = {
                "sent_input_ids": sent_inputs["input_ids"],
                "pos_input_ids": pos_inputs["input_ids"],
                "neg_input_ids": neg_inputs["input_ids"],
                "sent_attention_mask": sent_inputs["attention_mask"],
                "pos_attention_mask": pos_inputs["attention_mask"],
                "neg_attention_mask": neg_inputs["attention_mask"],
                "ss": ent_ss,
                "se": ent_se,
                "os": ent_os,
                "oe": ent_oe,
                "desc_ss": desc_ss,
                "desc_se": desc_se,
                "desc_os": desc_os,
                "desc_oe": desc_oe,
                'train_mode': args.train_mode
            }

            # 输入到模型
            loss = model(**inputs)
            if args.gradient_accumulation_steps > 1:
                loss = loss / args.gradient_accumulation_steps
            scaler.scale(loss).backward()
            # loss.backward()

            # 使用梯度缩放尽可能避免下溢出
            if (step + 1) % args.gradient_accumulation_steps == 0:
                scaler.unscale_(optimizer)
                torch.nn.utils.clip_grad_norm_(model.parameters(), args.max_grad_norm)
                scaler.step(optimizer)
                scaler.update()
                scheduler.step()
                model.zero_grad()
                # optimizer.step()
                # scheduler.step()  # Update learning rate schedule
                # model.zero_grad()
                num_steps += 1

        # local_rank为-1表示单卡，0表示是master
        if args.local_rank in [-1, 0] and args.logging_epochs > 0 and (epoch + 1) % args.logging_epochs == 0:
            # 进行评价
            if args.eval_during_training:
                model_to_eval = model.module if hasattr(model, "module") else model  # Take care of distributed/parallel training
                if "tacred" in args.eval_tasks:
                    eval_tacred(args, eval_datasets["tacred_dev"], model_to_eval, tokenizer, num_epochs=epoch+1, split="dev")
                    eval_tacred(args, eval_datasets["tacred_test"], model_to_eval, tokenizer, num_epochs=epoch+1, split="test")
                    eval_tacred(args, eval_datasets["tacred_unseen"], model_to_eval, tokenizer, num_epochs=epoch+1, split="unseen")
                    eval_tacred(args, eval_datasets["tacred_challenge"], model_to_eval, tokenizer, num_epochs=epoch+1, split="challenge")
                if "retacred" in args.eval_tasks:
                    eval_tacred(args, eval_datasets["retacred_dev"], model_to_eval, tokenizer, num_epochs=epoch+1, split="dev")
                    eval_tacred(args, eval_datasets["retacred_test"], model_to_eval, tokenizer, num_epochs=epoch+1, split="test")
                    eval_tacred(args, eval_datasets["retacred_unseen"], model_to_eval, tokenizer, num_epochs=epoch+1, split="unseen")
                    eval_tacred(args, eval_datasets["retacred_challenge"], model_to_eval, tokenizer, num_epochs=epoch+1, split="challenge")
                if "ufet" in args.eval_tasks:
                    threshold = eval_ufet(args, eval_datasets["ufet_dev"], model_to_eval, tokenizer, num_epochs=epoch+1, split="dev")["Threshold"]
                    eval_ufet(args, eval_datasets["ufet_test"], model_to_eval, tokenizer, num_epochs=epoch+1, split="test", threshold=threshold)
                if "maven" in args.eval_tasks:
                    eval_maven(args, eval_datasets["maven_dev"], model_to_eval, tokenizer, num_epochs=epoch+1, split="dev")
                if "fewrel" in args.eval_tasks:
                    eval_fewrel(args, eval_datasets["fewrel_dev"], model_to_eval, tokenizer, num_epochs=epoch+1, split="dev")

        # 开始保存模型
        if args.local_rank in [-1, 0] and args.save_epochs > 0 and (epoch+1) % args.save_epochs == 0 and epoch > 0.7*args.num_train_epochs:
            # Save model checkpoint
            output_dir = os.path.join(args.output_dir, "checkpoint-{}".format(epoch+1))
            if not os.path.exists(output_dir):
                os.makedirs(output_dir)
            logger.info("Saving model checkpoint to %s", output_dir)
            # 保存model.module（分布式训练场景下）
            model_to_save = model.module if hasattr(model, "module") else model  # Take care of distributed/parallel training
            model_to_save.save_pretrained(output_dir)
            torch.save(args, os.path.join(output_dir, "training_args.bin"))

    return 0

def eval_tacred(args, eval_dataset, model, tokenizer, num_epochs="", split=""):
    args.eval_batch_size = args.per_gpu_eval_batch_size * max(1, args.n_gpu)
    eval_sampler = SequentialSampler(eval_dataset)
    eval_dataloader = DataLoader(eval_dataset, sampler=eval_sampler, batch_size=args.eval_batch_size, collate_fn=lambda x: list(map(list, zip(*x))))

    logger.info("***** Running tacred %s evaluation at %s *****", split, num_epochs)
    logger.info("  Num examples = %d", len(eval_dataset))
    logger.info("  Batch size = %d", args.eval_batch_size)

    dists = []
    labels = []
    model.eval()

    with torch.no_grad():
        labelset = eval_dataset.labelset
        labelset_inputs = tokenizer(labelset, padding=True, truncation=True, max_length=args.max_label_length, return_tensors="pt").to(args.device)
        labelset_embeddings = model.embed(**labelset_inputs)

    for sent, pos, *other in tqdm(eval_dataloader, desc="Evaluating"):
        labels.extend(pos)
        sent_inputs = tokenizer(sent, padding=True, truncation=True, max_length=args.max_sent_length, return_tensors="pt", is_split_into_words=True).to(args.device)

        with torch.no_grad():
            sent_embeddings = model.embed(**sent_inputs)
            for i in range(len(sent_embeddings)):
                sent_embedding = sent_embeddings[i].expand(labelset_embeddings.shape)
                dist = model.dist_fn(sent_embedding, labelset_embeddings).detach().cpu().numpy().tolist()
                dists.append(dist)

    preds = []
    for i, dist in enumerate(dists):
        pred = min(labelset, key=lambda x:dist[labelset.index(x)])
        preds.append(pred)

    assert len(preds) == len(eval_dataset)
    p, r, f1 = tacred_f1(labels, preds)

    results = {
        "Micro precision": p,
        "Micro recall": r,
        "Micro f1": f1
    }

    print(split)
    print(results)

    for key in results:
        logger.info("  %s = %s", key, str(results[key]))

    return results

def eval_ufet(args, eval_dataset, model, tokenizer, num_epochs="", split="", threshold=None, threshold_step=1e-2):
    args.eval_batch_size = args.per_gpu_eval_batch_size * max(1, args.n_gpu)
    eval_sampler = SequentialSampler(eval_dataset)
    eval_dataloader = DataLoader(eval_dataset, sampler=eval_sampler, batch_size=args.eval_batch_size, collate_fn=lambda x: list(map(list, zip(*x))))

    logger.info("***** Running ufet %s evaluation at %s *****", split, num_epochs)
    logger.info("  Num examples = %d", len(eval_dataset))
    logger.info("  Batch size = %d", args.eval_batch_size)
    logger.info("  Threshold step = %f", threshold_step)

    dists = []
    labels = []
    model.eval()

    with torch.no_grad():
        labelset = eval_dataset.labelset
        labelset_inputs = tokenizer(labelset, padding=True, truncation=True, max_length=args.max_label_length, return_tensors="pt").to(args.device)
        labelset_embeddings = model.embed(**labelset_inputs)

    for batch in tqdm(eval_dataloader, desc="Evaluating"):
        sent, pos_all = batch[0], batch[3]
        labels.extend(pos_all)
        sent_inputs = tokenizer(sent, padding=True, truncation=True, max_length=args.max_sent_length, return_tensors="pt", is_split_into_words=True).to(args.device)

        with torch.no_grad():
            sent_embeddings = model.embed(**sent_inputs)
            for i in range(len(sent_embeddings)):
                sent_embedding = sent_embeddings[i].expand(labelset_embeddings.shape)
                dist = model.dist_fn(sent_embedding, labelset_embeddings).detach().cpu().numpy().tolist()
                dists.append(dist)

    if threshold is None:
        # Find the best threshold
        threshold = np.array(dists).min()

        best_f1 = 0.0
        best_f1_p = 0.0
        best_f1_r = 0.0
        best_threshold = 0.0
        while threshold <= np.array(dists).max():
            preds = []
            for dist in dists:
                pred = [labelset[i] for i, val in enumerate(dist) if val < threshold]
                preds.append(pred)

            assert len(preds) == len(eval_dataset)
            p, r, f1 = macro(labels=labels, preds=preds)
            if f1 > best_f1:
                best_f1 = f1
                best_f1_p = p
                best_f1_r = r
                best_threshold = threshold

            threshold += threshold_step

        results = {
            "Threshold": best_threshold,
            "Macro precision": best_f1_p,
            "Macro recall": best_f1_r,
            "Macro f1": best_f1
        }

    else:
        with open(os.path.join(args.data_dir, "ufet/test_type_frequencies_in_train_set.json"), "r") as f:
            label2freq = json.loads(f.read())

        preds = []
        for dist in dists:
            pred = [labelset[i] for i, val in enumerate(dist) if val < threshold]
            preds.append(pred)

        zero_labels=[label for label, freq in label2freq.items() if freq == 0]
        print(len(zero_labels))
        _, _, f1_zero = macro_fewshot(labels=labels, preds=preds, target_labels=zero_labels)

        few_labels=[label for label, freq in label2freq.items() if 1 <= freq <= 5]
        print(len(few_labels))
        _, _, f1_few = macro_fewshot(labels=labels, preds=preds, target_labels=few_labels)

        more_labels=[label for label, freq in label2freq.items() if 6 <= freq <= 10]
        print(len(more_labels))
        _, _, f1_more = macro_fewshot(labels=labels, preds=preds, target_labels=more_labels)

        p_all, r_all, f1_all = macro(labels=labels, preds=preds)

        results = {
            "Threshold": threshold,
            "Macro p-all": p_all,
            "Macro r-all": r_all,
            "Macro f1-all": f1_all,
            "Macro f1-zero": f1_zero,
            "Macro f1-few": f1_few,
            "Macro f1-more": f1_more,
        }

    for key in results:
        logger.info("  %s = %s", key, str(results[key]))

    return results

def eval_maven(args, eval_dataset, model, tokenizer, num_epochs="", split=""):
    args.eval_batch_size = args.per_gpu_eval_batch_size * max(1, args.n_gpu)
    eval_sampler = SequentialSampler(eval_dataset)
    eval_dataloader = DataLoader(eval_dataset, sampler=eval_sampler, batch_size=args.eval_batch_size, collate_fn=lambda x: list(map(list, zip(*x))))

    logger.info("***** Running maven %s evaluation at %s *****", split, num_epochs)
    logger.info("  Num examples = %d", len(eval_dataset))
    logger.info("  Batch size = %d", args.eval_batch_size)

    dists = []
    labels = []
    model.eval()

    with torch.no_grad():
        labelset = eval_dataset.labelset
        labelset_inputs = tokenizer(labelset, padding=True, truncation=True, max_length=args.max_label_length, return_tensors="pt").to(args.device)
        labelset_embeddings = model.embed(**labelset_inputs)

    for sent, pos, _ in tqdm(eval_dataloader, desc="Evaluating"):
        labels.extend(pos)
        sent_inputs = tokenizer(sent, padding=True, truncation=True, max_length=args.max_sent_length, return_tensors="pt", is_split_into_words=True).to(args.device)

        with torch.no_grad():
            sent_embeddings = model.embed(**sent_inputs)
            for i in range(len(sent_embeddings)):
                sent_embedding = sent_embeddings[i].expand(labelset_embeddings.shape)
                dist = model.dist_fn(sent_embedding, labelset_embeddings).detach().cpu().numpy().tolist()
                dists.append(dist)

    preds = []
    for i, dist in enumerate(dists):
        pred = min(labelset, key=lambda x:dist[labelset.index(x)])
        preds.append(pred)

    assert len(preds) == len(eval_dataset)
    results = {
        "Micro precision": precision_score(labels, preds, average="micro")
    }

    for key in results:
        logger.info("  %s = %s", key, str(results[key]))

    return results

def test_maven(args, eval_dataset, model, tokenizer, num_epochs="", split=""):
    """
    generate as MAVEN test format
    prediction file to submit to leaderboard: each line a json
       id: docid, predictions: list
            each ele = dict[id=(sent)id, type_id=event label (start from 0 = None)]
    """

    args.eval_batch_size = args.per_gpu_eval_batch_size * max(1, args.n_gpu)
    eval_sampler = SequentialSampler(eval_dataset)
    eval_dataloader = DataLoader(eval_dataset, sampler=eval_sampler, batch_size=args.eval_batch_size, collate_fn=lambda x: list(map(list, zip(*x))))

    logger.info("***** Running maven %s evaluation at %s *****", split, num_epochs)
    logger.info("  Num examples = %d", len(eval_dataset))
    logger.info("  Batch size = %d", args.eval_batch_size)

    docids = []
    ids = []
    dists = []
    model.eval()

    with torch.no_grad():
        labelset = eval_dataset.labelset
        labelset_inputs = tokenizer(labelset, padding=True, truncation=True, max_length=args.max_label_length, return_tensors="pt").to(args.device)
        labelset_embeddings = model.embed(**labelset_inputs)

    for sent, docid, id in tqdm(eval_dataloader, desc="Evaluating"):
        docids.extend(docid)
        ids.extend(id)
        sent_inputs = tokenizer(sent, padding=True, truncation=True, max_length=args.max_sent_length, return_tensors="pt", is_split_into_words=True).to(args.device)

        with torch.no_grad():
            sent_embeddings = model.embed(**sent_inputs)
            for i in range(len(sent_embeddings)):
                sent_embedding = sent_embeddings[i].expand(labelset_embeddings.shape)
                dist = model.dist_fn(sent_embedding, labelset_embeddings).detach().cpu().numpy().tolist()
                dists.append(dist)

    preds = []
    for i, dist in enumerate(dists):
        pred = min(labelset, key=lambda x:dist[labelset.index(x)])
        preds.append(pred)

    submissions = copy.deepcopy(eval_dataset.negative_trigger)
    for docid, id, pred in zip(docids, ids, preds):
        submissions[docid].append({"id": id, "type_id": labelset.index(pred)+1})

    # sanity check
    with open(os.path.join(args.output_dir, "%s_%s_results.jsonl" % (split, num_epochs)), "w") as f:
        for docid, preds in submissions.items():
            f.write(json.dumps({"id": docid, "predictions": preds}) + "\n")

def eval_fewrel(args, eval_dataset, model, tokenizer, num_epochs="", split=""):
    args.eval_batch_size = args.per_gpu_eval_batch_size * max(1, args.n_gpu)
    eval_sampler = SequentialSampler(eval_dataset)
    eval_dataloader = DataLoader(eval_dataset, sampler=eval_sampler, batch_size=args.eval_batch_size, collate_fn=lambda x: list(map(list, zip(*x))))

    # Eval!
    logger.info("***** Running fewrel %s evaluation at %s *****", split, num_epochs)
    logger.info("  Num examples = %d", len(eval_dataset))
    logger.info("  Batch size = %d", args.eval_batch_size)

    dists = []
    labels = []
    model.eval()

    with torch.no_grad():
        labelset = eval_dataset.labelset
        labelset_inputs = tokenizer(labelset, padding=True, truncation=True, max_length=20, return_tensors="pt").to(args.device)
        labelset_embeddings = model.embed(**labelset_inputs)

    for sent, pos, _ in tqdm(eval_dataloader, desc="Evaluating"):
        labels.extend(pos)
        sent_inputs = tokenizer(sent, padding=True, truncation=True, max_length=args.max_sent_length, return_tensors="pt", is_split_into_words=True).to(args.device)

        with torch.no_grad():
            sent_embeddings = model.embed(**sent_inputs)
            for i in range(len(sent_embeddings)):
                sent_embedding = sent_embeddings[i].expand(labelset_embeddings.shape)
                dist = model.dist_fn(sent_embedding, labelset_embeddings).detach().cpu().numpy().tolist()
                dists.append(dist)

    N = [10, 5]
    score_all_run = []

    n_runs = 10
    for run in range(n_runs):
        scores = []
        for n in N:
            preds = []
            for i, label in enumerate(labels):
                dist = dists[i]
                labelset_copy = labelset.copy()
                labelset_copy.remove(label)
                n_way_labelset = [label] + random.sample(labelset_copy, n-1)
                pred = min(n_way_labelset, key=lambda x:dist[labelset.index(x)])
                preds.append(pred)
            scores.append(accuracy_score(labels, preds))
        score_all_run.append(scores)
    score_all_run = list(zip(*score_all_run))

    results = {
        "10-way-0-shot Accuracy": sum(score_all_run[0])/len(score_all_run[0]),
        "5-way-0-shot Accuracy": sum(score_all_run[1])/len(score_all_run[1]),
    }

    for key in results:
        logger.info("  %s = %s", key, str(results[key]))

    return results

def main():
    parser = argparse.ArgumentParser()

    # directory
    parser.add_argument("--output_dir", type=str,
                        help="The output directory where the model predictions and checkpoints will be written.")
    parser.add_argument("--data_dir", type=str,
                        help="The input data directory.")
    parser.add_argument("--train_tasks", nargs="+",
                        help="Specify what task to train the model on")
    parser.add_argument("--eval_tasks", nargs="+",
                        help="Specify what task to evaluate the model on")
    parser.add_argument("--cache_dir", default=None, type=str,
                        help="Where do you want to store the pre-trained models downloaded from s3")
    parser.add_argument("--model_name_or_path", default="roberta-large", type=str,
                        help="The model checkpoint for weights initialization.")
    parser.add_argument("--overwrite_output_dir", action="store_true",
                        help="Overwrite the content of the output directory")
    parser.add_argument("--overwrite_cache", action="store_true",
                        help="Overwrite the cached training and evaluation sets")
    # 用来评价模型
    parser.add_argument("--eval_dir", default=None, type=str,
                        help="Where to find model checkpoints for evluation")
    parser.add_argument('--eval_name', default='test', type=str, help='测试的数据集的名称')
    parser.add_argument('--train_name', default='train', type=str, help='训练模型的文件')
    parser.add_argument('--eval_only', action='store_true') # 只用来评价测试集的模型
    parser.add_argument('--train_mode', default='baseline', type=str, help='baseline / data-aug / ours')
    # parser.add_argument('--use_pseudo', action='store_true') # 使用伪数据就是我们的模型
    # parser.add_argument('--ablation', action='store_true') # 对比实验
    # parser.add_argument('--aug_weight', default=0., type=float, help='伪数据的权重')

    # model config
    parser.add_argument("--margin", default=0.1, type=float,
                        help="The margin of the triplet loss function.")

    # 删除掉任务描述
    parser.add_argument("--no_task_desc", action="store_true",
                        help="Remove task desc.")
    parser.add_argument("--max_sent_length", default=160, type=int,
                        help="The maximum total input sentence length after tokenization. Sequences longer "
                             "than this will be truncated.")
    parser.add_argument("--max_label_length", default=20, type=int,
                        help="The maximum total input label length after tokenization. Sequences longer "
                             "than this will be truncated.")

    # procedure
    parser.add_argument("--do_train", action="store_true",
                        help="Whether to run training.")
    parser.add_argument("--do_eval", action="store_true",
                        help="Whether to run evaluation on the dev set.")
    parser.add_argument("--eval_during_training", action="store_true",
                        help="Run evaluation during training at each logging step.")
    parser.add_argument("--logging_epochs", type=int, default=10,
                        help="Log every X epochs.")
    parser.add_argument("--save_epochs", type=int, default=10,
                        help="Save checkpoint every X epochs.")
    parser.add_argument("--eval_all_checkpoints", action="store_true",
                        help="Evaluate all checkpoints ending with step number")

    # optimizer
    parser.add_argument("--per_gpu_train_batch_size", default=32, type=int,
                        help="Batch size per GPU/CPU for training.")
    parser.add_argument("--per_gpu_eval_batch_size", default=4, type=int,
                        help="Batch size per GPU/CPU for evaluation.")
    parser.add_argument("--gradient_accumulation_steps", type=int, default=1,
                        help="Number of updates steps to accumulate before performing a backward/update pass.")
    parser.add_argument("--learning_rate", default=5e-6, type=float,
                        help="The initial learning rate for Adam.")
    parser.add_argument("--weight_decay", default=0.0, type=float,
                        help="Weight deay if we apply some.")
    parser.add_argument("--max_grad_norm", default=1.0, type=float,
                        help="Max gradient norm.")
    parser.add_argument("--num_train_epochs", default=100.0, type=float,
                        help="Total number of training epochs to perform.")
    parser.add_argument("--warmup_ratio", default=0.1, type=float,
                        help="Warm up ratio for Adam.")

    # gpu
    parser.add_argument("--no_cuda", action="store_true",
                        help="Avoid using CUDA when available")
    # 开启分布式训练，本地编号
    parser.add_argument("--local_rank", type=int, default=-1,
                        help="For distributed training: local_rank")

    # seed
    parser.add_argument("--seed", type=int, default=42,
                        help="random seed for initialization")

    parser.add_argument('--mask_entity', action='store_true', help='mask entity name test.')

    args = parser.parse_args()

    if any(task for task in args.train_tasks if task not in ["tacred", "ufet", "maven", "fewrel", 'retacred']):
        raise ValueError("train tasks must be tacred, ufet, maven, or fewrel")

    if any(task for task in args.eval_tasks if task not in ["tacred", "ufet", "maven", "fewrel", 'retacred']):
        raise ValueError("eval tasks must be tacred, ufet, maven, or fewrel")

    # * 短路求值，优先判断处于训练模式
    if args.do_train and os.path.exists(args.output_dir) and os.listdir(args.output_dir) and not args.overwrite_output_dir:
        raise ValueError("Output directory ({}) already exists and is not empty. Use --overwrite_output_dir to overcome.".format(args.output_dir))

    # local_rank为0表示是master节点
    if args.do_train and not os.path.exists(args.output_dir) and args.local_rank in [-1, 0]:
        os.makedirs(args.output_dir)

    # Setup CUDA, GPU & distributed training
    if args.local_rank == -1 or args.no_cuda:
        device = torch.device("cuda" if torch.cuda.is_available() and not args.no_cuda else "cpu")
        args.n_gpu = torch.cuda.device_count() # 统计gpu的数量

    else:  # Initializes the distributed backend which will take care of sychronizing nodes/GPUs
        torch.cuda.set_device(args.local_rank)
        device = torch.device("cuda", args.local_rank)
        torch.distributed.init_process_group(backend="nccl")
        args.n_gpu = 1
    args.device = device

    # Setup logging
    if args.do_train:
        logging.basicConfig(filename=os.path.join(args.output_dir, "logs.log"),
                            format="%(asctime)s - %(levelname)s - %(name)s -   %(message)s",
                            datefmt="%m/%d/%Y %H:%M:%S",
                            level=logging.INFO if args.local_rank in [-1, 0] else logging.WARN)
        logger.warning("Process rank: %s, device: %s, n_gpu: %s, distributed training: %s",
                        args.local_rank, device, args.n_gpu, bool(args.local_rank != -1))

    # Set seed
    set_seed(args.seed)

    # Load pretrained model and tokenizer
    if args.local_rank not in [-1, 0]:
        torch.distributed.barrier()  # Barrier to make sure only the first process in distributed training download model & vocab

    config = RobertaConfig.from_pretrained(args.model_name_or_path,
                                          cache_dir=args.cache_dir if args.cache_dir else None)
    config.margin = args.margin
    config.no_task_desc = args.no_task_desc
    # config.aug_weight = args.aug_weight
    # config.use_pseudo = args.use_pseudo
    # config.ablation = args.ablation

    # * 切换为autoTokenizer和use_fast
    tokenizer = AutoTokenizer.from_pretrained(args.model_name_or_path,
                                                cache_dir=args.cache_dir if args.cache_dir else None,
                                                add_prefix_space=True,
                                                use_fast=True) # 使用fast才能够做反向映射

    model = UniSTModel.from_pretrained(args.model_name_or_path,
                                        config=config,
                                        cache_dir=args.cache_dir if args.cache_dir else None)
    model.to(args.device)

    # add new token
    special_tokens_dict = {"additional_special_tokens":["<E>", "</E>", "<SUBJ>", "</SUBJ>", "<OBJ>", "</OBJ>", "<T>", "</T>"]}
    num_added_toks = tokenizer.add_special_tokens(special_tokens_dict)
    print("We have added", num_added_toks, "tokens")
    model.resize_token_embeddings(len(tokenizer))  # Notice: resize_token_embeddings expect to receive the full size of the new vocabulary, i.e. the length of the tokenizer.

    if args.local_rank == 0:
        torch.distributed.barrier()  # End of barrier to make sure only the first process in distributed training download model & vocab

    logger.info("Training/evaluation parameters %s", args)

    # Prepare datasets
    if args.do_train or args.do_eval:
        #if args.local_rank not in [-1, 0]:
        #    torch.distributed.barrier()  # Barrier to make sure only the first process in distributed training process the dataset, and the others will use the cache

        # tacred
        tacred_train_dataset = (
            # 定义自己的raw_labelset
            TACREDDataset(os.path.join(args.data_dir, args.train_name + '.json'), no_task_desc=args.no_task_desc, mode='train')
            if "tacred" in args.train_tasks and not args.eval_only
            else None
        )
        tacred_dev_dataset = (
            TACREDDataset(os.path.join(args.data_dir, "dev.json"), no_task_desc=args.no_task_desc, mode='dev')
            if "tacred" in args.eval_tasks and not args.eval_only
            else None
        )
        tacred_test_dataset = (
            TACREDDataset(os.path.join(args.data_dir, os.path.join('splits', args.eval_name + '.json')), no_task_desc=args.no_task_desc, mask_entity=args.mask_entity, mode='test')
            if "tacred" in args.eval_tasks
            else None
        )
        tacred_unseen_dataset = (
            TACREDDataset(os.path.join(args.data_dir, os.path.join('splits', 'test_two_new_entity.json')), no_task_desc=args.no_task_desc, mask_entity=args.mask_entity, mode='test')
            if "tacred" in args.eval_tasks
            else None
        )
        tacred_challendge_dataset = (
            TACREDDataset(os.path.join(args.data_dir, os.path.join('splits', 'test_challenge.json')), no_task_desc=args.no_task_desc, mask_entity=args.mask_entity, mode='test')
            if "tacred" in args.eval_tasks
            else None
        )
        # retacred(TODO：加入retacred)
        retacred_train_dataset = (
            # 定义自己的raw_labelset
            RETACREDDataset(os.path.join(args.data_dir, args.train_name + '.json'), no_task_desc=args.no_task_desc, mode='train')
            if "retacred" in args.train_tasks and not args.eval_only
            else None
        )
        retacred_dev_dataset = (
            RETACREDDataset(os.path.join(args.data_dir, "dev.json"), no_task_desc=args.no_task_desc, mode='dev')
            if "retacred" in args.eval_tasks and not args.eval_only
            else None
        )
        retacred_test_dataset = (
            RETACREDDataset(os.path.join(args.data_dir, os.path.join('splits', args.eval_name + '.json')), no_task_desc=args.no_task_desc, mask_entity=args.mask_entity, mode='test')
            if "retacred" in args.eval_tasks
            else None
        )
        retacred_unseen_dataset = (
            RETACREDDataset(os.path.join(args.data_dir, os.path.join('splits', 'test_two_new_entity.json')), no_task_desc=args.no_task_desc, mask_entity=args.mask_entity, mode='test')
            if "retacred" in args.eval_tasks
            else None
        )
        retacred_challenge_dataset = (
            RETACREDDataset(os.path.join(args.data_dir, os.path.join('splits', 'test_challenge.json')), no_task_desc=args.no_task_desc, mask_entity=args.mask_entity, mode='test')
            if "retacred" in args.eval_tasks
            else None
        )

        # ufet
        ufet_train_dataset = (
            UFETDataset(os.path.join(args.data_dir, "ufet/train.json"), os.path.join(args.data_dir, "ufet/ufet_labels.txt"), no_duplicates=False, no_task_desc=args.no_task_desc)
            if "ufet" in args.train_tasks
            else None
        )
        if ufet_train_dataset and len(args.train_tasks) > 1:
            ufet_train_dataset.data *= 10
        ufet_dev_dataset = (
            UFETDataset(os.path.join(args.data_dir, "ufet/dev.json"), os.path.join(args.data_dir, "ufet/ufet_labels.txt"), no_duplicates=True, no_task_desc=args.no_task_desc)
            if "ufet" in args.eval_tasks
            else None
        )
        ufet_test_dataset = (
            UFETDataset(os.path.join(args.data_dir, "ufet/test.json"), os.path.join(args.data_dir, "ufet/ufet_labels.txt"), no_duplicates=True, no_task_desc=args.no_task_desc)
            if "ufet" in args.eval_tasks
            else None
        )

        # maven
        maven_train_dataset = (
            MAVENDataset(os.path.join(args.data_dir, "maven/train.jsonl"), no_task_desc=args.no_task_desc)
            if "maven" in args.train_tasks
            else None
        )
        maven_dev_dataset = (
            MAVENDataset(os.path.join(args.data_dir, "maven/valid.jsonl"), no_task_desc=args.no_task_desc)
            if "maven" in args.eval_tasks
            else None
        )

        # fewrel
        fewrel_train_dataset = (
            FewRelDataset(os.path.join(args.data_dir, "fewrel/train_wiki_processed.jsonl"), os.path.join(args.data_dir, "fewrel/train_labels.txt"), no_task_desc=args.no_task_desc)
            if "fewrel" in args.train_tasks
            else None
        )
        fewrel_dev_dataset = (
            FewRelDataset(os.path.join(args.data_dir, "fewrel/val_wiki_processed.jsonl"), os.path.join(args.data_dir, "fewrel/val_labels.txt"), no_task_desc=args.no_task_desc)
            if "fewrel" in args.eval_tasks
            else None
        )

        train_dataset = ConcatDataset([
            dataset for dataset in [tacred_train_dataset, ufet_train_dataset, maven_train_dataset, fewrel_train_dataset, retacred_train_dataset]
            if dataset is not None
        ]) if args.do_train else None
        eval_datasets = {
            "tacred_dev": tacred_dev_dataset,
            "tacred_test": tacred_test_dataset,
            "tacred_unseen": tacred_unseen_dataset,
            "tacred_challenge": tacred_challendge_dataset,
            "ufet_dev": ufet_dev_dataset,
            "ufet_test": ufet_test_dataset,
            "maven_dev": maven_dev_dataset,
            "fewrel_dev": fewrel_dev_dataset,
            "retacred_dev": retacred_dev_dataset,
            "retacred_test": retacred_test_dataset,
            "retacred_unseen": retacred_unseen_dataset,
            "retacred_challenge": retacred_challenge_dataset
        }

        #if args.local_rank == 0:
        #    torch.distributed.barrier()

    # Training
    if args.do_train:
        train(args, train_dataset, eval_datasets, model, tokenizer)

    # Saving best-practices: if you use save_pretrained for the model and tokenizer, you can reload them using from_pretrained()
    # 保存参数最好的模型
    if args.do_train and (args.local_rank == -1 or torch.distributed.get_rank() == 0):
        logger.info("Saving model checkpoint to %s", args.output_dir)
        # Save a trained model, configuration and tokenizer using `save_pretrained()`.
        # They can then be reloaded using `from_pretrained()`
        model_to_save = model.module if hasattr(model, "module") else model  # Take care of distributed/parallel training
        model_to_save.save_pretrained(args.output_dir)
        tokenizer.save_pretrained(args.output_dir)

        # Good practice: save your training arguments together with the trained model
        torch.save(args, os.path.join(args.output_dir, "training_args.bin"))

    # Evaluation
    if args.do_eval and args.local_rank in [-1, 0]:
        if args.eval_dir is None:
            checkpoints = [args.output_dir]
        else:
            checkpoints = [args.eval_dir] # 从eval_dir加载模型

        if args.eval_all_checkpoints:
            checkpoints = list(os.path.dirname(c) for c in sorted(glob.glob(args.output_dir + "/**/" + WEIGHTS_NAME, recursive=True)))
            logging.getLogger("transformers.modeling_utils").setLevel(logging.WARN)  # Reduce logging

        logger.info("Evaluating the following checkpoints: %s", checkpoints)

        for checkpoint in checkpoints:
            num_epochs = checkpoint.split("-")[-1] #if len(checkpoints) > 1 else "end"
            model = UniSTModel.from_pretrained(checkpoint) # 加载断点
            model.to(args.device)
            model_to_eval = model.module if hasattr(model, "module") else model  # Take care of distributed/parallel training

            if "tacred" in args.eval_tasks:
                if not args.eval_only: # 在验证集上评价
                    eval_tacred(args, eval_datasets["tacred_dev"], model_to_eval, tokenizer, num_epochs=num_epochs, split="dev")
                eval_tacred(args, eval_datasets["tacred_test"], model_to_eval, tokenizer, num_epochs=num_epochs, split="test")
            if "retacred" in args.eval_tasks:
                if not args.eval_only:
                    eval_tacred(args, eval_datasets["retacred_dev"], model_to_eval, tokenizer, num_epochs=num_epochs, split="dev")
                eval_tacred(args, eval_datasets["retacred_test"], model_to_eval, tokenizer, num_epochs=num_epochs, split="test")
            if "ufet" in args.eval_tasks:
                threshold = eval_ufet(args, eval_datasets["ufet_dev"], model_to_eval, tokenizer, num_epochs=num_epochs, split="dev")["Threshold"]
                eval_ufet(args, eval_datasets["ufet_test"], model_to_eval, tokenizer, num_epochs=num_epochs, split="test", threshold=threshold)
            if "maven" in args.eval_tasks:
                eval_maven(args, eval_datasets["maven_dev"], model_to_eval, tokenizer, num_epochs=num_epochs, split="dev")
            if "fewrel" in args.eval_tasks:
                eval_fewrel(args, eval_datasets["fewrel_dev"], model_to_eval, tokenizer, num_epochs=num_epochs, split="dev")

    return 0

if __name__ == "__main__":
    main()


menus = {
    "Baja Taco": 4.00,
    "Burrito": 7.50,
    "Bowl": 8.50,
    "Nachos": 11.00,
    "Quesadilla": 8.50,
    "Super Burrito": 8.50,
    "Super Quesadilla": 9.50,
    "Taco": 3.00,
    "Tortilla Salad": 8.00
}
totalprice = 0.0
while True:
    try:
        item = input('Item: ')
        for key, value in menus.items():
            if item == key:
                totalprice += value
                print(f'Total: ${totalprice}')
    except (EOFError, KeyError):
        break


from django.urls import path

from . import views

urlpatterns = [
    path("", views.index, name="index"),
    path("registration", views.registration_view, name="registration"),
    path("login", views.login_view, name="login"),
    path("logout", views.logout_view, name="logout"),
    path("error", views.error, name="error"),
    path("pizza/<int:pizza_id>", views.pizza, name="pizza"),
    path("price/<int:pizza_id>/<slug:size>/<int:topping>", views.price, name="price"),
    path("subsprice/<int:sub_id>/<slug:size>", views.sub_price, name="subprice"),
    path("subs/<int:sub_id>", views.subs, name="subs"),
    path("pasta/<int:pasta_id>", views.pasta, name="pasta"),
    path("salad/<int:salad_id>", views.salad, name="salad"),
    path("pastaprice/<int:pasta_id>", views.pasta_price, name="pastaprice"),
    path("saladprice/<int:salad_id>", views.salad_price, name="saladprice"),
    path("dinnerplatters/price/<int:dp_id>/<slug:size>", views.platters_price, name="platter_price"),
    path("pizzahandler", views.pizzaHandler, name="pizzaHandler"),
    path("dinnerplatters/<int:dp_id>", views.dinner_platters, name="dinner_platters"),
    path("subshandler/<slug:sub_id>/<slug:size>", views.subsHandler, name="subshandler"),
    path("saladhandler", views.saladHandler, name="saladhandler"),
    path("pastahandler", views.pastaHandler, name="pastaHandler"),
    path("plattershandler", views.dinnerPlattersHandler, name="platterHandler"),
    path("clearcart", views.clearCart, name="clearcart"),
    path("removeItem/<int:item_id>", views.removeItem, name="removeItem"),
    path("proceed", views.proceedToBuy, name="proceed"),
    path("myorders", views.myOrders, name="myOrders"),
    path("placeorder", views.placeOrder, name="placeOrder"),
]