import pytest
import numpy as np

from gym.vector.tests.utils import make_env

from gym.vector.async_vector_env import AsyncVectorEnv
from gym.vector.sync_vector_env import SyncVectorEnv

@pytest.mark.parametrize('shared_memory', [True, False])
def test_vector_env_equal(shared_memory):
    env_fns = [make_env('CubeCrash-v0', i) for i in range(4)]
    num_steps = 100
    try:
        async_env = AsyncVectorEnv(env_fns, shared_memory=shared_memory)
        sync_env = SyncVectorEnv(env_fns)

        async_env.seed(0)
        sync_env.seed(0)

        assert async_env.num_envs == sync_env.num_envs
        assert async_env.observation_space == sync_env.observation_space
        assert async_env.single_observation_space == sync_env.single_observation_space
        assert async_env.action_space == sync_env.action_space
        assert async_env.single_action_space == sync_env.single_action_space

        async_observations = async_env.reset()
        sync_observations = sync_env.reset()
        assert np.all(async_observations == sync_observations)

        for _ in range(num_steps):
            actions = async_env.action_space.sample()
            assert actions in sync_env.action_space

            async_observations, async_rewards, async_dones, _ = async_env.step(actions)
            sync_observations, sync_rewards, sync_dones, _ = sync_env.step(actions)

            assert np.all(async_observations == sync_observations)
            assert np.all(async_rewards == sync_rewards)
            assert np.all(async_dones == sync_dones)

    finally:
        async_env.close()
        sync_env.close()


import torch
from .mode import Mode

def err2gt(err, mode:Mode=Mode.JOINTS):
  gt = torch.zeros(mode.get_num_layers(), dtype=torch.float32)
  if mode == Mode.JOINTS:
    for (i, e) in enumerate(err):
      gt[int(i*4 + e)] = 1
  else:
    for i in range(0, len(gt), 2):
      if err[i//2] == 0:
        gt[i] = 1
      else:
        gt[i+1] = 1

  return gt

def errs2gts(errs, mode:Mode=Mode.JOINTS):
  num_error_labels = mode.get_num_error_label()

  gts = torch.zeros(len(errs), len(errs[0]) * num_error_labels, dtype=torch.float32)
  for (i, err) in enumerate(errs):
    gts[i] = err2gt(err, mode)
  return gts

def gt2err(gt, mode:Mode=Mode.JOINTS):
  num_error_labels = mode.get_num_error_label()

  err = torch.zeros(len(gt) // num_error_labels, dtype=torch.float32)
  confidence = torch.zeros(len(gt) // num_error_labels, dtype=torch.float32)

  for i in range(0, len(gt), num_error_labels):
    e = gt[i:i + num_error_labels]
    probs = torch.nn.functional.softmax(e, dim=0)
    conf, classes = torch.max(probs, 0)

    confidence[i // num_error_labels] = conf
    err[i // num_error_labels] = classes

  return err, confidence

def gts2errs(gts, mode:Mode=Mode.JOINTS):
  num_error_labels = mode.get_num_error_label()

  errs = torch.zeros(len(gts), len(gts[0]) // num_error_labels, dtype=torch.float32)
  confidences = torch.zeros(len(gts), len(gts[0]) // num_error_labels, dtype=torch.float32)
  for (i, gt) in enumerate(gts):
    errs[i], confidences[i] = gt2err(gt, mode)

  return errs, confidences


import pyttsx3
import datetime
import speech_recognition as sr
import webbrowser as wb
import os
tuesday=pyttsx3.init()
voice=tuesday.getProperty('voices')
tuesday.setProperty('voice', voice[1].id)

def speak(audio):
    print("Tuesday:"+ audio)
    tuesday.say(audio)
    tuesday.runAndWait()

def time():
    time=datetime.datetime.now().strftime("%I: %M: %p")
    speak(time)

def welcome():
    hour=datetime.datetime.now().hour
    if hour >= 6 and hour <= 12:
        speak("Good Morning sir")
    elif hour > 12 and hour <= 18:
        speak("Good Afternoon sir" )
    else:
        speak("Good Night Sir")
    speak("How can I help you")
def command():
    r=sr.Recognizer()

    with sr.Microphone() as source:
        r.pause_threshold= 1
        audio = r.listen(source)

        try:
            said=r.recognize_google(audio,language="en")
            print("Mr. Hoang "+ said)

        except Exception as e:
            print("Exception:" + str(e))
    return said

if __name__== "__main__":
    welcome()

    while True:
        said= command().lower()
        speak(said)
        if "google" in said :
            speak("What shoud I search boss?")
            search=command().lower()
            url=f"https://www.google.com/search?q={search}"
            wb.get().open(url)
            speak(f"Here is your {search} on google")
        if "Youtube" in said :
            speak("What shoud I search boss?")
            search=command().lower()
            url=f"https://www.youtube.com//search?q={search}"
            wb.get().open(url)
            speak(f"Here is your {search} on youtube")
        elif "open video" in said:
            meme=r"C:\Users\hoang\Videos\Captures\meme.mp4"
            os.startfile(meme)
        elif "sing" in said:
            sofa=r"C:\Users\hoang\Videos\Captures\sofa.mp3"
            os.startfile(sofa)
        elif "time" in said:
            time()
        elif "quit" in said:
            speak("Tuesday is quitting sir.Goodbye boss")
            quit()


import numpy as np
import matplotlib.pyplot as plt
import tools as tools
import time
start_time = time.time()

filein = '../core-softened-phase-diagram/CSA/temp-0.01/lambda_0.25/run/lammps_temp_0.01_press_6.5.snap'

r = tools.read_in_trajectory(filein, 4000, 100)

L1 = 1.1*np.absolute(np.max(r[:,:,0]) - np.min(r[:,:,0]))
L2 = 1.1*np.absolute(np.max(r[:,:,1]) - np.min(r[:,:,1]))
L3 = 0.0
rdf, r = tools.rdf_monomer_to_monomer(r[:,:,0],r[:,:,1],L1,L2)

sex, csum, r_s2 = tools.excess_entropy_from_rdf(rdf,r)
r_s2 = r_s2[r_s2>0]
csum = csum[csum>0]

rho = (0.5 * 4000) / (L1 * L2)

print(csum)
print(r_s2)
print("--- %s seconds ---" % (time.time() - start_time))

plt.figure()
#plt.ylim(0,12)
data = np.genfromtxt("../core-softened-phase-diagram/CSA/temp-0.01/lambda_0.25/ex_entropy/press_6.5_cumsex.dat")
plt.plot(r_s2,csum)
plt.plot(data[:,0],data[:,1],color="red")
#plt.yscale('log')
plt.show()


from common.base_utils.comm_utils import create_bankcard
from common.business_func.applet_func import Applet_func
from common.business_func.namelist import NameList
from common.business_func.mem_information_manag_func import Member_information_management_func
from common.login.web_login import Web_Login
from common.login.applet_login import Applet_Login
from common.venv.var import *
from common.base_utils.comm_param import *
from common.business_func.orders import Order

# 配置项
n = 1 # 录名单数量
entborrows = ['协和小时工1']  # 企业
ents = ['昆山协和']  # 标准企业
interviewdt = '2020-07-01' # 面试日期
OrderDt = '2020-07-01' # 订单报价日期
BeginDt = '2020-07-01' # 订单生效开始日期
repairclockdt = '2020-07-01' # 补卡开始日期
agentnames = ['殷海涛供应商'] #供应商列表
username_name = '13340000001'
username_order = '15995627659'
username_mem = '15995627659'
username_advance = '15995627659'
bankname = '兴业银行'
SettleBeginDate='2020-07-01'
SettleEndDate = '2020-07-01'
workdate = '2020-07-01' # 入职日期

login = Web_Login()

login.login(username_name)

name_manage = NameList(login)

# 录名单

mobiles = []
membernames = []
idcardnums = []
nameids = []
for i in range(n):
    mobile = create_phone()
    idnum = create_IDCard()
    name = create_name()
    name_manage.add_name_pq(entbrorrowname=entborrows[0],InterviewDate=interviewdt,FromSpName=agentnames[0],name=name)
    mobiles.append(mobile)
    membernames.append(name)
    idcardnums.append(idnum)
    nameids.append(name_manage.newnameid_pq)
    print(i)
# 建订单
order_manage = Order(login)
order_manage.create_order_pq(ReceiverType=2,entbrorrowname=entborrows[0],OrderDt=OrderDt,BeginDt=OrderDt,PriceUnit=1)
order_manage.Judge_Order(auditsts=2,orderid=order_manage.orderid)
order_manage.publishOrderToSupplier(agentname=agentnames[0])

# 名单绑订单
name_manage.bind_order(orderid=order_manage.orderid,namelist=nameids)

# 上传身份证
workcardnos = []
for i in range(n):
    applogin = Applet_Login()
    applogin.applogin(tenantype=2, phone=mobiles[i])
    member = Applet_func(applogin)
    mem_manage = Member_information_management_func(login)

    member.upload_idcard(fakeridcardpicture)
    # 审核身份证
    mem_manage.audit_idcard(idcardnum=idcardnums[i],rname=membernames[i],phone=mobiles[i])

    # 上传银行卡
    member.upload_bankcard(bankname=bankname,bankCardFile=fakerbankcardpicture)
    # 审核银行卡
    bankcardnum = create_bankcard()
    mem_manage.audit_bankcard(bankcardnum=bankcardnum,bankname=bankname,phone=mobiles[i])

    # 上传工牌
    member.upload_workcard(entname=ents[0],workCardFile=workCardpicture)
    # 审核工牌
    workcardno = create_workcardno()
    mem_manage.audit_workcard(entshortname=ents[0],workcardno=workcardno,phone=mobiles[i])
    # workcardnos.append(workcardno)


from collections import UserDict

class AddressBook(UserDict):
    def add_record(self, record):
        self.data[record.name.value] = record

class Record:
    def __init__(self, name, phone = None) -> None:
        self.name = name
        self.phones = []
        self.phones.append(phone)

    def add_phone(self, phone):
        self.phones.append(phone)
        return 'Done!'

    def del_phone(self, phone):
        for p in self.phones:
            if p.value == phone.value:
                self.phones = filter(lambda x: x != p, self.phones)
            return 'Done!'
        return "This phone doesn't exist in this contact."

    def edit_phone (self, phone, new_phone):
        for p in self.phones:
            if p.value == phone.value:
                p.value = new_phone.value
            return 'Done!'
        return "This phone doesn't exist in this contact."

class Field:
    def __init__(self, value):
        self.value = value

class Name(Field):
    pass

class Phone(Field):
    pass

def main():
    phone_book = AddressBook()
    while True:
        user_command = input('>>>')
        if user_command == '.':
            break
        elif user_command.lower() == 'hello':
            print(greeting())
        elif user_command.lower() in ("good bye", "close", "exit"):
            print(good_buy())
            break
        elif user_command.lower().startswith('add '):
            print(add(user_command, phone_book))
        elif user_command.lower().startswith('change '):
            print(change(user_command, phone_book))
        elif user_command.lower() == 'show all':
            print(show_all(phone_book))
        elif user_command.lower().startswith('phone '):
            print(phone(user_command, phone_book))
        elif user_command.lower().startswith('delate '):
            print(delate(user_command, phone_book))

def input_error(func):
    def inner(*args, **kwargs):
        try:
            return func(*args, **kwargs)
        except KeyError:
            return 'This name do not exist in your phone book!'
        except ValueError:
            return 'Please enter a phone number.'
        except IndexError:
            return 'Give me name and phone please.'
    return inner

def greeting():
    return 'How can I help you?'

def good_buy():
    return 'Good buy!'

def show_all(phones):
    result = ''
    for k, v in phones.items():
        all_phones = ''
        for p in v.phones:
            all_phones += str(p.value) + ', '
        result = result + f'{k} : {all_phones[:-2]}\n'
    return result[:-1]

@input_error
def add(user_command, phone_book):
    command = user_command.split(' ')
    if len(command) != 3:
        raise IndexError()
    name = Name(command[1])
    phone_number = Phone(int(command[2]))
    if name.value in phone_book.keys():
        rec = phone_book[name.value]
        rec.add_phone(phone_number)
        return 'Done!'
    rec = Record(name, phone_number)
    phone_book.add_record(rec)
    return 'Done!'

@input_error
def change(user_command, phone_book):
    command = user_command.split(' ')
    if len(command) != 4:
        raise IndexError()
    name = Name(command[1])
    phone_number = Phone(int(command[2]))
    new_phone = Phone(int(command[3]))
    if name.value not in phone_book.keys():
        raise KeyError()
    phone_book[name.value].edit_phone(phone_number, new_phone)
    return 'Done!'

@input_error
def delate(user_command, phone_book):
    command = user_command.split(' ')
    if len(command) != 3:
        raise IndexError()
    name = Name(command[1])
    phone_number = Phone(int(command[2]))
    if name.value not in phone_book.keys():
        raise KeyError()
    return phone_book[name.value].del_phone(phone_number)

@input_error
def phone(user_command, phone_book):
    command = user_command.split(' ')
    if len(command) != 2:
        raise KeyError()
    name = Name(command[1])
    all_phones = ''
    for p in phone_book[name.value].phones:
            all_phones += str(p.value) + ', '
    return (all_phones[:-2])

if __name__ == "__main__":
    main()


from config import CONFIG
from config import TOKEN, MODE, HEROKU_APP_NAME, PORT
from dialog_manager import LANGUAGES, MAIN_MENU, ANSWERS, SECOND_LEVEL

import logging

from telegram.ext import Updater, CommandHandler, MessageHandler, Filters, \
    CallbackQueryHandler
from telegram import ParseMode, InlineKeyboardButton, InlineKeyboardMarkup

logging.basicConfig(format=('%(asctime)s - %(name)s - '
                            '%(levelname)s - %(message)s'),
                    level=logging.INFO)
logger = logging.getLogger()

language = {}

def add_handlers(updater):
    """
    This function adds handlers for start and message_processing functions.
    :param updater: an Updater object
    :return: None
    """
    updater.dispatcher.add_handler(CommandHandler('start', start))
    updater.dispatcher.add_handler(CommandHandler('help', help))
    updater.dispatcher.add_handler(MessageHandler(Filters.all,
                                                  message_processing))
    updater.dispatcher.add_handler(CallbackQueryHandler(button))

def start(update, context):
    """
    Function sends reply every time the Bot receives message with
    /start command.
    :return: None
    """

    keyboard = []
    for item in LANGUAGES:
        keyboard.append([InlineKeyboardButton(item, callback_data=item)])

    reply_markup = InlineKeyboardMarkup(keyboard)

    start_text = (ANSWERS['greeting'] + '\n\n' +
                  ANSWERS['ru_greeting'])
    context.bot.send_message(parse_mode=ParseMode.MARKDOWN,
                             chat_id=update.effective_chat.id,
                             text=start_text, reply_markup=reply_markup)

def button(update, context):
    query = update.callback_query

    logger.info(f'Query {query.data} for '
                f'{update.effective_user.name} at '
                f'{update.effective_message.date}')

    keyboard = []

    if query.data in LANGUAGES:
        language[update.effective_user.name] = query.data
        for item in LANGUAGES[query.data]:
            keyboard.append([InlineKeyboardButton(item,
                                                  callback_data=item)])

    elif query.data in MAIN_MENU:
        for item in MAIN_MENU[query.data]:
            keyboard.append([InlineKeyboardButton(item,
                                                  callback_data=item)])

    elif query.data in SECOND_LEVEL:
        for item in SECOND_LEVEL[query.data]:
            keyboard.append([InlineKeyboardButton(item,
                                                  callback_data=item[:5])])

    elif query.data in ANSWERS:
        if language[update.effective_user.name] == 'English':
            back_text = 'Back to main menu'
        else:
            back_text = 'Назад в главное меню'

        keyboard = [[InlineKeyboardButton(back_text, callback_data=
        language[update.effective_user.name])]]
        reply_markup = InlineKeyboardMarkup(keyboard)

        context.bot.send_message(parse_mode=ParseMode.MARKDOWN,
                                 chat_id=update.effective_chat.id,
                                 text=ANSWERS[query.data],
                                 reply_markup=reply_markup,
                                 disable_web_page_preview=True)
        return 1

    else:
        if language[update.effective_user.name] == 'Русский':
            error_text = ANSWERS['ru_default']
        else:
            error_text = ANSWERS['default']

        context.bot.send_message(parse_mode=ParseMode.MARKDOWN,
                                 chat_id=update.effective_chat.id,
                                 text=error_text)
        return 1

    reply_markup = InlineKeyboardMarkup(keyboard)

    if language[update.effective_user.name] == 'Русский':
        intro_text = 'Выберите вопрос:'
    else:
        intro_text = 'Choose the question:'

    context.bot.send_message(parse_mode=ParseMode.MARKDOWN,
                             chat_id=update.effective_chat.id,
                             reply_markup=reply_markup,
                             text=intro_text)

def help(update, context):
    if language[update.effective_user.name] == 'Русский':
        help_text = 'Напиши /start для входа в меню.'
    else:
        help_text = 'Use /start command for FAQ.'
    context.bot.send_message(parse_mode=ParseMode.MARKDOWN,
                             chat_id=update.effective_chat.id,
                             text=help_text)

def message_processing(update, context):
    """
    Function saves voice messages in wav format with simple rate 16MHz and
    photos if a face is detected there. All path store in database `bot`.
    :return: None
    """

    logger.info(f'Waiting for message_processing function for '
                f'{update.effective_user.name} at '
                f'{update.effective_message.date}')

    if language == 'Русский':
        answer_text = ANSWERS['ru_default']
    else:
        answer_text = ANSWERS['default']

    context.bot.send_message(parse_mode=ParseMode.MARKDOWN,
                             chat_id=update.effective_chat.id,
                             text=answer_text)

    logger.info(f'Answer ready for {update.effective_user.name} '
                f'at {update.effective_message.date}')

if MODE == 'prod_heroku':
    def run():
        updater = Updater(TOKEN, use_context=True)
        updater.start_webhook(listen='0.0.0.0',
                              port=PORT,
                              url_path=TOKEN)
        add_handlers(updater)
        updater.bot.set_webhook(
            f'https://{HEROKU_APP_NAME}.herokuapp.com/{TOKEN}')

elif MODE == 'prod':
    def run():
        REQUEST_KWARGS = CONFIG['DEFAULT_REQUEST_KWARGS']
        updater = Updater(TOKEN,
                          request_kwargs=REQUEST_KWARGS,
                          use_context=True)
        add_handlers(updater)
        updater.start_polling()

elif MODE == 'dev':
    def run():
        # experiments here
        REQUEST_KWARGS = CONFIG['DEFAULT_REQUEST_KWARGS']
        updater = Updater(TOKEN,
                          request_kwargs=REQUEST_KWARGS,
                          use_context=True)
        add_handlers(updater)
        updater.start_polling()
else:
    logger.error('No MODE specified')
    exit(1)

if __name__ == '__main__':
    logger.info('Bot starting')
    run()


from flask import request, jsonify, Blueprint
from marshmallow import Schema, fields, ValidationError, validate

def UserModelBlueprint(database):

    UserModel = Blueprint('UserModel',__name__)

    class TimeRange(Schema):
        StartTime = fields.Time(required=True)
        EndTime = fields.Time(required=True)

    # Payload Schema for Store Initial Model API
    class StoreInitialModelSchema(Schema):
        UserId = fields.Integer(required=True)
        WorkingHours = fields.Nested(TimeRange(), required=True)
        BreakTime = fields.Nested(TimeRange(), required=True)
        TimePreference = fields.String(validate=validate.OneOf(['morning', 'afternoon', 'evening']), required=True)
        WeatherPreference = fields.String(validate=validate.OneOf(['sunny','rainy','none','any']), required=True)

    @UserModel.route("/store-initial-model", methods=["POST"])
    def StoreInitialModel():
        # Unmarshal Payload
        request_data = request.json

        try:
            result = StoreInitialModelSchema().load(request_data)
            result["WorkingHours"]["StartTime"] = result["WorkingHours"]["StartTime"].isoformat()
            result["WorkingHours"]["EndTime"] = result["WorkingHours"]["EndTime"].isoformat()
            result["BreakTime"]["StartTime"] = result["BreakTime"]["StartTime"].isoformat()
            result["BreakTime"]["EndTime"] = result["BreakTime"]["EndTime"].isoformat()
        except ValidationError as err:
            return jsonify(err.messages), 400

        try:
            database["userModel"].insert_one(result)
            return jsonify({"message": "Success"}), 200
        except Exception as e:
            return jsonify({"main_message": "Something went wrong!!", "detail_message": str(e)}), 400

    # Update Model Schema Payload
    class UpdateModelSchema(Schema):
        UserId = fields.Integer(required=True)
        WorkingHours = fields.Nested(TimeRange(), required=False)
        BreakTime = fields.Nested(TimeRange(), required=False)
        TimePreference = fields.String(validate=validate.OneOf(['morning', 'afternoon', 'evening']), required=False)
        WeatherPreference = fields.String(validate=validate.OneOf(['sunny', 'none']), required=False)

    @UserModel.route("/update-model", methods=["POST"])
    def UpdateModel():
        # Unmarshal Payload
        request_data = request.json

        try:
            result = UpdateModelSchema().load(request_data)
            if "WorkingHours" in result:
                result["WorkingHours"]["StartTime"] = result["WorkingHours"]["StartTime"].isoformat()
            if "WorkingHours" in result:
                result["WorkingHours"]["EndTime"] = result["WorkingHours"]["EndTime"].isoformat()
            if "BreakTime" in result:
                result["BreakTime"]["StartTime"] = result["BreakTime"]["StartTime"].isoformat()
            if "BreakTime" in result:
                result["BreakTime"]["EndTime"] = result["BreakTime"]["EndTime"].isoformat()
            UserId = result["UserId"]
            del result["UserId"]
        except ValidationError as err:
            return jsonify(err.messages), 400

        try:
            resp = database["userModel"].update_one(
                { 'UserId': UserId }, { '$set': result }
            )

            if resp.matched_count > 0:
                return jsonify({"message": "Success"}), 200
            else:
                return jsonify({"main_message": "Something went wrong!!", "detail_message": "The user does not exist"}), 400

        except Exception as e:
            return jsonify({"main_message": "Something went wrong!!", "detail_message": str(e)}), 400

    return UserModel


from prime import sieve
from math import sqrt, ceil
from itertools import count, combinations
from functools import reduce

maximum = 1000000
primes_list = tuple(sieve(maximum))
primes_set = set(primes_list)

def factorize(n):
    factors = []
    for prime in primes_list:
        if prime > n:
            return factors

        while n % prime == 0:
            factors.append(prime)
            n = n//prime

def dividors(factors):
    s = set()
    factors.append(1)
    mul = lambda a,b: a*b
    for r in range(1, len(factors)+1):
        for c in combinations(factors, r):
            s.add(reduce(mul, c))
    return s

def minmax(a,b):
    if a > b:
        return b,a
    else:
        return a,b

def solutions(n):
    n2 = n*n
    s = set()
    factors = factorize(n)
    factors = factors+factors
    for t in dividors(factors):
        x = n + t
        y = n2//t + n
        s.add(minmax(x,y))
    return s

for n in range(4,20):
    s = solutions(n)
    print(n, len(s))


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

from odoo import models, fields, api, _
import logging
import time
from odoo.exceptions import UserError

_logger = logging.getLogger(__name__)

class AccountTaxInvoiceWizard(models.TransientModel):
    _name = 'account.tax.invoice.wizard'
    _description = 'the way to make tax invoice'

    tax_invoice_no = fields.Char('Tax invoice no', required=True)
    partner_id = fields.Many2one('res.partner', 'Partner')
    invoice_line_ids = fields.Many2many('account.invoice.line', string='Invoice line')
    tax_invoice_method = fields.Selection([
        ('all', 'All'),
        ('part_amount', 'Part-amount'),
        ('part_percent', 'Part-rate'),
    ], required=True)
    tax_invoice_number = fields.Float('Tax invoice number')

    @api.model
    def default_get(self, fields_list):
        res = super(AccountTaxInvoiceWizard, self).default_get(fields_list)
        if self.env.context.get('active_ids'):
            current_model_name = self.env.context.get('current_model_name')
            invoice_model_name = self.env.context.get('invoice_model_name')
            if not current_model_name:
                if invoice_model_name == 'account.invoice.line':
                    invoice_line_ids = self.env['account.invoice.line'].browse(self.env.context.get('active_ids'))
                else:
                    invoice_ids = self.env['account.invoice'].browse(self.env.context.get('active_ids'))
                    invoice_line_ids = invoice_ids.mapped('invoice_line_ids')

            if current_model_name and current_model_name == 'verify.batch.reconciliation':
                ve_batch_re_ids = self.env['verify.batch.reconciliation'].browse(self.env.context.get('active_ids'))
                invoice_line_ids = ve_batch_re_ids.mapped('invoice_line_ids')

            partner_id = invoice_line_ids.mapped('partner_id')
            invoice_line_ids = invoice_line_ids.filtered(lambda x: x.tax_invoice_amount != x.price_unit)
            res.update({
                'invoice_line_ids': [(6, 0, invoice_line_ids.ids)],
                'partner_id': partner_id[0].id if partner_id else invoice_line_ids.mapped('invoice_id').mapped('partner_id')[0].id if invoice_line_ids.mapped('invoice_id').mapped('partner_id') else False
            })
        _logger.info({
            'res': res
        })
        return res

    # 解析数据
    def _parse_account_tax_invoice_data(self):
        data = {
            'partner_id': self.partner_id.id,
            'partner_shipping_id': self.partner_id.id,
            'user_id': self.env.user.id,
            'tax_invoice_no': self.tax_invoice_no
        }
        return data

    # 数据行的数据
    def _parse_account_tax_invoice_line_data(self, tax_invoice_method, tax_invoice_number, invoice_line_ids):
        line_data = []
        for line_id in invoice_line_ids:
            # 获取金额数据
            amount = getattr(self, '_compute_invoice_amount_{type_name}'.format(
                type_name=tax_invoice_method
            ))(line_id, tax_invoice_number, invoice_line_ids)
            line_data.append((0, 0, {
                'product_id': line_id.product_id.id,
                'name': line_id.product_id.name,
                'quantity': 1,
                'uom_id': line_id.product_id.uom_id.id,
                'price_unit': amount,
                'account_id': line_id.account_id.id,
                'invoice_line_id': line_id.id
            }))
        return line_data

    # 全部
    def _compute_invoice_amount_all(self, line_id, tax_invoice_number, invoice_line_ids):
        left_amount = line_id.price_unit - line_id.tax_invoice_amount
        line_id.write({
            'tax_invoice_amount': line_id.price_unit,
            # 'tax_invoice_state': tax_invoice_state
        })
        return round(float(left_amount) * 1000, -1) / 1000

    # 部分-金额
    def _compute_invoice_amount_part_amount(self, line_id, tax_invoice_number, invoice_line_ids):
        left_amount = line_id.price_unit - line_id.tax_invoice_amount
        if left_amount > tax_invoice_number / len(invoice_line_ids):
            line_id.write({
                'tax_invoice_amount': line_id.tax_invoice_amount + round(
                    float(tax_invoice_number / len(invoice_line_ids) * 1000), -1) / 1000
            })
            return round(float(tax_invoice_number / len(invoice_line_ids) * 1000), -1) / 1000
        else:
            line_id.write({
                'tax_invoice_amount': line_id.price_unit
            })
            return left_amount

    # 部分-比率
    def _compute_invoice_amount_part_percent(self, line_id, tax_invoice_number, invoice_line_ids):
        res = (line_id.price_unit - line_id.tax_invoice_amount) * (tax_invoice_number / 100)
        line_id.write({
            'tax_invoice_amount': line_id.tax_invoice_amount + round(float(res * 1000), -1) / 1000
        })
        return round(float(res * 1000), -1) / 1000

    def create_account_tax_invoice(self):
        try:
            self._judge_invoice_no()

            data = self._parse_account_tax_invoice_data()
            line_data = self._parse_account_tax_invoice_line_data(self.tax_invoice_method, self.tax_invoice_number,
                                                                  self.invoice_line_ids)

            data.update({
                'invoice_line_ids': line_data
            })
            tax_invoice_obj = self.env['account.tax.invoice']
            res = tax_invoice_obj.create(data)

            # 计算一次预开票
            self.invoice_line_ids._compute_pre_billing()

            self._create_invoice_no(res)
        except Exception as e:
            self._cr.rollback()
            raise UserError(e)

    # 创建发票批次号
    def _create_invoice_no(self, res):
        invoice_no_obj = self.env['invoice.no.tax.invoice']
        tax_invoice_line_ids = res.mapped('invoice_line_ids')
        invoice_line_ids = self.invoice_line_ids

        partner_ids = res.mapped('partner_id').ids
        partner_ids = list(set(partner_ids))
        if len(partner_ids) > 1:
            raise UserWarning('You must select same partner.')

        invoice_id = invoice_no_obj.search([('name', '=', self.tax_invoice_no)])

        # 搜索到就修改更新，没有找到才创建
        if invoice_id:
            # Update
            invoice_id.write({
                'invoice_line_ids': [(4, line_id.id) for line_id in invoice_line_ids],
                'tax_invoice_line_ids': [(4, line_id.id) for line_id in tax_invoice_line_ids]
            })
        else:
            # Create
            invoice_no_obj.create({
                'name': self.tax_invoice_no,
                'partner_id': partner_ids[0] if partner_ids else False,
                'invoice_line_ids': [(6, 0, invoice_line_ids.ids)],
                'tax_invoice_line_ids': [(6, 0, tax_invoice_line_ids.ids)] if tax_invoice_line_ids else False
            })

    # 如果结算清单已经存在发票批次号，就不能使用新的批次号
    def _judge_invoice_no(self):
        res = self.env['invoice.no.tax.invoice'].search([
            ('tax_invoice_line_ids.invoice_line_id', 'in', self.invoice_line_ids.ids)
        ])

        if not res:
            return True

        # 理论上这样的记录不能超过1
        if len(res) > 1:
            raise UserError(_('You can\'t create multi different invoice no tax invoice with same invoice'))

        if res.name != self.tax_invoice_no:
            raise UserError(_('There are already exist tax invoice, you must use the same tax invoice no!'))


#!/bin/python3

import math
import os
import random
import re
import sys

# Complete the sockMerchant function below.
def sockMerchant(n, ar):
    import collections

    c = collections.Counter(ar)
    num = 0
    for elem in c.values():
        if elem != 1:
                num += elem // 2
    return num

if __name__ == '__main__':
    fptr = open(os.environ['OUTPUT_PATH'], 'w')

    n = int(input())

    ar = list(map(int, input().rstrip().split()))

    result = sockMerchant(n, ar)

    fptr.write(str(result) + '\n')

    fptr.close()


BASIC_PARAMETERS_WORKSHEET_NAME = 'basic_parameters'
MIDI_POS_NAME = 'midi_pos'
DG_PROBS_NAME = 'group_probs'
NUDGE_AMT_NAME = 'nudge_amt'

import ast
import copy
import json
import random
from time import gmtime, strftime

import numpy as np
import pandas as pd
from midiutil import MIDIFile

class ChanceEntry:
    attributes = ['prob_hit', 'min_vol', 'max_vol', 'duration']

    def __init__(self):
        self.prob_hit = 0
        self.min_vol = 0
        self.max_vol = 0
        self.duration = 1

class BasicParameters:

    def __init__(self):
        self.map_worksheet_name = None
        self.hits_worksheet_name = None
        self.measures = None
        self.beats = None
        self.pulses = None
        pass

    # Example of json_data:
    # '{"map_worksheet_name": "midi_map", "hits_worksheet_name": "hits", "measures": 1, "beats": 4, "pulses": 4}'
    def from_json(self, json_data):
        # This is, by far, the most Python magic thing I've ever done.  The dictionary merge isn't all that big of
        # a deal, but loading back into the __dict__ attribute is.  This monkey-patches the JSON elements in as class
        # attributes (properties).  It avoids a bunch of boilerplate logic at the risk of (dramatically) reducing
        # readability.  Not sure if this is Pythonic; might be better served using the *args, **kwargs style packing.
        # It sure feels super dangerous
        self.__dict__ = {**self.__dict__, **json.loads(json_data)}

    def from_worksheet(self, path, sheet_name='basic_parameters'):
        _ = pd.read_excel(path, sheet_name)
        self.from_json(list(_.to_dict().keys())[0])

    @property
    def pulse_length(self):
        return 1 / self.pulses

    @property
    def pulses_per_measure(self):
        return self.beats * self.pulses

    @property
    def pulse_keys(self):
        # Pulse markers in the measure
        return [i / self.pulses for i in range(self.pulses_per_measure)]

def default_midi_map():
    # Maps Rock 32 Pad DW Live drum kit
    _ = {
        'g1': {MIDI_POS_NAME: [36, 37], DG_PROBS_NAME: [0.5, 0.5], NUDGE_AMT_NAME: 1},
        'g2': {MIDI_POS_NAME: [40, 41, 42, 43], DG_PROBS_NAME: [0.55, 0.25, 0.1, 0.1], NUDGE_AMT_NAME: 3},
        'g3': {MIDI_POS_NAME: [44, 45, 46, 47], DG_PROBS_NAME: [0.6, 0.2, 0.1, 0.1], NUDGE_AMT_NAME: 1},
        'g4': {MIDI_POS_NAME: [48, 49], DG_PROBS_NAME: [0.5, 0.5], NUDGE_AMT_NAME: 2}
    }
    return pd.DataFrame.from_dict(_, orient='index')

class ConfigFileGenerator:

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

    def write_file(self, path):
        writer = pd.ExcelWriter(path, engine='xlsxwriter')

        # Add the high level parms to the first cell of a known worksheet
        pd.DataFrame().to_excel(writer, startrow=4, startcol=0, sheet_name=BASIC_PARAMETERS_WORKSHEET_NAME)
        worksheet = writer.sheets[BASIC_PARAMETERS_WORKSHEET_NAME]
        worksheet.write(0, 0, json.dumps(self.config.__dict__))

        # Add the drum group definitions
        default_midi_map().to_excel(writer, sheet_name=self.config.map_worksheet_name)

        # Add the empty hits
        self.default_drum_hits().to_excel(writer, sheet_name=self.config.hits_worksheet_name)

        writer.save()
        writer.close()
        print('Created ' + path)

    def default_drum_hits(self):
        # Create a set of drum group names
        drum_groups = ['g' + str(i) for i in range(1, 5)]

        # Expand for all groups for all attributes
        column_headers = [dg + '_' + a for dg in drum_groups for a in ChanceEntry.attributes]

        # Add the pulse keys for the first column
        hits = pd.DataFrame(index=self.config.pulse_keys)

        # Add all the attribute columns
        hits = pd.concat([hits, pd.DataFrame(columns=column_headers)])

        # Default empty values to 0 and return
        return hits.fillna(0)

class MIDINote:

    def __init__(self, pitch=0, start=0, duration=0, volume=0, track=0, channel=0):
        self.track = track
        self.channel = channel
        self.pitch = pitch
        self.start = start
        self.duration = duration
        self.volume = volume

class DrumGroup:

    def __init__(self):
        self.midi_pitches = []
        self.midi_probs = []
        self.nudge_amt = 0

class MIDIFileGenerator:

    def __init__(self):
        self.config = BasicParameters()
        self.drum_groups = {}
        self.drum_probs = None

    def do(self, path):
        self.config.from_worksheet(path)
        self.read_data(path)
        # _ = self.generate_midi_notes()
        _ = self.generate_midi_notes_2()
        self.write_midi_file(_)

    def read_data(self, path):
        # Read data from the midi map worksheet
        _ = pd.read_excel(path, sheet_name=self.config.map_worksheet_name, index_col=0)
        for drum_group_name in _.index:
            # Load the data into a DrumGroup dictionary
            dg = DrumGroup()
            dg.midi_pitches = ast.literal_eval(_[MIDI_POS_NAME][drum_group_name])
            dg.midi_probs = ast.literal_eval(_[DG_PROBS_NAME][drum_group_name])
            dg.nudge_amt = _[NUDGE_AMT_NAME][drum_group_name]
            self.drum_groups[drum_group_name] = dg

        # Read data from the probability matrix, as it were
        _ = pd.read_excel(path, sheet_name=self.config.hits_worksheet_name, index_col=0).fillna(0)
        # Load the data into a dictionary of ChanceEntries
        self.drum_probs = {drum_group_name + str(r): ChanceEntry()
                           for drum_group_name in self.drum_groups.keys() for r in list(_.index)}
        for index, row in _.iterrows():
            for drum_group_name in self.drum_groups.keys():

                # Reference to the specific chance entry object
                entry = self.drum_probs.get(drum_group_name + str(row.name))

                for a in ChanceEntry.attributes:
                    # Set the attribute value
                    setattr(entry, a, row[drum_group_name + '_' + a])

    def generate_midi_notes_2(self):
        _ = {}
        for i in range(0, 2):
            _ = {**_, **(self.generate_midi_notes_2a(i * 4))}
        return _

    def generate_midi_notes_2a(self, base_measure):
        first_measure = self.build_measure_precursor(base_measure)
        _ = copy.deepcopy(first_measure)

        for i in range(1, 4):
            _ = {**_, **(self.duplicate(first_measure, i))}

        last_measure = self.build_measure_precursor(base_measure)
        self._shift_timing(last_measure, 4)
        _ = {**_, **last_measure}

        return _

    def build_measure_precursor(self, measure_number):
        all_notes = {}

        for drum_group_name, drum_group in self.drum_groups.items():
            notes = self.build_measure_for_dg(measure_number, drum_group_name, drum_group)

            if len(notes) > 0:
                # Drum group, measure number, and pulse key
                group_key = drum_group_name + '_m' + str(1)
                all_notes[group_key] = notes

        return all_notes

    def duplicate(self, notes, shift_amount):
        new_notes = copy.deepcopy(notes)
        new_notes = {k + '_s' + str(shift_amount): v for k, v in new_notes.items()}
        self._shift_timing(new_notes, shift_amount)
        return new_notes

    def _shift_timing(self, notes, shift_amount):
        for nl in notes.values():
            for n in nl:
                n.start = n.start + ((shift_amount - 1) * self.config.beats)

    def generate_midi_notes(self):
        all_notes = {}

        # TODO Generate and hold a pattern?  Let other drums revolve around a fixed point
        for measure in range(self.config.measures):

            for drum_group_name, drum_group in self.drum_groups.items():
                notes = self.build_measure_for_dg(measure, drum_group_name, drum_group)

                if len(notes) > 0:
                    # Drum group, measure number, and pulse key
                    group_key = drum_group_name + '_m' + str(measure)
                    all_notes[group_key] = notes

        return all_notes

    def build_measure_for_dg(self, measure_number, drum_group_name, drum_group):
        notes = []

        for pulse in self.config.pulse_keys:
            chance_key = drum_group_name + str(pulse)
            drum_chance = self.drum_probs.get(chance_key)

            if random.random() <= drum_chance.prob_hit:
                notes.append(self.build_note(drum_group, drum_chance, measure_number, pulse))

        return notes

    def build_note(self, drum_group, drum_chance, measure_number, pulse):
        n = MIDINote()
        n.pitch = self.choose_pitch(drum_group)
        measure_adjusted_pulse = pulse + (measure_number * self.config.beats)
        n.start = self.generate_start_time(drum_group, measure_adjusted_pulse, laidback=False)
        n.duration = self.generate_duration(drum_chance, measure_adjusted_pulse, n.start)
        n.volume = self.choose_volume(drum_chance)
        return n

    def choose_pitch(self, drum_group):
        # Choose which drum from set of drum groups based on stated probabilities
        pitch_pos = np.random.choice(np.arange(0, len(drum_group.midi_probs)), p=drum_group.midi_probs)
        return drum_group.midi_pitches[pitch_pos]

    def generate_start_time(self, drum_group, measure_adjusted_pulse, laidback):
        # Nudge off the grid, but can't be negative after the nudge
        return max(measure_adjusted_pulse + self.nudge(drum_group.nudge_amt, laidback), 0)

    def generate_duration(self, drum_chance, measure_adjusted_pulse, start):
        # Cap the length so that it doesn't run into the next measure
        return min(drum_chance.duration * self.config.pulse_length,
                   (measure_adjusted_pulse + self.config.pulse_length) - start)

    def choose_volume(self, drum_chance):
        # Range bound random volume
        return random.randint(drum_chance.min_vol, drum_chance.max_vol)

    def write_midi_file(self, notes):
        now = gmtime()
        midi_content = MIDIFile(1)
        midi_content.addTrackName(0, 0, strftime("%#m/%d %H:%M:%S", now))

        # filtered_notes = {k: notes[k] for k in notes.keys() if any(xk in k for xk in ['g2', 'g3', 'g4'])}
        filtered_notes = notes
        [[midi_content.addNote(n.track, n.channel, n.pitch, n.start, n.duration, n.volume) for n in v]
         for v in filtered_notes.values()]

        with open('c:/temp/' + strftime("%Y%m%d %H%M%S", now) + '.mid', "wb+") as _:
            midi_content.writeFile(_)
            _.close()

    def nudge(self, time=0, laidback=False):
        return 0 if time == 0 else random.randrange((0 if laidback else -1 * time), time) * 0.01


import time,socket,threading,datetime, json

# Set the UPD port here
UDP_PORT = 6006
# Set the debug level, 0 = no debug messages, 1 = UDP messages, 2 = inverter messages, 3 = both
DEBUG = 1

# Declare variables
data = '' # empty var for incoming data
y = []
rec = 0

# UDP setup for listening
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
sock.setblocking(1)
sock.bind(('', UDP_PORT))
#Set console color for easier UDP income reading
CRED = '\033[91m'
CEND = '\033[0m'

while True:
    data_raw, addr = sock.recvfrom(1024)
    data = data_raw.decode()    # My test message is encoded
    if DEBUG == 1 or DEBUG == 3:
        print(f"{CRED}{datetime.datetime.now().time()} UDP MESSAGE: {data}{CEND}")
    if data:                                                 # only do something when there's data
        decode_list = data.split()                              # byte decode the incoming list and split in two
        if decode_list[0].startswith("REC") and rec == 0:                    # if the first part of the list starts with "rec"
            print(decode_list[0],decode_list[1])                    # for debug purposes
            t0 = time.time()                                        # start the timer
            f = open(decode_list[1], 'w')                           # open or new file with the chosen file in the Max4Live patch
            rec = 1
        elif decode_list[0].startswith("BOARD") and rec == 1:   # if the first part of the list starts with "board"
            t1 = time.time() - t0                                   # see how much time elapsed since the beginning of rec
            udp_value = int(decode_list[1])
            if udp_value >= 1:                                  # if the incoming value really represents an input
                print(round(t1, 3), decode_list[0],decode_list[1])                # for debug purposes
                x = {                                                   # build a dict with the info from UDP
                    "time": round(t1, 3),
                    "values": {
                        "port": decode_list[0],
                        "value": udp_value
                        }
                    }
                y.append(x)                                             # append the dict to the list
        elif decode_list[0].startswith("stop"):                 # if the list starts with "stop"
            rec = 0
            json_dump = json.dumps(y, sort_keys=True, ensure_ascii=False) #transfer the list of dicts into a json format
            f.write(json_dump)                                      # write it to the file opened in "rec"
            f.close()                                               # close the file
            print("done writing file")
            print(decode_list[0],decode_list[1])                    # debug purposes
        elif decode_list[0].startswith("exit"):                 # if the list starts with "exit"
            sock.close()                                            # close the socket
            exit()


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

"""
Beta MA No.1

信号1 趋势中
信号2 大周期接近均线
信号3 小周期影线和成交量达到要求

"""
import json

from ..okx.AccountAndTradeApi import AccountAndTradeApi
from ...models import AccountInfo, Strategy, PlaceAlgo
import pandas as pd

import time
from ..basetrade.basetrade import BaseTrade

import re

class NewInstId(BaseTrade):
    def __init__(self, api_key=None, secret_key=None, passphrase=None, use_server_time=False, flag='1', **kwargs):
        super().__init__(api_key, secret_key, passphrase, use_server_time, flag, logfile=kwargs.get('logfile', None))
        self.df = None
        self.df_3mins = None
        self.stop_loss = 0
        self.flag = flag
        self.instId = kwargs.get('instId')
        self.slTriggerPx = kwargs.get('slTriggerPx')
        self.tpTriggerPx = kwargs.get('tpTriggerPx')
        self.sz = kwargs.get('sz')

        self.trader = kwargs.get('trader')
        self.accountinfo_obj = kwargs.get('accountinfo')
        self.strategy_obj = self.init_strategy(kwargs.get('strategy_obj'))
        self.all_accountinfo_data_list = None
        self.orderinfo_obj = None
        self.side_type = {"buy": "long", "sell": "short"}
        self.side = "buy"
        self.posSide = 'long'
        self.lever = "1"
        self.last_price = ''
        self.availPos = None
        self.avgpx = None
        self.signal_info_dict = {}

    def init_strategy(self, strategy_obj):
        strategy_obj.instid = self.instId
        strategy_obj.save()
        return strategy_obj

    def start_my_trade(self):
        self.all_accountinfo_data_list = self.set_initialization_account_all_by_newinstid(self.strategy_obj.accountinfo,
                                                                             self.strategy_obj.name,
                                                                             self.strategy_obj.instid,
                                                                             lever="1",
                                                                             )
        if not self.all_accountinfo_data_list:
            self.log.info('no account info data')
            return
        if self.strategy_obj.status < 5:
            self.track_trading_status(1)

        self.ready_order()

        for accountinfo in self.all_accountinfo_data_list:
            obj = accountinfo['obj']
            obj.status = 0
            obj.save()

    def ready_order(self):
        para = {
            "instId": self.instId,
            "tdMode": self.tdMode,
            "ccy": 'USDT',
            'side': "buy",
            'ordType': 'market',
            'px': '',
        }
        place_order_code = False
        place_order_error_code = False
        placc_algo_order_info_list = []
        for accountinfo in self.all_accountinfo_data_list:
            orderinfo_dict = {}
            obj = accountinfo['obj']
            obj_api = accountinfo['obj_api']
            orderinfo_dict['lever'] = self.lever
            para['sz'] = self.sz
            orderinfo_dict.update(para)
            while True:
                result = obj_api.tradeAPI.place_order(**para)
                ordId, sCode, sMsg = self.check_order_result_data(result, 'ordId')
                print(sMsg)
                if "Instrument ID doesn't exist" != sMsg:
                    break

            if sCode == "0":
                accountinfo['status'] = 2
                place_order_code = True
                # 获取持仓信息
                # self.get_order_details(self.instId, ordId)
                self.has_order = self.get_positions(instType='MARGIN')
                self.order_times += 1
                print('%s 开仓成功！！！！！！' % obj.account_text)
                self.log.info('%s 开仓成功！！！！！！' % obj.account_text)
                # self.track_trading_status(5)

                if self.order_lst:
                    self.avgpx = float(self.order_lst[0].get('avgPx'))
                    self.availPos = float(self.order_lst[0].get('availPos'))    # 可平仓数量，
                    orderinfo_dict['order_ctime'] = self.timestamp_to_date(self.order_lst[0].get('cTime'))
                    orderinfo_dict['order_utime'] = self.timestamp_to_date(self.order_lst[0].get('uTime'))
                else:
                    result = self.marketAPI.get_ticker(self.instId)
                    for data in result.get('data'):
                        self.last_price = data.get("last")
                    self.avgpx = self.last_price

                orderinfo_dict['ordId'] = ordId
                orderinfo_dict['avgPx'] = self.avgpx

                # 设置止损止盈
                algo_para = self.set_place_algo_order_oco(obj_api, self.sz)
                algo_para['orderid'] = ordId
                algo_para['accountinfo_id'] = obj.id
                algo_para['instid'] = self.instId
                placc_algo_order_info_list.append(algo_para)
                orderinfo_dict.update(algo_para)
                orderinfo_dict['posside'] = self.posSide
                orderinfo_dict['side'] = self.side
                self.has_order = True
            else:
                place_order_error_code = True
                # self.track_trading_status(-1)
                msg = '%s 账户异常！！！开仓失败！！！！！！' % obj.account_text
                accountinfo['status'] = -1
                accountinfo['msg'] = msg
                self.log.error(msg)
                self.has_order = False
            accountinfo['orderinfo'] = orderinfo_dict

        if place_order_code:
            self.has_order = True
            self.track_trading_status(5)
            # 发消息提示
            # self.send_msg_to_me(self.trader)
        if place_order_error_code:
            self.track_trading_status(6)

        # 保存订单信息
        for accountinfo in self.all_accountinfo_data_list:
            orderinfo_dict = accountinfo['orderinfo']
            orderinfo_dict['strategyid'] = self.strategy_obj.id
            accountinfo_obj = accountinfo['obj']

            # 保存订单信
            orderinfo_obj = self.set_trading_orderinfo(accountinfo_obj, **orderinfo_dict)
            accountinfo['orderinfo_obj'] = orderinfo_obj

            # 保存账户状态
            accountinfo_obj.status = accountinfo['status']
            accountinfo_obj.save()

        # 保存策略信息
        self.signal_info_dict['posSide'] = self.posSide
        self.signal_info_dict['instId'] = self.instId
        self.signal_info_dict['side'] = self.side
        self.signal_info_dict['avgPx'] = self.avgpx
        self.signal_info_dict['stop_loss_price'] = self.slTriggerPx
        self.set_strategy_info(self.signal_info_dict)

        # 保存委托订单信息
        for item in placc_algo_order_info_list:
            new_dict = {}
            for i, j in item.items():
                # 把key转小写
                new_dict[i.lower()] = j
            algo = PlaceAlgo(**new_dict, strategyid=self.strategy_obj.id)
            try:
                algo.save()
            except Exception as e:
                print(e)

    def track_trading_status(self, status=0, update_status=True):
        strategy_obj = Strategy.objects.get(pk=self.strategy_obj.id)
        if strategy_obj.status in (0, -2):
            self.log.info('已强行停止策略')
            raise Exception('已强行停止策略')
        if update_status:
            self.strategy_obj.status = status
            self.strategy_obj.save()
            self.log.info('更新运行状态--%s--' % status)

    def set_strategy_info(self, data):
        signalinfo = self.strategy_obj.signalinfo
        if signalinfo:
            try:
                signalinfo = json.loads(signalinfo)
            except Exception as e:
                pass
                # self.log.info(e)
                # self.log.info(signalinfo)
            if isinstance(signalinfo, list):
                signalinfo.append(data)
            else:
                signalinfo = [data]
        else:
            signalinfo = [data]
        self.strategy_obj.signalinfo = signalinfo
        self.strategy_obj.save()

    def set_place_algo_order_oco(self, obj_api, sz):
        side = 'sell'
        self.tpTriggerPx = float(self.avgpx) * float(self.tpTriggerPx) if self.tpTriggerPx else float(self.avgpx) * 5
        self.slTriggerPx = float(self.avgpx) * float(self.slTriggerPx) if self.slTriggerPx else float(self.avgpx) * 0.7
        price_para = {
            "tpTriggerPx": self.tpTriggerPx,
            "tpOrdPx": "-1",
            "slTriggerPx": self.slTriggerPx,
            "slOrdPx": "-1"
        }
        try:
            result = obj_api.tradeAPI.place_algo_order(self.instId, self.tdMode, side, ordType=self.ordType,
                                                       sz=self.availPos, **price_para, ccy='USDT',
                                                       tpTriggerPxType='last', slTriggerPxType='last')
        except Exception as e:
            self.log.error("委托单错误")
            self.log.error(e)
            return
        algoId, sCode, msg = self.check_order_result_data(result, "algoId")
        if sCode == "0":
            # 事件执行结果的code，0代表成功
            status = 1
            self.log.info("止损止盈设置成功 市价委托")
            try:
                result = obj_api.tradeAPI.order_algos_list(ordType=self.ordType, algoId=algoId, instType='SWAP')
                price_para['algo_ctime'] = self.timestamp_to_date(result.get('data')[0].get('cTime'))
            except Exception as e:
                self.log.error(e)
        else:
            # 可能是止损设置错误
            status = -1
            msg = "止损止盈设置错误，，，%s, 止损：%s, 止盈：%s, 现价：%s" % (
                msg, self.slTriggerPx, self.tpTriggerPx, self.last_price)
            self.log.error(msg)

        price_para['algoid'] = algoId
        price_para['posside'] = self.posSide
        price_para['side'] = side
        price_para['sz'] = sz
        price_para['scode'] = sCode
        price_para['smsg'] = msg
        price_para['status'] = status
        return price_para

    def set_initialization_account_all_by_newinstid(self, all_accountinfo, strategy_name, instid, interval=0.2, lever='50',
                                       mgnMode='cross'):
        # 初始化状态， 设置倍数， 账户状态。
        all_accountinfo_obj = AccountInfo.objects.filter(pk__in=all_accountinfo)
        all_accountinfo_data_list = []
        for obj in all_accountinfo_obj:
            if interval:
                time.sleep(interval)
            accountinfo_data = {}
            try:
                obj_api = AccountAndTradeApi(obj.api_key, obj.secret_key, obj.passphrase, False, obj.flag)
                # try:
                #     result = self.accountAPI.set_leverage(instId=self.instId, lever=lever, mgnMode=mgnMode)
                #     result = self.accountAPI.get_position_mode('long_short_mode')
                # except Exception as e:
                #     print(e)
                #     print('初始化账户 error')
                balance = obj_api.get_my_balance('availEq')
                obj.balance = float(balance)
                if obj.init_balance == -1:
                    obj.init_balance = float(balance)
                obj.strategy_name = strategy_name
                obj.status = 1
                accountinfo_data['id'] = obj.id
                accountinfo_data['name'] = obj.account_text
                accountinfo_data['balance'] = balance
                accountinfo_data['obj'] = obj
                accountinfo_data['obj_api'] = obj_api
                all_accountinfo_data_list.append(accountinfo_data)
            except Exception as e:
                obj.status = -1
                self.log.error('set_initialization_account_all error')
                self.log.error(e)
            obj.save()
        return all_accountinfo_data_list


import os
import sys
import glob
import re

import pickle as pkl

import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
from matplotlib.backends.backend_pdf import PdfPages

import numpy as np
from scipy.spatial.distance import cdist

# from sklearn.preprocessing import StandardScaler
from sklearn.decomposition import PCA
from sklearn.cluster import KMeans
from sklearn.metrics import silhouette_score

from scipy.spatial import Voronoi, voronoi_plot_2d
from voronoi_2d import voronoi_finite_polygons_2d

if len(sys.argv) < 2 or '-s' not in sys.argv:
	from imageio import imread

	import tensorflow as tf
	from keras.models import load_model
	from keras import backend as K

	import nnFactory as Factory

# silence tf compile warnings
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'

ACTIONS = 3
STATE_DIMENSIONS = (40, 40, 3)

NUM_SLICES = 10

PLOT_WIDTH = 0.25
FILENAME_PATTERN = 'actor_trial_'

IMAGE_TYPES =  ['left', 'right', 'forward']

num_images = 0

COLORMAP = ['tab:blue', 'tab:orange', 'tab:green', 'tab:red', 'tab:purple', 'tab:brown', 'tab:pink', 'tab:gray', 'tab:olive', 'tab:cyan']
MARKERMAP = ['o', 's', '^', '*', 'X', 'H']

# populate image lists so we can test these images later
# image lists must all have the same number of images
image_type_list = []
image_file_list = []
image_dict = {}
for image_type in IMAGE_TYPES:
	image_dict[image_type] = []
	num_images = 0
	for image_filename in glob.iglob('camera/' + image_type + '/*.png'):
			image_type_list.append(image_type)
			image_file_list.append(image_filename)
			image_dict[image_type].append(image_filename)
			num_images += 1

def setup_matplotlib():
	font = {'family' : 'League Spartan',
		'weight' : 'bold',
		'size' : '24'}
	plt.rc('font', **font)
	from matplotlib import rcParams
	rcParams.update({'figure.autolayout': True})
	plt.tight_layout()

# given a model, actually compute the actions for each image
def test_network(model, imagefiles_list):
	action_list = []
	for image_filename in imagefiles_list:

		img = imread(image_filename, as_gray=False, pilmode="RGB")
		img = img / np.max(img)

		graph = tf.get_default_graph()

		with graph.as_default():
				model._make_predict_function()
				K.set_learning_phase(0)

				action = np.reshape(model.predict(np.expand_dims(img, axis=0)), ACTIONS)

		if np.any(np.isnan(action)):
				raise ValueError("Net is broken!")

		# Actions:
		# Forward, Left (lateral), Left Rotation
		# x0.03, x0.03, x90*

		action_list.append(action)

	return action_list

def get_masks(original_weights):
	mask_list = []

	# for each group of neurons, create a mask dropping out that group
	SLICE_SIZE = 100 // NUM_SLICES
	for n in range(NUM_SLICES):
		mask_ = []
		for layer in original_weights:
			if layer.shape == (200, 100):
				# set weights to zero
				layer = np.ones_like(layer)
				n_ = n*SLICE_SIZE
				layer[:, n_:(n_ + SLICE_SIZE)] = 0
				mask_.append(layer)
			elif layer.shape == (100,):
				# set biases to zero
				layer = np.ones_like(layer)
				n_ = n*SLICE_SIZE
				layer[n_:(n_ + SLICE_SIZE)] = 0
				mask_.append(layer)
			else:
				mask_.append(np.ones_like(layer))
		mask_list.append(mask_)

	return mask_list

def num_to_color(arr):
	new_arr = []
	for item in arr.tolist():
		if item == 0:
			new_arr.append((0, 1, 0))
		else:
			new_arr.append((item, 0, 1 - item))
	return new_arr

def plot_actions(pdf, actions, action_max, title, colors=None, zero_index=True, y_label="Output"):
	font = {'family' : 'League Spartan',
		'weight' : 'bold'}
	plt.rc('font', **font)

	ind = np.arange(len(actions))
	if not zero_index:
		actions = np.delete(actions, (0), axis=0)
		if colors is not None:
			colors = np.delete(colors, (0), axis=0)
		ind = np.arange(len(actions)) + 1

	if colors is None:
		color_0 = ['#ea4626'] * len(actions)
		color_1 = ['#0060ff'] * len(actions)
	else:
		color_0 = num_to_color( np.abs(colors[:, 0] / action_max) )
		color_1 = num_to_color( np.abs(colors[:, 1] / action_max) )

	ax = plt.subplot(111)

	# use subplots2grid to add the images

	# plt.figure().imshow(plt.imread(image_filename), extent=[-0.5, 0.5, np.max(old_action) + PLOT_WIDTH, np.max(old_action) + 4*PLOT_WIDTH])

	ax.grid(color='#bbbbbb', linestyle='solid', linewidth=1)
	ax.set_axisbelow(True)

	ax.bar(ind - (PLOT_WIDTH / 2), actions[:, 0], width=PLOT_WIDTH, align='center', color=color_0)
	ax.bar(ind + (PLOT_WIDTH / 2), actions[:, 1], width=PLOT_WIDTH, align='center', color=color_1)

	ax.set_xlabel('Ablation Group')
	ax.set_ylabel(y_label)
	ax.set_xticks(range(1, 11))

	# ax2 = plt.figure().add_axes([0, 0.9, 0.1, 0.1])
	# ax2.imshow(plt.imread(image_filename))

	plt.title(title)
	pdf.savefig()
	plt.clf()

def test_network_knife(model, network_file_path, imagefiles_list, imagetypes_list):

	imagefiles_list = np.array(imagefiles_list)
	imagetypes_list = np.array(imagetypes_list)

	model.load_weights(network_file_path)

	original_weights = np.copy(model.get_weights())

	# test the network on the unmodified model as a baseline for comparison
	orig_actions = test_network(model, imagefiles_list)

	# for each group of neurons, create a mask dropping out that group
	mask_list = get_masks(original_weights)

	# calculate the actions for each mask
	# create a list with an inner list for each image
	new_action_array = [] # actions for each mask after it's applied
	for image_idx in range(len(orig_actions)):
				new_action_array.append([])

	all_differences = []
	trial_results = []
	# calculate each new action, then save in the arrays
	for mask_num, mask in enumerate(mask_list):
		trial_results.append([])

		new_weights = np.copy(original_weights)
		new_weights *= mask

		model.set_weights(new_weights)

		for imgtype_num, image_type in enumerate(IMAGE_TYPES):
			local_imagefiles = imagefiles_list[imagetypes_list == image_type]
			trial_results[mask_num].append([])

			new_actions = test_network(model, local_imagefiles)

			differences = []
			for image_idx, new in enumerate(new_actions):
				new_action_array[image_idx + imgtype_num * num_images].append(new.tolist())
				differences.append(new.tolist() - orig_actions[image_idx])

			# remove the 'forward' action, just focusing on the turns
			differences = np.array(differences)[:, 1:]
			# calculate the mean across all the images (in the group)
			# trial_results[mask_num][imgtype_num] = np.mean(differences, axis=0).tolist()
			trial_results[mask_num][imgtype_num] = np.array(new_actions)[:, 1:].tolist()
			all_differences.append(differences)

	action_max = np.max(np.abs(np.array(all_differences)))

	# visualize the new actions compared to the old
	# with PdfPages(re.sub('\..+', '.pdf', network_file_path)) as pdf:
	# 	for image_idx, image_filename in enumerate(image_file_list):

	# 		old_action = orig_actions[image_idx]
	# 		new_actions = new_action_array[image_idx]

	# 		# calculate the norm between each new action and the old action for coloring
	# 		differences = [[0, 0, 0]]
	# 		for new in new_actions:
	# 			differences.append(new - old_action)

	# 		actions = np.delete(np.array([old_action] + new_actions), 0, axis=1)
	# 		differences =  np.delete(np.array(differences), 0, axis=1)

	# 		plot_actions(pdf, actions, action_max, "Image " + str(image_idx + 1) + " (" + imagetypes_list[image_idx] + ")", colors=differences)
	# 		plot_actions(pdf, differences, action_max, "Image " + str(image_idx + 1), zero_index=False, y_label='Output Change (Action Space)')

	# for the entire trial, we've calculated the differences between the unmodified network and each network with different parts cut out.
	return (np.array(trial_results), np.array(orig_actions))

def get_colors(labels):
	colors = []
	for i in range(len(labels)):
		colors.append(COLORMAP[(int(labels[i]))])
	return colors

def get_markers(labels):
	# print(labels)
	markers = []
	for i in range(len(labels)):
		markers.append(MARKERMAP[(int(labels[i]))])
	# print(markers)
	return markers

def plot_3_2d(x, colors):
	fig = plt.figure(figsize=plt.figaspect(1/3))
	ax = fig.add_subplot(1, 3, 1)
	ax.scatter(x[:, 0], x[:, 1], c=colors)
	ax.set_xlabel('left')
	ax.set_ylabel('left_rotation')
	ax.set_title(IMAGE_TYPES[0])
	ax = fig.add_subplot(1, 3, 2)
	ax.scatter(x[:, 2], x[:, 3], c=colors)
	ax.set_xlabel('left')
	ax.set_ylabel('left_rotation')
	ax.set_title(IMAGE_TYPES[1])
	ax = fig.add_subplot(1, 3, 3)
	ax.scatter(x[:, 4], x[:, 5], c=colors)
	ax.set_xlabel('left')
	ax.set_ylabel('left_rotation')
	ax.set_title(IMAGE_TYPES[2])

	plt.show()

def save_plot_2d(filename, x, colors, size=100, markers=None, title='', cluster_centers=None, xlabel=None, ylabel=None):

	setup_matplotlib()
	fig = plt.figure(figsize=(1024/128, 1024/128), dpi=128)

	if len(x[0]) > 2: # use pca to remove extra dims
		pca = PCA(n_components=2)
		x = pca.fit_transform(x)
		xlabel = 'First Principal Component'
		ylabel = 'Second Principal Component'

	colors = np.array(colors)

	ax = fig.add_subplot(1, 1, 1)
	if markers is None:
		ax.scatter(x[:, 0], x[:, 1], c=colors, s=size)
	else:
		for m in np.unique(markers):
			this_trial = [m == mark for mark in markers]
			ax.scatter(x[this_trial, 0], x[this_trial, 1], c=colors[this_trial], marker=m, s=size)

	ax.set_xlabel(xlabel)
	ax.set_ylabel(ylabel)
	ax.set_title(title)

	if cluster_centers is not None:
		xlim = ax.get_xlim()
		ylim = ax.get_ylim()

		cluster_centers = pca.transform(cluster_centers)

		vor = Voronoi(cluster_centers)
		regions, vertices = voronoi_finite_polygons_2d(vor, 10)

		for region in regions:
			polygon = vertices[region]
			plt.fill(*zip(*polygon), alpha=0.15)

		plt.xlim(xlim)
		plt.ylim(ylim)

	plt.savefig(filename, dpi=128)

def plot_3d(x_list, c_list, t_list, use_pca):
	if len(x_list) != len(c_list) or len(c_list) != len(t_list):
		print('plot_3d: Length of x, color, and title lists must be the same')

	if len(x_list) > 1:
		fig = plt.figure(figsize=plt.figaspect(1 / len(x_list)))
	else:
		fig = plt.figure(figsize=(1024, 1024))

	for i, (x, colors, title) in enumerate(zip(x_list, c_list, t_list)):
		ax = fig.add_subplot(1, len(x_list), i+1, projection='3d')
		ax.scatter(x[:, 0], x[:, 1], x[:, 2], c=colors)
		if not use_pca:
			ax.set_xlabel(IMAGE_TYPES[0])
			ax.set_ylabel(IMAGE_TYPES[1])
			ax.set_zlabel(IMAGE_TYPES[2])
		ax.set_title(title)

	plt.show()

def plot_results(x, cluster_labels, trial_labels, cluster_centers=None, use_pca=True):
	setup_matplotlib()

	cluster_colors = get_colors(cluster_labels)
	trial_colors = get_colors(trial_labels)
	trial_markers = get_markers(trial_labels)

	if use_pca:
		pca = PCA(n_components=3)
		x_pca = pca.fit_transform(x)
		# print(pca.explained_variance_ratio_.cumsum())
		# print(pca.components_)
	else:
		x = np.mean(x.reshape(len(trial_colors), 6, num_images), axis=2)

	if use_pca:
		x_list = [x_pca, x_pca]
		c_list = [cluster_colors, trial_colors]
		t_list = ['cluster labels', 'trial labels']
	else:
		# plot_3_2d(x, cluster_colors)
		# plot_3_2d(x, trial_colors)

		x_list = [x[:, :3], x[:, :3], x[:, 3:], x[:, 3:]]
		c_list = [cluster_colors, trial_colors, cluster_colors, trial_colors]
		t_list = ['cluster labels, x 0-2', 'trial labels, x 0-2', 'cluster labels, x 3-6', 'trial labels, x 3-6']

	# plot_3d(x_list, c_list, t_list, use_pca)
	save_plot_2d('graphs/network_knife_ours.png', x, cluster_colors, markers=trial_markers, cluster_centers=cluster_centers)

def match_data(trial_results_arr, orig_actions_arr, trials):
	# print(np.array(trial_results_arr).shape)
	NUM_TRIALS = len(trials)
	# num_clusters = 6 # value of 6 always gets the highest silhouette score

	trial_labels = np.zeros((NUM_TRIALS, NUM_SLICES))
	for i in range(NUM_TRIALS):
		trial_labels[i, :] = i
	trial_labels = trial_labels.reshape(NUM_TRIALS * NUM_SLICES,)

	trial_results_arr = np.array(trial_results_arr).reshape(NUM_TRIALS * NUM_SLICES, 6 * num_images)
	trial_results_scaled = np.copy(trial_results_arr)

	for trial_num in range(NUM_TRIALS):
		trial_results_scaled[trial_labels == trial_num] -= np.mean(trial_results_scaled[trial_labels == trial_num], axis=0)
		# trial_results_scaled is now centered around the mean
		trial_results_scaled[trial_labels == trial_num] /= np.max(np.abs(trial_results_scaled[trial_labels == trial_num]), axis=0)
		# trial_results_scaled is now between 1 and -1

	# print("silhouette scoring")
	import random
	clusters_to_check = range(2, 20)
	sh_scores = []
	i = 0
	for random_num in random.sample(range(1, 99999), 10):
		sh_scores.append([])
		for num_clusters in clusters_to_check:
			kmeans = KMeans(n_clusters=num_clusters, random_state=random_num).fit(trial_results_scaled)
			sh = silhouette_score(trial_results_scaled, kmeans.labels_)
			sh_scores[i].append(sh)
		i += 1
	sh_scores = np.mean(np.array(sh_scores), axis=0)
	# print(sh_scores)
	max_score = np.max(sh_scores)
	num_clusters = clusters_to_check[sh_scores.tolist().index(max_score)]
	# print(max_score, num_clusters)

	kmeans = KMeans(n_clusters=num_clusters, random_state=23588).fit(trial_results_scaled)
	cluster_labels = kmeans.labels_
	cluster_centers = kmeans.cluster_centers_

	# print(np.column_stack((trial_labels, cluster_labels)))

	plot_results(trial_results_scaled, cluster_labels, trial_labels, cluster_centers=cluster_centers, use_pca=True)

	# calculate stats for each cluster
	# print("Scaled:", trial_results_scaled.shape)
	x = []
	for i in range(num_clusters):
		cluster_data = trial_results_scaled[
			(cluster_labels == i)
		 	# & (trial_labels  == 0)
		 ]
		if len(cluster_data) > 0:
			avg = np.mean(cluster_data, axis=0).reshape(3, num_images, 2)
			avg = np.mean(avg, axis=(0, 1))
			x.append(avg)
			# print('cluster', i)
			# print(avg)
		else:
			print('cluster', i, 'empty')
	x = np.stack(x)
	# print(x)
	save_plot_2d('graphs/network_knife_clusters.png', x, get_colors(range(num_clusters)),
		size=200, xlabel='Lateral Action', ylabel='Rotational Action')

if __name__ == "__main__":

	trial_results_arr = []
	orig_actions_arr = []
	trials = []

	if len(sys.argv) < 2 or '-s' not in sys.argv:

		K.set_learning_phase(0)
		actor_model = Factory.actor_network(STATE_DIMENSIONS)

		for network_file_path in glob.iglob('test_networks/' + FILENAME_PATTERN + '*.h5'):
			# extract the trial number from the filename
			trial_num = int(re.search(r'\d+', re.sub('.*(\\\/)', '', network_file_path)).group(0))

			# test the network!
			trial_results, orig_actions = test_network_knife(actor_model, network_file_path, image_file_list, image_type_list)

			trial_results_arr.append(trial_results)
			orig_actions_arr.append(orig_actions)

			trials.append(trial_num)

		with open("trial_results.p", "wb") as tr:
			pkl.dump((trial_results_arr, orig_actions_arr, trials), tr, protocol=pkl.HIGHEST_PROTOCOL)

		K.clear_session()

	else:
		with open("trial_results.p", "rb") as tr:
			trial_results_arr, orig_actions_arr, trials = pkl.load(tr)

	match_data(trial_results_arr, orig_actions_arr, trials)


from django.contrib.gis.geos import GEOSGeometry

from rest_framework import response, status, views

from oppurtunity.models import GeoOpportunityZone

class OpportunityZoneView(views.APIView):
    """
    API for opportunity zone.
    """

    def post(self, request):
        data = request.data
        response_list = []
        geo_oppurtunity_objs_all = GeoOpportunityZone.objects.filter(state='New Jersey')
        for each in data:
            longitude = each.get('longitude', None)
            latitude = each.get('latitude', None)
            lookup_type = each.get('lookup_type')
            geom = None
            zones_list = []
            try:
                geom = GEOSGeometry("Point({} {})".format(longitude, latitude), srid=4269)
            except:
                pass
            if geom:
                if lookup_type == "contains":
                    geo_oppurtunity_objs = geo_oppurtunity_objs_all.filter(poly__contains=geom)
                else:
                    geo_oppurtunity_objs = geo_oppurtunity_objs_all.filter(poly__intersects=geom)
                if geo_oppurtunity_objs:
                    each.update({"is_opportunity_zone": True})
                else:
                    each.update({"is_opportunity_zone": False})
            response_list.append(each)
        return response.Response(response_list)


# -*- coding: utf-8 -*-
"""
Éditeur de Spyder

Renaud.
"""

import numpy as np
import matplotlib.pyplot as plt

l1=0.17
m1=2.8
l2=1.
m2=1.
g=9.81
Jeq=m1*l1**2+m2*l2**2
K=0.45
theta0=np.pi/2.
Cf=4

def F(y,t):
    mP=(l1*m1+(l1+l2)*m2)*g*np.cos(y[1])
    yl=(K*(180/np.pi)*(-y[1]+theta0)-mP-Cf*y[0])/Jeq,y[0]
    return yl

def euler(F,y0,t):
    N = len(t)
    y=np.zeros((len(t),2))
    y[:0] = y0
    for i in range(N-1):
        dt=(t[i+1]-t[i])
        s = [j*dt for j in F(y[i],t[i])]
        y[i+1] = y[i]+s
    return y

t = np.linspace(0,5,100)
y = euler(F,[0,0],t)
y1 = (180/np.pi)*y[:,1]
plt.plot(t,y1,label='Euler')
plt.legend(loc='upper left')
plt.show()


from sqlalchemy import Table

from flaskr.db import get_db, metadata, Base

class Favour(Base):
    __table__ = Table('favours', metadata, autoload=True)

    def __init__(self, author_id, post_id):
        self.author_id = author_id
        self.post_id = post_id

    def get(self):
        """
        Get the favour record with author_id and post_id in Favour instance.

        :return: one favour or None
        """
        favour = get_db().execute(
            'SELECT * FROM favours WHERE post_id = ? AND author_id = ?', (self.post_id, self.author_id)
        ).fetchone()
        return favour

    def insert(self):
        con = get_db()
        try:
            con.execute(
                'INSERT OR IGNORE INTO favours (post_id, author_id)'
                ' VALUES (?, ?)', (self.post_id, self.author_id)
            )
        except BaseException:
            con.rollback()
            raise
        else:
            con.commit()
        return

    def delete(self):
        con = get_db()
        try:
            con.execute(
                'DELETE FROM favours WHERE post_id = ? AND author_id = ?', (self.post_id, self.author_id)
            )
        except BaseException:
            con.rollback()
            raise
        else:
            con.commit()
        return


# coding=utf-8
import tensorflow as tf
import numpy as np
import sklearn as sk
import time
import matplotlib
import matplotlib.pyplot as plt
from sklearn.datasets.samples_generator import make_circles

import os
os.environ['TF_CPP_MIN_LOG_LEVEL']='2'

N = 210
K = 2
MAX_ITERS = 1000
cut = int(N*0.7)

start = time.time()
data, features = make_circles(n_samples=N,shuffle=True,noise=0.12,factor=0.4)
tr_data, tr_features = data[:cut], features[:cut]
te_data, te_feature = data[cut:], features[cut:]

fig, ax = plt.subplots()
ax.scatter(tr_data.transpose()[0], tr_data.transpose()[1], marker = 'o', s = 100, c = tr_features, cmap=plt.cm.coolwarm )
plt.show()

points = tf.Variable(data)
cluster_assignment = tf.Variable(tf.zeros([N], dtype=tf.int64))

sess = tf.Session()
sess.run(tf.global_variables_initializer())

test = []
for i, j in zip(te_data, te_feature): #元素个数与最短的列表一致
    distances = tf.reduce_sum(tf.square(i- tr_data), reduction_indices=1) #计算te_data中某个样本与tr_data中所有样本的距离值
    neighor = tf.argmin(distances,axis=0) # te_data中该样本与tr_data中距离最小的样本所在的索引
    # print("the shape of distance = ", sess.run(tf.shape(distances)))
    test.append(tr_features[sess.run(neighor)])

print(test)
fig, ax = plt.subplots()
ax.scatter(te_data.transpose()[0], te_data.transpose()[1], marker = 'o', s = 100, c = test, cmap=plt.cm.coolwarm )
plt.show()


from sklearn.cluster import FeatureAgglomeration
from fastsklearnfeature.declarative_automl.optuna_package.optuna_utils import categorical
import numpy as np
from fastsklearnfeature.declarative_automl.optuna_package.optuna_utils import id_name

class FeatureAgglomerationOptuna(FeatureAgglomeration):
    def init_hyperparameters(self, trial, X, y):
        self.name = id_name('FeatureAgglomeration_')

        self.n_components_fraction = trial.suggest_uniform(self.name + 'n_components_fraction', 0.0, 1.0)

        self.linkage = trial.suggest_categorical(self.name + "linkage", ["ward", "complete", "average"])

        if self.linkage == 'ward':
            self.affinity = "euclidean"
        else:
            self.affinity = trial.suggest_categorical(self.name + "affinity", ["euclidean", "manhattan", "cosine"])

        self.pooling_func = trial.suggest_categorical(self.name + "pooling_func", [np.mean, np.median, np.max])

        self.sparse = False

    def fit(self, X, y=None, **params):
        self.n_clusters = max(1, int(self.n_components_fraction * X.shape[1]))
        #print('ncom: ' + str(self.n_clusters))
        return super().fit(X=X, y=y, **params)

    def generate_hyperparameters(self, space_gen, depending_node=None):
        self.name = id_name('FeatureAgglomeration_')

        space_gen.generate_number(self.name + 'n_components_fraction', 0.5, depending_node=depending_node)
        space_gen.generate_cat(self.name + "linkage", ["ward", "complete", "average"], "ward", depending_node=depending_node)
        space_gen.generate_cat(self.name + "affinity", ["euclidean", "manhattan", "cosine"], "euclidean", depending_node=depending_node)
        space_gen.generate_cat(self.name + "pooling_func", [np.mean, np.median, np.max], np.mean, depending_node=depending_node)


#%%
import sys
sys.path.append('.')

from typer import Typer
from TenderCrab.DataModels import Session, TenderItem
from sqlalchemy import select, func
from parsel import Selector
import re
import logging
import typer

logging.basicConfig(filename='analyze.log', level=logging.INFO)

#%%
session = Session()

#%%
def get_buyer1(body: str):
    temp = re.findall(r'采购人[：:]([\u4e00-\u9fa5\w]+)', body)
    if temp:
        return temp[0]
    else:
        wrm = re.sub(r'<[^>]+>', ' ', body)
        temp = re.findall(r'采购人名?称?[：:]\s*([\u4e00-\u9fa5\w]+)', wrm)
        if temp:
            return temp[0]
        else:
            return None

def get_buyer2(body: str):
    temp = re.sub(r'<[^>]+>', '', body)
    temp1 = re.findall(r'采购人信息[\xa0\s]*名[\xa0\s]*称：([\u4e00-\u9fa5\w]+)', temp)
    if temp1:
        return temp1[0]
    else:
        return None

def update_buyer(batch:int=100, offset:int=0, total_count:int=0):
    global session
    if total_count == 0:
        stmt = select(func.count()).select_from(TenderItem)
        result = session.execute(stmt).fetchone()
        total_count = result[0]

    count = 0
    while count < total_count:
        stmt = select(TenderItem).limit(batch).offset(count + offset)
        result = session.execute(stmt).fetchall()
        count += batch
        for k, row in enumerate(result):
            temp = get_buyer1(row[0].body)
            if temp:
                row[0].buyer = temp
                continue
            temp = get_buyer2(row[0].body)
            if temp:
                row[0].buyer = temp
            else:
                logging.info(f"Failed to find buyer {row[0].id}")
        logging.info(f'{count} of {total_count} is completed.')
        session.commit()
#%%
if __name__ == "__main__":
    typer.run(update_buyer)

# %%
stmt = select(TenderItem).limit(20).offset(38)
result = session.execute(stmt).fetchall()


from ast import Lambda
from telebot import types
from telebot.types import InlineKeyboardMarkup, InlineKeyboardButton
import texts
import credentials

bot = credentials.bot

# Key words
start_commands = ["/start", "/help", "/home"]
other_commands = ['/profile', '/aboutus', '/services', '/question']
menu_options = ['💇 Services', '🌎 About us', '✍ Sign up', '📝 My appointments']
menu_hello_options = ['home','hi','hello','start','help','menu','back']
menu_ask_options = ['question','questions','ask','suggestion']
menu_products = ['products','product','service','services']
menu_price_services = ['price', 'prices','cost'] +menu_products
all_keywords = start_commands+other_commands+menu_options+menu_hello_options+menu_ask_options+menu_price_services

#---------------------BUTTONS LAYOUT DESIGN------------------
# Helper function for building a list of buttons in a grid
def build_menu(buttons, n_cols, header_buttons=None, footer_buttons=None):
    menu = [buttons[i:i + n_cols] for i in range(0, len(buttons), n_cols)]
    if header_buttons:
        menu.insert(0, header_buttons)
    if footer_buttons:
        menu.append(footer_buttons)
    return menu

# ----------KEYBOARD MENU----------
# Define keyboard options
def keyboard(n_cols=3):
    menu_keyboard = types.ReplyKeyboardMarkup(resize_keyboard=True)
    for i in range(0, len(menu_options), n_cols):
        row = menu_options[i:i+n_cols]
        menu_keyboard.add(*row)
    btn_back = types.KeyboardButton("⬅ Back")
    btn_home = types.KeyboardButton("⬆ Home")
    menu_keyboard.add(btn_back,btn_home)
    return menu_keyboard


from bench.common import (
    SampleConfig,
    register_sample,
    SampleSource,
    SampleTag,
)
import numpy as np

def get_sample_config():
    return SampleConfig(
        args_cases=[(3000,), (2000,), (1000,)],
        requires_grad=[False] * 4,
        performance_iters=1000,
        backward=[False] * 4,
        save_timeline=False,
        source=SampleSource.MMDET,
        url="https://github.com/open-mmlab/mmdetection/blob/c76ab0eb3c637b86c343d8454e07e00cfecc1b78/mmdet/core/bbox/coder/bucketing_bbox_coder.py#L145",  # noqa
        tags=[
            SampleTag.IfElseBranch,
            SampleTag.ForLoop,
            SampleTag.AdvancedIndexing,
            SampleTag.ViewAttribute,
        ],
    )

def gen_np_args(M):
    proposals = np.random.randn(M, 4)
    proposals = proposals.astype(np.float32)
    gt = np.random.randn(M, 4)
    gt = gt.astype(np.float32)
    return [proposals, gt]

register_sample(__name__, get_sample_config, gen_np_args)


import cv2
import numpy as np
from matplotlib import pyplot as plt

cap = cv2.VideoCapture(1)

for i in range(0, 30):
	ret, im = cap.read();

while(True):
	ret, img = cap.read()
	edges = cv2.Canny(img,100,250)

	# plt.subplot(121),plt.imshow(img,cmap = 'gray')
	# plt.title('Original Image'), plt.xticks([]), plt.yticks([])
	# plt.subplot(122),plt.imshow(edges,cmap = 'gray')
	# plt.title('Edge Image'), plt.xticks([]), plt.yticks([])

	# plt.show()
	# gray = cv2.cvtColor(edges, cv2.COLOR_BGR2GRAY)

	# Display the resulting frame
	cv2.imshow('frame', edges)
	cv2.imshow('frame2', img)
	if cv2.waitKey(1) & 0xFF == ord('q'):
		break

cap.release()
cv2.destroyAllWindows()


from housing.logger import logging
from housing.exception import housing_exception
from housing.entity.config_entity import Data_Validation_Config
from housing.entity.artifact_entity import DataIngestionArtifact, DataValidationArtifact
import os,sys
import pandas  as pd
from evidently.model_profile import Profile
from evidently.model_profile.sections import DataDriftProfileSection
from evidently.dashboard import Dashboard
from evidently.dashboard.tabs import DataDriftTab
import json
from housing.util.util import read_yaml_file
from housing.constant import *

class DataValidation:

    def __init__(self, data_validation_config:Data_Validation_Config,
        data_ingestion_artifact:DataIngestionArtifact):
        try:
            logging.info(f"{'>>'*30}Data Valdaition log started.{'<<'*30} \n\n")
            self.data_validation_config = data_validation_config
            self.data_ingestion_artifact = data_ingestion_artifact
        except Exception as e:
            raise housing_exception(e,sys) from e

    def get_train_and_test_df(self):
        try:
            train_df = pd.read_csv(self.data_ingestion_artifact.train_file_path)
            test_df = pd.read_csv(self.data_ingestion_artifact.test_file_path)
            return train_df,test_df
        except Exception as e:
            raise housing_exception(e,sys) from e

    def is_train_test_file_exists(self)->bool:
        try:
            logging.info("Checking if training and test file is available")
            is_train_file_exist = False
            is_test_file_exist = False

            train_file_path = self.data_ingestion_artifact.train_file_path
            test_file_path = self.data_ingestion_artifact.test_file_path

            is_train_file_exist = os.path.exists(train_file_path)
            is_test_file_exist = os.path.exists(test_file_path)

            is_available =  is_train_file_exist and is_test_file_exist

            logging.info(f"Is train and test file exists?-> {is_available}")

            if not is_available:
                training_file = self.data_ingestion_artifact.train_file_path
                testing_file = self.data_ingestion_artifact.test_file_path
                message=f"Training file: {training_file} or Testing file: {testing_file}" \
                    "is not present"
                raise Exception(message)

            return is_available
        except Exception as e:
            raise housing_exception(e,sys) from e

    def validate_dataset_schema(self)->bool:#,schema_file_path,file_path)->bool:
        try:
            # validation_status = True#
            # column_count_equal= False#
            # column_names_same= False#

            #Assigment validate training and testing dataset using schema file
            #1. Number of Column
            #2. Check the value of ocean proximity
            # acceptable values     <1H OCEAN
            # INLAND
            # ISLAND
            # NEAR BAY
            # NEAR OCEAN
            #3. Check column names

            # we dont mmodify any data(thats done in the feature engineering stage) here we just check the above steps

            # dataset_schema=read_yaml_file(schema_file_path)#
            # schema=dataset_schema[DATASET_SCHEMA_COLUMNS_KEY]#

            # df=pd.read_csv(file_path=file_path)#

# checking column numbers in the schema file and dataset of the column same or not

            # if len(list(schema.keys()))==len(df.columns):#
            #     column_count_equal=True#

# checking columns name in the schema file and dataset same or not

            # for col in df.columns:
            #     if col in list(schema.keys()):
            #         df[col].astype(schema[col])
            #         column_names_same=True
            #     else:
            #         column_names_same=False

            # if column_count_equal and column_names_same:
            #     validation_status=True

            validation_status = True
            return validation_status
        except Exception as e:
            raise housing_exception(e,sys) from e

    def get_and_save_data_drift_report(self):
        try:
            profile = Profile(sections=[DataDriftProfileSection()])

            train_df,test_df = self.get_train_and_test_df()

            profile.calculate(train_df,test_df)

            report = json.loads(profile.json())

            # profile.json is a string which is from json file we need
            # json.loads loads the string format into the json file format

            report_file_path = self.data_validation_config.report_file_path
            report_dir = os.path.dirname(report_file_path)
            os.makedirs(report_dir,exist_ok=True)

            with open(report_file_path,"w") as report_file:
                json.dump(report, report_file, indent=6)
            return report
        except Exception as e:
            raise housing_exception(e,sys) from e

    def save_data_drift_report_page(self):
        try:
            dashboard = Dashboard(tabs=[DataDriftTab()])
            train_df,test_df = self.get_train_and_test_df()
            dashboard.calculate(train_df,test_df)

            report_page_file_path = self.data_validation_config.report_page_file_path
            report_page_dir = os.path.dirname(report_page_file_path)
            os.makedirs(report_page_dir,exist_ok=True)

            dashboard.save(report_page_file_path)
        except Exception as e:
            raise housing_exception(e,sys) from e

    def is_data_drift_found(self)->bool:
        try:
            report = self.get_and_save_data_drift_report()
            self.save_data_drift_report_page()
            return True
        except Exception as e:
            raise housing_exception(e,sys) from e

    def initiate_data_validation(self)->DataValidationArtifact :
        try:
            self.is_train_test_file_exists()
            self.validate_dataset_schema()
            self.is_data_drift_found()

            data_validation_artifact = DataValidationArtifact(
                schema_file_path=self.data_validation_config.schema_file_path,
                report_file_path=self.data_validation_config.report_file_path,
                report_page_file_path=self.data_validation_config.report_page_file_path,
                is_validated=True,
                message="Data Validation performed successully."
            )
            logging.info(f"Data validation artifact: {data_validation_artifact}")
            return data_validation_artifact
        except Exception as e:
            raise housing_exception(e,sys) from e

    def __del__(self):
        logging.info(f"{'>>'*30}Data Validation log completed.{'<<'*30} \n\n")