from os import get_inheritable
from kollider_api_client.ws import KolliderWsClient
from kollider_api_client.rest import KolliderRestClient
from utils import *
from console_logger import *
from lnd_client import LndClient
from kollider_msgs import OpenOrder, Position, TradableSymbol, Ticker
from time import sleep
from threading import Lock
import json
from math import floor
import uuid
from pprint import pprint
import threading

import zmq

SATOSHI_MULTIPLIER = 100000000

SOCKET_ADDRESS = "tcp://*:5556"

class HedgerState(object):
	position_quantity = 0
	ask_open_order_quantity = 0
	bid_open_order_quantity = 0
	target_quantity = 0
	target_value = 0
	is_locking = False
	lock_price = None
	side = None
	predicted_funding_payment = 0

	def to_dict(self):
		return {
			"position_quantity": self.position_quantity,
			"bid_open_order_quantity": self.bid_open_order_quantity,
			"ask_open_order_quantity": self.ask_open_order_quantity,
			"target_quantity": self.target_quantity,
			"target_value": self.target_value,
			"is_locking": self.is_locking,
			"lock_price": self.lock_price,
			"side": self.side,
			"predicted_funding_payment": self.predicted_funding_payment
		}

class Wallet(object):

	def __init__(self):
		self.channel_balance = 0
		self.nchain_balance = 0
		self.kollider_balance = 0

	def update_channel_balance(self, balance):
		self.channel_balance = balance

	def update_onchain_balance(self, balance):
		self.onchain_balance = balance

	def update_kollider_balance(self, balance):
		self.kollider_balance = balance

	def to_dict(self):
		return {
			"channel_balance": self.channel_balance,
			"onchain_balance": self.onchain_balance,
			"kollider_balance": self.kollider_balance
		}

	def total_ln_balance(self):
		return self.channel_balance + self.kollider_balance

class HedgerEngine(KolliderWsClient):
	def __init__(self, lnd_client):
		# Orders that are currently open on the Kollider platform.
		self.open_orders = {}
		# Positions that are currently open on the Kollider platform.
		self.positions = {}
		self.current_index_price = 0
		self.current_mark_price = 0
		self.target_fiat_currency = "USD"
		self.target_symbol = "BTCUSD.PERP"
		self.target_index_symbol = ".BTCUSD"
		self.ws_is_open = False
		self.contracts = {}

		self.hedge_value = 0
		self.hedge_proportion = 0
		self.hedge_side = None
		self.target_leverage = 100

		# Last hedge state.
		self.last_state = None

		# Summary of the connected node.
		self.node_info = None

		# Order type that is used to make trades on Kollider.
		self.order_type = "Market"

		self.wallet = Wallet()

		self.lnd_client = lnd_client

		self.last_ticker = Ticker()

		self.received_tradable_symbols = False

		# Average hourly funding rates for each symbol. Used
		# as an prediction of the next funding rate.
		self.average_hourly_funding_rates = {}

		self.is_locked = True

	def to_dict(self):
		average_funding = self.average_hourly_funding_rates.get(self.target_symbol)
		average_funding = average_funding if average_funding else 0
		return {
			"node_info": self.node_info,
			"wallet": self.wallet.to_dict(),
			"current_index_price": self.current_index_price,
			"current_mark_price": self.current_mark_price,
			"last_state": self.last_state.to_dict(),
			"target_fiat_currency": self.target_fiat_currency,
			"target_symbol": self.target_index_symbol,
			"target_index_symbol": self.target_index_symbol,
			"hedge_value": self.hedge_value,
			"hedge_proportion": self.hedge_proportion,
			"average_hourly_funding_rate": average_funding
		}

	def set_params(self, **args):
		self.hedge_proportion = args.get("hedge_proportion") if args.get("hedge_proportion") else 0
		self.hedge_side = args.get("hedge_side") if args.get("hedge_side") else None
		self.target_fiat_currency = args.get("target_fiat_currency") if args.get("target_fiat_currency") else None
		self.target_symbol = args.get("target_symbol") if args.get("target_symbol") else None
		self.target_index_price = args.get("target_index_symbol") if args.get("target_index_symbol") else None
		self.target_leverage = args.get("target_leverage") if args.get("target_leverage") else None
		self.order_type = args.get("order_type") if args.get("order_type") else "Market"

	def on_open(self, event):
		self.auth()
		sleep(1)
		self.sub_index_price([self.target_index_symbol])
		self.sub_mark_price([self.target_symbol])
		self.sub_ticker([self.target_symbol])
		self.sub_position_states()
		self.fetch_positions()
		self.fetch_open_orders()
		self.fetch_tradable_symbols()
		self.fetch_ticker(self.target_symbol)
		self.fetch_balances()
		self.ws_is_open = True

	def on_pong(self, ctx, event):
		None

	def on_error(self, ctx, event):
		pass

	def on_message(self, _ctx, msg):
		msg = json.loads(msg)
		t = msg["type"]
		data = msg["data"]
		if t == 'authenticate':
			if data["message"] == "success":
				self.is_authenticated = True
			else:
				print("Auth Unsuccessful: {}".format(data))
				self.is_authenticated = False
				self.__reset()

		elif t == 'index_values':
			self.current_index_price = float(data["value"])

		elif t == 'mark_prices':
			self.current_mark_price = float(data["price"])

		elif t == 'positions':
			print("Received positions.")
			positions = data["positions"]
			for key, value in positions.items():
				self.positions[key] = Position(msg=value)

		elif t == 'open_orders':
			print("Received open orders")
			open_orders = data["open_orders"]
			for symbol, open_orders in open_orders.items():
				for open_order in open_orders:
					if self.open_orders.get(symbol) is None:
						self.open_orders[symbol] = []
					oo = OpenOrder(msg=open_order)
					self.open_orders[symbol].append(oo)

		elif t == 'tradable_symbols':
			for symbol, contract in data["symbols"].items():
				self.contracts[symbol] = TradableSymbol(msg=contract)
			self.received_tradable_symbols = True

		elif t == 'open':
			open_order = data
			contract = self.get_contract()
			dp = contract.price_dp
			open_order_parsed = OpenOrder(data, dp)
			if self.open_orders.get(open_order_parsed.symbol) is None:
				self.open_orders[open_order_parsed.symbol] = []
			self.open_orders[open_order_parsed.symbol].append(open_order_parsed)

		elif t == 'done':
			symbol = data["symbol"]
			order_id = data["order_id"]
			self.open_orders[symbol] = [open_order for open_order in self.open_orders[symbol] if open_order.order_id != order_id]

		elif t == 'fill':
			symbol = msg["symbol"]
			order_id = msg["order_id"]
			quantity = msg["quantity"]
			orders = self.open_orders.get(symbol)
			if orders is None:
				return
			for order in orders:
				if order.order_id == order_id:
					order.quantity -= quantity

		elif t == 'position_states':
			position = Position(msg=data)
			if position.symbol == self.target_symbol:
				self.positions[self.target_symbol] = position

		elif t == 'ticker':
			self.last_ticker = Ticker(msg=data)

		elif t == 'order_invoice':
			print("Received Pay to Trade invoice for: {}".format(data["margin"]))
			res = self.lnd_client.send_payment(data["invoice"])

		elif t == 'settlement_request':
			print("Received settlement Request")
			amount = data["amount"]
			self.make_withdrawal(amount, "Kollider Trade Settlement")

		elif t == 'balances':
			total_balance = 0
			cash_balance = float(data["cash"])
			if cash_balance > 1:
				self.make_withdrawal(cash_balance, "Kollider Payout")
			total_balance += cash_balance
			isolated_margin = data["isolated_margin"].get(self.target_symbol)
			if isolated_margin is not None:
				total_balance += float(isolated_margin)

			order_margin = data["order_margin"].get(self.target_symbol)
			if order_margin is not None:
				total_balance += float(order_margin)
			self.wallet.update_kollider_balance(total_balance)

		elif t == 'error':
			print("ERROR")
			print(data)

	def make_withdrawal(self, amount, message):
		amt = int(amount)
		res = self.lnd_client.add_invoice(amt, message)
		withdrawal_request = {
			"withdrawal_request": {
				"Ln": {
					"payment_request": res.payment_request,
					"amount": amt,
				}
			}
		}
		self.withdrawal_request(withdrawal_request)

	def cancel_all_orders_on_side(self, side):
		orders = self.open_orders.get(self.target_symbol)

		if orders is None:
			return

		for order in orders:
			if order.side == side:
				self.cancel_order({"order_id": order.order_id, "symbol": self.target_symbol, "settlement_type": "Delayed"})

	def calc_contract_value(self):
		if self.contracts.get(self.target_symbol) is not None:
			contract = self.get_contract()
			price = self.current_mark_price
			if contract.is_inverse_priced:
				return contract.contract_size / price * SATOSHI_MULTIPLIER
			else:
				return contract.contract_size * price * SATOSHI_MULTIPLIER
		else:
			raise Exception("Target contract not available")

	def calc_number_of_contracts_required(self, value_target):
		try:
			value_per_contract = self.calc_contract_value()
			qty_of_contracts = floor(value_target / value_per_contract)
			return qty_of_contracts
		except Exception as e:
			print(e)

	def get_open_orders(self):
		return self.open_orders.get(self.target_symbol)

	def get_open_position(self):
		return self.positions.get(self.target_symbol)

	def get_contract(self):
		return self.contracts.get(self.target_symbol)

	def get_best_price(self, side):
		if side == "Bid":
			return self.last_ticker.best_bid
		else:
			return self.last_ticker.best_ask

	def update_average_funding_rates(self):
		rest_client = KolliderRestClient("http://api.staging.kollider.internal/v1/")
		average_funding_rates = rest_client.get_average_funding_rates()
		for funding_rate in average_funding_rates["data"]:
			self.average_hourly_funding_rates[funding_rate["symbol"]] = funding_rate["mean_funding_rate"]

	def build_target_state(self):
		state = HedgerState()

		target_value = self.wallet.total_ln_balance()
		hedge_value = (target_value * self.hedge_proportion)

		# The number a contracts we need to cover the value.
		target_number_of_contracts = self.calc_number_of_contracts_required(hedge_value)

		# Getting current open orders.
		open_orders = self.get_open_orders()

		open_ask_order_quantity = 0
		open_bid_order_quantity = 0

		current_position_quantity = 0

		if open_orders is not None:
			open_bid_order_quantity = sum([open_order.quantity for open_order in open_orders if open_order.side == "Bid"])
			open_ask_order_quantity = sum([open_order.quantity for open_order in open_orders if open_order.side == "Ask"])

		# Getting current position on target symbol.
		open_position = self.get_open_position()

		if open_position is not None:
			current_position_quantity = open_position.quantity
			state.side = open_position.side
			# If current position is on the wrong side we adding a minus to reflect that.
			if open_position.side != opposite_side(self.hedge_side):
				current_position_quantity = current_position_quantity * -1
			else:
				state.lock_price = open_position.entry_price

		state.target_quantity = target_number_of_contracts
		state.target_value = hedge_value
		state.bid_open_order_quantity = open_bid_order_quantity
		state.ask_open_order_quantity = open_ask_order_quantity
		state.position_quantity = current_position_quantity

		hourly_funding_rate = self.average_hourly_funding_rates.get(self.target_symbol)
		if hourly_funding_rate is not None:
			state.predicted_funding_payment = hedge_value * hourly_funding_rate
		else:
			state.predicted_funding_payment = 0

		self.last_state = state

		return state

	def converge_state(self, state):
		# Nothing needs to be done if target is current.

		target_side = opposite_side(self.hedge_side)

		current = 0
		if target_side == "Bid":
			current = state.bid_open_order_quantity + state.position_quantity
		else:
			current = state.ask_open_order_quantity + state.position_quantity

		target = state.target_quantity

		if target == current:
			self.cancel_all_orders_on_side(self.hedge_side)
			return

		contract = self.get_contract()

		dp = contract.price_dp

		side = None

		if target > current:
			side = opposite_side(self.hedge_side)
			self.cancel_all_orders_on_side(self.hedge_side)

		elif target < current:
			side = self.hedge_side
			if target_side == "Bid" and state.bid_open_order_quantity > 0:
				self.cancel_all_orders_on_side(target_side)
				return
			elif target_side == "Ask" and state.ask_open_order_quantity > 0:
				self.cancel_all_orders_on_side(target_side)
				return

		price = self.get_best_price(side)

		# Adding the order to the top of the book by adding/subtracting one tick.
		if side == "Bid":
			price += contract.tick_size
		else:
			price -= contract.tick_size

		price = int(price * (10**dp))

		qty_required = abs(target - current)

		order = {
			'symbol': self.target_symbol,
			'side': side,
			'quantity': qty_required,
			'leverage': self.target_leverage,
			'price': price,
			'order_type': self.order_type,
			'margin_type': 'Isolated',
			'settlement_type': 'Instant',
			'ext_order_id': str(uuid.uuid4()),
		}

		self.place_order(order)

	def check_state(self, state):
		side = opposite_side(self.hedge_side)
		# If our current position has the right quantity and the right side we are fully locked
		if state.target_quantity == state.position_quantity and state.side == side:
			state.is_locking = False
			self.is_locked = True
		else:
			state.is_locking = True
			self.is_locked = False
		return state

	def print_state(self, state):
		pprint(state.to_dict())
		pprint(self.wallet.to_dict())

	def update_node_info(self):
		try:
			node_info = self.lnd_client.get_info()
			self.node_info = {
				"alias": node_info.alias,
				"identity_pubkey": node_info.identity_pubkey,
				"num_active_channels": node_info.num_active_channels,
			}
		except Exception as e:
			print(e)

	def update_wallet_data(self):
		channel_balances = self.lnd_client.get_channel_balances()
		onchain_balances = self.lnd_client.get_onchain_balance()
		self.wallet.update_channel_balance(channel_balances.balance)
		self.wallet.update_onchain_balance(onchain_balances.total_balance)

	def cli_listener(self):
		context = zmq.Context()
		socket = context.socket(zmq.REP)
		socket.bind(SOCKET_ADDRESS)
		while True:
			message = socket.recv_json()
			if message.get("action") is not None:
				action = message.get("action")
				value = message.get("value")
				if action == "set_hedge_proportion":
					print("here")
					self.hedge_proportion = value
			sleep(0.5)
			msg = self.to_dict()
			socket.send_json(msg)
			sleep(0.5)

	def start(self, settings):
		pprint(settings)
		print("Connecting to Kollider websockets..")
		while not self.ws_is_open:
			pass
		print("Connected to websockets.")

		cycle_speed = settings["cycle_speed"]

		self.set_params(**settings)

		self.update_node_info()

		cli_listener = threading.Thread(target=self.cli_listener, daemon=False)
		cli_listener.start()

		while True:
			# Don't do anything if we haven't received the contracts.
			if not self.received_tradable_symbols and not self.is_authenticated:
				continue

			# Don't do anything if we haven't received mark or index price.
			if self.current_index_price == 0 or self.current_mark_price == 0:
				continue

			# Don't do anything if we have no ticker price.
			if self.last_ticker.last_side is None:
				continue

			self.update_wallet_data()

			self.update_average_funding_rates()

			# Getting current state.
			state = self.build_target_state()
			self.check_state(state)
			# Printing the state.
			# Converging to that state.
			self.converge_state(state)

			sleep(cycle_speed)

if __name__ in "__main__":

	settings = None
	with open('config.json') as a:
		settings = json.load(a)

	kollider_api_key = settings["kollider"]["api_key"]
	kollider_url = settings["kollider"]["ws_url"]

	node_url = settings["lnd"]["node_url"]
	macaroon_path = settings["lnd"]["admin_macaroon_path"]
	tls_path = settings["lnd"]["tls_path"]

	lnd_client = LndClient(node_url, macaroon_path, tls_path)

	rn_engine = HedgerEngine(lnd_client)

	lock = Lock()

	rn_engine.connect(settings["kollider"]["ws_url"], settings["kollider"]["api_key"], settings["kollider"]["api_secret"], settings["kollider"]["api_passphrase"])

	rn_engine.start(settings)


def isMod3Eq0(x):
    return x % 3 == 0

if __name__ == "__main__":
    arr = []
    for _ in range(5):
        temp = int(input("정수 입력 : "))
        arr.append(temp)

    result_arr = list(filter(isMod3Eq0, arr))

    print("원본 리스트 : ", arr)
    print("결과 리스트 : ", result_arr)


'''
给定一个数组 nums，编写一个函数将所有 0 移动到数组的末尾，同时保持非零元素的相对顺序。

示例:

输入: [0,1,0,3,12]
输出: [1,3,12,0,0]
说明:

必须在原数组上操作，不能拷贝额外的数组。
尽量减少操作次数。

来源：力扣（LeetCode）
链接：https://leetcode-cn.com/problems/move-zeroes
著作权归领扣网络所有。商业转载请联系官方授权，非商业转载请注明出处。
'''

class Solution:
    def moveZeroes(self, nums):
        """
        Do not return anything, modify nums in-place instead.
        """
        # l = len(nums)  #原始数组长度
        # while True:   #删除数组中的所有0
        #     try:
        #         nums.remove(0)
        #     except:
        #         break
        # nums += [0]*(l-len(nums)) #数组长度减少的就是删除的0的个数
        # return nums

        i = -1
        for j in range(len(nums)):
            print(j)
            if nums[j]!=0:
                i+=1
                nums[i],nums[j]= nums[j], nums[i]
        return nums

obj=Solution()
print(obj.moveZeroes([0,1,0,3,12]))


import yaml
import requests
import time
from datetime import datetime, timedelta, date
import pandas as pd

# INITIALISATION DE VARIABLES GLOBALES
sDateDebut = "2020-01-23"
sAujourdhui = date.today().strftime("%Y-%m-%d")
dDemarrageDate = datetime.fromisoformat(sDateDebut)
cols = ['Date',
        'FR Tot Cas Confirmés',
        'FR Tot Décès',
        'WW Tot Cas Confirmés',
        'WW Tot Décès',
        'Source',
        'FR Tot Guéris',
        'FR Tot Hospitalisés'
       ]

# FONCTIONS
def recupDataWithException2(_jsonout, _index1, _index2):
    try:
        data = _jsonout[_index1][_index2]
    except:
        data = 0
    return data

def AjouteSantePubliqueFrLigne(jsonout, df):
    df = df.append({
                    cols[0] : jsonout['date'] ,
                    cols[1] : recupDataWithException2(jsonout, 'donneesNationales', 'casConfirmes') ,
                    cols[2] : recupDataWithException2(jsonout, 'donneesNationales', 'deces'),
                    cols[3] : recupDataWithException2(jsonout,'donneesMondiales', 'casConfirmes'),
                    cols[4] : recupDataWithException2(jsonout,'donneesMondiales', 'deces'),
                    cols[5] : 'sante-publique-france',
                    cols[6] : 0,
                    cols[7] : 0
                 } ,
                 ignore_index=True)
    return df

def ajouteLigneVide(df, madate):
    df = df.append({
                    cols[0] : madate ,
                    cols[1] : 0,
                    cols[2] : 0,
                    cols[3] : 0,
                    cols[4] : 0,
                    cols[5] : 'no-data',
                    cols[6] : 0,
                    cols[7] : 0
                 } ,
                 ignore_index=True)
    return df

# RECUPERATION DONNEES SANTE PUBLIQUE FRANCE
def RecupereDonneesSantePubliqueFrance():
    print ('--> Démarrage du process')
    sDateParcours = sDateDebut
    i=1
    requesReturnCode=200
    yamls = pd.DataFrame()
    while (sDateParcours != sAujourdhui):
        myDate = dDemarrageDate + timedelta(days=i)
        sDateParcours = myDate.strftime("%Y-%m-%d")
        fichier = 'https://raw.githubusercontent.com/opencovid19-fr/data/master/sante-publique-france/' + sDateParcours + '.yaml'
        #print ('--> sante-publique-france / ', sDateParcours)
        req = requests.get(fichier)
        requesReturnCode = req.status_code
        if (requesReturnCode==200):
            yamlout = yaml.load(req.text, Loader=yaml.FullLoader)
            yamls = AjouteSantePubliqueFrLigne(yamlout, yamls)
        else:
            print ("(*) Pas de données pour ", myDate.strftime("%Y-%m-%d"))
            # ajoute une ligne vide
            yamls = ajouteLigneVide(yamls, myDate.strftime("%Y-%m-%d"))
        i=i+1
    print ('--> Fin du process')
    return yamls

# RECUPERATION DONNEES MINISTERE SANTE
def RecupereDonneesMinistereSante(yamls):
    i=1
    sDateParcours = sDateDebut
    print ('--> Démarrage du process')
    while (sDateParcours != sAujourdhui):
        myDate = dDemarrageDate + timedelta(days=i)
        sDateParcours = myDate.strftime("%Y-%m-%d")
        #print("Traintement date: ",  dateParcours)
        fichier = 'https://raw.githubusercontent.com/opencovid19-fr/data/master/ministere-sante/' + sDateParcours + '.yaml'
        req = requests.get(fichier)
        requesReturnCode = req.status_code
        if (requesReturnCode==200):
            yamlout = yaml.load(req.text, Loader=yaml.FullLoader)
            if (yamls[cols[5]][i-1] == "no-data"):
                print ("(*) Modifie les données manquantes pour la date du ", myDate.strftime("%Y-%m-%d"))
                # Modifie toute la ligne
                yamls.loc[i-1, cols[1]] = recupDataWithException2(yamlout, 'donneesNationales', 'casConfirmes')
                yamls.loc[i-1, cols[2]]  = recupDataWithException2(yamlout, 'donneesNationales', 'deces')
                yamls.loc[i-1, cols[3]]  = recupDataWithException2(yamlout, 'donneesMondiales', 'casConfirmes')
                yamls.loc[i-1, cols[4]]  = recupDataWithException2(yamlout, 'donneesMondiales', 'deces')
                yamls.loc[i-1, cols[5]]  = "ministere-sante"
            # Ajoute les nouveaux champs
            yamls.loc[i-1, cols[6]] = recupDataWithException2(yamlout, 'donneesNationales', 'hospitalises')
            yamls.loc[i-1, cols[7]] = recupDataWithException2(yamlout, 'donneesNationales', 'gueris')
        i=i+1
    print ('--> Fin du process')
    return yamls

def Bouchetrous(yamls):
    # On reparcourre toutes les lignes déjà récupérées précédemment
    i=1
    for index, row in yamls.iterrows():
        if (yamls[cols[5]][i-1] == "no-data"):
            for j in [1, 2, 3, 4, 6, 7]:
                yamls.loc[i-1, cols[j]] = yamls[cols[j]][i-2]
        i += 1
    return yamls

# Programme principal
print ("Récupération des données de Santé Publique France")
data = RecupereDonneesSantePubliqueFrance()
print ("Récupération des données du ministère de la santé")
data = RecupereDonneesMinistereSante(data)
print ("Comble les jours manquants")
data = Bouchetrous(data)

# quelques calculs
data['FR Nvx cas confirmés'] = 0
data['FR Nvx Décès'] = 0
data['FR Nvx Guéris'] = 0
data['FR Nvx Hospitalisés'] = 0

# Calcule les différence vs cumuls
for index, row in data.iterrows():
    if index > 0:
        data.loc[index, 'FR Nvx cas confirmés'] = data['FR Tot Cas Confirmés'][index] - data['FR Tot Cas Confirmés'][index-1] if (data['FR Tot Cas Confirmés'][index] - data['FR Tot Cas Confirmés'][index-1])>0 else 0
        data.loc[index, 'FR Nvx Décès'] = data['FR Tot Décès'][index] - data['FR Tot Décès'][index-1] if (data['FR Tot Décès'][index] - data['FR Tot Décès'][index-1])>0 else 0
        data.loc[index, 'FR Nvx Guéris'] = data['FR Tot Guéris'][index] - data['FR Tot Guéris'][index-1] if (data['FR Tot Guéris'][index] - data['FR Tot Guéris'][index-1] )>0 else 0
        data.loc[index, 'FR Nvx Hospitalisés'] = data['FR Tot Hospitalisés'][index] - data['FR Tot Hospitalisés'][index-1] if (data['FR Tot Hospitalisés'][index] - data['FR Tot Hospitalisés'][index-1] )>0 else 0

# Retire la dernière ligne (aujourd'hui) si pas de données récupérées
if (data.loc[len(data)-1,'Source'] == 'no-data'):
    data = data.drop([len(data)-1])

print ("Ecriture dans un fichier csv")
data.to_csv("./data/covid19_" + sAujourdhui + ".csv", index=False)
data.to_csv("./data/latest.csv", index=False)


# USAGE
# python object_detector.py --conf config/config.json --image florida_trip.png

# import the necessary packages

from config.conf import Conf
from yolo_parser.parseyolooutput import ParseYOLOOutput
from datetime import datetime
from imutils import paths
import numpy as np
import argparse
import imutils
import cv2
import os

#imagePaths = list(paths.list_images(args["dataset"]))

# construct the argument parser and parse the arguments
ap = argparse.ArgumentParser()
ap.add_argument("-c", "--conf", required=True,
	help="Path to the input configuration file")
ap.add_argument("-i", "--image", required=True,
	help="Path of the image")
args = vars(ap.parse_args())

# load the image configuration file
conf = Conf(args["conf"])
image = cv2.imread(args["image"])

# load the COCO class labels our YOLO model was trained on
labelsPath = os.path.sep.join([conf["yolo_path"], "coco.names"])
LABELS = open(labelsPath).read().strip().split("\n")

# initialize a list of colors to represent each possible class label
np.random.seed(42)
COLORS = np.random.randint(0, 255, size=(len(LABELS), 3),
	dtype="uint8")

# derive the paths to the YOLO weights and model configuration
weightsPath = os.path.sep.join([conf["yolo_path"], "yolov3.weights"])
configPath = os.path.sep.join([conf["yolo_path"], "yolov3.cfg"])

# load our YOLO object detector trained on COCO dataset (80 classes)
# and determine only the *output* layer names that we need from YOLO
print("[INFO] loading YOLO from disk...")
net = cv2.dnn.readNetFromDarknet(configPath, weightsPath)
ln = net.getLayerNames()
ln = [ln[i[0] - 1] for i in net.getUnconnectedOutLayers()]

# initialize the YOLO output parsing object
pyo = ParseYOLOOutput(conf)

# resize the image, convert it to grayscale, and blur it
image = imutils.resize(image, width=400)
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
gray = cv2.GaussianBlur(gray, (7, 7), 0)

# construct a blob from the input image and then perform
# a forward pass of the YOLO object detector, giving us
# our bounding boxes and associated probabilities
blob = cv2.dnn.blobFromImage(image, 1 / 255.0,
            (416, 416), swapRB=True, crop=False)
net.setInput(blob)
layerOutputs = net.forward(ln)

(H, W) = image.shape[:2]

# parse YOLOv3 output
(boxes, confidences, classIDs) = pyo.parse(layerOutputs, LABELS, H, W)

# apply non-maxima suppression to suppress weak,
# overlapping bounding boxes
idxs = cv2.dnn.NMSBoxes(boxes, confidences,
				conf["confidence"], conf["threshold"])

# ensure at least one detection exists
if len(idxs) > 0:
    # loop over the indexes we are keeping
    for i in idxs.flatten():
        # extract the bounding box coordinates
        (x, y) = (boxes[i][0], boxes[i][1])
        (w, h) = (boxes[i][2], boxes[i][3])

        # draw a bounding box rectangle and label on the frame
        color = [int(c) for c in COLORS[classIDs[i]]]
        cv2.rectangle(image, (x, y), (x + w, y + h), color, 2)
        text = "{}: {:.4f}".format(LABELS[classIDs[i]],confidences[i])
        y = (y - 15) if (y - 15) > 0 else h - 15
        cv2.putText(image, text, (x, y), cv2.FONT_HERSHEY_SIMPLEX, 0.5, color, 2)
        # show the frame
        cv2.imshow("show", image)
        cv2.waitKey(0)

# do a bit of cleanup
cv2.destroyAllWindows()


from tkinter import messagebox, filedialog
from save_load.uid_converter import encoder
from save_load import DEFAULT_SAVE_FOLDER

def create_save_file(save_slot: int, all_key_attributes: dict) -> None:
    """
    Saves an encoded dictionary as a string to a file, given a save slot and all key attributes.

    :parameter save_slot: an integer that represents the slot in which the save file will be stored,
                          or -1 to indicate for open file window for selection
    :parameter all_key_attributes: a dictionary that contains all player data and game environment data
    :precondition: save_slot must be greater than or equal to -1
    :precondition: all_key_attributes must be a dictionary that contains all player data and game environment data
    :postcondition: create a plan text file, which contains an encoded dictionary as string
    :raises TypeError: if all_key_attributes is not a dictionary
    """
    if type(all_key_attributes) is not dict:
        raise TypeError("all_key_attributes must be dictionary")
    if save_slot == -1:
        filename = filedialog.askopenfilename(title="Select a File", initialdir=DEFAULT_SAVE_FOLDER,
                                              filetypes=(("SAVE File", "*.save"), ("SAVE File", " ")))
    else:
        filename = f'{DEFAULT_SAVE_FOLDER}SAVE{str(save_slot).zfill(2)}.save'
    if filename:
        saves = encoder(phrase=str(all_key_attributes))
        with open(filename, 'w') as file_object:
            file_object.write(saves)
        messagebox.showinfo(title="Saved!", message=f"Progress Saved - {filename[-11:]}")
    else:
        messagebox.showinfo(title="Warning!", message=f"Select a file to save your progress.")

def main():
    """
    Drive the program.
    """

if __name__ == "__main__":
    main()


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

# **************************
# src/main.py
# **************************

import datetime

from calculation import (
    calculate_line_daily_mileage,
    calculate_train_lenght,
    calculate_transportation_values
)
from changing import (
    update_wagons_attrs,
)
from classes import (
    Normatives,
    Registry
)
from confirmation import (
    confirm_possible_trains
)
from conversion import (
    convert_confirmed_trains,
    convert_preplanned_services,
    convert_wagons_attrs
)
from creation import (
    create_debug_file_output,
    create_trains,
    create_wagons
)
from normatives import (
    mileage_frequency_standards,
    service_duration_standards
)
from parsing import (
    convert_start_date,
    pars_wagons_data
)
from planning import (
    service_planning
)
from selection import (
    select_current_idle_end,
    select_extra_wagon_data_path,
    select_hitched_wagons,
    select_idle_wagons,
    select_line_motion_time,
    select_main_wagon_data_path,
    select_output_data_path,
    select_planning_end_date,
    select_possible_trains,
    select_preplanned_services,
    select_text_result_data_path,
    select_transportation_values,
    select_unhitched_wagons
)
from utility import (
    daterange,
    print_result_services_to_file
)
from verification import (
    verify_planning_results,
)

raw_start_date, raw_main_wagons_attrs = pars_wagons_data(
    select_main_wagon_data_path())

Registry.planning_start_date = convert_start_date(raw_start_date)

Registry.planning_end_date = select_planning_end_date()

Registry.mileage_standards = mileage_frequency_standards()
Registry.duration_standards = service_duration_standards()
wagons_attrs = convert_wagons_attrs(raw_main_wagons_attrs)

Registry.wagons = create_wagons(wagons_attrs,
                                start_date=Registry.planning_start_date,
                                end_date=Registry.planning_end_date)

update_wagons_attrs(pars_wagons_data(select_extra_wagon_data_path()))

hitched_wagons = select_hitched_wagons()
Registry.train_lenght = calculate_train_lenght(hitched_wagons)
Registry.unhitched_wagons = select_unhitched_wagons()
possible_trains = select_possible_trains()
confirmed_trains = confirm_possible_trains(possible_trains)
Registry.trains = create_trains(
    Registry.train_lenght, hitched_wagons, verbose=False)
if not confirmed_trains is None:
    Registry.trains.update(create_trains(
        Registry.train_lenght, convert_confirmed_trains(confirmed_trains)))

Registry.transportation_values = calculate_transportation_values(
    start_date=Registry.planning_start_date,
    end_date=Registry.planning_end_date,
    basic_values=select_transportation_values(),
    line_motion_time=select_line_motion_time())

calculate_line_daily_mileage()

for wagon_number, wagon_object in Registry.wagons.items():
    serv_date = Registry.wagons[wagon_number].usage_start_date
    wagon_object.change_idle_reason(serv_date,
                                    wagon_object.define_service_type(
                                        serv_date),
                                    verbose=False)

for train_object in Registry.trains.values():
    if not train_object.verify_wagons_idle_reasons(Registry.planning_start_date,
                                                   verbose=False):
        train_object.unify_train_service_type(Registry.planning_start_date,
                                              verbose=False)

# Проставляем на начало расчета отстой сцепу №904 (56009-56010) по ремонту редукторов
# ТОЛЬКО ДЛЯ РАСЧЕТА ОТ 31.03.2022!!!
for wagon_object in Registry.trains[904].wagons.values():
    wagon_object.change_idle_reason(Registry.planning_start_date,
                                    "o",
                                    verbose=False)

Registry.result_services = select_current_idle_end(
    select_idle_wagons(Registry.planning_start_date))

# Вносим в расчет информацию о выходе из ТОиР вагонов,
# находящихся в ТОиР на дату начала расчета
for service_type, periods in Registry.result_services.items():
    for (start_date, end_date), rolling_stock_data in periods.items():
        first_date = start_date + datetime.timedelta(days=1)
        for rolling_stock_type, objects in rolling_stock_data.items():
            for rolling_stock_object in objects:
                if rolling_stock_type == "trains":
                    for wagon_object in rolling_stock_object.wagons.values():
                        for date in daterange(first_date, end_date):
                            wagon_object.change_idle_reason(date,
                                                            service_type,
                                                            verbose=False)
                if rolling_stock_type == "single_wagons":
                    for date in daterange(first_date, end_date):
                        rolling_stock_object.change_idle_reason(date,
                                                                service_type,
                                                                verbose=False)

converted_preplanned_services = convert_preplanned_services(
    select_preplanned_services())
# print(converted_preplanned_services)  # debug
# Вносим в расчет информацию о предзапланированных ТОиР
for wagon_number, services in converted_preplanned_services.items():
    Registry.wagons[wagon_number].preplanned_services = services

service_types = (  # "sr",
    "tr3",
    "tr2",
    "tr1",
    # "to2",
    # "to1"
)

service_planning(service_types)
verify_planning_results(service_types)

create_debug_file_output(select_output_data_path())
print_result_services_to_file(select_text_result_data_path())

print("END")

# Откорректировать метод verify_wagons_idle_reasons для Train


# Nama: Habibi
# NIM: 0110220247
# Kelas: TI07

def convert_list(multilist):
  # Tulis kode fungsi convert_list() di bawah ini
  # Hapus pass jika implementasi sudah dibuat

  # Buat nama variabel newMultilist dengan tipe data array
  newMultilist = []
  # Lakukan perulangan dengan nilai yang diterima sebagai parameter multilist
  for baris in multilist:
    # lakukan perulangan kembali dengan nilai yanga ada di variabel baris
    for elemen in baris:
      #tambahkan nilai kedalam variabel newMultilist
      newMultilist.append(elemen)
  # kembalikan nilai yang ada di varibel newMultilist
  return newMultilist

def get_nilai(filename, nama):
  # Tulis kode fungsi get_nilai() di bawah ini
  # Hapus pass jika implementasi sudah dibuat

  # buka file dengan nama file yang diterima oleh parameter filename, dan simpan datanya kedalam variabel f
  f = open(filename)
  # lakukan perulangan dengan data yang ada di variabel f
  for each_line in f:
    # masukan nilai each_line yang sudah dipisah menggunakan split dan simpan di variabel data
    data = each_line.split()
    # lakukan pengecekan, jika nilai yang ada di variabel data dan index ke 0 sama dengan nilai yang diterima oleh parameter nama
    if data[0].lower() == nama.lower():
      # jika sama maka akan mengembalikan nilai dalam bentuk float
      return round(float(data[1]))
  # panggil fungsi close untuk menyatakan telah selesai membuka file
  f.close()

def nilai_max(filename):
  # Tulis kode fungsi nilai_max() di bawah ini
  # Hapus pass jika implementasi sudah dibuat

  # Buat nama variabel list_nilai dengan tipe data array
  list_nilai = []
  # buka file dengan nama file yang diterima oleh parameter filename, dan simpan datanya kedalam variabel f
  f = open(filename)
  # lakukan perulangan dengan data yang ada di variabel f
  for each_line in f:
    # masukan nilai each_line yang sudah dipisah menggunakan split dan simpan di variabel data
    data = each_line.split()
    # masukan nilai data dan index ke 0 kedalam variabel nama
    nama = data[0]
    # masukan nilai data dan index ke 1 kedalam variabel nama dan bertipe float
    nilai = float(data[1])
    #tambahkan nilai kedalam variabel list_nilai, dengan nilai sebagai index 0 dan nama sebagai index 1
    list_nilai.append([nilai, nama])
  # panggil fungsi close untuk menyatakan telah selesai membuka file
  f.close()

  # mencari nilai max yang ada di variabel list_nilai
  max_nilai = max(list_nilai)
  # kembalikan nilai dari variabel max_nilai dengan index ke 1 baru index ke 2
  return max_nilai[1],max_nilai[0]

# Mulai baris ini hingga baris paling bawah
# digunakan untuk mengetes fungsi yang telah dibuat.
# Tidak perlu mengubah bagian ini.
# Ketika dijalankan, program akan menampilkan contoh
# pemanggilan fungsi dan solusi yang seharusnya.
# Cocokkan hasil pemanggilan fungsi dengan solusi
# yang seharusnya.
def test():
  r = convert_list([[1,2], [3,4], [5,6]])
  print(f"convert_list([[1,2], [3,4], [5,6]]) = {r} \n(solusi: [1, 2, 3, 4, 5, 6])")
  print()
  r = get_nilai('nilai1.txt','joni')
  print(f"get_nilai('nilai1.txt','joni') = {r} \n(solusi: 76)")
  print()
  r = get_nilai('nilai2.txt','joni')
  print(f"get_nilai('nilai2.txt','joni') = {r} \n(solusi: None)")
  print()
  r = nilai_max('nilai1.txt')
  print(f"nilai_max('nilai1.txt') = {r} \n(solusi: ('Zack', 88.05)")
  print()
  r = nilai_max('nilai2.txt')
  print(f"nilai_max('nilai2.txt') = {r} \n(solusi: ('Arya', 90.00)")
  print()

if __name__ == '__main__':
  test()


import staff
import yeehoo
from os import system

if __name__=='__main__':
    while True:
        system("cls")
        print("Welcome to our YEEhoO system!")
        option=int(input("Which system will want to use?\n1:Customer\n2:Staff system\n3:Quit\n"))
        system("cls")
        if option==1 or option==2:
            if option==1:
                yeehoo.yeehoo_system()
            else:
                staff.staff_system()
        else:
            break
    print("Thanks for using YEEhoO!!!")


from flask import Flask
import sqlite3
import installation

app = Flask(__name__)

try:
    import LocalSettings
except:
    print(' * LocalSettings.py를 찾을 수 없습니다. ')
    installation.start()

dictionary = open('dic.json', 'r', encoding = 'utf-8').read()
webview = open('view/index.html', 'r', encoding = 'utf-8').read()

@app.route('/')
def main():
    publish_unit = '공개 범위 : '
    if LocalSettings.ENTREE_HOST_PUBLISH == 'local':
        publish_unit += '로컬'
    elif LocalSettings.ENTREE_HOST_PUBLISH == 'server':
        publish_unit += '서버'
    else:
        return 0

app.run(LocalSettings.FLASK_HOST, LocalSettings.FLASK_HOST_PORT)


import tkinter as tk

import customtkinter as ctk

from src.camera_input_screen import CameraInputScreen
from src.file_input_screen import FileInputScreen
from src.model_types import ModelTypes

class HomeScreen(ctk.CTk):
    def __init__(self):
        super().__init__()
        self.title("Traffic Assistant")
        task_frame = ctk.CTkFrame(self, fg_color="transparent")
        button_frame = ctk.CTkFrame(task_frame, fg_color="transparent")
        mode_frame = ctk.CTkFrame(self, fg_color="transparent")
        radio_frame = ctk.CTkFrame(mode_frame, fg_color="transparent")

        helper_lbl_1 = ctk.CTkLabel(task_frame, text="Mode")
        helper_lbl_1.pack(pady=20)

        helper_lbl_2 = ctk.CTkLabel(radio_frame, text="Image Source")
        helper_lbl_2.pack(pady=20)

        sign_detection_btn = ctk.CTkButton(
            button_frame,
            text="Traffic Signs",
            command=lambda: self.openWindow(ModelTypes.TRAFFIC_SIGNS),
        )
        sign_detection_btn.pack(side=tk.LEFT, padx=10)
        road_markings_detection_btn = ctk.CTkButton(
            button_frame,
            text="Road Markings",
            command=lambda: self.openWindow(ModelTypes.ROAD_MARKINGS),
        )
        road_markings_detection_btn.pack(side=tk.LEFT, padx=10)
        traffic_signs_detection_btn = ctk.CTkButton(
            button_frame,
            text="Traffic Lights",
            command=lambda: self.openWindow(ModelTypes.TRAFFIC_LIGHTS),
        )
        traffic_signs_detection_btn.pack(side=tk.LEFT, padx=10)

        self.phone = tk.StringVar(value="file")
        home = ctk.CTkRadioButton(
            radio_frame, text="Camera", variable=self.phone, value="camera"
        )
        home.pack(side=tk.LEFT, padx=10)
        office = ctk.CTkRadioButton(
            radio_frame, text="File", variable=self.phone, value="file"
        )
        office.pack(side=tk.LEFT, padx=10)
        radio_frame.pack()
        button_frame.pack()

        task_frame.pack(pady=20, expand=True)
        mode_frame.pack(side=tk.TOP, pady=20, expand=True)

    def openWindow(self, model_type):
        if self.phone.get() == "camera":
            CameraInputScreen(self, model_type)
        else:
            FileInputScreen(self, model_type)


"""
    Written by Jonny Hyman, 2020
        www.jonnyhyman.com
        www.github.com/jonnyhyman

    MIT License

    This code shows three ways of understanding the logistic
    map : cobweb plot, time series, and bifurcation plot

"""

from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import (QApplication, QHBoxLayout,
                             QLabel, QSizePolicy, QSlider, QSpacerItem,
                             QVBoxLayout, QWidget)

from PyQt5 import QtWidgets, QtCore, QtGui
import pyqtgraph as pg

from numba import jit, prange, njit
import numpy as np

from pathlib import Path
import sys

from time import time
import types

colors =  {
            'lightest':"#eeeeee",
            'lighter':"#e5e5e5",
            'light':"#effffb",
            'himid':"#50d890",
            'midmid':"#1089ff",
            'lomid':"#4f98ca",
            'dark' :"#272727",
            'darker' :"#23374d",
}

numlabelsize = 22
txtlabelsize = 20

# STYLING
numfont = QtGui.QFont("Avenir Next") # requires macos
numfont.setPixelSize(numlabelsize)

txtfont = QtGui.QFont("Avenir Next") # requires macos
txtfont.setPixelSize(txtlabelsize)

brushes = { k: pg.mkBrush(c) for k, c in colors.items() }

pg.setConfigOptions(antialias=True)
pg.setConfigOption('background', colors['dark'])
pg.setConfigOption('foreground', colors['light'])

QPushButton_style = f"""
QPushButton{{
	color: {colors['light']};
	background-color: transparent;
	border: 1px solid #4589b2;
	padding: 5px;

}}

QPushButton::hover{{
	background-color: rgba(255,255,255,.2);
}}

QPushButton::pressed{{
	border: 1px solid {colors['himid']};
	background-color: rgba(0,0,0,.3);
}}"""

QLabel_style = f"""
QLabel{{
    color: {colors['light']};
}}
"""

QCheckBox_style = f"""
QCheckBox{{
    background-color: {colors['darker']};
    color: {colors['light']};
    padding:5px;
}}
"""

def custom_axis_item_resizeEvent(self, ev=None):
    """ custom implementation of AxisItem.resizeEvent to control `nudge`

        this overwrites the instance method for `AxisItem`
    """

    #s = self.size()

    ## Set the position of the label
    nudge = 15

    br = self.label.boundingRect()
    p = QtCore.QPointF(0, 0)
    if self.orientation == 'left':
        p.setY(int(self.size().height()/2 + br.width()/2))
        p.setX(-nudge)
    elif self.orientation == 'right':
        p.setY(int(self.size().height()/2 + br.width()/2))
        p.setX(int(self.size().width()-br.height()+nudge))
    elif self.orientation == 'top':
        p.setY(-nudge)
        p.setX(int(self.size().width()/2. - br.width()/2.))
    elif self.orientation == 'bottom':
        p.setX(int(self.size().width()/2. - br.width()/2.))
        p.setY(int(self.size().height()-br.height()+nudge))
    self.label.setPos(p)
    self.picture = None

@njit
def linear_interp(x, in_min, in_max, out_min, out_max, lim=True, dec=None):
    y = (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min

    if dec is not None:
        y = round(y, dec)

    if not lim:
        return y

    else:
        y = max(out_min, y)
        y = min(out_max, y)

        return y

@jit(cache=True, nopython=True) # pragma: no cover
def logistic_map(pop, rate):
    """
    From pynamical `https://github.com/gboeing/pynamical`
    Define the equation for the logistic map.

    Arguments
    ---------
    pop: float
        current population value at time t
    rate: float
        growth rate parameter values

    Returns
    -------
    float
        scalar result of logistic map at time t+1
    """

    return pop * rate * (1 - pop)

def get_function_points(model, r, n, start, end):
    """
    From pynamical
    Calculate model results for n population values evenly spaced between start and end values.

    Arguments
    ---------
    model: function
        defining an iterated map to simulate
    r: float
        growth rate parameter value to pass to the map
    n: int
        number of iterations to run
    start: float
        lower limit of the function range
    end: float
        upper limit of the function range

    Returns
    -------
    tuple
        x_vals, y_vals
    """

    x_vals = np.linspace(start, end, n)
    y_vals = [model(x, r) for x in x_vals]
    return x_vals, y_vals

def get_cobweb_points(model, r, x, n):
    """
    From pynamical `https://github.com/gboeing/pynamical`
    Calculate the vertices of cobweb lines for a cobweb plot.

    Steps in the calculation:
    1) Let x = 0.5
    2) Start on the x-axis at the point (x, 0).
    3) Draw a vertical line to the red function curve: this point has the coordinates (x, f(x)).
    4) Draw a horizontal line from this point to the gray diagonal line: this point has the coordinates (f(x), f(x)).
    5) Draw a vertical line from this point to the red function curve: this point has the coordinates (f(x), f(f(x))).
    6) Repeat steps 4 and 5 recursively one hundred times.

    Arguments
    ---------
    model: function
        defining an iterated map to simulate
    r: float
        growth rate parameter value to pass to the map
    x: float
        starting population value
    n: int
        number of iterations to run

    Returns
    -------
    tuple
        cobweb_x_vals, cobweb_y_vals
    """

    cobweb_points = [(x, 0)]
    for _ in range(n):
        y1 = model(x, r)
        cobweb_points.append((x, y1))
        cobweb_points.append((y1, y1))
        y2 = model(y1, r)
        cobweb_points.append((y1, y2))
        x = y1
    return zip(*cobweb_points)

def cobweb_plot(plt, idx=-1,
                model=logistic_map, r=0, cobweb_x=0.5,

                function_n=1000,

                cobweb_n=100, num_discard=0,
                title='', filename='', show=True, save=True,
                start=0, end=1, figsize=(6,6), diagonal_linewidth=1.35,
                cobweb_linewidth=1, function_linewidth=1.5,
                folder='images', dpi=300, bbox_inches='tight', pad=0.1):

    plt.clear()

    initial_pop = float(cobweb_x)

    stride_idx = (idx-1)*3

    func_x_vals, func_y_vals = get_function_points(
                        model=model, r=r, n=function_n, start=start, end=end)
    cobweb_x_vals, cobweb_y_vals = get_cobweb_points(
                        model=model, r=r, x=cobweb_x, n=cobweb_n)

    cobweb_x_vals = cobweb_x_vals[:stride_idx]
    cobweb_y_vals = cobweb_y_vals[:stride_idx]

    plt.setTitle(f"Cobweb Plot")

    diagonal_line = plt.plot((0,1), (0,1))
    diagonal_line.setPen(width=diagonal_linewidth)

    function_line = pg.PlotDataItem(x=func_x_vals, y=func_y_vals)
    function_line.setPen(color=colors['lomid'], width=3.0)
    function_line = plt.addItem(function_line)

    sizes = 1/np.linspace(.1,1,len(cobweb_x_vals))
    sizes = np.maximum(5, sizes)

    cobweb_line = plt.plot(cobweb_x_vals, cobweb_y_vals, symbol='o', symbolSize=sizes)
    cobweb_line.setPen(color=colors['lomid'], width=cobweb_linewidth)
    cobweb_line.setSymbolPen(color=(1,1,1,0), width=0.0)
    cobweb_line.setSymbolBrush(color=colors['himid'])

    xaxis = plt.getAxis("bottom")
    #xaxis.setTickSpacing(4,4)

    xaxis.tickFont = numfont
    xaxis.setStyle(tickTextOffset = 20)

    yaxis = plt.getAxis("left")
    #yaxis.setTickSpacing(.2, .2)

    yaxis.resizeEvent = types.MethodType(custom_axis_item_resizeEvent, yaxis)

    yaxis.tickFont = numfont
    yaxis.setStyle(tickTextOffset = 10, tickLength=10)

    xaxis.label.setFont(txtfont)
    yaxis.label.setFont(txtfont)
    plt.titleLabel.item.setFont(txtfont)

    return np.concatenate(([initial_pop,], np.array(cobweb_y_vals[1::3])))

def series_plot(plt, y_vals, idx=100, r=0, xall=False):

    plt.clear()
    plt.setTitle("Population vs Time, growth rate: {:4.2f}".format(r))

    t = np.arange(len(y_vals))
    y = y_vals[:idx]
    t = t[:idx]

    if len(t) < 20:
        plt.setXRange(*[0,20])
    else:
        if not xall:
            plt.setXRange(*[len(t)-20, len(t)])
        else:
            plt.setXRange(*[0, 30])

    plt.setYRange(*[0,1])
    plt.showGrid(x=True, y=True)

    s = 20/len(t)
    s = max(10,s)

    line = plt.plot(x=t, y=y)
    line.setPen(color=colors['lomid'], width=3.0)

    scat = pg.ScatterPlotItem(x=t, y=y, size=s, name='series')
    scat.setPen(color=(1,1,1,0), width=0.0)
    scat.setBrush(color=colors['himid'])
    plt.addItem(scat)

    xaxis = plt.getAxis("bottom")
    #xaxis.setTickSpacing(4,4)

    xaxis.tickFont = numfont
    xaxis.setStyle(tickTextOffset = 20)

    yaxis = plt.getAxis("left")
    #yaxis.setTickSpacing(.2, .2)

    yaxis.resizeEvent = types.MethodType(custom_axis_item_resizeEvent, yaxis)

    yaxis.tickFont = numfont
    yaxis.setStyle(tickTextOffset = 10, tickLength=10)

    xaxis.label.setFont(txtfont)
    yaxis.label.setFont(txtfont)
    plt.titleLabel.item.setFont(txtfont)

def bifurc_plot(plt, y_vals, r=0, ipop=0.5, discard=64):

    if (y_vals.shape[0]) < discard:
        return

    ys = y_vals[discard:]
    xs = np.repeat(r,len(ys))
    s = 1
    new_s = 5

    if len(plt.items) == 0:
        # __init__
        bifurcation = pg.ScatterPlotItem(x=xs, y=ys, size=new_s, antialias=True, name='bifurc')
        bifurcation.setBrush(color=colors['himid'], alpha=0.5, width=1)
        bifurcation.setPen(color=(0,0,0,0), width=0, alpha=0.5)
        plt.addItem(bifurcation)

        plt.titleLabel.item.setFont(txtfont)

        xaxis = plt.getAxis("bottom")
        xaxis.setTickSpacing(1, .5)

        xaxis.tickFont = numfont
        xaxis.setStyle(tickTextOffset = 20)

        yaxis = plt.getAxis("left")
        #yaxis.setTickSpacing(.2, .2)

        yaxis.tickFont = numfont
        yaxis.setStyle(tickTextOffset = 10, tickLength=10)

        xaxis.label.setFont(txtfont)
        yaxis.label.setFont(txtfont)

    else:
        # __update__
        bifurcation = plt.items[0]

        n_new = len(xs)

        xs = np.concatenate((xs, bifurcation.data['x']))
        ys = np.concatenate((ys, bifurcation.data['y']))

        ss = np.repeat(1,len(xs))
        ss[0:n_new] = new_s

        bs = [brushes['lomid'] for b in range(len(xs))]
        bs[0:n_new] = [brushes['himid'] for _ in range(n_new)]

        bifurcation.setData(xs,ys, size=ss, brush=bs)

    plt.setXRange(*[0,4])
    plt.setYRange(*[0,1])

class Controls(QWidget):
    def __init__(self, variable='', parent=None):
        super(Controls, self).__init__(parent=parent)
        self.verticalLayout = QVBoxLayout(self)

        self.l1 = QVBoxLayout()
        self.l1.setAlignment(Qt.AlignTop)

        self.cobweb_box = QtWidgets.QCheckBox('ðŸ•¸ï¸� Plot', parent=self)
        self.l1.addWidget(self.cobweb_box)
        self.cobweb_box.setChecked(0)

        self.series_box = QtWidgets.QCheckBox("ðŸ“ˆ Plot", parent=self)
        self.l1.addWidget(self.series_box)
        self.series_box.setChecked(1)

        self.bifurc_box = QtWidgets.QCheckBox("â�„ï¸� Plot", parent=self)
        self.l1.addWidget(self.bifurc_box)
        self.bifurc_box.setChecked(0)

        self.verticalLayout.addLayout(self.l1)

        self.l2 =  QVBoxLayout()
        self.l2.setAlignment(Qt.AlignTop)

        self.animlabel = QLabel(self)
        self.l2.addWidget(self.animlabel)
        self.animlabel.setText("Animation FPS")

        self.animrate = QtWidgets.QSlider(self)
        self.animrate.setOrientation(Qt.Horizontal)
        self.l2.addWidget(self.animrate)
        self.animrate.setFixedWidth(self.animrate.width())

        self.verticalLayout.addLayout(self.l2)

        self.l3 =  QVBoxLayout()
        self.l3.setAlignment(Qt.AlignTop)

        self.sub1 = QHBoxLayout()
        self.sub1.setAlignment(Qt.AlignLeft)
        self.rate_txt = QLabel("Rate", self)

        self.rate_box = QtWidgets.QDoubleSpinBox(self)
        self.rate_box.setSingleStep(0.01)
        self.rate_box.setDecimals(2)

        self.sub1.addWidget(self.rate_txt)
        self.sub1.addWidget(self.rate_box)

        self.l3.addLayout(self.sub1)

        self.rate = QSlider(self)
        self.rate.setOrientation(Qt.Horizontal)
        self.l3.addWidget(self.rate)

        self.verticalLayout.addLayout(self.l3)

        self.l4 =  QVBoxLayout()
        self.l4.setAlignment(Qt.AlignTop)

        self.sub2 = QHBoxLayout()
        self.sub2.setAlignment(Qt.AlignLeft)

        self.ipoptxt = QLabel(self)
        self.sub2.addWidget(self.ipoptxt)
        self.ipoptxt.setAlignment(Qt.AlignHCenter)
        self.ipoptxt.setText("Initial\nPop.")

        self.ipop_box = QtWidgets.QDoubleSpinBox()
        self.ipop_box.setSingleStep(0.01)
        self.ipop_box.setDecimals(2)
        self.ipop_box.setValue(0.5)
        self.sub2.addWidget(self.ipop_box)

        self.l4.addLayout(self.sub2)

        self.ipop = QSlider(self)
        self.ipop.setOrientation(Qt.Horizontal)
        self.l4.addWidget(self.ipop)
        self.ipop.setValue(50)

        self.verticalLayout.addLayout(self.l4)

        self.resize(self.sizeHint())

        self.setFixedWidth(self.animrate.width() + 20)

        self.rate.valueChanged.connect(lambda: self.setValues('rate_slider'))
        self.rate_box.valueChanged.connect(lambda: self.setValues('rate_box'))
        self.ipop.valueChanged.connect(lambda: self.setValues('ipop_slider'))
        self.ipop_box.valueChanged.connect(lambda: self.setValues('ipop_box'))

        self.rateval = None

        self.l5 =  QVBoxLayout()
        self.l5.setAlignment(Qt.AlignTop)

        self.animb = QtWidgets.QPushButton('Play', parent=self)
        self.l5.addWidget(self.animb)
        self.animb.setFixedWidth(self.animlabel.width())

        self.reset = QtWidgets.QPushButton('Reset', parent=self)
        self.l5.addWidget(self.reset)
        self.reset.setFixedWidth(self.animlabel.width())

        self.clear = QtWidgets.QPushButton('Clear', parent=self)
        self.clear.setCheckable(False)
        self.clear.setFixedWidth(self.animlabel.width())
        self.l5.addWidget(self.clear)

        self.verticalLayout.addLayout(self.l5)

        # STYLING
        self.clear.setStyleSheet(QPushButton_style)
        self.animb.setStyleSheet(QPushButton_style)
        self.reset.setStyleSheet(QPushButton_style)

        self.animlabel.setStyleSheet(QLabel_style)
        self.rate_txt.setStyleSheet(QLabel_style)
        self.ipoptxt.setStyleSheet(QLabel_style)

        self.cobweb_box.setStyleSheet(QCheckBox_style)
        self.series_box.setStyleSheet(QCheckBox_style)
        self.bifurc_box.setStyleSheet(QCheckBox_style)

    def resizeEvent(self, event):
        super(Controls, self).resizeEvent(event)

    def setValues(self, kind=''):

        if kind == 'rate_slider':
            self.rateval = linear_interp(self.rate.value(),
                                            0, 99, 0, 3.99, lim=1, dec=2)
            self.rate_box.blockSignals(True)
            self.rate_box.setValue(self.rateval)
            self.rate_box.blockSignals(False)

        elif kind == 'rate_box':
            self.rateval = linear_interp(self.rate_box.value(),
                                            0, 3.99, 0, 3.99, lim=1, dec=2)
            self.rate.blockSignals(True)
            self.rate.setValue( int(linear_interp(self.rateval,
                                            0, 3.99, 0, 99, lim=1, dec=2)) )
            self.rate.blockSignals(False)

        elif kind == 'ipop_slider':
            self.ipopval = linear_interp(self.ipop.value(),
                                            0, 100, 0, 1, lim=1)

            self.ipop_box.blockSignals(True)
            self.ipop_box.setValue(float(self.ipopval))
            self.ipop_box.blockSignals(False)

        elif kind == 'ipop_box':
            self.ipopval = self.ipop_box.value()

            self.ipop.blockSignals(True)
            self.ipop.setValue( int(linear_interp(self.ipopval,
                                            0, 1, 0, 100, lim=1)) )
            self.ipop.blockSignals(False)

        else:
            # defaults
            self.rate_box.setValue(1.0)
            self.ipop_box.setValue(0.5)
            self.setValues('rate_box')
            self.setValues('ipop_box')

class Widget(QWidget):
    def __init__(self, app, parent=None):
        super(Widget, self).__init__(parent=parent)

        self.setStyleSheet(f"Widget {{ background-color: {colors['dark']}; }}")

        self.app = app

        self.horizontalLayout = QHBoxLayout(self)
        self.controls = Controls(parent=self)

        self.controls.setValues()
        self.horizontalLayout.addWidget(self.controls)

        self.win = pg.GraphicsLayoutWidget()

        self.setWindowTitle("Logistic Map ðŸ¤¯")
        self.horizontalLayout.addWidget(self.win)

        self.plots = [
                        self.win.addPlot(col=1, title="Cobwebb",
                                        labels={'left':"Population Next",
                                                'bottom':"Population"}),

                        self.win.addPlot(col=2, title="Population vs Time",
                                        labels={'left':"Population",
                                                'bottom':"Time"}),

                        self.win.addPlot(col=3, title="Bifurcations",
                                        labels={'left':"Equilibrium Population",
                                                'bottom':"Rates"}),
        ]

        self.timer = QtCore.QTimer()
        self.timer.timeout.connect(self.animate_plot)
        self.animate = False
        self.f = 0

        self.update_plot()

        self.controls.rate.valueChanged.connect(self.update_plot)
        self.controls.rate_box.valueChanged.connect(self.update_plot)
        self.controls.ipop.valueChanged.connect(self.update_plot)
        self.controls.cobweb_box.stateChanged.connect(self.update_plot)
        self.controls.series_box.stateChanged.connect(self.update_plot)
        self.controls.bifurc_box.stateChanged.connect(self.update_plot)
        self.controls.reset.pressed.connect(self.reset)
        self.controls.clear.pressed.connect(self.clear)
        self.controls.animb.pressed.connect(self.animate_toggle)

    def clear(self):
        print('Clear')
        for p in self.plots:
            p.clear()
        self.update_plot()

    def reset(self):
        print('Reset')
        self.animate = False
        self.timer.stop()
        self.f = 0
        self.update_plot()

    def animate_toggle(self):

        self.animate = not self.animate

        if self.animate:
            print('Animation play')
            self.update_plot()
            self.controls.animb.setText('Pause')
        else:
            print("Animation pause")
            self.timer.stop()
            self.controls.animb.setText('Play')

    def keyPressEvent(self, event):

        if event.key() == 32: # Space
            self.animate_toggle()

        elif event.key() == 16777219: # Backspace
            self.reset()

        else:
            print(f'Unknown keypress: {event.key()}, "{event.text()}"')

    def update_plot(self):

        if self.animate and self.f == 0:
            # start animate
            self.animspeed = self.controls.animrate.value()
            self.animspeed = max(1, self.animspeed)
            self.animspeed = 1000/self.animspeed # sec/frame -> frames/msec

            self.f = 0
            self.fmax = 100
            self.timer.start(int(self.animspeed))

            self.redraw_plots()

        elif self.animate and self.f != 0:

            # continue animate
            self.animspeed = self.controls.animrate.value()
            self.animspeed = max(1, self.animspeed)
            self.animspeed = 1000/self.animspeed

            self.timer.start(int(self.animspeed))

        elif not self.animate and self.f == 0:

            self.redraw_plots()

    def redraw_plots(self, index=0):

        """ redraw plots ; controlled by checkmarks """

        rate = self.controls.rateval
        ipop = self.controls.ipopval

        y_vals = cobweb_plot(self.plots[0], idx=0, r=rate, cobweb_x=ipop)

        if self.controls.cobweb_box.isChecked():
            self.plots[0].setVisible(True)
        else:
            self.plots[0].setVisible(False)

        if self.controls.series_box.isChecked():
            self.plots[1].setVisible(True)
            series_plot(self.plots[1], y_vals, r=rate, xall=True)
        else:
            self.plots[1].setVisible(False)

        if self.controls.bifurc_box.isChecked():
            self.plots[2].setVisible(True)
            bifurc_plot(self.plots[2], y_vals, r=rate, ipop=ipop)
        else:
            self.plots[2].setVisible(False)

    def animate_plot(self):

        rate = self.controls.rateval
        ipop = self.controls.ipopval

        y_vals = cobweb_plot(self.plots[0], idx=1 + self.f, r=rate, cobweb_x=ipop)

        if self.controls.cobweb_box.isChecked():
            self.plots[0].setVisible(True)
        else:
            self.plots[0].setVisible(False)

        if self.controls.series_box.isChecked():
            self.plots[1].setVisible(True)
            series_plot(self.plots[1], y_vals, idx =1 + self.f, r=rate)
        else:
            self.plots[1].setVisible(False)

        if self.controls.bifurc_box.isChecked():
            self.plots[2].setVisible(True)
            bifurc_plot(self.plots[2], y_vals, r=rate, ipop=ipop)
        else:
            self.plots[2].setVisible(False)

        self.f += 1

        if self.f >= self.fmax:
            self.timer.stop()

if __name__ == '__main__':
    app = QApplication(sys.argv)
    w = Widget(app)
    w.show()
    sys.exit(app.exec_())


# coding= utf-8
import requests
from bs4 import BeautifulSoup
import urllib
import re
import sys
import gzip
import os
from common import config
URIBASE = None
DYNAMIC_URI = 'https://tellme.pw/btsow'

def get_headers():
    return {
        'Host': URIBASE,
        'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3053.3 Safari/537.36',
        'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8',
        'Connection': 'keep-alive',
        'Accept-Encoding': 'gzip, deflate, sdch, br',
        'Accept-Language': 'zh-CN,zh;q=0.8,en;q=0.6'
    }

def save_file(data):
    with open('one.html', 'w', encoding='utf-8') as fw:
        fw.write(data)

def get_save(fn=None):
    if not fn:
        fn = 'test.html'
    with open(fn, 'r', encoding='utf-8') as fr:
        return fr.read()

def get_content(urlPath, is_save=False):
    ret = requests.get(urlPath, headers=get_headers())
    html = ret.text
    if is_save:
        save_file(html)
    return html

class BtOne(object):
    def __init__(self, url, size, name):
        self.mag = url
        self.size = size
        self.name = name

    def __str__(self):
        return '{},{}'.format(self.mag, self.size)

    def parse_mag(self, content):
        pat = re.compile(r'(magnet:\?xt=urn:btih:[^"><]+)["<>]')
        ret = pat.findall(content)
        return ret[0]

def rec_content(content):
    rets = []
    for inner in content.contents:
        if hasattr(inner, 'contents'):
            rets.append(rec_content(inner))
        else:
            rets.append(inner)

    return ''.join(rets)

def parse_content(content):
    soup = BeautifulSoup(content, "html.parser")
    div = soup.select('div[class="data-list"]')
    for _div in div:
        for ret in _div.select('div[class="row"]'):
            a = ret.select('a')[0]
            name = a.select('div')[0]
            name = rec_content(name)
            size = a.find_next_siblings('div')[0].string
            url = a['href']
            hash_code = url.split('/')[-1]
            mag = 'magnet:?xt=urn:btih:{}'.format(hash_code)
            yield BtOne(mag, size, name)

def parse_cur_url(data):
    soup = BeautifulSoup(data, "html.parser")
    strongs = soup.select('strong')
    for strong in strongs:
        a = strong.select('a')[0]
        return rec_content(a)

def get_cur_uri(isSave=False):
    ret = requests.get(DYNAMIC_URI)
    if isSave:
        with open(os.path.join('tmp', 'pellow'), 'w') as fw:
            fw.write(ret.text)

    return parse_cur_url(ret.text)

def _get_all_magnet(code):
    code = urllib.parse.quote(code)
    url = 'https://{}/search/{}'.format(URIBASE, code)
    content = get_content(url, False)
    ret_list = []
    for bo in parse_content(content):
        ret_list.append((bo.mag, bo.name, bo.size))

    return ret_list

def get_all_magnet(code):
    # code=urllib.quote_plus(code)
    global URIBASE
    cur_url = config.Config().get('cur_url')
    if not config.Config().get('cur_url'):
        cur_url = get_cur_uri()
        config.Config().set_val('cur_url', cur_url)

    URIBASE = cur_url[len('https://'):]
    try:
        ret = _get_all_magnet(code)
        return ret
    except:
        cur_url = get_cur_uri()
        config.Config().set_val('cur_url', cur_url)
        URIBASE = cur_url[len('https://'):]
        return _get_all_magnet(code)

def main():
    ret = get_all_magnet('复仇者')
    print(ret)

if __name__ == '__main__':
    parse_content(get_save())
    #     bo = BtOne(1)
    # getAllMagnet('复仇者')
#     if (len(sys.argv) == 2):
#         getAllMagnet(sys.argv[1])


import openai
import pandas as pd
from google.colab import files
from langchain.text_splitter import RecursiveCharacterTextSplitter
import tiktoken

openai.api_key = "<API_KEY>"

# this is the file you will chunk and iterate over each chunk to fine-tuned model
filename = '<FILE_PATH>'

output_filename = f"_output_{filename.split('/')[-1]}"

with open(filename, 'r') as f:
    article_text = f.read()

def recursive_text_split(text):
    sections = RecursiveCharacterTextSplitter(
        chunk_size=1000,
        chunk_overlap=5,
        length_function=len,
    ).split_text(text)

    df = pd.DataFrame({'section': sections})
    return df
# I tokenize so I can get token count of chunk and ensure its under 1k
def run_api_call(df):
    tokenizer = tiktoken.get_encoding("cl100k_base")
    generated_texts = []

    for _, row in df.iterrows():
        section = row['section']
        combined_prompt = f'{section}\n\n###\n\n'

        token_count = len(tokenizer.encode(combined_prompt))
        # I am keeping my input text "prompt" under 1k so i can save 1k for completon (Fine-tuned Model limit is 2k tokens)
        if token_count > 1000:
            print("Tokens exceed the limit of 1000. Stopping the code execution.")
            break

        completion = openai.Completion.create(
            model="<FINE_TUNED_MODEL_NAME>",
            prompt=combined_prompt
        )

        generated_text = completion['choices'][0]['text']
        generated_texts.append(generated_text)

    return generated_texts

df_sections = recursive_text_split(article_text)

generated_texts = run_api_call(df_sections)

# outputs saved to file and downloaded
with open(output_filename, 'w') as output_file:
    for generated_text in generated_texts:
        output_file.write(generated_text)
        output_file.write("\n\n")

files.download(output_filename)

print(f"Output file '{output_filename}' has been generated.")

Query Fine-tuned model with chunked article.py


from bs4 import BeautifulSoup as bs
import requests
import cssutils
import pandas as pd

def scrape():

    mars_data = {}

    #retrieve new mars news
    news = {}
    mars_news = requests.get("https://mars.nasa.gov/news/")
    soup = bs(mars_news.text, 'html.parser')
    topNews = soup.find("div", class_="image_and_description_container")

    news_p = topNews.find("div", class_="rollover_description_inner").text
    news_title = topNews.find_all("img")[1]
    news_title = news_title.get("alt","")

    mars_data["news_title"] = news_title
    mars_data["news_p"] = news_p

    #retrieve jpl featured image
    jpl = requests.get("https://www.jpl.nasa.gov/spaceimages/?search=&category=Mars")
    jplsoup = bs(jpl.text, 'html.parser')
    featured = jplsoup.find("div", id="page")
    featured = featured.find("article")
    featured = featured.get("style")
    style = cssutils.parseStyle(featured)
    url = style['background-image']
    url = url.replace('url(', '').replace(')', '')
    featured_image_url = "https://www.jpl.nasa.gov" + url

    mars_data["featured_image"] = featured_image_url

    #retrieve most recent mars weather
    weather = requests.get("https://twitter.com/marswxreport?lang=en")
    wsoup = bs(weather.text, "html.parser")

    latest = wsoup.find('div', {'class': 'ProfileTimeline'})
    latest = latest.find("p", {'class': "TweetTextSize TweetTextSize--normal js-tweet-text tweet-text"})
    mars_weather = latest.text

    mars_data["weather"] = mars_weather

    #retrieve mars fact table
    facts = requests.get("https://space-facts.com/mars/")
    fsoup = bs(facts.text, "html.parser")

    def souptable(table):
        for row in table.find_all('tr'):
            yield [col.text for col in row.find_all('td')]

    table = fsoup.find("table")
    mf_df = pd.DataFrame(souptable(table))
    mf_df.columns = ['','value']
    facts = pd.DataFrame.to_html(mf_df)

    mars_data["facts"] = facts

    #retrieve mars hemisphere enhanced photos
    hemi = requests.get("https://astrogeology.usgs.gov/search/results?q=hemisphere+enhanced&k1=target&v1=Mars")
    hsoup = bs(hemi.text, "html.parser")

    picsource = hsoup.find_all("div", class_="item")

    hemi_dicts = []
    baseurl = "https://astrogeology.usgs.gov"

    for i in range(len(picsource)):
        img_info = {}
        title = picsource[i]("h3")[0].text
        imagehunt = picsource[i].find("a").get("href", "")
        temp = requests.get(baseurl + imagehunt)
        tempsoup = bs(temp.text, "html.parser")
        image_ext = tempsoup.find("img", class_="wide-image").get("src","")
        img_url = baseurl + image_ext
        img_info["title"] = title
        img_info["img_url"] = img_url
        hemi_dicts.append(img_info)

    mars_data["hemispheres"] = hemi_dicts

    print("SCRAPE COMPLETE")
    #print(mars_data)

    return mars_data

#scrape()


# @Time : 2022/3/16 22:32
# @Author : Liang er qian
# @File : atest_03.py
import allure
import pytest
import requests
from comm.DButils import DBUtils
from comm.excel_Utils import ReadExcel
from comm.constants import DATA_FILE
import openpyxl
import json
from comm.logUtils import logger

@allure.feature("用户登录模块")
class TestDemo:
    @pytest.fixture(autouse=True)
    def star_prepare(self):
        self.db = DBUtils()
        yield
        self.db.close()

    cases = ReadExcel.read_data_all(DATA_FILE, "login")

    @allure.Severity("critical")
    @allure.description("用户登录接口")
    @pytest.mark.parametrize('case', cases)
    def test_login(self, case):
        allure.dynamic.title(case.case_title)
        allure.attach(body=case.url, name='接口路径')
        allure.attach(body=case.case_data, name='请求参数')
        respons = requests.post(url=case.url, data=eval(case.case_data))
        res_body = respons.json()
        print(res_body)
        allure.attach(body=str(res_body), name='响应结果')

        try:
            if case.case_id==1:
                assert case.expct in res_body
            else:
                assert eval(case.expet) == res_body

        except AssertionError as e:
            ReadExcel.wirte_data(DATA_FILE,'login',case.case_id,7,'失败')
            logger.error('测试编号{},测试标题{},执行失败,实际结果为{}'.format(case.case_id,case.case_title,res_body))
            logger.exception(e)
            raise e
        else:
            ReadExcel.wirte_data(DATA_FILE,'login',case.cae_id,7,'成功')
            logger.info('测试编号{},测试标题{},执行成功。'.format(case.case_id,case.case_title))

if __name__ == '__main__':
    pytest.main(["-vs", "./testsuite/atest_03.py"])


import socket
import time
import fcntl
import struct

import server

def linuxifip4hack(ifname):
    req = ifname + ("\0" * (32 - len(ifname)))
    sk = socket.socket()
    res = fcntl.ioctl(sk.fileno(), 0x8915, req)
    sk.close()
    sockaddr = res[16:]
    return sockaddr[4:8]

class valuecache:
    def __init__(self, func, expire):
        self.func = func
        self.expire = expire
        self.last = 0

    def __call__(self, *args):
        now = int(time.time())
        if self.last == 0 or now - self.last > self.expire:
            self.val = self.func(*(args))
            self.last = now
        return self.val

class prefix6to4(server.handler):
    def __init__(self, next, v4addr):
        self.next = next
        if callable(v4addr):
            self.packed = v4addr
        elif len(v4addr) == 4:
            self.packed = v4addr
        else:
            self.packed = socket.inet_pton(socket.AF_INET, v4addr)

    def handle(self, *args):
        resp = self.next.handle(*args)
        if resp is None:
            return None
        for rr in resp.allrrs():
            if rr.head.istype("AAAA"):
                addr = rr.data["address"]
                if addr[0:6] == "\x20\x02\x00\x00\x00\x00":
                    packed = self.packed
                    if callable(packed):
                        packed = packed()
                    addr = addr[0:2] + packed + addr[6:]
                    rr.data["address"] = addr
        return resp

class addrfilter(server.handler):
    def __init__(self, default = None, matchers = []):
        self.matchers = matchers
        self.default = default

    def setdefault(self, handler):
        self.default = handler

    def addmatcher(self, af, prefix, preflen, handler):
        self.matchers += [(af, socket.inet_pton(af, prefix), preflen, handler)]

    def handle(self, query, pkt, origin):
        matchlen = -1
        match = self.default
        if pkt.addr is not None:
            for af, prefix, preflen, handler in self.matchers:
                if pkt.addr[0] == af:
                    addr = socket.inet_pton(af, pkt.addr[1])
                    bytes = preflen >> 3
                    restmask = 255 ^ ((1 << (8 - (preflen & 7))) - 1)
                    if prefix[0:bytes] == addr[0:bytes] and \
                           (ord(prefix[bytes]) & restmask) == (ord(addr[bytes]) & restmask):
                        if preflen > matchlen:
                            matchlen = preflen
                            match = handler
        if match is not None:
            return match.handle(query, pkt, origin)
        return None


#!/usr/bin/env python

"""Implementation and improvement of the paper:
Unsupervised learning and segmentation of complex activities from video.
"""

__author__ = 'Anna Kukleva'
__date__ = 'August 2018'

import BF_utils.update_argpars as bf_utils
import YTI_utils.update_argpars as yti_utils
from corpus import Corpus
from utils.arg_pars import opt
from utils.logging_setup import logger
from utils.utils import timing, update_opt_str, join_return_stat, parse_return_stat

@timing
def baseline(iterations=7):
    """Implementation of the paper"""

    corpus = Corpus(Q=opt.gmm, subaction=opt.subaction)

    for iteration in range(iterations):
        logger.debug('Iteration %d' % iteration)
        corpus.iter = iteration
        corpus.accuracy_corpus()
        if (opt.gt_training and iteration == 0) or not opt.gt_training:
            corpus.embedding_training()
        # one version of gaussian mixtures for the entire dataset
        if opt.gmms == 'one':
            corpus.one_gaussian_model()
        # different gmm for different subsets of videos, i.e. leave one out for
        # each video subset
        elif opt.gmms == 'many':
            corpus.many_gaussian_models()
            # with multiprocessing package
            # corpus.gaussians_mp(n_threads=3)
        else:
            raise RuntimeError('define number of gmms for the video collection')

        if opt.viterbi:
            # corpus.viterbi_decoding()
            # corpus.accuracy_corpus(prefix='pure vit ')

            # corpus.viterbi_ordering()
            # take into account Mallow Model
            corpus.ordering_sampler()
            corpus.rho_sampling()
            # corpus.accuracy_corpus(prefix='vit+ord ')

            corpus.viterbi_decoding()
            # corpus.viterbi_alex_decoding()
        else:
            corpus.subactivity_sampler()

            # take into account Mallow Model
            corpus.ordering_sampler()
            corpus.rho_sampling()

    logger.debug('Iteration %d' % iteration)
    corpus.accuracy_corpus()

@timing
def all_actions():
    return_stat_all = None
    if opt.dataset == 'bf':
        actions = ['coffee', 'cereals', 'tea', 'milk', 'juice', 'sandwich', 'scrambledegg', 'friedegg', 'salat', 'pancake']
    if opt.dataset == 'yti':
        actions = ['changing_tire', 'coffee', 'jump_car', 'cpr', 'repot']
    lr_init = opt.lr
    for action in actions:
        opt.subaction = action
        if not opt.resume:
            opt.lr = lr_init
        update_opt_str()
        if opt.viterbi:
            return_stat_single = baseline(iterations=1)
        else:
            return_stat_single = baseline(iterations=7)
        return_stat_all = join_return_stat(return_stat_all, return_stat_single)
    parse_return_stat(return_stat_all)

def resume_segmentation(iterations=10):
    logger.debug('Resume segmentation')
    corpus = Corpus(Q=opt.gmm,
                    subaction=opt.subaction)

    for iteration in range(iterations):
        logger.debug('Iteration %d' % iteration)
        corpus.iter = iteration
        corpus.resume_segmentation()
        corpus.accuracy_corpus()
    corpus.accuracy_corpus()

if __name__ == '__main__':
    if opt.dataset == 'bf':
        bf_utils.update()
    if opt.dataset == 'yti':
        yti_utils.update()
    if opt.subaction == 'all':
        all_actions()
    else:
        baseline()


import sys

sys.path.append('./FIR_models')
import time
import const as c
from FIR_8 import *
from FIR_12 import *
from FIR_420 import *
from FIR_480 import *
from FIR_565 import *
from FIR_720 import *
from FIR_780 import *

class fir(object):
    def __init__(self, h):
        """initialization"""
        self.index = 0
        self.h = h
        self.size = len(self.h)
        self._data = [0] * self.size

    def proc(self, sample):
        """sample processed """
        if len(self._data) == self.size:
            self._data[self.index] = sample
        else:
            self._data.append(sample)
        self.index = (self.index + 1) % self.size
        acc = 0  # accumulator
        indx = self.index

        for j in range(self.size):
            acc += self._data[indx] * self.h[j]
            if indx == ((self.size) - 1):
                indx = 0
            else:
                indx += 1
        return (int(acc) / 32768)  # result to 16 bit value

    def proc2(self, y):
        """buffer processed """
        filtered_y = lfilter(self.h, 1.0, c.inp_signal_buff)

        return filtered_y


"""Audio signal feature extraction utilitary functions."""
import librosa
import numpy as np

def extract_features(signal, freq=16000, n_mfcc=5, size=512, step=16):
    """Extract MFCC features from an audio signal.

    Args:
        signal (np.ndarray): audio signal
        freq (int, optional): MFCC features sampling rate. Defaults to 16000.
        n_mfcc (int, optional): number of MFCC features to extract. Defaults to 5.
        size (int, optional): MFCC features size. Defaults to 512.
        step (int, optional): MFCC features step. Defaults to 16.

    Returns:
        features (np.ndarray): MFCC features as an array
    """
    # Mel Frequency Cepstral Coefficents
    mfcc = librosa.feature.mfcc(
        y=signal,
        sr=freq,
        n_mfcc=n_mfcc,
        n_fft=size,
        hop_length=step,
    )
    mfcc_delta = librosa.feature.delta(mfcc)
    mfcc_delta2 = librosa.feature.delta(mfcc, order=2)

    # Root Mean Square Energy
    mel_spectogram = librosa.feature.melspectrogram(
        y=signal, sr=freq, n_fft=size, hop_length=step
    )
    rmse = librosa.feature.rms(S=mel_spectogram, frame_length=size, hop_length=step)

    mfcc = np.asarray(mfcc)
    mfcc_delta = np.asarray(mfcc_delta)
    mfcc_delta2 = np.asarray(mfcc_delta2)
    rmse = np.asarray(rmse)

    features = np.concatenate((mfcc, mfcc_delta, mfcc_delta2, rmse), axis=0)
    return features


from django.conf.urls import url
from django.contrib import admin

from .views import (
	olymps_list,
	olymp_create,
	olymp_detail,
	olymp_update,
	olymp_delete,
	)

app_name = 'Enigmath'
urlpatterns = [
	url(r'^$', olymps_list, name='list'),
    url(r'^create/$', olymp_create, name='create'),
    url(r'^(?P<slug>[\w-]+)/$', olymp_detail, name='detail'),
    url(r'^(?P<slug>[\w-]+)/edit/$', olymp_update, name='update'),
    url(r'^(?P<slug>[\w-]+)/delete/$', olymp_delete, name='delete'),
]


import cv2, math
import numpy as np
from BitPlanes_Compress import *

def Vacate_Room(PE_I, block_size, L_fix, L, num_of, overflow):
    h, w = PE_I.shape
    num = math.ceil(math.log2(h)) + math.ceil(math.log2(w))
    side = []
    num_side = 0

    bin_BS = "{:04b}".format(block_size)
    side[: 4] = list(map(int, bin_BS))
    num_side += 4

    bin_LF = "{:03b}".format(L_fix)
    side[num_side: num_side+3] = list(map(int, bin_LF))
    num_side += 3

    len_num_of = [0 for _ in range(num)]
    bin_num_of = bin(num_of)[2:]
    length = len(bin_num_of)
    len_num_of[num-length: num] = list(map(int, bin_num_of))
    side[num_side: num_side+num] = len_num_of
    num_side += num

    if num_of > 0:
        for i in range(num_of):
            x = overflow[0][i]
            y = overflow[1][i]
            pos = x * w + y + 1
            len_pos = [0 for _ in range(num)]
            bin_pos = bin(pos)[2:]
            length = len(bin_pos)
            len_pos[num-length: num] = list(map(int, bin_pos))
            side[num_side: num_side+num] = len_pos
            num_side += num

    Image_bits = side
    t = num_side

    PL_room = [0, 0, 0, 0, 0, 0, 0, 0]    # 紀錄空出後的大小
    PL_len = [0, 0, 0, 0, 0, 0, 0, 0]     # 紀錄壓縮後的bit長度
    num_pl = 0
    bit_plane = np.unpackbits(PE_I.astype(np.uint8)).reshape([8, h, w], order='F')
    for i in range(8):
        plane = bit_plane[i].T
        CBS, type = BitPlanes_Compress(plane, block_size, L_fix, L)
        len_CBS = len(CBS)
        len_comp_PL = len_CBS + num + 2 + 1

        if len_comp_PL <= h * w:
            num_pl += 1
            Image_bits.append(1)
            t += 1

            bin2_type = list(map(int, list(bin(type)[2:].zfill(2))))
            Image_bits += bin2_type
            t += 2

            len_CBS_bits = np.zeros(num, dtype=int)
            bin2_len_CBS = list(map(int, list(bin(len_CBS)[2:].zfill(num))))
            length = len(bin2_len_CBS)
            len_CBS_bits[num - length: num] = bin2_len_CBS
            Image_bits = Image_bits + len_CBS_bits.tolist()
            t += num
            Image_bits += CBS
            t += len_CBS

            PL_len[i] = len_CBS
            room = h * w - len_comp_PL
            PL_room[i] = room

        else:
            Image_bits.append(0)
            t += 1
            T_Plane = np.array(plane)
            PL_bits = T_Plane.flatten().tolist()
            Image_bits += PL_bits
            t += h * w

    num_t = 0
    RI = np.zeros([8, h, w], dtype=np.uint8)

    for i in range(8):
        re = t - num_t
        if re >= h * w:
            PL_bits = np.array(Image_bits[num_t: num_t + h * w])
            num_t += h * w
        else:
            PL_bits = np.zeros(h * w, dtype=int)
            PL_bits[: re] = Image_bits[num_t: num_t+re]
            num_t += re

        Plane = PL_bits.reshape(h, w)
        RI[i] = Plane

    RI = np.packbits(RI, axis=0)
    total_room = h * w * 8 - t
    return RI[0], PL_len, PL_room, total_room


from django.conf import settings
from django.core.files.storage import get_storage_class

DEFAULT_SETTINGS = {
    'LOGO_STORAGE': settings.DEFAULT_FILE_STORAGE,
    'PROJECT_TYPES': enumerate((
        'Django Content App',
        'Django Decorator App',
        'Django Utility',
        'Python App',
        'Web Site',
    )),
    'STATUSES': enumerate((
        'Live',
        'Archived'
    )),

}

USER_SETTINGS = DEFAULT_SETTINGS.copy()
USER_SETTINGS.update(getattr(settings, 'PROJECTS_SETTINGS', {}))

USER_SETTINGS['LOGO_STORAGE'] = get_storage_class(USER_SETTINGS['LOGO_STORAGE'])

globals().update(USER_SETTINGS)


from PIL.Image import Image
import torch

import torch.nn as nn
import torch.nn.functional as F
from torch.utils.data import Dataset, DataLoader
from torch.optim.lr_scheduler import ReduceLROnPlateau
from tqdm import tqdm
import matplotlib.pyplot as plt
import random
import logging
import json
from pprint import pprint
from math import inf
from sklearn.metrics import accuracy_score
from torchinfo import summary
import pdb
import os
import sys
import time
from datetime import timedelta

sys.path.append("..")

from models.multi_image_vqa import MultiImageVQA
from models.custom_logging import TqdmLoggingHandler
from utils.dataset import MultiImageVQADataset, arrange_batch, VQAOne

import warnings
warnings.filterwarnings('ignore')

torch.manual_seed(42)
start_time = time.time()

# ========================================= < Label Smoothing > =======================================
def linear_combination(x, y, epsilon):
    return epsilon*x + (1-epsilon)*y

def reduce_loss(loss, reduction='mean'):
    return loss.mean() if reduction=='mean' else loss.sum() if reduction=='sum' else loss

#  Implementation of Label smoothing with CrossEntropy and ignore_index
class LabelSmoothingCrossEntropy(nn.Module):
    def __init__(self, epsilon:float=0.1, reduction='mean',ignore_index=-100):
        super().__init__()
        self.epsilon = epsilon
        self.reduction = reduction
        self.ignore_index = ignore_index
    def forward(self, preds, target):
        n = preds.size()[-1]
        log_preds = F.log_softmax(preds, dim=-1)
        loss = reduce_loss(-log_preds.sum(dim=-1), self.reduction)
        nll = F.nll_loss(log_preds, target, reduction=self.reduction,ignore_index=self.ignore_index)
        return linear_combination(loss/n, nll, self.epsilon)

# ========================================= <\ Label Smoothing > =======================================

# ========================================= < Logging > ===========================
log = logging.getLogger(__name__)
log.setLevel(logging.INFO)
log.addHandler(TqdmLoggingHandler())

# ========================================= </ Logging > ==========================
num_epochs = 180
vocab_size = 30000 # from bert
seq_len = 12 # from dataset
feat_dim = 640 # from paper, the final vector vq, vi
embed_size = 768 # from paper, dimention of embedding of each word
n_attention_stacks = 2
hidden_dim_img = feat_dim
batch_size = 20
num_workers = 20
lambda_ = 5
device = 'cuda' if torch.cuda.is_available() else 'cpu'

answers = ['6', 'yes', 'small', 'blue', 'brown', 'red', 'cyan', '1', '0', 'rubber', '7', 'no', 'purple', 'large', '5', 'green', '10', 'cube', '4', '9', '3', 'cylinder', 'metal', '2', 'gray', 'sphere', '8', 'yellow']

class Multi(Dataset):
    def __init__(self):
        self.n_images = 3

    def __len__(self):
        return 20

    def __getitem__(self, idx):
        dct = {
            f'images': [torch.randint(255, size=(3, 448, 448)) / 255 for x in range(1, self.n_images+1)]
        }

        batch_size, seq_len = 1, 5
        dct['ques'] = torch.tensor([500 for _ in range(seq_len)])  # torch.randint(1000, size=(seq_len,))
        dct['ans'] = torch.tensor([30]) # torch.randint(9000-2, size=(1,))
        dct['true_img_index'] = 1 # random.randint(0, self.n_images-1)
        return dct

ds = MultiImageVQADataset('/home/prabhu/vqa/models/cleaned.json', '/home/prabhu/CLEVR_v1.0/images/val', '/home/prabhu/Tiny/tiny-imagenet-200/test/images')
# ds = VQAOne("/home/prabhu/VQA1.0/v2_mscoco_train2014_annotations_cleaned.json", "/home/prabhu/VQA1.0/v2_OpenEnded_mscoco_train2014_questions.json", "/home/prabhu/VQA1.0/train2014")
datasetLength = len(ds)

# answer_tokens = ds.tokenizer.tokenize(answers)
# answer_indices = ds.tokenizer.convert_tokens_to_ids(answer_tokens)
# crossentropy_weights = [0 for _ in range(30000)]
# for answer_index in answer_indices:
#     crossentropy_weights[answer_index] = 1 / len(answer_indices)

print("Dataset Loaded. ", datasetLength)
# pdb.set_trace()
train_, validation_ = torch.utils.data.random_split(ds, [int(0.8*datasetLength), len(ds) - int(0.8*datasetLength)], generator=torch.Generator().manual_seed(42))
dl_train = DataLoader(train_, batch_size=batch_size, num_workers=num_workers, collate_fn=arrange_batch, shuffle=True)
dl_val = DataLoader(validation_, batch_size=batch_size+10, num_workers=num_workers, collate_fn=arrange_batch, shuffle=True)

model = MultiImageVQA(feat_dim, vocab_size, embed_size, n_attention_stacks, hidden_dim_img)
state_dict = torch.load('/home/prabhu/vqa/models/exp89/models/exp0/weights.pth')
# # print(*state_dict.keys(), sep='\n')
# del state_dict['pred.4.weight']
# del state_dict['pred.4.bias']
model.load_state_dict(state_dict['state_dict'], strict=False)
print(f'Loaded model weights....')
model = model.to(device)
# model = nn.DataParallel(model)

criterian = nn.CrossEntropyLoss() # LabelSmoothingCrossEntropy() #
optimizer = torch.optim.Adam(model.parameters(), lr=1e-3)
scheduler = ReduceLROnPlateau(optimizer, verbose=True, patience=6, min_lr=1e-6, factor=0.5)

# ============================== < Set up the project dir > =============================

PROJECT_DIR = '/home/prabhu/vqa/models'
counts = list(filter(lambda x: x.startswith("exp"), os.listdir(PROJECT_DIR)))
# print(counts)
counts = list(map(lambda x: int(x.replace('exp', '')), counts))

EXP_DIR = f'exp{max(counts) + 1}'

os.mkdir(os.path.join(PROJECT_DIR, EXP_DIR))
# ============================== <\ Set up the project dir > =============================

# batch = next(dl)
# for name, param in model.named_parameters():
#     if param.requires_grad:
#         print(name, end=' ')

# for inx, x in enumerate(dl_train):
#     batch = x
#     break
# summary(model, input_data=(batch, batch['ques_features']))
# exit(0)

# dl_train, dl_val = dl, dl

IMG_CLS_CONST, IMG_CLS_FACTOR = 600, 0.5

epoch, train_losses, val_losses, best_val_loss = 0, [], [], inf
word_accuracy, image_accuracy = {'train': [], 'val': []}, {'train': [], 'val': []}
losses = {
    'train': {
        'image_loss': [],
        'word_loss': []
    },
    'val': {
        'image_loss': [],
        'word_loss': []
    }
}
for epoch in tqdm(range(num_epochs), desc=f"on epoch {epoch}"):

    for dataloader, phase in [(dl_train, 'train'),(dl_val, 'val')]:
        if phase == 'train':
            model.train()
        elif phase == 'val':
            model.eval()

        phase_loss, phase_word_loss, phase_image_loss = 0, 0, 0
        phase_word_accuracy, phase_image_accuracy = 0, 0
        for batch in tqdm(dataloader, desc=f"iter {phase} | time: {timedelta(seconds=time.time() - start_time)}"):
            # batch = x
            optimizer.zero_grad()
            keys = batch.keys()

            for key in keys:
                batch[key] = batch[key].to(device)

            if phase == 'val':
                with torch.no_grad():
                    attention_weights, out = model(batch, batch['ques_features'])
            else:
                attention_weights, out = model(batch, batch['ques_features'])

            # log.info(attention_weights)
            pred = torch.argmax(out, dim=1)
            tqdm.write(f'pred: {pred.clone().detach().cpu().tolist()} {torch.argmax(attention_weights, dim=1).clone().detach().cpu().tolist()}\nAns:  {batch["ans"].squeeze(-1).clone().detach().cpu().tolist()} {batch["true_img_index"].squeeze(-1).clone().detach().cpu().tolist()}')
            # tqdm.write(f'Debug: {attention_weights.shape}, {batch["true_img_index"]}')
            # print('out: ', out.shape, 'ans: ', batch['ans'].shape, batch['ans'].detach().cpu().tolist())
            word_loss = criterian(out, batch['ans'].squeeze(-1))
            # torch.tensor([0]).to(device) #
            img_classification_loss = criterian(attention_weights, batch['true_img_index'].squeeze(-1))
            #tqdm.write(f'wetmux ight: {attention_weights}')
            #continue
            loss = (lambda_ * word_loss) # + (IMG_CLS_CONST * img_classification_loss)
            phase_word_loss += lambda_ * word_loss.item() * len(batch['ans'])
            phase_image_loss += img_classification_loss.item() * len(batch['ans'])
            phase_loss += loss.item() * len(batch['ans'])

            phase_word_accuracy += accuracy_score(
                batch['ans'].squeeze(-1).clone().detach().cpu().tolist(),
                pred.clone().detach().cpu().tolist(),
                normalize=False
                )

            phase_image_accuracy += accuracy_score(
                batch["true_img_index"].squeeze(-1).clone().detach().cpu().tolist(),
                torch.argmax(attention_weights, dim=1).clone().detach().cpu().tolist(),
                normalize=False
                )

            if phase == 'train':
                # train_losses.append(loss.detach().cpu().item())
                loss.backward()
                optimizer.step()

            elif phase == 'val':
                pass
                # val_losses.append()
                # scheduler.step(loss)

        tqdm.write(f'phase: {phase} | loss: {phase_loss / len(dataloader.dataset):.3f}, word_Loss: {phase_word_loss / len(dataloader.dataset):.3f}, img_cls_loss: {phase_image_loss / len(dataloader.dataset):.3f}, img_cls_cnst: {IMG_CLS_CONST} | word_accuracy: {phase_word_accuracy / len(dataloader.dataset):.3f} | LR: {optimizer.param_groups[0]["lr"]}')

        word_accuracy[phase].append(phase_word_accuracy / len(dataloader.dataset))
        image_accuracy[phase].append(phase_image_accuracy / len(dataloader.dataset))

        losses[phase]['word_loss'].append(phase_word_loss / len(dataloader.dataset))
        losses[phase]['image_loss'].append(phase_image_loss / len(dataloader.dataset))

        if phase == 'train':
            train_losses.append(phase_loss / len(dataloader.dataset))
        else:
            val_losses.append(phase_loss / len(dataloader.dataset))
            if best_val_loss > phase_loss / len(dataloader.dataset):
                best_val_loss = phase_loss / len(dataloader.dataset)
                torch.save({'state_dict': model.state_dict(), 'lr': optimizer.param_groups[0]["lr"]}, os.path.join(EXP_DIR, 'weights.pth'))
            scheduler.step(phase_loss)
            tqdm.write(f'Val Loss: {best_val_loss:.3f}, Saving weights....')

    IMG_CLS_CONST = IMG_CLS_CONST * IMG_CLS_FACTOR
    IMG_CLS_CONST = max(IMG_CLS_CONST, 1.0)
    # print(f' Ans: {batch["ans"].detach().cpu().tolist()}, ques: {batch["ques"].shape}, out: {out.shape}, pred: {pred.detach().cpu().tolist()}')

# losses = [3, 4, 2, 5]
    plt.clf()
    plt.plot(train_losses, color = 'r', label = 'train')
    plt.plot(val_losses, color = 'g', label = 'val')
    plt.title(f'Dataset: {datasetLength}, lambda: {lambda_}')
    plt.legend()
    plt.xlabel('Epochs')
    plt.ylabel('Loss')
    plt.savefig(os.path.join(EXP_DIR, 'LossGraph.png'))

    with open(os.path.join(EXP_DIR, 'losses.json'), 'w') as f:
        json.dump(
            {'word_accuracy': word_accuracy,
            'image_accuracy': image_accuracy,
            'losses': losses
            },
            f,
            indent=4
        )