#!/usr/bin/env python3

'''
connect to: 84:28:D7:8F:54:70
notificationhandler installed
services:
Service <uuid=Generic Attribute handleStart=1 handleEnd=4>
Service <uuid=Generic Access handleStart=5 handleEnd=13>
Service <uuid=6e400001-b5a3-f393-e0a9-e50e24dcca9e handleStart=14 handleEnd=65535>

characteristics:
Characteristic <Service Changed> uuid: 00002a05-0000-1000-8000-00805f9b34fb handle: 3 properties: INDICATE
indicate enabled: 4
Characteristic <Device Name> uuid: 00002a00-0000-1000-8000-00805f9b34fb handle: 7 properties: READ
length: 7 value: b'libatt\x00'
Characteristic <Appearance> uuid: 00002a01-0000-1000-8000-00805f9b34fb handle: 9 properties: READ
length: 2 value: b'\x00\x00'
Characteristic <Peripheral Preferred Connection Parameters> uuid: 00002a04-0000-1000-8000-00805f9b34fb handle: 11 properties: READ
length: 8 value: b'\x00\x00\x00\x00\x00\x00\x00\x00'
Characteristic <Central Address Resolution> uuid: 00002aa6-0000-1000-8000-00805f9b34fb handle: 13 properties: READ
length: 1 value: b'\x00'
Characteristic <0002> uuid: 00000002-0000-1000-8000-00805f9b34fb handle: 16 properties: READ
length: 2 value: b'\x01\x02'
Characteristic <6e400002-b5a3-f393-e0a9-e50e24dcca9e> uuid: 6e400002-b5a3-f393-e0a9-e50e24dcca9e handle: 19 properties: WRITE NO RESPONSE WRITE
Characteristic <6e400003-b5a3-f393-e0a9-e50e24dcca9e> uuid: 6e400003-b5a3-f393-e0a9-e50e24dcca9e handle: 21 properties: NOTIFY
send notify: desc: [<bluepy.btle.Descriptor object at 0xb655ae30>] handle[0]: 22
Characteristic <0001> uuid: 00000001-0000-1000-8000-00805f9b34fb handle: 24 properties: INDICATE
indicate enabled: 25
'''
import sys
sys.path.append('..')
import os
os.environ['PATH'] = 'C:/msys64/mingw64/bin' + os.pathsep + os.environ['PATH']
import time
import atorlib
import threading
import logging

# read data from notification
class SupervoltBatteryBleak(atorlib.BleBleakBase):

    cellV = [None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None]
    totalV = None
    soc = None
    workingState = None
    alarm = None
    chargingA = None;
    dischargingA = None;
    loadA = None
    tempC = [None, None, None, None]
    completeAh = None
    remainingAh = None
    designedAh = None

    def __init__(self,
                 name=None,
                 mac=None,
                 data=None,
                 verbose=False,
                 updatetimeS=1,
                 timeout=None,
                 callbackAfterData=None,
                 disconnectAfterData=False):
        super().__init__(mac=mac, name=name, mtuSize=246,
                         timeout=timeout,
                         data=data, verbose=verbose, updatetimeS=updatetimeS, callbackAfterData=callbackAfterData,
                         disconnectAfterData=disconnectAfterData);
        if data:
            self.parseData(data)

    async def enableNotifications(self):
        if False:
            data = b"\x02\x00"
            ret = await self.peripheral.writeCharacteristic(0x0004, data)
            if self.verbose:
                logging.info("0x0004: " + str(ret) + " " + str(data))
        data = b"\x01\x00"
        handle = 0x0015
        handle = "6e400003-b5a3-f393-e0a9-e50e24dcca9e"
        await self.device.start_notify(char_specifier=handle, callback=self.handleNotification)
        # ret = await self.peripheral.writeCharacteristic(0x0016, data)
        # if self.verbose:
        #    logging.info("0x0016: " + str(ret) + " " + str(data))
        if False:
            data = b"\x02\x00"
            ret = await self.peripheral.writeCharacteristic(0x0019, data)
            if self.verbose:
                logging.info("0x0019: " + str(ret) + " " + str(data))
        if self.verbose:
            logging.info("notifications enabled")

    def setData(self, data):
        if data:
            self.parseData(data)

    # send request to battery for Realtime-Data
    async def requestRealtimeData(self):
        data = bytes(":000250000E03~", "ascii")
        handle = 0x0013
        handle = 19
        handle = "6e400002-b5a3-f393-e0a9-e50e24dcca9e"
        # 0x0013 -> 19 -> 6e400002-b5a3-f393-e0a9-e50e24dcca9e
        ret = await self.device.write_gatt_char(char_specifier=handle, data=data)
        # ret = self.device.writeCharacteristic(0x0013, data)
        if self.verbose:
            logging.debug(":000250000E03~: " + str(ret) + " " + str(data))

    # send request to battery for Capacity-Data
    async def requestCapacity(self):
        data = bytes(":001031000E05~", "ascii")
        handle = 0x0013
        handle = 19
        handle = "6e400002-b5a3-f393-e0a9-e50e24dcca9e"
        # 0x0013 -> 19 -> 6e400002-b5a3-f393-e0a9-e50e24dcca9e
        ret = await self.device.write_gatt_char(char_specifier=handle, data=data)
        if self.verbose:
            logging.debug(":001031000E05~: " + str(ret) + " " + str(data))

    async def requestData(self):
        dis = self.disconnectAfterData
        try:
            await self.enableNotifications()
            # disable, cause we will need two answers
            self.disconnectAfterData = False
            self.notificationReceived = False
            await self.requestRealtimeData()
            await self.waitForNotification(10.0)

            self.notificationReceived = False
            self.disconnectAfterData = dis
            await self.requestCapacity()
            await self.waitForNotification(10.0)
        except:
            logging.error(sys.exc_info(), exc_info=True)
            await self.disconnect()
        self.disconnectAfterData = dis

    # try to read values from data
    def parseData(self, data):
        if self.verbose:
            logging.debug("parseData: {}".format(len(data)))
        try:
            if data:
                if len(data) == 128:
                    if self.verbose:
                        logging.info("parse Realtimedata: {}".format(type(data)))
                    if type(data) is bytearray:
                        data = bytes(data)
                    if type(data) is bytes:
                        # print("bytes")

                        start = 1
                        end = start + 2
                        self.address = int(data[start: end].decode(), 16)
                        if self.verbose:
                            logging.debug("address: " + str(self.address))

                        start = end
                        end = start + 2
                        self.command = int(data[start: end].decode(), 16)
                        if self.verbose:
                            logging.debug("command: " + str(self.command))

                        start = end
                        end = start + 2
                        self.version = int(data[start: end].decode(), 16)
                        if self.verbose:
                            logging.debug("version: " + str(self.version))

                        start = end
                        end = start + 4
                        self.length = int(data[start: end].decode(), 16)
                        if self.verbose:
                            logging.debug("length: " + str(self.length))

                        start = end
                        end = start + 14
                        bdate = data[start: end]
                        if self.verbose:
                            logging.debug("date: " + str(bdate))

                        start = end
                        end = start + 16 * 4
                        bvoltarray = data[start: end]
                        # print("voltarray: " + str(bvoltarray))
                        self.totalV = 0
                        for i in range(0, 11):
                            bvolt = data[(start + i * 4): (start + i * 4 + 4)]
                            self.cellV[i] = int(bvolt.decode(), 16) / 1000.0
                            self.totalV += self.cellV[i]
                            if self.verbose:
                                logging.debug("volt" + str(i) + ": " + str(bvolt) + " / " + str(self.cellV[i]) + "V")

                        if self.verbose:
                            logging.debug("totalVolt: " + str(self.totalV))

                        start = end
                        end = start + 4
                        bcharging = data[start: end]
                        self.chargingA = int(bcharging.decode(), 16) / 100.0
                        if self.verbose:
                            logging.debug("charching: " + str(bcharging) + " / " + str(self.chargingA) + "A")
                        if self.chargingA > 500:
                            # problem with supervolt
                            logging.info("charging too big: {}".format(self.chargingA))
                            self.chargingA = 0.0

                        start = end
                        end = start + 4
                        bdischarging = data[start: end]
                        self.dischargingA = int(bdischarging.decode(), 16) / 100.0
                        if self.verbose:
                            logging.debug("discharching: " + str(bdischarging) + " / " + str(self.dischargingA) + "A")
                        if self.dischargingA > 500:
                            # problem with supervolt
                            logging.info("discharging too big: {}".format(self.dischargingA))
                            self.dischargingA = 0.0

                        self.loadA = -self.chargingA + self.dischargingA

                        for i in range(0, 4):
                            start = end
                            end = start + 2
                            btemp = data[start: end]
                            self.tempC[i] = int(btemp.decode(), 16) - 40
                            if self.verbose:
                                logging.debug("temp" + str(i) + ": " + str(btemp) + " / " + str(self.tempC[i]) + "°C")

                        start = end
                        end = start + 4
                        self.workingState = int(data[start: end].decode(), 16)
                        if self.verbose:
                            logging.debug("workingstate: " + str(self.workingState) + " / " + str(data[start: end])
                              +" / " + self.getWorkingStateTextShort() + " / " + self.getWorkingStateText())

                        start = end
                        end = start + 2
                        self.alarm = int(data[start: end].decode(), 16)
                        if self.verbose:
                            logging.debug("alarm: " + str(self.alarm))

                        start = end
                        end = start + 4
                        self.balanceState = int(data[start: end].decode(), 16)
                        if self.verbose:
                            logging.debug("balanceState: " + str(self.balanceState))

                        start = end
                        end = start + 4
                        self.dischargeNumber = int(data[start: end].decode(), 16)
                        if self.verbose:
                            logging.debug("dischargeNumber: " + str(self.dischargeNumber))

                        start = end
                        end = start + 4
                        self.chargeNumber = int(data[start: end].decode(), 16)
                        if self.verbose:
                            logging.debug("chargeNumber: " + str(self.chargeNumber))

                        # State of Charge (%)
                        start = end
                        end = start + 2
                        self.soc = int(data[start: end].decode(), 16)
                        if self.verbose:
                            logging.debug("soc: " + str(self.soc))
                            logging.info("end of parse realtimedata")
                    else:
                        logging.warning("no bytes")
                elif len(data) == 30:
                    if self.verbose:
                        logging.debug("capacity")
                    if type(data) is bytearray:
                        data = bytes(data)
                    if type(data) is bytes:
                        start = 1
                        end = start + 2
                        self.address = int(data[start: end].decode(), 16)
                        if self.verbose:
                            logging.debug("address: " + str(self.address))

                        start = end
                        end = start + 2
                        self.command = int(data[start: end].decode(), 16)
                        if self.verbose:
                            logging.debug("command: " + str(self.command))

                        start = end
                        end = start + 2
                        self.version = int(data[start: end].decode(), 16)
                        if self.verbose:
                            logging.debug("version: " + str(self.version))

                        start = end
                        end = start + 4
                        self.length = int(data[start: end].decode(), 16)
                        if self.verbose:
                            logging.debug("length: " + str(self.length))

                        start = end
                        end = start + 4
                        breseved = data[start: end]
                        if self.verbose:
                            logging.debug("reseved: " + str(breseved))

                        start = end
                        end = start + 4
                        self.remainingAh = int(data[start: end].decode(), 16) / 10.0
                        if self.verbose:
                            logging.debug("remainingAh: " + str(self.remainingAh) + " / " + str(data[start: end]))

                        start = end
                        end = start + 4
                        self.completeAh = int(data[start: end].decode(), 16) / 10.0
                        if self.verbose:
                            logging.debug("completeAh: " + str(self.completeAh))

                        start = end
                        end = start + 4
                        self.designedAh = int(data[start: end].decode(), 16) / 10.0
                        if self.verbose:
                            logging.debug("designedAh: " + str(self.designedAh))
                            logging.info("end of parse capacity")

                else:
                    logging.warning("wrong length: " + str(len(data)))
            else:
                logging.debug("no data")
        except:
            logging.error(sys.exc_info(), exc_info=True)

    def resetValues(self):
        try:
            logging.info("reset")
            self.alarm = None
            self.balanceState = None
            for i in range(0, 11):
                self.cellV[i] = None
            self.chargeNumber = None
            self.chargingA = None
            self.completeAh = None
            self.designedAh = None
            self.dischargeNumber = None
            self.dischargingA = None
            self.loadA = None
            self.remainingAh = None
            self.soc = None
            for i in range(0, 4):
                self.tempC[i] = None
            self.totalV = None
            self.version = None
            self.workingState = None
        except:
            logging.error(sys.exc_info(), exc_info=True)

    def getWorkingStateTextShort(self):
        if self.workingState is None:
            return "nicht erreichbar"
        if self.workingState & 0xF003 >= 0xF000:
            return "Normal"
        if self.workingState & 0x000C > 0x0000:
            return "Schutzschaltung"
        if self.workingState & 0x0020 > 0:
            return "Kurzschluss"
        if self.workingState & 0x0500 > 0:
            return "Überhitzt"
        if self.workingState & 0x0A00 > 0:
            return "Unterkühlt"
        return "Unbekannt"

    def getWorkingStateText(self):
        text = ""
        if self.workingState is None:
            return "Unbekannt"
        if self.workingState & 0x0001 > 0:
            text = self.appendState(text, "Laden")
        if self.workingState & 0x0002 > 0:
            text = self.appendState(text , "Entladen")
        if self.workingState & 0x0004 > 0:
            text = self.appendState(text , "Überladungsschutz")
        if self.workingState & 0x0008 > 0:
            text = self.appendState(text , "Entladeschutz")
        if self.workingState & 0x0010 > 0:
            text = self.appendState(text , "Überladen")
        if self.workingState & 0x0020 > 0:
            text = self.appendState(text , "Kurzschluss")
        if self.workingState & 0x0040 > 0:
            text = self.appendState(text , "Entladeschutz 1")
        if self.workingState & 0x0080 > 0:
            text = self.appendState(text , "Entladeschutz 2")
        if self.workingState & 0x0100 > 0:
            text = self.appendState(text , "Überhitzt (Laden)")
        if self.workingState & 0x0200 > 0:
            text = self.appendState(text , "Unterkühlt (Laden)")
        if self.workingState & 0x0400 > 0:
            text = self.appendState(text , "Überhitzt (Entladen)")
        if self.workingState & 0x0800 > 0:
            text = self.appendState(text , "Unterkühlt (Entladen)")
        if self.workingState & 0x1000 > 0:
            text = self.appendState(text , "DFET an")
        if self.workingState & 0x2000 > 0:
            text = self.appendState(text , "CFET an")
        if self.workingState & 0x4000 > 0:
            text = self.appendState(text , "DFET Schalter an")
        if self.workingState & 0x8000 > 0:
            text = self.appendState(text , "CFET Schalter an")

        return text

    def appendState(self, text, append):
        if text is None  or len(text) == 0:
            return append
        return text + " | " + append

    def toJSON(self, prefix="battery"):
        self.checkAgeOfValues()
        json = ""
        prefixText = ""
        if prefix is not None:
            prefixText = prefix + "_"
        try:
            if self.tempC[0] is not None:
                json += "\"" + prefixText + "temperature\": {}".format(self.tempC[0]) + ",\n"
            if self.totalV is not None:
                json += "\"" + prefixText + "voltage\": {}".format(self.totalV) + ",\n"
            if self.cellV[0] is not None:
                json += "\"" + prefixText + "voltage_cell0\": {}".format(self.cellV[0]) + ",\n"
            if self.cellV[1] is not None:
                json += "\"" + prefixText + "voltage_cell1\": {}".format(self.cellV[1]) + ",\n"
            if self.cellV[2] is not None:
                json += "\"" + prefixText + "voltage_cell2\": {}".format(self.cellV[2]) + ",\n"
            if self.cellV[3] is not None:
                json += "\"" + prefixText + "voltage_cell3\": {}".format(self.cellV[3]) + ",\n"
            if self.soc is not None:
                json += "\"" + prefixText + "soc\": {}".format(self.soc) + ",\n"
            if self.chargingA is not None:
                json += "\"" + prefixText + "chargingA\": {}".format(self.chargingA) + ",\n"
            if self.dischargingA is not None:
                json += "\"" + prefixText + "dischargingA\": {}".format(self.dischargingA) + ",\n"
            if self.loadA is not None:
                json += "\"" + prefixText + "loadA\": {}".format(self.loadA) + ",\n"
            if self.alarm is not None:
                json += "\"" + prefixText + "alarm\": {}".format(self.alarm) + ",\n"
            if self.workingState is not None:
                json += "\"" + prefixText + "workingState\": {}".format(self.workingState) + ",\n"
                withoutUmlaute = self.getWorkingStateText().replace("Ü", "Ue").replace("ü", "ue")
                json += "\"" + prefixText + "workingStateText\": \"{}\"".format(withoutUmlaute) + ",\n"
                withoutUmlaute = self.getWorkingStateTextShort().replace("Ü", "Ue").replace("ü", "ue")
                json += "\"" + prefixText + "workingStateTextShort\": \"{}\"".format(withoutUmlaute) + ",\n"
            if self.completeAh is not None:
                json += "\"" + prefixText + "completeAh\": {}".format(self.completeAh) + ",\n"
            if self.remainingAh is not None:
                json += "\"" + prefixText + "remainingAh\": {}".format(self.remainingAh) + ",\n"
            if self.designedAh is not None:
                json += "\"" + prefixText + "designedAh\": {}".format(self.designedAh) + ",\n"

        except:
            logging.warning(sys.exc_info(), exc_info=True)
        return json

def main():
    try:
        logging.basicConfig(level=logging.DEBUG, format='%(asctime)s.%(msecs)03d %(levelname)s %(module)s - %(funcName)s: %(message)s')

        mac = "84:28:D7:8F:XX:XX"
        if len(sys.argv) > 1 and sys.argv[1] is not None:
            mac = sys.argv[1]
        else:
            logging.warning("usage: supervoltbatterybleak.py <BLE-Address>")
            return
        logging.info("connect to " + mac)
        battery = SupervoltBatteryBleak(mac=mac, name="SuperVoltTest", verbose=True, updatetimeS=10, disconnectAfterData=True)
        battery.startReading()
        while(True):
            time.sleep(10000)
    except:
        logging.error(sys.exc_info(), exc_info=True)

if __name__ == '__main__':
    main()


from flask import Flask, request, render_template
import tensorflow as tf
import numpy as np
from PIL import Image
import io

app = Flask(__name)

# 모델 로드 (VGG16)
model = tf.keras.applications.VGG16(weights='imagenet')

# 모델 예측 함수
def predict_image(image_data):
    img = Image.open(io.BytesIO(image_data))
    img = img.resize((224, 224))  # 모델의 입력 크기에 맞게 이미지 크기 조정
    img = np.array(img)
    img = tf.keras.applications.vgg16.preprocess_input(img)  # 이미지 전처리
    img = np.expand_dims(img, axis=0)  # 배치 차원 추가
    prediction = model.predict(img)
    return tf.keras.applications.vgg16.decode_predictions(prediction)

@app.route('/', methods=['GET', 'POST'])
def upload_image():
    if request.method == 'POST':
        if 'file' not in request.files:
            return render_template('index.html', prediction="이미지를 업로드하세요")

        file = request.files['file']
        if file.filename == '':
            return render_template('index.html', prediction="파일을 선택하세요")

        if file:
            image_data = file.read()
            prediction = predict_image(image_data)
            # 상위 3개 예측 결과 표시
            top3_predictions = prediction[0][:3]
            return render_template('index.html', prediction=top3_predictions)

    return render_template('index.html', prediction=None)

if __name__ == '__main__':
    app.run(debug=True)


import arrays
import random

def create_sorted_array_descending(size):
    array = arrays.Array(size, 0)
    count = size
    for i in range(len(array)):
        array[i] = count
        count -= 1
    return array

def random_int_array(size, min = 1, max = 10):
    rand_array = arrays.Array(size)
    for i in range(len(rand_array)):
        rand_array[i] = random.randint(min, max)
    return rand_array

def split(array):
    evens_index = 0
    odds_index = 0
    if len(array) % 2 == 1:
        evens = arrays.Array(len(array)//2 + 1)
        odds = arrays.Array(len(array)//2)
    else:
        evens = arrays.Array(len(array)//2)
        odds = arrays.Array(len(array)//2)
    for i in range(len(array)):
        if i % 2 == 0:
            evens[evens_index] = array[i]
            evens_index += 1
        else:
            odds[odds_index] = array[i]
            odds_index += 1
    return evens, odds

def merge(sorted1, sorted2):
    result = arrays.Array(len(sorted1) + len(sorted2))
    i1 = 0
    i2 = 0
    i = 0
    while i1 < len(sorted1) and i2 < len(sorted2):
        if sorted1[i1] <= sorted2[i2]:
            result[i] = sorted1[i1]
            i1 += 1
            i += 1
        else:
            result[i] = sorted2[i2]
            i2 += 1
            i +=1
    if i1 < len(sorted1):
        while i1 < len(sorted1):
            result[i] = sorted1[i1]
            i1 += 1
            i += 1
    else:
        while i2 < len(sorted2):
            result[i] = sorted2[i2]
            i2 += 1
            i += 1
    return result

def merge_sort(array):
    if len(array) <= 1:
        return array
    else:
        half1, half2 = split(array)
        half1 = merge_sort(half1)
        half2 = merge_sort(half2)
        merged_array = merge(half1, half2)
        return merged_array

def main():
    # array = create_sorted_array_descending(10)
    array = random_int_array(30, 1, 100)
    print(array)
    merged_array = merge_sort(array)
    print(merged_array)

main()


# !/usr/bin/python
# -*- coding: UTF-8 -*-
import sys
sys.path.append("/Users/liyang/Desktop/Course/Database/Project/code/nlp/")
from query_process import *
from tkinter import *
import tkinter

window = tkinter.Tk()
#window.geometry('1000x618')
window.title('DataBase')
window.resizable(0,0)
Label(window, text="Input", font="Times 15 bold italic").grid(row=0)
Label(window, text="Output", font="Times 15 bold italic").grid(row=1)
entry1 = Text(window, width = 50, height=3, font="Helvetica 20 bold")#, bg='red')
text1 = Text(window, width = 50, height=20, font="Helvetica 20 bold", bg='#f0ffff')
entry1.grid(row=0, column=1)
text1.grid(row=1, column=1)

def database():
    text1['state'] = 'normal'
    text1.delete('1.0', END)
    input_blank  = entry1.get('1.0', END)
    result = str(analysis(input_blank))
    text1.insert(INSERT, result)
    text1['state'] = 'disabled'

Button(window, text='Quit', command=window.quit, font="Times 15 bold italic", fg='red').grid(row=2, column=0, sticky=W, padx=5, pady=5)
Button(window, text='Search', command=database, relief = 'solid', font="Times 15 bold italic", fg='blue').grid(row=2, column=1, sticky=W, padx=5, pady=5)
##flat, groove, raised, ridge, solid, or sunken
window.mainloop()


#!/usr/bin/python
# -*- coding: UTF-8 -*-
# 性别年龄识别WebAPI 接口：即机器对说话者的年龄大小以及性别属性进行分析，可以通过收到的音频数据判定发音人的性别（男，女）及年龄范围（小孩，中年，老人），对语音内容和语种不做限制。
# 该语音能力是通过Websocket API的方式给开发者提供一个通用的接口。Websocket API具备流式传输能力，适用于需要流式数据传输的AI服务场景，比如边说话边识别。
import datetime
import hashlib
import base64
import hmac
import json
import time
from urllib.parse import urlencode
from wsgiref.handlers import format_date_time
from datetime import datetime
from time import mktime
import websocket
import ssl
import _thread as thread

STATUS_FIRST_FRAME = 0  # 第一帧的标识
STATUS_CONTINUE_FRAME = 1  # 中间帧标识
STATUS_LAST_FRAME = 2  # 最后一帧的标识

# 用于存储年龄和性别信息
age_data = []
gender_data = []

class Ws_Param(object):  # 定义类用于管理 websocket 参数
    # 初始化
    def __init__(self, APPID, APIKey, APISecret, AudioFile):
        self.APPID = APPID
        self.APIKey = APIKey
        self.APISecret = APISecret
        self.AudioFile = AudioFile  # 说话人的音频文件

        # 公共参数(common)
        self.CommonArgs = {"app_id": self.APPID}
        # 业务参数(business)
        self.BusinessArgs = {"ent": "igr",  # 引擎类型，目前仅支持igr
                             "aue": "raw",  # 音频格式 raw：支持pcm格式和wav格式
                             "rate": 16000  # 音频采样率 16000/8000
                             }

    # 生成url，通过在请求地址后面加上鉴权相关参数
    def create_url(self):
        # 参数1：生成RFC1123格式的时间戳
        now = datetime.now()
        date = format_date_time(mktime(now.timetuple()))

        # 参数2： 生成鉴权authorization参数（包括下面step1、2、3、4、5)
        # step1 拼接signature原始字段的字符串（signature原始字段包括host、date、authorization）
        signature_origin = "host: " + "ws-api.xfyun.cn" + "\n"
        signature_origin += "date: " + date + "\n"
        signature_origin += "GET " + "/v2/igr " + "HTTP/1.1"
        # step2 结合apiSecret对signature_origin，使用hmac-sha256进行加密（签名）
        signature_sha = hmac.new(self.APISecret.encode('utf-8'), signature_origin.encode('utf-8'),
                                 digestmod=hashlib.sha256).digest()
        # step3 使用base64编码对signature_sha进行编码获得最终的signature_sha
        signature_sha = base64.b64encode(signature_sha).decode(encoding='utf-8')
        # step4 根据以上信息拼接authorization base64编码前（authorization_origin）的字符串
        authorization_origin = "api_key=\"%s\", algorithm=\"%s\", headers=\"%s\", signature=\"%s\"" % (
            self.APIKey, "hmac-sha256", "host date request-line", signature_sha)
        # step5 对authorization_origin进行base64编码获得最终的authorization参数
        authorization = base64.b64encode(authorization_origin.encode('utf-8')).decode(encoding='utf-8')

        # 将请求的鉴权参数1、2及host组合为字典
        v = {
            "authorization": authorization,
            "date": date,
            "host": "ws-api.xfyun.cn"
        }
        # 请求地址
        url = 'wss://ws-api.xfyun.cn/v2/igr'
        # 在请求地址后面加上鉴权相关参数（拼接鉴权参数），生成url
        url = url + '?' + urlencode(v)
        return url

# 收到websocket错误的处理
def on_error(ws, error):  # websocket报错时，就会触发on_error事件
    print("错误信息:", error)

# 收到websocket关闭的处理
def on_close(ws):  # websocket关闭时，就会触发on_close事件
    print("websocket连接关闭")

def data_send(ws, file, commonargs, businessargs):
    frameSize = 5000  # 每一帧的音频大小
    intervel = 0.04  # 发送音频间隔(单位:s)
    status = STATUS_FIRST_FRAME  # 音频的状态信息，标识音频是第一帧，还是中间帧、最后一帧
    # 业务数据流参数
    data_format = "audio/L16;rate=16000"  # 音频的采样率支持16k和8k, 8k音频：audio/L16;rate=8000
    data_encoding = "raw"  # 音频数据格式, lame：mp3格式  raw：原生音频（支持单声道的pcm,wav）

    with open(file, "rb") as fp:
        while True:
            buf = fp.read(frameSize)
            # 文件结束
            if not buf:
                status = STATUS_LAST_FRAME
            # 第一帧处理
            # 发送第一帧音频，带business 参数
            # appid 必须带上，只需第一帧发送
            if status == STATUS_FIRST_FRAME:
                d = {"common": commonargs,  # 公共参数APPid
                     "business": businessargs,
                     "data": {"status": 0,  # 音频的状态 0 :第一帧音频
                              "format": data_format,
                              "audio": str(base64.b64encode(buf), 'utf-8'),  # 音频内容，采用base64编码
                              "encoding": data_encoding
                              }
                     }
                d = json.dumps(d)  # 将请求数据转化为字符串
                ws.send(d)  # 发送数据
                status = STATUS_CONTINUE_FRAME

            # 中间帧处理
            elif status == STATUS_CONTINUE_FRAME:
                d = {"data": {"status": 1,  # 音频的状态 1 :中间的音频
                              "format": data_format,
                              "audio": str(base64.b64encode(buf), 'utf-8'),
                              "encoding": data_encoding
                              }
                     }
                ws.send(json.dumps(d))
            # 最后一帧处理
            elif status == STATUS_LAST_FRAME:
                d = {"data": {"status": 2,  # 音频的状态 2 :最后一帧音频，最后一帧必须要发送
                              "format": data_format,
                              "audio": str(base64.b64encode(buf), 'utf-8'),
                              "encoding": data_encoding
                              }
                     }
                ws.send(json.dumps(d))
                time.sleep(1)
                break
            # 模拟音频采样间隔
            time.sleep(intervel)
    ws.close()  # 关闭websocket

def data_write(message, age_data, gender_data):
    try:
        code = json.loads(message)["code"]  # 返回码，0表示成功，其它表示异常
        sid = json.loads(message)["sid"]  # 本次会话的id，只在握手成功后第一帧请求时返回
        if code != 0:
            errMsg = json.loads(message)["message"]
            print("sid:%s call error:%s code is:%s" % (sid, errMsg, code))

        else:
            age_data.append(json.loads(message)["data"]["result"]["age"])
            gender_data.append(json.loads(message)["data"]["result"]["gender"])
    except Exception as e:
        print("接收消息，但解析异常:", e)

def age_gender_api_get_result(APPID, APIKey, APISecret, filename):
    # 实例化websocket参数类
    wsParam = Ws_Param(APPID=APPID,
                       APIKey=APIKey,
                       APISecret=APISecret,
                       AudioFile=filename)
    wsUrl = wsParam.create_url()  # 获取鉴权url

    # 收到websocket消息的处理：把服务端返回的json数据进行解析
    def on_message(ws, message):
        data_write(message, age_data, gender_data)

    # 建立websocket连接,客户端的数据发送给服务端
    def on_open(ws):  # 连接到服务器之后就会触发on_open事件
        def run(*args):
            data_send(ws, wsParam.AudioFile, wsParam.CommonArgs, wsParam.BusinessArgs)
        thread.start_new_thread(run, ())  # 产生新线程

    # 向服务器端发送Websocket协议握手请求
    # 握手成功后，客户端通过Websocket连接同时上传和接收数据。
    # 接收到服务器端的结果全部返回标识后断开Websocket连接
    websocket.enableTrace(False)  # 调试关闭
    ws = websocket.WebSocketApp(wsUrl,
                                on_open=on_open,
                                on_message=on_message,
                                on_error=on_error,
                                on_close=on_close)

    ws.run_forever(sslopt={"cert_reqs": ssl.CERT_NONE})  # CERT_NONE 禁用SSL证书验证

    return age_data, gender_data


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

"""
НЕ сделал
"""

import re
import sys
import requests

def reqsts(link):
    res = requests.get(link)
    if res.status_code == 200:
        return res.text
    else:
        return False

links = list()

for line in sys.stdin:
    links.append(line.strip())

for link in links:
    # req_link = re.findall(r"href=\"(.*)\"", reqsts(link))
    req_link = re.match(r"href=\"([\w\s:/\.]+?)\"", 'href="aaa" href="bbb"')
    print(req_link.groups())
    """
    res = requests.get(line)
    if res.status_code == 200:
        link = re.search(r"href=\"(.*)\"", res.text)
        print(link.group(1))
    """


from game_api import *
from color_api import *

set_heap()
player = 1

while True:
    out_color( 'yellow', 'This is the heap: ', get_heap() )
    out_color( 'blue', "Player {} can remove stones".format( player ) )
    pos = int( input( "Remove from position: " ) )
    qua = int( input( "Remove number of stones: " ) )
    remove_from_heap( pos - 1, qua )
    if is_gameover():
        break;
    player = 1 if player == 2 else 2

out_color( 'red', "Player {} won.".format( player ) )


import torch.nn as nn
import torch
from torch.autograd import Function

class Retain(nn.Module):
    def __init__(self, dict_len, embedding_dim,  transformer_hidden, attn_heads, transformer_dropout, transformer_layers):
        super().__init__()

        retain_embed = 2*embedding_dim
        self.softmax = torch.nn.Softmax(dim=-1)
        self.retain_embed = nn.Linear(dict_len, retain_embed)
        self.gru = nn.GRU(input_size = retain_embed, hidden_size = retain_embed, batch_first = True, bidirectional = False)
        self.retain_attn_a = nn.Linear(retain_embed, 1)
        self.gru_b = nn.GRU(input_size = retain_embed, hidden_size = retain_embed, batch_first = True, bidirectional = False)
        self.retain_attn_b = nn.Sequential(nn.Linear(retain_embed, retain_embed), nn.Tanh())
        self.pred_feat = nn.Sequential(nn.Linear(4*retain_embed, 2*retain_embed), nn.Tanh())
        self.classify_layer = nn.Linear(retain_embed, 1)

    def forward(self, batch_input, time_info, visit_length):
        batch_input = batch_input[:,0:50,:]
        input_embedding = self.retain_embed(batch_input)
        gru_output = self.gru(input_embedding)

        gru_embedding = gru_output[0]

        attn_a = self.retain_attn_a(gru_embedding).squeeze(-1)
        attn_a = self.softmax(attn_a).unsqueeze(-1).permute(0, 2, 1)

        gru_b_output = self.gru_b(input_embedding)
        gru_b_embedding = gru_b_output[0]
        attn_b = self.retain_attn_b(gru_b_embedding)

        attn_b_input = input_embedding * attn_b
        context = torch.matmul(attn_a, attn_b_input).squeeze(1)

        classify_score = self.classify_layer(context)
        binary_output = torch.sigmoid(classify_score)

        return binary_output


# -*- coding: utf-8 -*-
"""
Created on Thu May 12 13:51:11 2022

@author: vlasenko
"""

import win32com.client
import os
import pandas as pd
import re
import time
from datetime import datetime
from tqdm import tqdm

script_dir = r'C:\Users\kavlasenko\Documents\05.PYTHON\Projects\san_report_automation\san_tmp_scipts'
# Change the current working directory
os.chdir(script_dir)
import general_cmd_module as dfop

# # DataLine OST
# db_path = r"D:\Documents\01.CUSTOMERS\DataLine\SAN OST\NOV2022\database_DataLine OST"
# db_file = r"DataLine OST_topology_database.db"

# DataLine SPB
db_path = r"D:\Documents\01.CUSTOMERS\DataLine\SAN SPB\NOV2022\database_DataLine SPB"
db_file = r"DataLine SPB_topology_database.db"

data_names = ['san_graph_switch', 'san_graph_sw_pair', 'san_graph_isl', 'san_graph_npiv', 'storage_shape_links', 'server_shape_links', 'san_graph_sw_pair_group', 'fabric_name_duplicated', 'fabric_name_dev']
data_lst = dfop.read_database(db_path, db_file, *data_names)
data_lst = dfop.verify_read_data(20, data_names, *data_lst,  show_status=True)

san_graph_switch_df, san_graph_sw_pair_df, san_graph_isl_df, san_graph_npiv_df, storage_shape_links_df, server_shape_links_df, san_graph_sw_pair_group_df, fabric_name_duplicated_sr, fabric_name_dev_sr, *_ = data_lst

fabric_name_duplicated_lst = fabric_name_duplicated_sr.tolist()
fabric_name_dev_lst = fabric_name_dev_sr.tolist()

log_file = "visio_graph_log.txt"

san_template_path = r'C:\Users\kavlasenko\Documents\05.PYTHON\Projects\san_report_automation\san_tmp_scipts\SAN_Drawings_template_DataLine3.vsdm'
stencil_path = r"C:\Users\kavlasenko\Documents\05.PYTHON\Projects\san_report_automation\san_tmp_scipts\san_assessment_stn_upd.vssx"

HPE_PALETTE = ['RGB(0,169,103)', 'RGB(255,141,109)']
LINE_PATTERN = {2: 'USE("Parallel Lines x2")', 3: 'USE("Parallel Lines x3")', 4: 'USE("Parallel Lines x4")', '4+': 'USE("Parallel Lines x4+")'}
X_START = 35
SHAPE_FONT_SIZE = "12 pt"
LINK_FONT_SIZE = "12 pt"

# str_dev = connected_devices_df.to_string()

start_time = f'start: {current_datetime()}'
add_log_entry(log_file, '*'*40, start_time)

fabric_name_lst = list(san_graph_sw_pair_df['Fabric_name'].unique())
# fabric_labels = sorted(list(switch_pair_df['Fabric_label'].unique()))
fabric_labels = sorted(list(san_graph_switch_df['Fabric_label'].unique()))

fabric_label_colours_dct = dict(zip(fabric_labels, HPE_PALETTE))

# for _, (idx, switch_pair_sr) in zip(tqdm(range(1, len(san_graph_sw_pair_df.index)+1), desc="Switch pairs"), san_graph_sw_pair_df.iterrows()):
#     continue
    # print(idx, switch_pair_sr)

# doc = visio.ActiveDocument
# # page = visio.ActiveWindow
# # for shape in page.Shapes:
# #     print(shape.Text)

# for page in doc.Pages:
#     for shape in page.Shapes:

#         print(shape.Text)

#         if shape.Text == 'Customer / SAN Assessment':
#             shape.Text = 'Data Line' + ' / ' + 'SAN Inventory'

# for page in doc.Pages:
#     for shape in page.Shapes:
#         if shape.Text == 'Fabric Name':
#             shape.Text = 'Фабрика ' + page.Name
#         elif project_name and shape.Text == 'Project title':
#             shape.Text = project_name

# HPE_PALETTE = {'green': 'RGB(0,169,103)',  'red': 'RGB(255,141,109)'}

# HPE_PALETTE.values() = {'green': 'RGB(0,169,103)',  'red': 'RGB(255,141,109)'}

# initialize Visio Documet with template
visio, stn = visio_document_init(san_template_path, stencil_path, fabric_name_lst)
# add swith and vc shapes
add_visio_switch_shapes(san_graph_sw_pair_df, visio, stn)
# add isl links
add_visio_inter_switch_connections(san_graph_isl_df, visio, stn, fabric_label_colours_dct, link_type='isl')
# add npiv links
add_visio_inter_switch_connections(san_graph_npiv_df, visio, stn, fabric_label_colours_dct, link_type='npiv')

####################
# add pages for duplicated fabric_names
for fabric_name_duplicated, fabric_name_device in zip(fabric_name_duplicated_lst, fabric_name_dev_lst):
    visio.ActiveWindow.Page = fabric_name_duplicated
    visio.ActivePage.Duplicate()
    visio.ActivePage.Name = fabric_name_device

# add server and unknown
add_visio_devices(server_shape_links_df, visio, stn, fabric_label_colours_dct, device_class='server')
# add storage and lib
add_visio_devices(storage_shape_links_df, visio, stn, fabric_label_colours_dct, device_class='storage')
# create visio groups for switch Pairs
group_switch_pairs(san_graph_sw_pair_group_df, visio)

finish_time = f'finish: {current_datetime()}'
add_log_entry(log_file, '\n', finish_time, '^'*40, )

# doc = visio.ActiveDocument
# doc.MacrosEnabled
# doc.saveas(r'C:\Users\kavlasenko\Documents\05.PYTHON\Projects\san_report_automation\san_tmp_scipts\testsave.vsdm')
# doc.Close()

########################################################
# Functions

SWITCH_DESC = 'Switche pairs'
ISL_DESC = 'ISL, ICL, IFL links'
NPIV_DESC = 'NPIV links'
STORAGE_DESC = 'Storages'
SERVER_DESC = 'Servers'
SWITCH_GROUPS_DESC = 'Switch groups'
LEFT_INDENT = 16
RIGHT_INDENT = 10

def max_desc_len(san_graph_isl_df, san_graph_npiv_df):

    desc_link_lst = [desc for (desc, link_df) in zip(
        (ISL_DESC, NPIV_DESC),
        (san_graph_isl_df, san_graph_npiv_df)
        ) if not link_df.empty]
    desc_lst = [SWITCH_DESC, STORAGE_DESC, SERVER_DESC, SWITCH_GROUPS_DESC]
    desc_lst.extend(desc_link_lst)
    return max([len(desc) for desc in desc_lst])

def get_desc_indented(desc_str):
    return ' '*LEFT_INDENT + desc_str.ljust(max_desc_len())

def get_ncols_num():

    max_title  = 25
    return max_title + 80 - RIGHT_INDENT

def visio_document_init(san_template_path, stencil_path, fabric_name_lst):
    """Fuction to initialize visio document with template,
    add fabric_name pages and add page notes: customer, project title,
    fabric_name"""

    visio = win32com.client.Dispatch("Visio.Application")
    visio.Visible = 1
    visio.Documents.Add(san_template_path)
    stn = visio.Documents.OpenEx(stencil_path, 64)

    # rename first page
    visio.ActivePage.Name = fabric_name_lst[0]
    for fabric_name in fabric_name_lst[1:]:
        # duplicate and rename template page
        visio.ActivePage.Duplicate()
        visio.ActivePage.Name = fabric_name
    # add notes to the Document pages
    set_visio_page_note(visio)
    return visio, stn

def set_visio_page_note(visio, customer=None, project=None):
    """Function to add page notes: customer name, project title, fabric_name"""

    doc = visio.ActiveDocument
    for page in doc.Pages:
        for shape in page.Shapes:
            if shape.Text == 'Description':
                shape.Text = page.Name
            elif all((customer, project, shape.Text=='Customer / Project')):
                shape.Text = customer + ' / ' + project

            elif customer and shape.Text == 'Customer / Project':
                shape.Text = customer

    # doc = visio.ActiveDocument
    # for page in doc.Pages:
    #     print('\n')
    #     print(shape)
    #     for shape in page.Shapes:
    #         print(shape.Text)

def activate_visio_page(visio, page_name):
    """Function activates page with page_name in Visio document
    and returns this page object"""

    doc = visio.ActiveDocument
    page = doc.Pages.ItemU(page_name)
    visio.ActiveWindow.Page = page_name
    return page

def add_visio_switch_shapes(san_graph_sw_pair_df, visio, stn):
    """Function to add swith and VC shapes to Visio document pages (fabric_name)"""

    fabric_name_prev = None
    graph_level_prev = None
    x_group_current = 0

    add_log_entry(log_file, '\nSwitches\n', 'Fabric, switchName, switchWwn, swithNumber_in_pair, x-coordinate, y-coordinate')

    desc_indented = get_desc_indented(SWITCH_DESC)
    ncols_num = get_ncols_num()

    for _, (idx, switch_pair_sr) in zip(tqdm(range(len(san_graph_sw_pair_df.index)), desc=desc_indented, ncols=ncols_num), san_graph_sw_pair_df.iterrows()):

    # for idx, switch_pair_sr in san_graph_sw_pair_df.iterrows():
        # add_log_entry(log_file, '\n', switch_pair_sr.to_string())
        fabric_name_current = switch_pair_sr['Fabric_name']
        # graph_level: core, edge, ag
        graph_level_current = switch_pair_sr['graph_level']
        # activate page with switch_pair
        page = activate_visio_page(visio, page_name=fabric_name_current)
        # reset x-coordinate if new page (fabric_name) selected
        if fabric_name_current != fabric_name_prev:
            x_group_current = X_START
            fabric_name_prev = fabric_name_current

        # reset x-coordinate if shape drop level (y_graph_level) changed
        if graph_level_current != graph_level_prev:
            x_group_current = X_START
            graph_level_prev = graph_level_current

        # print("X: ", x_group_current)

        drop_switch_pair_shapes(switch_pair_sr, x_group_current, page, stn)
        # move cursor to the next switch pair location x-coordinate
        x_group_current =  x_group_current + switch_pair_sr['x_group_offset']

def drop_switch_pair_shapes(switch_pair_sr, x_group_current, page, stn):
    """Function to drop switch shapes from single switch_pair to the active visio page and
    add shape text (to all shapes of the switch_pair in case of directors and to
    the bottom shape onlyk in case if switches and vcs"""

    # split switch_pair_srs details to build Visio graph
    master_shapes = switch_pair_sr['master_shape'].split(', ')
    shape_names = switch_pair_sr['switchName_Wwn'].split(', ')
    shape_text = switch_pair_sr['switchName_DID'].split('/ ')[::-1]

    # first drop second switch of the switch_pair_sr to make the first switch visually overlap to the second switch
    # two ENT swtiches sw1 and sw2 -> [(0, 'ENT', 'sw2'), (1, 'ENT', 'sw1')]
    for i, master_shape, shape_name in list(zip(range(len(master_shapes)-1, -1, -1), master_shapes, shape_names))[::-1]:

        # choose shape icon
        master = stn.Masters(master_shape)
        # set x, y coordinates
        # x_shape_offset is for Direcors only (for all other devices it's 0)
        x = x_group_current - i * switch_pair_sr['x_shape_offset']
        # y_shape_offset makes fabic_label A switch shape to be located above fabic_label B switch shape
        y = switch_pair_sr['y_group_level'] + i * switch_pair_sr['y_shape_offset']

        # print(switch_pair_sr['Fabric_name'], shape_name, i, x, y)

        # add enrty to visio graph creation log
        log_entry = ' '.join([switch_pair_sr['Fabric_name'], shape_name, str(i), str(x), str(y)])
        add_log_entry(log_file, log_entry)

        # add switch shape to the Visio page
        shape = page.Drop(master, x, y)
        shape.Name = shape_name

        # for Directors shape text is under each shape with
        # Director name, DID and model individually
        if 'DIR' in switch_pair_sr['switchClass_mode']:
            shape.Text = shape_text[i] + "\n" + switch_pair_sr['ModelName']
        else:
            shape.Text = " "

    # for all switches except Directors shape text with switch name, DID and model
    # for the switch pair on the bottom shape of the switch pair
    if not 'DIR' in switch_pair_sr['switchClass_mode']:
        bottom_shape = page.Shapes.ItemU(shape_names[-1])
        if switch_pair_sr['ModelName']:
            bottom_shape.Text = switch_pair_sr['switchName_DID'] + "\n" + switch_pair_sr['ModelName']
        else:
            bottom_shape.Text = switch_pair_sr['switchName_DID']

def current_datetime(join=False):
    """Function returns current datetime in 03/11/2022 11:37:45 format"""

    now = datetime.now()
    if join:
        return now.strftime("%d%m%Y_%H%M%S")
    return now.strftime("%d/%m/%Y %H:%M:%S")

def add_log_entry(file_name, *args):
    """Function add lines (args) to the file_name"""

    # Open the file in append & read mode ('a+')
    with open(file_name, "a+") as file_object:
        appendEOL = False
        # Move read cursor to the start of file.
        file_object.seek(0)
        # Check if file is not empty
        data = file_object.read(100)
        if len(data) > 0:
            appendEOL = True
        # Iterate over each string in the list
        for log_entry in args:
            # If file is not empty then append '\n' before first line for
            # other lines always append '\n' before appending line
            if appendEOL == True:
                file_object.write("\n")
            else:
                appendEOL = True
            # Append element at the end of file
            file_object.write(log_entry)

def add_visio_inter_switch_connections(inter_switch_links_df, visio, stn, fabric_label_colours_dct, link_type):
    """Function to create inter switch shape connections"""

    if inter_switch_links_df.empty:
        return None

    # log entry header
    add_log_entry(log_file, '\nLinks\n', 'Fabric, switchName, switchWwn ----> Connected_switchName, Connected_switchWwn')

    if link_type == 'isl':
        desc_str = ISL_DESC
    elif link_type == 'npiv':
        desc_str = NPIV_DESC
    else:
        desc_str = 'Uknown link'

    desc_indented = get_desc_indented(desc_str)
    ncols_num = get_ncols_num()

    # for _, (idx, switch_pair_sr) in zip(tqdm(range(len(san_graph_sw_pair_df.index)), desc=desc_indented, ncols=ncols_num), san_graph_sw_pair_df.iterrows()):

    for _, (_, link_sr) in zip(tqdm(range(len(inter_switch_links_df.index)), desc=desc_indented, ncols=ncols_num), inter_switch_links_df.iterrows()):
        # add connection log entry
        log_entry =  ' '.join([link_sr['Fabric_name'], link_sr['shapeName'], '  ---->  ', link_sr['Connected_shapeName']])
        add_log_entry(log_file, log_entry)
        # print(link_sr['shapeName'], '  ---->  ', link_sr['Connected_shapeName'])

        # activate page with shapes to be connected
        fabric_name_current = link_sr['Fabric_name']
        page = activate_visio_page(visio, page_name=fabric_name_current)
        # drop connection between shapes
        drop_connector_shape(link_sr, page, stn, fabric_label_colours_dct, source='shapeName', destination='Connected_shapeName')

def add_visio_devices(san_links_df, visio, stn, fabric_label_colours, device_class):
    """Function to add servers, storages and libraries shapes to Visio document page and
    create connections between device shapes and switch shapes"""

    fabric_name_prev = None
    x_coordinate = 0

    add_log_entry(log_file, '\nEdge devices')
    # find unique devices on fabric_name -> device_shapename -> device_class level
    san_device_shapes_df = find_device_shapes(san_links_df)

    # print(san_device_shapes_df)

    if device_class == 'server':
        desc_str = SERVER_DESC
    elif device_class == 'storage':
        desc_str = STORAGE_DESC
    else:
        desc_str = 'Uknown device'

    desc_indented = get_desc_indented(desc_str)
    ncols_num = get_ncols_num()

    for _, (_, device_sr) in zip(tqdm(range(len(san_device_shapes_df.index)), desc=desc_indented, ncols=ncols_num), san_device_shapes_df.iterrows()):
        # print(device_sr)
        add_log_entry(log_file, '\n', '-'*30, device_sr.to_string())
        fabric_name_current = device_sr['Fabric_name']
        # activate page with shape to be dropped
        page = activate_visio_page(visio, page_name=fabric_name_current)

        # reset x-coordinate if new page (fabric_name) is activated
        if fabric_name_current != fabric_name_prev:
            x_coordinate = X_START
            fabric_name_prev = fabric_name_current

        # print(fabric_name_current, device_sr['Device_shapeText'])
        # drop shape on active page
        drop_device_shape(device_sr, page, stn, x_coordinate)
        # filter device_shapename links for the dropped shape
        # each row is switch -> device_shapename link with link quantity
        # device_shapename is single device or list of devices groped on fabric connection description
        shape_links_df = find_device_shape_links(device_sr, san_links_df)
        add_log_entry(log_file, shape_links_df.to_string())

        # print(shape_links_df)
        for _, link_sr in shape_links_df.iterrows():
            # drop device_shapename -> switch links
            drop_connector_shape(link_sr, page, stn, fabric_label_colours, source='Device_shapeName', destination='switch_shapeName')
        # shift x-coordinate to the right for the next device_shapename location
        x_coordinate =  x_coordinate + device_sr['x_group_offset']

def find_device_shapes(san_links_df):
    """Function to filter unique devices or device groups on
    fabric_name -> device_shapename -> device_class level"""

    san_device_shapes_df = san_links_df.drop_duplicates(subset=['Fabric_name', 'Device_shapeName', 'deviceType']).copy()
    san_device_shapes_df = san_device_shapes_df[
        ['Fabric_name', 'Device_shapeText', 'Device_shapeName',  'deviceType', 'master_shape', 'y_graph_level', 'x_group_offset']]
    return san_device_shapes_df

def drop_device_shape(device_sr, page, stn, x_coordinate):
    """Function to drop shape on page with x_coordinate"""

    master = stn.Masters(device_sr['master_shape'])

    # drop page on page with x, y coordinates
    device_shape = page.Drop(master, x_coordinate, device_sr['y_graph_level'])
    device_shape.Name = device_sr['Device_shapeName']

    shape_text = device_sr['Device_shapeText']
    # synergy and blade server names are each on new line
    # replace ': ' and ', ' in device_shapetext with new line
    if device_sr['deviceType'] in ['SRV_BLADE', 'SRV_SYNERGY']:
        shape_text = re.sub(': |, ', '\n', shape_text)

    device_shape.Text = shape_text
    # device_shape.Cells("Char.Size").FormulaU = SHAPE_FONT_SIZE

    # # make title bold
    # shape_chars = device_shape.Characters
    # device_shape.CharProps(2, 1)
    return device_shape

def find_device_shape_links(device_sr, san_links_df):
    """Function to filter device_shapename links in the fabric_name.
    Each row is switch -> device_shapename link with link quantity for the device_sr fabric_name.
    Device_shapename is a single device or list of devices groped on fabric connection description"""

    mask_fabric_name = san_links_df['Fabric_name'] == device_sr['Fabric_name']
    mask_shape_name = san_links_df['Device_shapeName'] == device_sr['Device_shapeName']
    mask_device_type = san_links_df['deviceType'] == device_sr['deviceType']
    return san_links_df.loc[mask_fabric_name & mask_shape_name & mask_device_type]

def drop_connector_shape(link_sr, page, stn, fabric_label_colours_dct, source, destination):
    """Function to connect source and destination shapes from link_sr with connector_master shape.
    source and destination parameters are links_sr Series row titles with source and destination shapeNames accordingly"""

    source_shape_name = link_sr[source]
    destination_shape_name =  link_sr[destination]
    connector_master = stn.Masters('Link - HPE')

    # verify if source and desrinataion exist
    page_shape_name_lst = [page.Shapes.ItemU(i).Name  for i in range(1, page.Shapes.count + 1)]
    absent_shape_name_lst = [shape_name for shape_name in [source_shape_name, destination_shape_name] if shape_name not in page_shape_name_lst]

    if not absent_shape_name_lst:
        # sorce and destination shape objects
        source_shape = page.Shapes.ItemU(link_sr[source])
        destination_shape = page.Shapes.ItemU(link_sr[destination])
        # connect source and destionation shape objects (0 - connect without relocating the shapes)
        source_shape.AutoConnect(destination_shape, 0, connector_master)
        # last shape in the page shapes list is connector added above
        connector = page.Shapes.ItemU(page.Shapes.count)
        set_connector_attributes(connector, link_sr, fabric_label_colours_dct)
    else:
        print(f"Can't create link between {source_shape_name} and {destination_shape_name}. "
              f"{', '.join(absent_shape_name_lst)} missing on page {page.Name}")

def set_connector_attributes(connector, link_sr, fabric_label_colours_dct):
    """Function to set connector shape name, text, colour and lines number"""

    # connection shape colour
    fabric_label_colour = fabric_label_colours_dct[link_sr['Fabric_label']]
    link_quantity = link_sr['Physical_link_quantity']

    # set shape connector name
    connector.Name = link_sr['Link_shapeName']
    # set shape connector colour
    connector.Cells('LineColor' ).FormulaU = fabric_label_colour
    # set shape connector text (links number, trunk, npiv etc) if exist
    if pd.notna(link_sr['Link_description']):
        connector.Text = link_sr['Link_description']
    else:
        connector.Text = ""
    # connector.Cells("Char.Size").FormulaU = LINK_FONT_SIZE
    # set shape connector text colour
    connector.Cells('Char.Color' ).FormulaU = fabric_label_colour

    # show lines number for connector with links quantity up to four
    if  1 < link_quantity <= 4:
        connector.Cells("LinePattern").FormulaU = LINE_PATTERN[link_quantity]
    # for connector with links quantity greater than 4 show multiline connector
    elif link_quantity > 4:
        connector.Cells("LinePattern").FormulaU = LINE_PATTERN['4+']

def group_switch_pairs(san_graph_sw_pair_df, visio, ):
    """Function to create Visio groups for each switch pair"""

    add_log_entry(log_file, '\nSwitch groups')

    desc_indented = get_desc_indented(SWITCH_GROUPS_DESC)
    ncols_num = get_ncols_num()

    for _, (idx, switch_pair_sr) in zip(tqdm(range(len(san_graph_sw_pair_df.index)), desc=desc_indented, ncols=ncols_num), san_graph_sw_pair_df.iterrows()):
        add_log_entry(log_file, '\n', switch_pair_sr.to_string())
        fabric_name_current = switch_pair_sr['Fabric_name']
        # activate page with shapes to be grouped
        page = activate_visio_page(visio, page_name=fabric_name_current)
        active_window = visio.ActiveWindow
        shape_names = switch_pair_sr['switchName_Wwn'].split(', ')

        if len(shape_names) > 1:
            # drop any previous selections if they exist
            active_window.DeselectAll()
            # select all switches from switch_pair
            for shape_name in shape_names:
                # print(shape_name)
                active_window.Select(page.Shapes.ItemU(shape_name), 2)
            # group all switches from switch_pair
            active_window.Selection.Group()
            # set name attribute for the group
            sw_group = page.Shapes.ItemU(len(page.Shapes))
            sw_group.Name = ' - '.join(shape_names)

##############################################################################################
    # break

# san_graph_npiv_df.columns
# page = doc.Pages.ItemU("VZ")

# len(page.Shapes)

# page.Shapes.ItemU("xtau-fcsw2 10:00:50:eb:1a:3f:c2:12").NameU

# page.Shapes("Sheet.34").NameU

# page.Shapes.count
# visio.ActiveWindow.Page = "BB"

# active_window = visio.ActiveWindow
# active_window.DeselectAll()

# active_window.Type
# # active_window.SelectAll()

# # active_window.Selection.SelectAll()
# # active_window.Selection.Group()

# page = visio.ActivePage

# active_window.Selection.Select(shape2, 2)

# # active_window.Select(shape1, 2)
# active_window.Select(shape2, 2)
# active_window.Select(shape3, 2)
# # active_window.Selection.ContainingShape
# active_window.Selection.Count

# sw_group = active_window.Selection.Group()

# master = stn.Masters("fcr_fd")
# shape = page.Drop(master, 100, 100)
# shape.Text = "FCR switch"
# shape.Cells("Char.Size").FormulaU = SHAPE_FONT_SIZE

# shape_tst = page.Shapes.ItemU("dr03av07-r2-228 10:00:88:94:71:7e:7d:88")
# len(shape_tst.Text)
# shape_chars = shape_tst.Characters

# shape_chars.Begin = 0
# shape_chars.End = 15
# shape_chars.Cells("CharProps").FormulaU = 2

# shape_chars.CharProps(2, 1)

# bool(switch_pair['ModelName'])

# for i, a, b in zip(range(len(master_shapes)), ['a', 'b', 'c'], [1,2,3]):
#     print(i, a,b)

# list(range(2, -1, -1))


# IceCloud 3D viewer
import icecloud

UiModule.instance().setPointerInteractionEnabled(True)

divePath = "X:/ENDURANCE/dttools/trunk/data-mh/bonney/"
posePath = "X:/ENDURANCE/test-dives/bonney_2009/"
lod = icecloud.LODInfo(10000,1, 10, 1, 10)

diveFile = divePath + "bonney-09-dive27.xyzb"
poseFile = posePath + "Dive27/derived_data/Dive27_02Dec09_poseCorrected.0.txt"
d = icecloud.Dive("09-27", "Dive27", diveFile, poseFile, lod)

diveFile = divePath + "bonney-09-dive17.xyzb"
poseFile = posePath + "Dive17/derived_data/Dive17_21Nov09_poseCorrected.0.txt"
d2 = icecloud.Dive("09-17", "Dive17", diveFile, poseFile, lod)

icecloud.DiveMenu.addDives([d, d2])
icecloud.sondeLayer.load()

# load a mesh
#icecloud.meshLayer.loadMesh("Sonde Bathymetry", "icecloud/data/bonney-sonde-bathy.obj")

getDefaultCamera().getController().setSpeed(100)


import sys
import numpy as np
from sklearn.model_selection import GridSearchCV
from sklearn.linear_model import SGDClassifier
from sklearn.model_selection import cross_val_score
from numpy import mean
from numpy import std
from sklearn.model_selection import cross_val_score
from sklearn.model_selection import cross_validate
from sklearn.metrics import confusion_matrix
from sklearn.metrics import accuracy_score
from sklearn.metrics import recall_score
from sklearn.metrics import precision_score
from sklearn.metrics import f1_score
from ClassificationMetrics import ClassificationMetrics

def SGDClass(data, labels, nof,file,filename ):
    params = {
        'loss' : ['hinge' , 'log', 'modified_huber', 'squared_hinge', 'perceptron'],
        'penalty' : ['l2', 'l1', 'elasticnet'],
        'max_iter' : [100 , 500 ,1000],
        'learning_rate': ['constant' , 'optimal' , 'invscaling' , 'adaptive'],
    }
    clf = GridSearchCV(SGDClassifier(), params, n_jobs=-1, cv=nof)
    clf.fit(data, labels)
    best_parameters = clf.best_params_
    ls = best_parameters['loss']
    pe = best_parameters['penalty']
    mi = best_parameters['max_iter']
    lr = best_parameters['learning_rate']

    model = SGDClassifier(loss=ls , penalty=pe ,max_iter=mi,learning_rate=lr)
    # cvs = cross_val_score(model, data, labels, cv=nof)
    # print(cvs)
    # print(cvs.mean() , "\t" , cvs.std())
    r = ClassificationMetrics()
    r.set_predictorName("SGDClassifier")
    r.set_contin(False)
    r.set_DatasetName(filename)

    bestparameters = 'loss= ' +str(ls) + ' penalty= '+str(pe)+ ' max_iter= '+str(mi)+ ' learning_rate= '+str(lr)
    r.set_best(bestparameters)
    r.PrintbestParameters()

    cv_results = cross_validate(model, data, labels, cv=nof, scoring=r.confusion_matrix_scorer, return_train_score = True)
    r.Print("SGDClassifier")
    r.Print("test")
    r.Results("acc" , cv_results['test_acc'])
    r.Results("MCR" , cv_results['test_MisclassificationRate'])
    r.Results("re" , cv_results['test_re'])
    r.Results("Sen" , cv_results['test_Sensitivity'])
    r.Results("pre" , cv_results['test_pre'])
    r.Results("F_S" , cv_results['test_f_sc'])
    # r.Results("Specificity" , cv_results['test_Specificity'])
    # r.Results("roc" , cv_results['test_roc'])
    # r.Results("fpr" , cv_results['test_fpr'])
    # r.Results("tpr" , cv_results['test_tpr'])
    # r.Results("auc" , cv_results['test_auc'])
    r.Print("train")
    r.Results("acc" , cv_results['train_acc'])
    r.Results("MCR" , cv_results['train_MisclassificationRate'])
    r.Results("re" , cv_results['train_re'])
    r.Results("Sen" , cv_results['train_Sensitivity'])
    r.Results("pre" , cv_results['train_pre'])
    r.Results("F_S" , cv_results['train_f_sc'])
    # r.Results("Specificity" , cv_results['train_Specificity'])
    # r.Results("roc" , cv_results['train_roc'])
    # r.Results("fpr" , cv_results['train_fpr'])
    # r.Results("tpr" , cv_results['train_tpr'])
    # r.Results("auc" , cv_results['train_auc'])


import glob
import random

def label_pop(text_list):

    for pop_lyric_file in glob.glob("../ProcessedData/pop/*.txt"):
        txt_file = open(pop_lyric_file, 'r', encoding="utf-8")
        for line in txt_file.readlines():
            text_list.append("pop "+ line)
    return text_list

def label_traditional(text_list):

    for traditional_lyric_file in glob.glob("../ProcessedData/traditional/*.txt"):
        txt_file = open(traditional_lyric_file, 'r', encoding="utf-8")
        for line in txt_file.readlines():
            text_list.append("traditional "+ line)
    return text_list

def seperate_train_test(text_list):

    test_lines = []
    train_text = ''
    test_text = ''
    i = 0
    while i != int(0.2*len(text_list)):
        random_line = random.randint(0, len(text_list)-1)
        if text_list[random_line] not in test_lines:
            test_lines.append(text_list[random_line])
            i += 1
    for line in text_list:
        if line in test_lines:
            test_text += line
            test_lines.pop(test_lines.index(line))
        else:
            train_text += line
    print(i)
    return train_text, test_text

text_list = label_pop([])
text_list = label_traditional(text_list)
train_text, test_text = seperate_train_test(text_list)

train = open("train.txt", 'w', encoding="utf-8")
test = open("test.txt", 'w', encoding="utf-8")
train.write(train_text)
test.write(test_text)


from flask import request, current_app as app
from flask_api import status
from flask_jwt import current_identity, jwt_required
from sqlalchemy.sql import exists, and_, expression

from receipt_split.models import Friend, User
from receipt_split.schemas import friend_schema, friends_schema, users_schema
from receipt_split.meta import db
from . import create_view, Call, View, get_model_view, accept_reject_view,\
    is_authorized, views, err

@views.route('/friend/<username>', methods=['POST'])
@jwt_required()
def friend_add(username):
    friend = User.query.filter_by(username=username).first()

    if friend is None:
        app.logger.info("/friend/%s does not exist - %s", username,
                        current_identity.username)
        return err("friend does not exist"), status.HTTP_400_BAD_REQUEST

    if friend == current_identity:
        app.logger.info("/friend/%s is self - %s", username,
                        current_identity.username)
        return err("cannot friend yourself"), status.HTTP_400_BAD_REQUEST

    if friend in current_identity.friends:
        return err("friend already added"), status.HTTP_400_BAD_REQUEST

    if db.session.query(expression.literal(True)).filter(
        db.session.query(Friend)
        .filter(
            Friend.from_user_id == current_identity.id,
            Friend.to_user_id == friend.id,
            Friend.accepted.is_(None)
        )
        .exists()
    ).scalar():
        return err("Friend request already sent"), status.HTTP_404_NOT_FOUND

    friend_request = Friend(from_user=current_identity, to_user=friend)

    db.session.add(friend_request)
    db.session.commit()

    friend_dump = friend_schema.dump(friend_request)

    app.logger.info("/friend/%s request for %s - ",
                    current_identity.username, friend_dump)

    return friend_dump, status.HTTP_200_OK

@views.route('/friends', methods=['GET', 'PUT'])
@jwt_required()
def friend_list():
    friends = users_schema.dump(current_identity.friends)
    friends_received = friends_schema.dump(
        Friend.get_received(current_identity)
    )
    friends_sent = friends_schema.dump(
        Friend.get_sent(current_identity)
    )
    app.logger.info("/friend list get - %s - %s", current_identity.username,
                    friends)

    friend_result = {
        "friends_received": friends_received,
        "friends_sent": friends_sent,
        "friends": friends
    }

    if request.method == 'PUT':
        Friend.archive_sent(current_identity)

    return friend_result, status.HTTP_200_OK

@views.route('/friends/<int:id>')
@views.route('/friends/<int:id>/<action>', methods=["GET", "POST"])
@jwt_required()
def friends(id, action=None):
    friend = Friend.query.get(id)

    if not friend:
        app.logger.info("/friend/%s NOT FOUND", id)
        return err("friend not found"), \
            status.HTTP_404_NOT_FOUND

    if friend.to_user_id != current_identity.id:
        app.logger.info("/friend/%s from_user incorrect", id)
        return err("you are not authorized to add friends from this user"), \
            status.HTTP_403_FORBIDDEN

    if friend.from_user_id == current_identity.id:
        app.logger.info("/friend/%s can't friend self", id)
        return err("Cannot friend self"), status.HTTP_403_FORBIDDEN

    if not db.session.query(exists().where(
                            User.id == friend.to_user_id)).scalar():
        return err("User to friend not found"), status.HTTP_404_NOT_FOUND

    if action is None and request.method == 'GET':
        friend_dump = friend_schema.dump(friend)
        return friend_dump

    # accept or reject bahavior after

    if (action == "accept" or action == "reject") and request.method == 'POST':
        # change accepted value

        if action == "accept":
            if friend.accept():
                db.session.commit()

        if action == "reject":
            if friend.reject():
                db.session.commit()

        friend_dump = friend_schema.dump(friend)
        return friend_dump

    return err("Should not get here"), status.HTTP_500_INTERNAL_SERVER_ERROR


# AdventCode Day 6
import time

lList = []
groups_answers = []
tmp = ""

input_list = open("day6.lst").readlines()

for line in input_list:
    if line != "\n":
        tmp += line
    else:
        lList.append(tmp.strip())
        tmp = ""
lList.append(tmp.strip())

def timing(f):
    def wrap(*args, **kwargs):
        time1 = time.time()
        ret = f(*args, **kwargs)
        time2 = time.time()
        print('{:s} function took {:.3f} ms'.format(f.__name__, (time2 - time1) * 1000.0))
        return ret

    return wrap

def get_unique(group_answers):
    answers = []
    # print(group_answers)
    for answer in group_answers:
        # print(answer)
        answers += [char for char in answer if not char in answers and char.isalpha() and char != "\n"]

    return {"nb": len(answers), "answers": answers}

def get_groups(groups, part):
    res = []
    idx = 0
    # new_groups = [group for group in groups.split("\n\n")]
    for ngroup in groups:
        g_res = get_unique(ngroup) if part == 1 else get_common(ngroup)
        # print(" group:", ngroup.replace('\n', ','), "group res:", g_res)
        res.append(g_res)
        idx += 1
    return res

def get_total(reps):
    total = 0
    # print(reps)
    for rep in reps:
        # print(rep)
        total += rep['nb']
    return total

@timing
def part1(to_decode):
    start_time = time.time()
    reps = get_groups(to_decode, 1)
    total = get_total(reps)
    # print("len reps: ", len(reps), "total: ", total, "reps:", reps)
    print("part1: nb groups: {}, count yes answer: {}, time {} seconds".format(len(reps), total,
                                                                               time.time() - start_time))

@timing
def part2(to_decode):
    start_time = time.time()
    res = get_groups(to_decode, 2)
    total = sum(my_res['nb'] for my_res in res)
    print("part2: nb groups: {}, common yes: {}, time: {} seconds".format(len(res), total, time.time() - start_time))

def get_common(ngroup):
    group_answers = []
    answers_by_person = ngroup.split('\n')
    for answers in answers_by_person:
        group_answers.append([char for char in answers])

    if len(group_answers) == 1:
        all_answered = set(group_answers[0]).intersection(group_answers[0])
    else:
        all_answered = set(group_answers[0]).intersection(*group_answers[1:])
    # print("\nby person: ", answers_by_person, ", split answer by person: ", group_answers, ", all: ", all_answered)

    # print("common answers: {}, details: {}, by person: {}".format(len(all_answered), all_answered, answers_by_person))
    return {'nb': len(all_answered), "answers": all_answered}

print("checks")
# 6 yes a b c x y z = 1 group
to_decode = "abcx\nabcy\nabcz"
rep = [get_unique(to_decode)]

print("expected 1 group, 6 yes, curreent: group: {}, rep: {}, details: {}".format(len(rep), get_total(rep), rep))

# This list represents answers from five groups:
# The first group contains one person who answered "yes" to 3 questions: a, b, and c.
#    The second group contains three people; combined, they answered "yes" to 3 questions: a, b, and c.
#    The third group contains two people; combined, they answered "yes" to 3 questions: a, b, and c.
#    The fourth group contains four people; combined, they answered "yes" to only 1 question, a.
#    The last group contains one person who answered "yes" to only 1 question, b.
#    In this example, the sum of these counts is 3 + 3 + 3 + 1 + 1 = 11.
inp = ['abc', 'a\nb\nc', 'ab\nac\n', 'a\na\na\na', 'b']
reps = get_groups(inp, 1)
# print("Expected 5 groups, 3,3,3,1,1 = 11 yes, current group: {}, yes: {}, details: {}".format(len(reps),get_total(reps), reps))
print(
    "Expected 5 groups, 3,3,3,1,1 = 11 yes, current group: {}, yes: {}, details: {}".format(len(reps), get_total(reps),
                                                                                0))

print("list size: {0}".format(str(len(lList))))
part1(lList)  # 6351
print("\n ********************** \n")
# 3 + 0 + 1 + 1 + 1 = 6
inp = ['abc', 'a\nb\nc', 'ab\nac', 'a\na\na\na', 'b']
res = get_groups(inp, 2)
total = sum(my_res['nb'] for my_res in res)
print("Expected 5 groups, 6 common yes, nb groups: {}, common yes: {}".format(len(res), total))
part2(lList)  # 3143
quit()


import sys
sys.path.append('/Users/linus/Desktop/slow-is-fast/manimgl_1.6.1/3b1b-videos-master')

"""
需要注意两点：

1.当用vscode打开路径在/Users/linus/Desktop/slow-is-fast/manimgl_1.6.1的项目的时候
点击下面的`manim_imports_ext_new`是可以正常跳转的
是因为在
/Users/linus/Desktop/slow-is-fast/manimgl_1.6.1/.vscode/settings.json文件中进行了配置
{
    "python.analysis.extraPaths": [
        "./3b1b-videos-master"
    ]
}

2.当在/Users/linus/Desktop/slow-is-fast/manimgl_1.6.1/3b1b-videos-master/_2017/eoc路径下执行
manimgl chapter1.py
为了不报错, 需要执行
import sys
sys.path.append('/Users/linus/Desktop/slow-is-fast/manimgl_1.6.1/3b1b-videos-master')

两者缺一不可！！！
"""
from manim_imports_ext_new import *

class Eoc1Thumbnail(GraphScene):
    CONFIG = {

    }

    def construct(self):
        title = TexText(
            "The Essence of\\\\Calculus",
            tex_to_color_map={
                "\\emph{you}": YELLOW,
            },
        )
        subtitle = TexText("Chapter 1")
        subtitle.match_width(title)
        subtitle.scale(0.75)
        subtitle.next_to(title, DOWN)
        # title.add(subtitle)
        title.set_width(FRAME_WIDTH - 2)
        title.to_edge(UP)
        title.set_stroke(BLACK, 8, background=True)
        # answer = OldTexText("...yes")
        # answer.to_edge(DOWN)

        axes = Axes(
            x_range=(-1, 5),
            y_range=(-1, 5),
            y_axis_config={
                "include_tip": False,
            },
            x_axis_config={
                "unit_size": 2,
            },
        )
        axes.set_width(FRAME_WIDTH - 1)
        axes.center().to_edge(DOWN)
        axes.shift(DOWN)
        self.x_axis = axes.x_axis
        self.y_axis = axes.y_axis
        self.axes = axes

        graph = self.get_graph(self.func)
        rects = self.get_riemann_rectangles(
            graph,
            x_min=0, x_max=4,
            dx=0.2,
        )
        rects.set_submobject_colors_by_gradient(BLUE, GREEN)
        rects.set_opacity(1)
        rects.set_stroke(BLACK, 1)

        self.add(axes)
        self.add(graph)
        self.add(rects)
        # self.add(title)
        # self.add(answer)

        # 为了视频能够渲染出来, 需要加上下面这一行
        self.wait(1)

    def func(slef, x):
        return 0.35 * ((x - 2)**3 - 2 * (x - 2) + 6)


class User:
    bank_name = "First National Dojo"
    def __init__(self, n, ea):
        self.name = n
        self.email_address = ea
        self.account_balance = 0
    def make_deposit(self, amount):
        self.account_balance += amount
        return self
    def make_withdrawal(self, amount):
        if self.account_balance - amount < 0:
            print("Transaction decline: insufficient funds")
        else:
            self.account_balance -= amount
        return self
    def display_user_balance(self):
        print(self.name + " Account Balance: $" + str(self.account_balance))
        if self.account_balance == 0:
            print("Get your bread up, " + self.name)
    def transfer_money(self, other_user, amount):
        if self.account_balance - amount < 0:
            print("Transaction decline: insufficient funds")
        else:
            self.account_balance -= amount
            other_user.account_balance += amount
        return self

Michael = User("Michael G. Scott", "MichaelScarn@DunderMifflin.com")
Dwight = User("Dwight K. Schrute", "DwightKSchrute@DunderMifflin.com")
Jim = User("Jim Halpert", "JimHalpert@DunderMifflin.com")

Michael.make_deposit(1000).make_deposit(1000).make_deposit(1000).make_withdrawal(2500).display_user_balance()
print()

Dwight.make_deposit(700).make_deposit(700).make_withdrawal(3).make_withdrawal(7).display_user_balance()
print()

Jim.make_deposit(700).make_withdrawal(15).make_withdrawal(10).make_withdrawal(25).display_user_balance()
print()

Michael.transfer_money(Jim, 50)
Michael.display_user_balance()
Jim.display_user_balance()


from typing import List

def quick_sort(array: List) -> List:
    """Quick Sorting algorithum
    pivot 을 기준으로 분류하고, 최소 크기로 쪼개어 정렬하는 방법

    Args:
        array (List): 정렬할 리스트

    Returns:
        List: 정렬된 리스트
    """
    if len(array) <= 1:
        return array

    else:
        pivot = array[0]

        greater_list = []
        less_list = []
        eq_list = []
        for element in array:
            if element < pivot:
                less_list.append(element)

            elif element == pivot:
                eq_list.append(element)

            else:
                greater_list.append(element)

        return quick_sort(less_list) + eq_list + quick_sort(greater_list)

if __name__ == "__main__":
    item_list = [2, 5, 1, 9, 2, 3, 2, 1]
    result = quick_sort(item_list)
    print(result)


import unittest
import numpy as np
import fixgw.netfix as netfix
import time

class TestPyEfisConnection(unittest.TestCase):

	def test_connect(self):

            c = netfix.Client('127.0.0.1', 3490)
            c.connect()

            t = np.arange(0,5, .01)
            p = 10*np.sin(2*np.pi/5*t)
            t0 = time.time()
            n = 0
            while True:
                while t[n] > (time.time()-t0):
                    time.sleep(.003)
                c.writeValue("PITCH", p[n])
                n += 1
                if n == len(p):
                    break


# New & Improved Version 2
from tkinter import Tk, Button, Entry, Label, mainloop
from tkinter.font import Font

class API_CONFIG(object):
    def __init__(self):
        self.state = {
            'anchor': ['e', 'n', 's', 'w'],
            'expand': [False, True],
            'fill': [False, True],
            'root': [350, 0],
            'padx': 0,
            'pady': 7,
            'side': ['bottom', 'left', 'right', 'top'],
        }
        self.anime_name, self.resolution, self.first_episode, self.last_episode = '', '', '', ''
        self.master = self.Master(title='Download Preferences')
        self.ANCHOR, self.PADY, self.SIDE = self.state['anchor'][1], self.state['pady'], self.state['side'][3]
        self.default_font = Font(root=self.master, family='Helvetica', size=15, weight='bold')
        self.entry_font = Font(root=self.master, family='Helvetica', size=14, weight='normal')
        Label(self.master, text='On Data Entry, Click Submit!', font=Font(root=self.master, family='Times New Roman', size=13, weight='bold', slant='italic'), fg='red').pack(anchor=self.ANCHOR, side=self.SIDE)

    def Destroy(self):
        self.GetData()
        self.master.destroy()

    def Download(self):
        self.state['root'][1] += 60
        self.master.geometry(f"{self.state['root'][0]}x{self.state['root'][1]}")
        button = Button(self.master, text='Download', command=self.Destroy, font=self.default_font, fg='indigo', borderwidth=5, border=3, relief='ridge')
        button.pack(anchor=self.ANCHOR, pady=self.PADY, side=self.SIDE)

    def Master(self, setWidth:bool=False, setHeight:bool=False, title:str=''):
        root = Tk()
        root.geometry(f"{self.state['root'][0]}x{self.state['root'][1]}")
        root.resizable(width=setWidth, height=setHeight)
        root.title(title)
        return root

    def Frame(self, type:str='', label_text:str='', button_text:str=''):
        self.state['root'][1] += 150
        self.master.geometry(f"{self.state['root'][0]}x{self.state['root'][1]}")

        label = Label(self.master, text=label_text, font=self.default_font, fg='crimson')
        label.pack(anchor=self.ANCHOR, pady=self.PADY, side=self.SIDE)

        entry = Entry(self.master, font=self.entry_font, fg='gold')
        entry.pack(anchor=self.ANCHOR, pady=self.PADY, side=self.SIDE)

        def getEntry():
            if (type == 'anime_name'): self.anime_name = f'{entry.get()}'
            if (type == 'resolution'):
                if (int(f'{entry.get()}') > 1080 or int(f'{entry.get()}') < 480):
                    self.resolution = '720'
                    print('Resolution Not Supported, Using Default!')
                else:
                    self.resolution = f'{entry.get()}'
            if (type == 'first_episode'): self.first_episode = f'{entry.get()}'
            if (type == 'last_episode'): self.last_episode = f'{entry.get()}'

        button = Button(self.master, text=button_text, command=getEntry, font=self.default_font, relief='ridge', borderwidth=5, border=3, fg='teal')
        button.pack(anchor=self.ANCHOR, pady=self.PADY, side=self.SIDE)

    def FetchAnime(self):
        self.Frame('anime_name', 'Anime Name'.upper(), 'Submit')
        self.Frame('resolution', 'Resolution [480/720/1080]'.upper(), 'Submit')
        self.Frame('first_episode', 'First Episode'.upper(), 'Submit')
        self.Frame('last_episode', 'Last Episode'.upper(), 'Submit')
        self.Download()

    def GetData(self):
        print(f'Name: {self.anime_name}\nResolution: {self.resolution}\nFirst Episode: {self.first_episode}\nLast Episode: {self.last_episode}')

if __name__ == '__main__':
    main = API_CONFIG()
    main.FetchAnime()
    mainloop()


"""
ELEKTRON © 2022
Written by Nilusink and melektron
www.elektron.work
30.09.22, 13:57

Module to handle capturing screenshots from the external video device
"""

import os
import shutil
import asyncio

DEVICE_ID = 0

async def take_picture(x=1920, y=1080, format="yuyv422", file="./new.png") -> str:
    #shutil.copy("./new.png", file)
    # ffmpeg -f v4l2 -video_size 1920x1080 -input_format yuyv422 -r 1 -i /dev/video0 -update 1 -frames 1 -y new.png
    #os.system(f"ffmpeg -f v4l2 -video_size {x}x{y} -input_format {format} -i /dev/video{DEVICE_ID} -update 1 -frames 1 -y {file}")
    # run ffmpeg in an async subprocess
    process = await asyncio.create_subprocess_exec(
        "ffmpeg",
        "-f", "v4l2",
        "-video_size", f"{x}x{y}",
        "-input_format", format,
        "-i", f"/dev/video{DEVICE_ID}",
        "-update", "1",
        "-frames", "1",
        "-y",
        file)
    await process.wait()
    return file


"""
D. Уравнение с корнем

Решите в целых числах уравнение:
sqrt(ax + b) = c

a, b, c – данные целые числа: найдите все решения или сообщите,
что решений в целых числах нет.
"""

def input_data():
    a = int(input())
    b = int(input())
    c = int(input())
    return a, b, c

def work(a, b, c):
    if c < 0:
        res = "NO SOLUTION"
    elif a == 0:
        if b == c**2:
            res = "MANY SOLUTIONS"
        else:
            res = "NO SOLUTION"
    else:
        # есть только одно решение
        x = (c**2 - b) / a
        if int(x) == x:
            res = int(x)
        else:
            res = "NO SOLUTION"

    return res

if __name__ == "__main__":
    a, b, c = input_data()
    print(work(a, b, c))
    # assert work(1, 0, 0) == 0
    # assert work(1, 2, 3) == 7
    # assert work(1, 2, -3) == "NO SOLUTION"
    # assert work(0, 0, 0) == "MANY SOLUTIONS"
    # assert work(1, -3, 0) == 3


# -*- encoding: utf-8 -*-

from datetime import datetime, timezone, timedelta
from functools import wraps
import jwt
import os

from flask import request
from flask_restx import Api, Resource, fields, reqparse
from imageai.Classification import ImageClassification
from imageai.Detection import ObjectDetection

from .models import db, Users, JWTTokenBlocklist
from .config import BaseConfig
from .thread_queue import ThreadQueue
from .thread_runner import ThreadRunner
from .detection_thread import ObjectDetectionThread
from .prediction_thread import PredictionThread

parser = reqparse.RequestParser()
parser.add_argument("image", type=str, action="split")
parser.add_argument("eval", type=str, action="split")

rest_api = Api(version="1.0", title="Eval API")

execution_path = os.getcwd()

"""
    SETUP DETECTION DEPENDECIES
"""
prediction = ImageClassification()
prediction.setModelTypeAsResNet50()
# prediction.setModelPath(os.path.join(execution_path, "inception_v3_weights_tf_dim_ordering_tf_kernels.h5"))
prediction.setModelPath(os.path.join(execution_path, "models/resnet50_imagenet_tf.2.0.h5"))
prediction.loadModel()

detector = ObjectDetection()
# detector.setModelTypeAsYOLOv3()
# detector.setModelPath( os.path.join(execution_path , "models/yolo.h5"))
detector.setModelTypeAsRetinaNet()
# print(dir(detector))
detector.setModelPath( os.path.join(execution_path , "models/resnet50_coco_best_v2.1.0.h5"))
detector.loadModel()

"""
    SETUP QUEUE AND RUNNER
"""
thread_queue = ThreadQueue()
thread_runner = ThreadRunner(thread_queue,5)
# tr.start()

"""
    Flask-Restx routes
"""
@rest_api.route('/health')
class Health(Resource):
    """
       health check
    """
    def get(self):
        return {"ok": True, "success": True, "test": True, }, 200

@rest_api.route('/run-object')
class Run(Resource):
    """
       run image detection
    """
    @rest_api.expect(parser)
    def get(self):
        imagePath = parser.parse_args()['image'][0]
        evalId = parser.parse_args()['eval'][0]
        # print('img:', imagePath)

        try:
            # create detection job
            detectionThread = ObjectDetectionThread (evalId,imagePath,detector)
            # add to que
            thread_queue.enqueue(detectionThread)
            # tell runner to start if not already
            thread_runner.start()
        except:
            print('Failed to add job to queue. ', imagePath)

        return {"ok": True, "success": True, "evalId": evalId, "img": imagePath}, 200

"""
    classify endpoint
"""
@rest_api.route('/run-prediction')
class RunPrediction(Resource):
    """
       run image classification
    """
    @rest_api.expect(parser)
    def get(self):

        imagePath = parser.parse_args()['image'][0]
        evalId = parser.parse_args()['eval'][0]
        print('img:', imagePath)

        predictionThread = PredictionThread (evalId,imagePath,prediction)
        predictionThread.start()
        print('Thread: ', predictionThread.ident)

        # "ident": predictionThread.ident,
        return {"ok": True, "success": True, "evalId": evalId, "img": imagePath}, 200

# class TestThread(threading.Thread):
#     def __init__(self,evalId, imagePath):
#         threading.Thread.__init__(self)
#         self.evalId = evalId
#         self.imagePath = imagePath
#     def run(self):
#         print('--------------------')
#         print('Running job ', self.imagePath)
#         time.sleep(random.random() *5)
#         print('Stopping job ', self.imagePath)
#         print('--------------------')

# time.sleep(random.random() *5)
# tt = TestThread('testimage.jpg','1')
# tq.enqueue(tt)
# tr.start()

# time.sleep( 10)
# tt = TestThread('testimage2.jpg','2')
# tq.enqueue(tt)
# tr.start()


import requests
from bs4 import BeautifulSoup as bs
import json
import csv

def parc():
    headers={
        'accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9',
        'user-agent': 'Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Mobile Safari/537.36'
        }

    all_list=[]
    for i in range(1,9):

        ur=f'https://shop.casio.ru/catalog/?PAGEN_1={i}'
        req=requests.get(ur,headers=headers)
        src=req.content
        soup=bs(src,'lxml')
        item__link=soup.find_all(class_='product-item__link')
        item__articul=soup.find_all(class_='product-item__articul')
        item_price=soup.find_all(class_='product-item__price')

        for e,m,t in zip(item__articul,item_price,item__link):
            s='https://shop.casio.ru'+t.get('href')
            s=s.strip()
            e=e.text
            e=e.strip()
            m=m.text
            m=m.strip()
            all={
                'модель часов':e,
                'цена':m,
                'ссылка':s

            }

            all_list.append(all)

            with open('parc.csv','a',encoding='utf-8') as file:
                file_writer = csv.writer(file)
                file_writer.writerow((
                        e,
                        m,
                        s
                        ))
    with open('parc.json','a',encoding='utf-8') as file:
        json.dump(all_list,file,indent=4,ensure_ascii=False)

parc()


import torch
import torch.nn as nn
import torchvision
import torch.backends.cudnn as cudnn
import torch.optim
import os
import sys
import argparse
import time
import image_data_loader
import lightdehazeNet
import numpy as np
from torchvision import transforms

def weights_init(m):
    classname = m.__class__.__name__
    if classname.find('Conv') != -1:
        m.weight.data.normal_(0.0, 0.02)
    elif classname.find('BatchNorm') != -1:
        m.weight.data.normal_(1.0, 0.02)
        m.bias.data.fill_(0)

def train(args):

	ld_net = lightdehazeNet.LightDehaze_Net().cuda()
	ld_net.apply(weights_init)

	training_data = image_data_loader.hazy_data_loader(args["train_original"],
											 args["train_hazy"])
	validation_data = image_data_loader.hazy_data_loader(args["train_original"],
											 args["train_hazy"], mode="val")
	training_data_loader = torch.utils.data.DataLoader(training_data, batch_size=8, shuffle=True, num_workers=4, pin_memory=True)
	validation_data_loader = torch.utils.data.DataLoader(validation_data, batch_size=8, shuffle=True, num_workers=4, pin_memory=True)

	criterion = nn.MSELoss().cuda()
	optimizer = torch.optim.Adam(ld_net.parameters(), lr=float(args["learning_rate"]), weight_decay=0.0001)

	ld_net.train()

	num_of_epochs = int(args["epochs"])
	for epoch in range(num_of_epochs):
		for iteration, (hazefree_image, hazy_image) in enumerate(training_data_loader):

			hazefree_image = hazefree_image.cuda()
			hazy_image = hazy_image.cuda()

			dehaze_image = ld_net(hazy_image)

			loss = criterion(dehaze_image, hazefree_image)

			optimizer.zero_grad()
			loss.backward()
			torch.nn.utils.clip_grad_norm(ld_net.parameters(),0.1)
			optimizer.step()

			if ((iteration+1) % 10) == 0:
				print("Loss at iteration", iteration+1, ":", loss.item())
			if ((iteration+1) % 200) == 0:

				torch.save(ld_net.state_dict(), "trained_weights/" + "Epoch" + str(epoch) + '.pth')

		# Validation Stage
		for iter_val, (hazefree_image, hazy_image) in enumerate(validation_data_loader):

			hazefree_image = hazefree_image.cuda()
			hazy_image = hazy_image.cuda()

			dehaze_image = ld_net(hazy_image)

			torchvision.utils.save_image(torch.cat((hazy_image, dehaze_image, hazefree_image),0), "training_data_captures/" +str(iter_val+1)+".jpg")

		torch.save(ld_net.state_dict(), "trained_weights/" + "trained_LDNet.pth")

if __name__ == "__main__":

	ap = argparse.ArgumentParser()
	ap.add_argument("-th", "--train_hazy", required=True, help="path to hazy training images")
	ap.add_argument("-to", "--train_original", required=True, help="path to original training images")
	ap.add_argument("-e", "--epochs", required=True, help="number of epochs for training")
	ap.add_argument("-lr", "--learning_rate", required=True, help="learning rate for training")

	args = vars(ap.parse_args())

	train(args)


from django.shortcuts import render, redirect

# Create your views here.

def view_bag(request):
    """ A view to return the bag content page """

    return render(request, 'bag/bag.html')

def add_to_bag(request, item_id):
    """ Add product to shopping bag """

    redirect_url = request.POST.get('redirect_url')
    bag = request.session.get('bag', {})

    bag[item_id] = 1

    request.session['bag'] = bag
    print(request.session['bag'])
    return redirect(redirect_url)

def remove_from_bag(request, item_id):
    if request.method == 'POST':
        # Perform the necessary logic to remove the item from the bag using the item_id
        bag = request.session.get('bag', {})
        if item_id in bag:
            del bag[item_id]
            request.session['bag'] = bag

        return redirect('view_bag')


from bs4 import BeautifulSoup
import requests
import re

MYTISCHTENNIS_URI = "https://www.mytischtennis.de"

def readTableDataLink(link):
    request = requests.get(link)
    if request.status_code != 200:
        return None

    data = request.content
    soup = BeautifulSoup(data, 'html.parser')
    table = soup.find('table')

    tableData = []
    row = 0
    for tr in table.findAll("tr"):
        trs = tr.findAll("td")
        column = 0
        rowData = []
        for e in trs:
            text = e.text.replace('\n', '')
            link = None
            try:
                link = e.find('a')['href']
                # Some links seem to be internal.
                if link[:5] != 'https':
                    link = MYTISCHTENNIS_URI + link
            except:
                pass
            rowData.append((text, link))
            column += 1
        if len(rowData) > 0:
            tableData.append(rowData)
        row += 1
    return tableData

setPattern = re.compile(r'(\d+):(\d+)')
def parseSets(listSets):
    parsedList = []
    for s in listSets:
        parsed = setPattern.match(s)
        if parsed is not None:
            parsedList.append((int(parsed.group(1)), int(parsed.group(2))))
        else:
            parsedList.append(None)

    return parsedList

mannschaften = readTableDataLink("https://www.mytischtennis.de/clicktt/TTBW/22-23/verein/21015/TTC-GW-Konstanz/mannschaften/")

schaeferPositiv = []
schaeferNegativ = []

for m in mannschaften:
    mannschaft, begegnungenLink = m[0]
    begegnungen = readTableDataLink(begegnungenLink)
    print('\n________ Mannschaft: %s ________' % mannschaft)
    for b in begegnungen:
        heim = b[3][0]
        gast = b[4][0]
        weAreLeftSide = True
        if "TTC GW Konstanz" in gast:
            weAreLeftSide = False

        ergebnisBegegnung, link = b[7]
        if link is not None:
            spiele = readTableDataLink(link)
            print("Begegnung %s - %s - %s" % (heim, gast, ergebnisBegegnung))
            for s in spiele:
                if len(s) < 10:
                    continue
                name1 = s[2][0]
                name2 = s[4][0]
                sets = [s[5][0], s[6][0], s[7][0], s[8][0], s[9][0]]
                sets = parseSets(sets)
                for set in sets:
                    if set is None or "nicht anwesend" in name1 or "nicht anwesend" in name2:
                        break
                    if set[0] == 11 and set[1] == 0:
                        schaeferDoku = [heim, gast, name1, name2, link]
                        print(schaeferDoku)
                        if weAreLeftSide:
                            schaeferPositiv.append(schaeferDoku)
                        else:
                            schaeferNegativ.append(schaeferDoku)
                    if set[0] == 0 and set[1] == 11:
                        schaeferDoku = [heim, gast, name1, name2, link]
                        print(schaeferDoku)
                        if weAreLeftSide:
                            schaeferNegativ.append(schaeferDoku)
                        else:
                            schaeferPositiv.append(schaeferDoku)

print("\n\n ____ ERGEBNISSE ____")
print("Für uns:")
print(schaeferPositiv)
print("\nGegen uns:")
print(schaeferNegativ)
print("\n\nEndergebnis:")
print(len(schaeferPositiv), ':', len(schaeferNegativ))


import seaborn as sns
import matplotlib.pyplot as plt
import numpy as np
flights = sns.load_dataset('flights')
tips = sns.load_dataset('tips')
iris = sns.load_dataset("iris")
print(iris.head())
print(iris["species"].unique())
# g = sns.PairGrid(iris)
g = sns.FacetGrid(data=tips,col="time",row="smoker")
g.map(plt.scatter,"total_bill","tip")
plt.show()