from ..ops import TORCH_CONV, TORCH_BATCHNORM, TORCH_PRELU, TORCH_LINEAR
from ..ops import module2type
import torch
from .op_counter import count_ops_and_params
import torch.nn as nn

@torch.no_grad()
def count_params(module):
    return sum([p.numel() for p in module.parameters()])

def flatten_as_list(obj):
    if isinstance(obj, torch.Tensor):
        return [obj]
    elif isinstance(obj, (list, tuple)):
        flattened_list = []
        for sub_obj in obj:
            flattened_list.extend(flatten_as_list(sub_obj))
        return flattened_list
    elif isinstance(obj, dict):
        flattened_list = []
        for sub_obj in obj.values():
            flattened_list.extend(flatten_as_list(sub_obj))
        return flattened_list
    else:
        return obj

def draw_computational_graph(DG, save_as, title='Computational Graph', figsize=(16, 16), dpi=200, cmap=None):
    import numpy as np
    import matplotlib.pyplot as plt
    plt.style.use('bmh')
    n_nodes = len(DG.module2node)
    module2idx = {m: i for (i, m) in enumerate(DG.module2node.keys())}
    G = np.zeros((n_nodes, n_nodes))
    fill_value = 1
    for module, node in DG.module2node.items():
        for input_node in node.inputs:
            G[module2idx[input_node.module], module2idx[node.module]] = fill_value
            G[module2idx[node.module], module2idx[input_node.module]] = fill_value
        for out_node in node.outputs:
            G[module2idx[out_node.module], module2idx[node.module]] = fill_value
            G[module2idx[node.module], module2idx[out_node.module]] = fill_value
        pruner = DG.get_pruner_of_module(module)
    fig, ax = plt.subplots(figsize=(figsize))
    ax.imshow(G, cmap=cmap if cmap is not None else plt.get_cmap('Blues'))
    # plt.hlines(y=np.arange(0, n_nodes)+0.5, xmin=np.full(n_nodes, 0)-0.5, xmax=np.full(n_nodes, n_nodes)-0.5, color="#444444", linewidth=0.1)
    # plt.vlines(x=np.arange(0, n_nodes)+0.5, ymin=np.full(n_nodes, 0)-0.5, ymax=np.full(n_nodes, n_nodes)-0.5, color="#444444", linewidth=0.1)
    if title is not None:
        ax.set_title(title)
    fig.tight_layout()
    plt.savefig(save_as, dpi=dpi)
    return fig, ax

def draw_groups(DG, save_as, title='Group', figsize=(16, 16), dpi=200, cmap=None):
    import numpy as np
    import matplotlib.pyplot as plt
    plt.style.use('bmh')
    n_nodes = 2*len(DG.module2node)
    node2idx = {m: i for (i, m) in enumerate(DG.module2node.values())}
    G = np.zeros((n_nodes, n_nodes))
    fill_value = 10
    for i, (module, node) in enumerate(DG.module2node.items()):
        pruning_fn = DG.get_pruner_of_module(module).prune_out_channels
        prunable_ch = DG.get_out_channels(module)
        if prunable_ch is None: continue
        group = DG.get_pruning_group(module, pruning_fn, list(range(prunable_ch)))
        grouped_idxs = []
        for dep, _ in group:
            source, target, trigger, handler = dep.source, dep.target, dep.trigger, dep.handler
            if DG.is_out_channel_pruning_fn(trigger):
                grouped_idxs.append(node2idx[source]*2+1)
            else:
                grouped_idxs.append(node2idx[source]*2)

            if DG.is_out_channel_pruning_fn(handler):
                grouped_idxs.append(node2idx[target]*2+1)
            else:
                grouped_idxs.append(node2idx[target]*2)
        grouped_idxs = list(set(grouped_idxs))
        for k1 in grouped_idxs:
            for k2 in grouped_idxs:
                G[k1, k2] = fill_value

    fig, ax = plt.subplots(figsize=(figsize))
    ax.imshow(G, cmap=cmap if cmap is not None else plt.get_cmap('Blues'))
    # plt.hlines(y=np.arange(0, n_nodes)+0.5, xmin=np.full(n_nodes, 0)-0.5, xmax=np.full(n_nodes, n_nodes)-0.5, color="#999999", linewidth=0.1)
    # plt.vlines(x=np.arange(0, n_nodes)+0.5, ymin=np.full(n_nodes, 0)-0.5, ymax=np.full(n_nodes, n_nodes)-0.5, color="#999999", linewidth=0.1)
    if title is not None:
        ax.set_title(title)
    fig.tight_layout()
    plt.savefig(save_as, dpi=dpi)
    return fig, ax

def draw_dependency_graph(DG, save_as, title='Group', figsize=(16, 16), dpi=200, cmap=None):
    import numpy as np
    import matplotlib.pyplot as plt
    plt.style.use('bmh')
    n_nodes = len(DG.module2node)
    node2idx = {node: i for (i, node) in enumerate(DG.module2node.values())}
    G = np.zeros((2*n_nodes, 2*n_nodes))
    fill_value = 10
    for module, node in DG.module2node.items():
        for dep in node.dependencies:
            trigger = dep.trigger
            handler = dep.handler
            source = dep.source
            target = dep.target

            if DG.is_out_channel_pruning_fn(trigger):
                G[2*node2idx[source]+1, 2*node2idx[target]] = fill_value
            else:
                G[2*node2idx[source], 2*node2idx[target]+1] = fill_value

        pruner = DG.get_pruner_of_module(module)
        if pruner.prune_out_channels == pruner.prune_in_channels:
            G[2*node2idx[node], 2*node2idx[node]+1] = fill_value

    fig, ax = plt.subplots(figsize=(figsize))
    ax.imshow(G, cmap=cmap if cmap is not None else plt.get_cmap('Blues'))
    # plt.hlines(y=np.arange(0, 2*n_nodes)+0.5, xmin=np.full(2*n_nodes, 0)-0.5, xmax=np.full(2*n_nodes, 2*n_nodes)-0.5, color="#999999", linewidth=0.05)
    # plt.vlines(x=np.arange(0, 2*n_nodes)+0.5, ymin=np.full(2*n_nodes, 0)-0.5, ymax=np.full(2*n_nodes, 2*n_nodes)-0.5, color="#999999", linewidth=0.05)
    if title is not None:
        ax.set_title(title)
    fig.tight_layout()
    plt.savefig(save_as, dpi=dpi)
    return fig, ax


import numpy as np
import pandas as pd
import json

from flask import jsonify
from markupsafe import escape

from os.path import dirname, abspath
import sys

SCRIPT_DIR = dirname(abspath(__file__))
sys.path.append(dirname(SCRIPT_DIR))

import utils.simple_utils.simple_tools as su_tools

def characters_of_the_guild_m (
    g_id,
    dn_db_guilds_table,
    dn_db_characters_table,

):
    guild_id = int(escape(g_id))

    #read table w/ guilds info
    df_for_guild = pd.read_csv(
        dn_db_guilds_table
    )

    #get all guild's info
    guild_info = su_tools.find_one_row_in_DataFrame(
        df_for_guild,
        object_to_search_for = guild_id,
        item_column = "guild_id"
    )

    #check is there such guild
    guild_info_type = guild_info.__class__.__name__
    if guild_info_type == "NoneType" :
        return jsonify("There is no such guild")

    #read table w/ characters info
    df_for_characters = pd.read_csv(
        dn_db_characters_table
    )

    #find all members of the given guild
    df_to_return = pd.DataFrame.merge(
        guild_info.to_frame().T,
        df_for_characters,
        on="guild_id"
    )

    #transform guild_id and guild_name columns into index
    #   to create list of characters
    df_to_return = df_to_return.set_index(["guild_id", "guild_name"])

    #forming propper respons for the FE
    dict_to_return ={
        "guild_name": guild_info["guild_name"],
        "characters": df_to_return.to_dict(orient="records")
    }

    return json.dumps(dict_to_return, indent=2)


import requests
import bs4
import json
import time
import main
import threading
import os
import random

# This is the ensure you're not pulling the page 5000 times...
page_cache = {}

# This is literally only because GOGO inflight wifi is really slow...
def get_page_from_url(url):
	if url not in page_cache:
		res = requests.get(url)
		page_cache[url] = bs4.BeautifulSoup(res.text)
	return page_cache[url]

# This is just a really bad way to split strings
def split_between(string, part1, part2):
	return string.partition(part1)[2].partition(part2)[0]

EXAMPLE_SONGS = ['https://open.spotify.com/track/2SG0RPcyWgUPqLCKWLtYc1',
'https://open.spotify.com/track/7oK9VyNzrYvRFo7nQEYkWN',
'https://open.spotify.com/track/2Fxmhks0bxGSBdJ92vM42m',
'https://open.spotify.com/track/3Yh9lZcWyKrK9GjbhuS0hR',
'https://open.spotify.com/track/6u7jPi22kF8CTQ3rb9DHE7',
'https://open.spotify.com/track/4yI3HpbSFSgFZtJP2kDe5m',
'https://open.spotify.com/track/2bT1PH7Cw3J9p3t7nlXCdh',
'https://open.spotify.com/track/1p80LdxRV74UKvL8gnD7ky']

random.shuffle(EXAMPLE_SONGS)

# This is going to do the song ranking
class controller():
	def __init__(self):
		self.count = {}
		self.fingerprint_info = {}
		self.order = []
		return

	def add(self, songInfo):
		if len(self.order) == 0:
			prevOrder = "None"
		else:
			prevOrder = str(self.order[0]['fingerprint'])
		fingerPrint = songInfo['fingerprint']
		print("Adding {} to the queue".format(fingerPrint))
		if fingerPrint not in self.count:
			self.count[fingerPrint] = 0
		self.count[fingerPrint] += 1

		if fingerPrint not in self.fingerprint_info:
			self.fingerprint_info[fingerPrint] = songInfo

		while len(self.order) > 0:
			self.order.pop()

		allCountNumbers = sorted(list(set(self.count.values())))[::-1]

		while len(allCountNumbers) > 0:
			infoVals = []
			for fingerPrintVal, info in self.fingerprint_info.iteritems():
				if self.count[fingerPrintVal] == allCountNumbers[0]:
					infoVals.append(info)
			allCountNumbers.pop(0)
			infoVals.sort(key=lambda k: k['time_added'])
			for val in infoVals:
				self.order.append(val)
		if str(self.order[0]['fingerprint']) != prevOrder:
			print("ORDER CHANGED: {} is now next".format(self.order[0]['fingerprint']))

	def play_next(self):
		if len(self.order) == 0:
			return None
		nextSong = self.order.pop(0)
		info = self.fingerprint_info[nextSong['fingerprint']]
		del self.fingerprint_info[nextSong['fingerprint']]
		del self.count[nextSong['fingerprint']]
		return nextSong['fingerprint']
		return info

	def play_current(self):
		if len(self.order) == 0:
			return None
		return self.order[0]['fingerprint']

	def get_next(self):
		# Returns next song if one exists
		if len(self.order) == 0:
			return None
		return self.order[0]['fingerprint']

	def reset_vals(self):
		self.count = {}
		self.fingerprint_info = {}
		self.order = []
		random.shuffle(EXAMPLE_SONGS)
		for val in EXAMPLE_SONGS:
			self.add(vars(parseURL(val)))

class parseURL():
	def __init__(self, url, download=True):
		# This maps the given url to a specific function
		# AKA really bad code but okay...
		functionMap = {
			'spotify': self.parse_spotify,
			'music.apple.com': self.parse_apple_music,
			'googleplaymusic': self.parse_google_play,
			'youtube': self.parse_youtube
		}

		self.url = url

		urlParse = self.parse_error

		# this is probably the worst code/logic so far...
		for key, val in functionMap.iteritems():
			if key in url.lower():
				urlParse = val
				# lol wut
				break

		self.time_added = int(time.time())
		self.album_art = None
		self.artist = None
		self.song = None
		self.year = None
		self.album = None
		self.fingerprint = None

		self.do_download = download

		urlParse()

	def gen_fingerprint(self):
		return "{}_{}".format(self.artist.replace(" ", "-"), self.song.replace(" ", "-")).lower()

	def recount(self):
		RANKING.add(vars(self))

	def parse_error(self):
		raise Exception("[CUSTOM ERROR] Error with parsing URL: {}".format(self.url))

	def parse_spotify(self):

		page = get_page_from_url(self.url)

		tempVal = split_between(str(page), "Spotify.Entity = ", '"};') + '"}'
		spotifyDoc = json.loads(tempVal)
		if 'album' in spotifyDoc:
			spotifyDoc = spotifyDoc['album']
		self.album_art = spotifyDoc["images"][0]['url']
		self.year = spotifyDoc["release_date"].partition("-")[0]
		self.artist = spotifyDoc["artists"][0]["name"]
		self.album = spotifyDoc["name"]
		self.song = page.title.string.partition(", a ")[0]
		self.fingerprint = self.gen_fingerprint()

		self.download()
		return

	def parse_apple_music(self):

		page = get_page_from_url(self.url)

		# page.select("is-deep-linked")
		self.song = page.select(".is-deep-linked .table__row__headline")[0].getText().strip()
		self.artist = page.select(".section__headline")[0].getText().replace("More By ", "")
		# self.album_art = split_between(str(page.select(".we-artwork__source")[0]), 'srcset="', '"')
		self.year = page.select(".link-list__item__date")[0].getText().split(", ")[1]
		listOfAllUrlsAsString = split_between(str(page.select(".we-artwork__source")[0]), 'srcset="', '"/').split(",")
		self.album_art = listOfAllUrlsAsString[-1].partition(" ")[0]
		self.album = page.select(".product-header__title")[0].getText()
		# duration = page.select(".is-deep-linked .table__row__duration-counter")[0].getText()
		self.fingerprint = self.gen_fingerprint()

		# threading.Thread(target=self.download).start()
		self.download()
		return

	def parse_google_play(self):
		return

	def download(self):
		if self.do_download and os.path.exists("songs/{}.mp3".format(self.fingerprint)) == False:
			main.download_song(self.fingerprint, self.song, self.artist)

	def parse_youtube(self):
		return

	def return_values(self):
		return vars(self)

if __name__ == '__main__':
	songController = controller()
	# parseURL("https://open.spotify.com/track/3h3pOvw6hjOvZxRUseB7h9?si=XeSg8xLFQpC8LED2A1uWaQ")
	# parseURL("https://music.apple.com/us/album/one-thing-right-firebeatz-remix/1475133249?i=1475133252")
	for val in EXAMPLE_SONGS:
		songInfo = parseURL(val)
		songController.add(vars(songInfo))
	for i, val in enumerate(songController.order):
		print("{} - {}".format(i, val['song']))

	for i in range(5):
		song = songController.play_next()
		print("Playing: {} | Next Song: {}".format(song, songController.get_next()))


import pytest
import numpy as np

from sklearn.datasets import load_iris, make_classification
from sklearn.utils.testing import assert_array_equal
from sklearn.utils.testing import assert_allclose

from sklearn.linear_model import SGDClassifier
from sqlalchemy import create_engine
import pandas as pd

from sklearn_predict.linear_model import LinearSVMSQL

@pytest.fixture
def data():
    return load_iris(return_X_y=True)

def test_sgd_estimator_iris(data):
    est = SGDClassifier(max_iter=1000, tol=1e-3, random_state=10)
    est.fit(*data)
    assert hasattr(est, "coef_")

    X = data[0]
    y_pred = est.predict(X)
    assert_array_equal(y_pred[:10], data[1][:10])

    # build iris table in sqlite...
    engine = create_engine("sqlite://", echo=False)
    iris = load_iris()
    data = pd.DataFrame(
        data=np.c_[iris["data"], iris["target"]],
        columns=iris["feature_names"] + ["target"],
    )
    data.to_sql("iris", con=engine)

    queries = LinearSVMSQL(est, iris["feature_names"]).export()
    assert len(queries) == 3

    select_query = ",".join(
        ["{} as p{}".format(x, idx) for idx, x in enumerate(queries)]
    )
    sql_query = """
    select *, case when p0 > p1 and p0 > p2 then 0 when p1 > p0 and p1 > p2 then 1 when p2 > p0 and p2 > p1 then 2 else 0 end as prediction
    from (
    SELECT {} from iris)""".format(
        select_query
    )
    data_out = pd.read_sql(sql_query, engine)
    # print(data_out.columns)
    # print(y_pred)
    # print(data_out)
    data_out["pred0"] = y_pred == 0
    data_out["pred1"] = y_pred == 1
    data_out["pred2"] = y_pred == 2
    assert_array_equal(data_out["pred0"][:20], data_out["p0"][:20] > 0)
    assert_array_equal(data_out["pred1"][:20], data_out["p1"][:20] > 0)
    assert_array_equal(data_out["pred2"][:20], data_out["p2"][:20] > 0)
    assert_array_equal(data_out["prediction"], y_pred)

def test_sgd_estimator_mandelon():
    X, y = make_classification()
    est = SGDClassifier(max_iter=1000, tol=1e-3)
    est.fit(X, y)
    assert hasattr(est, "coef_")

    y_pred = est.predict(X)
    # assert_array_equal(y_pred[:10], y[:10])

    # build iris table in sqlite...
    engine = create_engine("sqlite://", echo=False)
    feature_names = ["c{}".format(x) for x in range(20)] + ["target"]
    data = pd.DataFrame(data=np.c_[X, y], columns=feature_names)
    data.to_sql("iris", con=engine)

    queries = LinearSVMSQL(est, feature_names).export()
    assert len(queries) == 1

    select_query = ",".join(
        ["{} as p{}".format(x, idx) for idx, x in enumerate(queries)]
    )
    sql_query = "SELECT {} from iris".format(select_query)
    data_out = pd.read_sql(sql_query, engine)
    # print(data_out.columns)
    # print(y_pred)
    # print(data_out)
    data_out["pred0"] = y_pred == 1
    assert_array_equal(data_out["pred0"], data_out["p0"] > 0)


import sqlite3
import json

from util.battlestalker import *
from util.db_utils import get_username, d_dogbloon

DB_FILE = "multi.db"
MAX_ROUNDS = 5
START_DOSH = 100000
STOCK_NUM = 5
def reset():
    '''clears all data from table'''
    s_reset()
    db = sqlite3.connect(DB_FILE)
    c = db.cursor()
    c.execute("DROP TABLE IF EXISTS a;")
    c.execute("CREATE TABLE a (matchid INTEGER PRIMARY KEY, u1 INTEGER, u2 INTEGER, dosh1 INTEGER, dosh2 INTEGER, choice1 INTEGER, choice2 INTEGER, round INTEGER);")
    db.commit()

def add_user(uid):
    '''adds a user to the list looking for matches, either placing them in a match with another user or searching for a match for them by themselves'''
    db = sqlite3.connect(DB_FILE)
    c = db.cursor()
    if  uid == None or uid == 0:
        return False
    if c.execute("SELECT count(*) FROM a WHERE a.u2 == ? OR a.u1 == ?;",(uid,uid)).fetchall()[0][0]==0:
        a = c.execute("SELECT * FROM a WHERE a.u2 == 0;").fetchall()
        if len(a)>0: # if other players are waiting for someone to join a match, join their match, else create a row indicating waiting for match.
            c.execute("UPDATE a SET u2 = ? WHERE a.matchid == ?;",(uid,a[0][0]))
            db.commit()
            db.close()
            init_match(uid)
        else:
            q=c.execute("SELECT matchid FROM a;").fetchall()
            print(q)
            c.execute("INSERT INTO a (matchid, u1, u2) VALUES (?, ?, 0);",(min_new_id(q),uid))
            db.commit()

        return True

def min_new_id(q):
    '''returns the lowest id not in q so we don;t have duplicate ids because uhh that would b bad'''
    if len(q) == 0:
        return 1
    i = 1
    b = set(j[0] for j in q)
    while i < 5000: # will crash after 5000 simeltaneous but it's not like we have servers to support a ton of traffic anyways nor do I expect + 10,000 to use this website at once so not really a problem
        if i not in b:
            return i
        i += 1
    return 1

def rdy_chk(uid):
    '''checks a match found by searching for one user to see if to players have been found'''
    db = sqlite3.connect(DB_FILE)
    c = db.cursor()
    b = c.execute("SELECT * FROM a WHERE a.u1 == ? OR a.u2 == ?;",(uid,uid)).fetchall();
    db.close()
    return len(b)>0 and b[0][1]>0 and b[0][2]>0

def rm_match(mid):
    '''obliterates a match from out of existence pretty epic really'''
    db = sqlite3.connect(DB_FILE)
    c = db.cursor()
    c.execute("DELETE FROM a WHERE a.matchid == ?;",(mid,))
    db.commit()

def ok2rm(uid):
    '''marks a user as having left from the match screen. once both users leave, match gets removed.'''
    i = matchinfo(uid)
    db = sqlite3.connect(DB_FILE)
    c = db.cursor()
    if i!=None and i[7]==0:
        if i[2] == -1 or i[1] == -1:
            db.close()
            rn_match(i[0])
        elif i[1] == uid:
            c.execute("UPDATE a SET u1 = -1 WHERE a.matchid == ?;",(mid,)) # 0 represents slot open to player joining for match, -1 already ended match.
        else:
            c.execute("UPDATE a SET u2 = -1 WHERE a.matchid == ?;",(mid,))
    db.commit()
    db.close()

def match_info(uid):
    '''returns database row for match with uid as player'''
    db = sqlite3.connect(DB_FILE)
    c = db.cursor()
    b = c.execute("SELECT * FROM a WHERE a.u1 == ? OR a.u2 == ?;",(uid,uid)).fetchall();
    db.close()
    return b[0] if len(b)>0 else None;

def init_match(uid):
    '''sets up database values for start of match (starting currency, rounds left)'''
    i = match_info(uid)
    db = sqlite3.connect(DB_FILE)
    c = db.cursor()
    if i != None and i[7] == None:
        c.execute("UPDATE a SET round = ?, dosh1 = ?, dosh2 = ? WHERE a.matchid == ?;", (MAX_ROUNDS, START_DOSH, START_DOSH, i[0])) # possible giving players starting $ based on total money?
        add_stocks(i[0],STOCK_NUM)
    db.commit()
    db.close()

def move(uid, mv):
    '''marks a player as having made a move, if both players have moved advances to next round'''
    i = match_info(uid)
    if i != None and i[7]>0 and -1*STOCK_NUM <= int(mv) <= 1*STOCK_NUM: # - short + buy |mv| stockno, 0 do nothing
        db = sqlite3.connect(DB_FILE)
        c = db.cursor()
        if i[1] == uid and i[5] == None: # check if u u1 or u2 & that u not already moved this round
            c.execute("UPDATE a SET choice1 = ? WHERE a.matchid == ?;",(int(mv),i[0]))
            db.commit()
            db.close()
            if i[6] != None:
                nxt_round(i[0])
        elif i[2] == uid and i[6] == None:
            c.execute("UPDATE a SET choice2 = ? WHERE a.matchid == ?;",(int(mv),i[0]))
            db.commit()
            db.close()
            if i[5] != None:
                nxt_round(i[0])

def nxt_round(mid):
    '''calculats change in $ based on stocks purchased, decrements rounds left, generates a new list of stocks.'''
    db = sqlite3.connect(DB_FILE)
    c = db.cursor()
    b = c.execute("SELECT * FROM a WHERE a.matchid == ?;",(mid,)).fetchone();
    if b != None and b[5] != None and b[6] != None:
        if b[5] != 0:
            s1 = inf_stock(mid, b[5])
            d1 = int(b[3] + b[3]*s1[4]*(1 if b[5]>0 else -1))
            print(d1)
            c.execute("UPDATE a SET dosh1 = ? WHERE a.matchid == ?;",(d1, mid))
        if b[6] != 0:
            s2 = inf_stock(mid, b[6])
            d2 = int(b[4] + b[4]*s2[4]*(1 if b[6]>0 else -1))
            print(d2)
            c.execute("UPDATE a SET dosh2 = ? WHERE a.matchid == ?;",(d2, mid))
        if d2 <= 0 or d1 <= 0:
            b[7] = 1
        c.execute("UPDATE a SET round = ?, choice1 = ?, choice2 = ?;",(b[7] - 1, None, None))
        db.commit()
        db.close()
        if b[7] > 1:
            rm_stocks(mid)
            add_stocks(mid,STOCK_NUM)
        else:
            distr_winnings(mid)

def distr_winnings(mid):
    '''after match has ended, picks winners and gives them money'''
    db = sqlite3.connect(DB_FILE)
    c = db.cursor()
    b = c.execute("SELECT * FROM a WHERE a.matchid == ?;",(mid,)).fetchone();
    if b != None and b[7] == 0:
        if b[3] > b[4]:
            d_dogbloon(b[1], START_DOSH / 100)
            d_dogbloon(b[2], START_DOSH / 100 * -1)
        elif b[4] > b[3]:
            d_dogbloon(b[1], START_DOSH / 100 * -1)
            d_dogbloon(b[2], START_DOSH / 100)
    db.commit()
    db.close()

def match_info_json(uid): # returns all relavent info about match as json -- match id, players, money, round, stocks (not price change ofc).
    '''json string of info on match & stocks in display players need to display.'''
    b = match_info(uid)
    if b != None:
        s = inf_stock(b[0],0)
        if len(s) > 0:
            if uid == b[1]:
                d = {"p":get_username(b[1]), "pdosh":int(b[3]), "e":get_username(b[2]), "edosh":int(b[4]), "round":b[7], "stocks":[(i[2],i[3]) for i in s]}
            else:
                d = {"p":get_username(b[2]), "pdosh":int(b[4]), "e":get_username(b[1]), "edosh":int(b[3]), "round":b[7], "stocks":[(i[2],i[3]) for i in s]}
            return json.dumps(d)

if __name__ == "__main__": # unit testing
    reset()
    s_reset()
    add_user(766)
    add_user(554)
    add_user(123)
    add_user(66)
    add_user(5)
    print(rdy_chk(5))
    print(rdy_chk(123))
    print(match_info_json(123))


import numpy as np
import tensorflow as tf
import cv2

#Analyzes given video footage (could be live streamed) to determine number of vehicles and pedestrians
class VideoRecognize:
    #videoName - the path of the video file (use 0 for computer camera)
    #graphName - the path to the .pd file containing the byte samples of feature
    def __init__(self, videoName, graphName):
        self.running = False
        #setup
        self.cap = cv2.VideoCapture(videoName)
        # Read the graph.
        with tf.gfile.FastGFile(graphName, 'rb') as f:
            self.graph_def = tf.GraphDef()
            self.graph_def.ParseFromString(f.read())

    def getInfo(self, index):
        if (index == 1):
            return 'person'
        elif (index == 3):
            return 'car'
        elif (index == 8):
            return 'truck'

    #Starts the session (must be called before analyzeFrame)
    def startSess(self):
        self.running = True
        try:
            self.sess = tf.Session()
            # Restore session
            self.sess.graph.as_default()
            tf.import_graph_def(self.graph_def, name='')
        except:
            self.running = False
            print("Error starting session")

    def analyzeFrame(self):
        if (self.running):
            # Read and preprocess an image.
            ret, img = self.cap.read()
            if (ret == False):
                return (-1, -1)
            rows = img.shape[0]
            cols = img.shape[1]
            inp = img
            inp = cv2.resize(img, (300, 300))
            inp = inp[:, :, [2, 1, 0]]  # BGR2RGB

            # Run the model
            out = self.sess.run([self.sess.graph.get_tensor_by_name('num_detections:0'),
                            self.sess.graph.get_tensor_by_name('detection_scores:0'),
                            self.sess.graph.get_tensor_by_name('detection_boxes:0'),
                            self.sess.graph.get_tensor_by_name('detection_classes:0')],
                           feed_dict={'image_tensor:0': inp.reshape(1, inp.shape[0], inp.shape[1], 3)})

            # Visualize detected bounding boxes.
            num_detections = int(out[0][0])
            for i in range(num_detections):
                classId = int(out[3][0][i])
                score = float(out[1][0][i])
                bbox = [float(v) for v in out[2][0][i]]
                if score > 0.3:
                    x = bbox[1] * cols
                    y = bbox[0] * rows
                    right = bbox[3] * cols
                    bottom = bbox[2] * rows
                    cv2.rectangle(img, (int(x), int(y)), (int(right), int(bottom)), (125, 255, 51), thickness=2)
            cv2.imshow('video', img)

            #getting the counts of different objects
            personCount = 0
            bikeCount = 0
            carCount = 0
            motorcycleCount = 0
            busCount = 0
            truckCount = 0
            trafficCount = 0

            objCount = int(out[0][0])
            objList = out[3][0][:objCount]
            print(objList)
            for i in range(objCount):
                if objList[i] == 1:
                    personCount = personCount + 1
                elif objList[i] == 2:
                    bikeCount = bikeCount + 1
                elif objList[i] == 3:
                    carCount = carCount + 1
                elif objList[i] == 4:
                    motorcycleCount = motorcycleCount + 1
                elif objList[i] == 6:
                    busCount = busCount + 1
                elif objList[i] == 8:
                    truckCount = truckCount + 1
            trafficCount = carCount + motorcycleCount + busCount + truckCount
            cv2.waitKey(50)
            return (trafficCount, personCount)
        else:
            return (-1, -1)

    #Stops the session from running
    def stopSess(self):
        cv2.destroyAllWindows()
        del self.sess


from PySide import QtCore, QtGui
from safbookmarks_ui import Ui_SafBookmarks

import os, sqlite3
from datetime import datetime

PLUGIN_NAME = "Safari Bookmarks"
import plugins_utils

class SafBookmarksWidget(QtGui.QWidget):

	def __init__(self, cursor, path, daemon = False):
		QtGui.QWidget.__init__(self)

		self.ui = Ui_SafBookmarks()
		self.ui.setupUi(self)

		self.setAttribute(QtCore.Qt.WA_DeleteOnClose)

		self.cursor = cursor
		self.backup_path = path

		self.filename = os.path.join(self.backup_path, plugins_utils.realFileName(self.cursor, filename="Bookmarks.db", domaintype="HomeDomain"))

		if (not os.path.isfile(self.filename)):
			raise Exception("Safari Bookmarks Database not found: \"%s\""%self.filename)

		self.ui.bookmarksTree.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
		QtCore.QObject.connect(self.ui.bookmarksTree, QtCore.SIGNAL('customContextMenuRequested(QPoint)'), self.ctxMenu)

		if (daemon == False):
			self.populateUI()

	def ctxMenu(self, pos):

		currentSelectedElement = self.ui.bookmarksTree.currentItem()
		if (currentSelectedElement): pass
		else: return

		# if url
		if (len(currentSelectedElement.text(1)) > 0):

			menu =  QtGui.QMenu();

			action1 = QtGui.QAction("Open in browser", self)
			action1.triggered.connect(self.openSelectedURL)
			menu.addAction(action1)

			action1 = QtGui.QAction("Copy URL", self)
			action1.triggered.connect(self.copySelected)
			menu.addAction(action1)

			menu.exec_(self.ui.bookmarksTree.mapToGlobal(pos));

	def openSelectedURL(self):

		currentSelectedElement = self.ui.bookmarksTree.currentItem()
		if (currentSelectedElement): pass
		else: return

		url = currentSelectedElement.text(1)

		QtGui.QDesktopServices.openUrl(url)

	def copySelected(self):

		currentSelectedElement = self.ui.bookmarksTree.currentItem()
		if (currentSelectedElement): pass
		else: return

		url = currentSelectedElement.text(1)

		clipboard = QtGui.QApplication.clipboard()
		clipboard.setText(url)

	def insertBookmark(self, parent_node, parent_id):
		query = "SELECT id, title, num_children, type, url, editable, deletable, order_index, external_uuid FROM bookmarks WHERE parent = \"%s\" ORDER BY order_index"%parent_id
		self.tempcur.execute(query)
		bookmarks = self.tempcur.fetchall()

		folderIcon = self.style().standardIcon(QtGui.QStyle.SP_DirIcon)
		urlIcon = self.style().standardIcon(QtGui.QStyle.SP_FileDialogContentsView)

		for bookmark in bookmarks:
			id = bookmark['id']
			title = bookmark['title']
			num_children = bookmark['num_children']

			# creating new node
			newNode = QtGui.QTreeWidgetItem(parent_node)

			# setting title
			#title = str(title.encode("utf-8"))
			if (bookmark['type'] != 0):
				title += " (%i)"%num_children
				newNode.setIcon(0, folderIcon)
			else:
				newNode.setIcon(0, urlIcon)

			newNode.setText(0, title)

			# adding node to bookmarks tree
			self.ui.bookmarksTree.addTopLevelItem(newNode)

			if (num_children != 0):
				self.insertBookmark(newNode, id)

			# type 0 for simple bookmarks, not 0 for folders
			if (bookmark['type'] == 0):

				newNode.setText(1, bookmark['url'])

				keyNode = QtGui.QTreeWidgetItem(newNode)
				keyNode.setText(0, bookmark['url'])
				keyNode.setText(1, bookmark['url'])
				self.ui.bookmarksTree.addTopLevelItem(keyNode)

	def printBookmark(self, parent_id):

		ritorno = ""

		# opening database
		self.tempdb = sqlite3.connect(self.filename)
		self.tempdb.row_factory = sqlite3.Row
		self.tempcur = self.tempdb.cursor()

		query = "SELECT id, title, num_children, type, url, editable, deletable, order_index, external_uuid FROM bookmarks WHERE parent = \"%s\" ORDER BY order_index"%parent_id
		self.tempcur.execute(query)
		bookmarks = self.tempcur.fetchall()
		for bookmark in bookmarks:
			id = bookmark['id']
			title = bookmark['title']
			num_children = bookmark['num_children']

			title = str(title.encode("utf-8"))
			if (bookmark['type'] != 0):
				title = "[" + title + "] (%i)"%num_children
			else:
				ref = ""%str(bookmark['url'].encode("utf-8"))
				title = ref + title + ""

			ritorno += "
"

			ritorno += "
"
			ritorno += title

			if (num_children != 0):
				#ritorno += "
"
				ritorno += self.printBookmark(id)

			ritorno += "
"

		# closing database
		self.tempdb.close()

		return ritorno

	def populateUI(self):

		# opening database
		self.tempdb = sqlite3.connect(self.filename)
		self.tempdb.row_factory = sqlite3.Row
		self.tempcur = self.tempdb.cursor()

		# populating tree with Safari Bookmarks
		self.insertBookmark(None, 0)

		# closing database
		self.tempdb.close()

def main(cursor, path):
	return SafBookmarksWidget(cursor, path)

def report(cursor, path):
	safBookManager = SafBookmarksWidget(cursor, path, False)
	ritorno = "
Safari Bookmarks
"
	ritorno += safBookManager.printBookmark(0)
	del safBookManager
	return (ritorno, None)


import argparse
import os
import shutil
from tqdm import tqdm
import torch.nn as nn
import torch.nn.functional as F
import logging
import torch
from src.utils.common import read_yaml, create_directories
import random
import warnings

STAGE = "BASE_MODEL_CREATION" ## <<< change stage name

logger = logging.getLogger(__name__)
logger.setLevel(logging.DEBUG)

formatter = logging.Formatter("[%(asctime)s: %(levelname)s: %(module)s]: %(message)s")

file_handler = logging.FileHandler(os.path.join("logs", "running_logs.log"))
file_handler.setFormatter(formatter)

logger.addHandler(file_handler)

warnings.filterwarnings('ignore')

class CNN(nn.Module):
  def __init__(self, in_, out_):
    super(CNN, self).__init__()
    self.conv_pool_01 = nn.Sequential(
        nn.Conv2d(in_channels=in_, out_channels=8, kernel_size=5, stride=1, padding=0),
        nn.ReLU(),
        nn.MaxPool2d(kernel_size=2, stride=2)
    )

    self.conv_pool_02 = nn.Sequential(
        nn.Conv2d(in_channels=8, out_channels=16, kernel_size=5, stride=1, padding=0),
        nn.ReLU(),
        nn.MaxPool2d(kernel_size=2, stride=2)
    )

    self.flatten = nn.Flatten()
    self.FC_01 = nn.Linear(in_features=16*4*4, out_features=128)
    self.FC_02 = nn.Linear(in_features=128, out_features=64)
    self.FC_03 = nn.Linear(in_features=64, out_features=out_)

  def forward(self, x):
    x = self.conv_pool_01(x)
    x = self.conv_pool_02(x)
    x = self.flatten(x)
    x = self.FC_01(x)
    x = F.relu(x)
    x = self.FC_02(x)
    x = F.relu(x)
    x = self.FC_03(x)
    return x

def main(config_path):
    ## read config files
    config = read_yaml(config_path)
    model = CNN(1, 10)
    logger.info("base model created")

    model_dir = config['artifacts']['model_dir']
    model_name = config['artifacts']['base_model_name']

    model_save_path = os.path.join(model_dir, model_name)
    create_directories([model_dir])

    torch.save(model, model_save_path)
    logger.info(f"base model saved at {model_save_path}")

if __name__ == '__main__':
    args = argparse.ArgumentParser()
    args.add_argument("--config", "-c", default="configs/config.yaml")
    parsed_args = args.parse_args()

    try:
        logger.info("\n********************")
        logger.info(f">>>>> stage {STAGE} started <<<<<")
        main(config_path=parsed_args.config)
        logger.info(f">>>>> stage {STAGE} completed!<<<<<\n")
    except Exception as e:
        logger.exception(e)
        raise e


#!/usr/bin/env python2
# -*- coding: utf-8 -*-
"""
Created on Fri Apr 20 14:24:20 2018
@author: Alma Andersson

Created for Exercise 1. A small script just to better visualize the typical
solutions to the Fitzhugh-Nagumo model as constructed in the exercise.

"""

import numpy as np
import matplotlib.pyplot as plt
from homework2 import *

class Function:
    """
    Fitzhugh Nagumo dynamical system.
    Function to be used for the numerical integration.
    """
    def __init__(self,b):
        self.b = b
    def function(self,t,y):
        return [100*(y[0]-y[0]**3-y[1]), 2*y[0]-y[1]+self.b]

if __name__ == '__main__':
#%% Setup and perform integration
    b1 = 0. #Specify this parameter to test for different systems
    T = [0,100]
    y0 = [1,0]
    fun = Function(b1)
    system = Orbit_Maker(fun.function,h=0.01)
    system.generate_trajectory(T,y0)
#%% Plot result
    xt = system.traj[:,0]
    yt = system.traj[:,1]
    time = np.arange(T[0],T[1],0.01)
    plt.plot(time,xt,'b')
    plt.plot(time,yt,'r')
    plt.xlim([0,10])
    plt.legend(['x','y'])


from PIL import Image
import torch
import torchvision.transforms as transforms
import torch.nn.functional as F
from srcnn import SRCNN

# 加载已经训练好的 SRCNN 模型
model = SRCNN()
model.load_state_dict(torch.load('srcnn_model_green.pth'))
model.eval()

# 打开待恢复的图像
img_path = 'test_green.jpg'
img = Image.open(img_path).convert('RGB')

# 对图像进行处理，缩放和转换为Tensor格式
transform = transforms.Compose([
    transforms.Resize((400, 400)),
    transforms.ToTensor(),
])

img_input = transform(img)
img_input = img_input.unsqueeze(0)

# 将图像输入到模型中，获取模型输出
with torch.no_grad():
    img_output = model(img_input)

# 转换模型输出为PIL.Image 格式，并保存
img_out = transforms.ToPILImage()(img_output.squeeze())
img_out.save('restored.jpg')

def calculate_psnr(image1, image2):
    mse = F.mse_loss(image1, image2)
    psnr = 20 * torch.log10(1.0 / torch.sqrt(mse))
    return psnr.item()

src = transform(Image.open("./test.jpg").convert("RGB"))
img_in = transform(Image.open(img_path).convert("RGB"))
img_out = transform(Image.open("./restored.jpg").convert("RGB"))

print("恢复前："+str(calculate_psnr(src, img_in)))
print("恢复后："+str(calculate_psnr(src, img_out)))


"""smp_graphs utils

some general utils for data structures and ops
"""

from collections import OrderedDict
from functools import partial

from numpy import ndarray
from numpy import float64
from numpy import transpose, roll, arange, array

def print_dict(pdict = {}, level = 1, indent = None):
    """pretty print a dictionary for debugging by recursive construction of print string

    replace classes, objects, functions with their repr string within ''
    """
    # if level == 0:
    #     print "#" * 80
    pstring = ""
    level_indent = 3
    level_marker = " "
    level_indent_str    = level_marker * level * level_indent
    level_indent_str_m1 = level_marker * (level - 1) * level_indent

    if indent is None:
        indent = level_indent_str

    # print "pdict[level = %d] = %s, type = %s\n\n" % (level, pdict, type(pdict))
    if type(pdict) in [dict, OrderedDict]:
        # pstring += "\n%s{" % (indent)
        pstring += "{"
        for i, item in enumerate(pdict.items()):
            k, v = item
            # if i > 0:
            pstring += "\n%s" % (indent)
            pstring += print_dict(pdict = k, level = level+1)
            pstring += ": "
            if type(v) in [dict, OrderedDict, list, ndarray, tuple]:
                pstring += print_dict(pdict = v, level = level+1)
            else:
                pstring += print_dict(pdict = v, level = level+1, indent = "")
            pstring += ", "
        pstring += "\n%s}" % (level_indent_str_m1)
    elif type(pdict) in [list, ndarray, tuple]:
        # fix start end markers for list / array / tuple
        s1 = '['
        s2 = ']'
        if type(pdict) == tuple:
            s1 = '('
            s2 = ')'

        pstring += s1
        for i, pdict_elem in enumerate(pdict):
            pstring += print_dict(pdict = pdict_elem, level = level+1)
            pstring += ', '
        pstring += s2
    else:
        if type(pdict) not in [int, float, float64, bool, tuple, None]:
            # replace single quotes within string
            pdictstr = str(pdict).replace("'", "\\'")
            # print type(pdictstr), pdict, pdictstr.replace("'", "X")
            pstring += "'%s'"  % (pdictstr,)
        else:
            pstring += "%s"  % (pdict,)

    # print "level %d: %s: %s" % (level, k, pstring)
    # if "array" in pstring:
    #     print "array", pstring, level, indent
    return pstring

################################################################################
# utils, TODO move to utils.py
def ordereddict_insert(ordereddict = None, insertionpoint = None, itemstoadd = []):
    """ordereddict_insert

    Self rolled ordered dict insertion from http://stackoverflow.com/questions/29250479/insert-into-ordereddict-behind-key-foo-inplace
    """
    assert ordereddict is not None
    assert insertionpoint in list(ordereddict.keys()), "insp = %s, keys = %s, itemstoadd = %s" % (insertionpoint, list(ordereddict.keys()), itemstoadd)
    new_ordered_dict = ordereddict.__class__()
    for key, value in list(ordereddict.items()):
        new_ordered_dict[key] = value
        if key == insertionpoint:
            # check if itemstoadd is list or dict
            if type(itemstoadd) is list:
                for item in itemstoadd:
                    keytoadd, valuetoadd = item
                    new_ordered_dict[keytoadd] = valuetoadd
            else:
                for keytoadd, valuetoadd in list(itemstoadd.items()):
                    new_ordered_dict[keytoadd] = valuetoadd
        # else:
        #     print "insertionpoint %s doesn't exist in dict" % (insertionpoint)
        #     sys.exit(1)
    ordereddict.clear()
    ordereddict.update(new_ordered_dict)
    return ordereddict

def xproduct(f, tup):
    """compute the cartesian product of a variable number of tensor dimensions"""
    assert len(tup) > 0
    if len(tup) > 1: # still dimensions left
        return xproduct(partial(f, list(range(tup[0]))), tup[1:]) # call yourself with partial of current dim and remaining dims
    # until nothings left
    return [elem for elem in f(list(range(tup[0])))]

def mytupleroll(tup, direction = 1):
    return tuple(roll(array(tup), shift = direction))

def mytuple(tup, direction = 1):
    return tuple(roll(arange(len(tup)), shift = direction))

def myt(a, direction = 1):
    """my transpose (transpose 'time' axis first to last)"""
    return a.transpose(mytuple(a.shape, direction))


import re
import numpy as np
import matplotlib.pyplot as plt

import re
import numpy as np
import matplotlib.pyplot as plt

def plotHistoryGraph(strData='nothing', epoch=100):

	# parsing point : loss: [6글자], accuracy: [6글자], val_loss: [6글자], val_accuracy: [6글자]
	epoch_data = strData.split(sep="Epoch")
	nums = [re.findall(r' [0-9]+[.][0-9]+', i) for i in epoch_data[1:]] # loss, accuracy, val_loss, val_accuracy

	# loss, accuracy, val_loss, val_accuracy
	loss = np.array([ float(i[0].strip()) for i in nums ])
	accuracy = np.array([ float(i[1].strip()) for i in nums ])
	val_loss = np.array([ float(i[2].strip()) for i in nums ])
	val_accuracy = np.array([ float(i[3].strip()) for i in nums ])

	# loss 기준점 : 0.8
	# accuracy 기준점 : 0.8
	dt = 0.01
	t = np.arange(0, epoch)
	fig, axs = plt.subplots(4, 1, figsize=(15,20))

	# Loss
	lines = axs[0].plot(t, loss, t, val_loss)
	plt.setp(lines[0], alpha=0.6)
	plt.setp(lines[1], linewidth=3)
	axs[0].set_xlim(0, epoch-1)
	axs[0].set_xlabel('Epoch')
	axs[0].set_ylim(0, 1.1)
	axs[0].set_ylabel('Training loss and Validation loss')
# 	axs[0].grid(True)

	line = axs[1].plot(t, abs(loss-val_loss)*100)
	plt.setp(line, linewidth=3)
	axs[1].set_xlim(0, epoch-1)
	axs[1].set_xlabel('Epoch')
	axs[1].set_ylim(0, 100)
	axs[1].set_ylabel('Loss Coherence %')
# 	axs[1].grid(True)
# 	cxy, f = axs[1].cohere(loss, val_loss, 1, 0.2)

	# Accuracy
	lines = axs[2].plot(t, accuracy, t, val_accuracy)
	plt.setp(lines[0], alpha=0.6)
	plt.setp(lines[1], linewidth=3)
	axs[2].set_xlim(0, epoch-1)
	axs[2].set_xlabel('Epoch')
	axs[2].set_ylim(0, 1.1)
	axs[2].set_ylabel('Training accuracy and Validation accuracy')
# 	axs[2].grid(True)

# 	cxy2, f2 = axs[3].cohere(accuracy, val_accuracy)
	line = axs[3].plot(t, abs(loss-val_loss)*100)
	plt.setp(line, linewidth=3)
	axs[3].set_xlim(0, epoch-1)
	axs[3].set_xlabel('Epoch')
	axs[3].set_ylim(0, 100)
# 	axs[3].grid(True)
# 	cxy, f = axs[1].cohere(loss, val_loss, 1, 0.2)
	axs[3].set_ylabel('Acc Coherence %')

	fig.tight_layout()
	plt.show()

def plotDiffGraph(strData='', epoch=100):

	# parsing point : loss: [6글자], accuracy: [6글자], val_loss: [6글자], val_accuracy: [6글자]
	epoch_data = strData.split(sep="Epoch")
	nums = [re.findall(r' [0-9]+[.][0-9]+', i) for i in epoch_data[1:]] # loss, accuracy, val_loss, val_accuracy

	# loss, accuracy, val_loss, val_accuracy
	loss = np.array([ float(i[0].strip()) for i in nums ])
	accuracy = np.array([ float(i[1].strip()) for i in nums ])
	val_loss = np.array([ float(i[2].strip()) for i in nums ])
	val_accuracy = np.array([ float(i[3].strip()) for i in nums ])

	# loss 기준점 : 0.6 (사람의 오류율)
	# accuracy 기준점 : 0.8
	t = np.arange(0, epoch)
	fig, (ax1, ax2) = plt.subplots(2, 1, sharex=True, figsize=(15,6))

	ax1.fill_between(t, 0.6, val_loss)
	ax1.set_xlim(0, epoch-1)
	ax1.set_ylim(0, max(val_accuracy))
	ax1.set_ylabel('Between 1 to 0')
	ax1.set_xlabel('Epoch')

	ax2.fill_between(t, 0.8, val_loss)
	ax1.set_xlim(0, epoch-1)
	ax1.set_ylim(0, max(val_accuracy))
	ax2.set_ylabel('Between 1 to 0')
	ax2.set_xlabel('Epoch')

	fig.tight_layout()
	plt.show()


#import relevant libraries
from flask import Flask, jsonify, request, render_template
import pandas as pd
import numpy as np
import pickle
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LogisticRegression

app = Flask(__name__)

model = pickle.load(open("capstone.pkl", 'rb')) #load model

@app.route('/')
def home():
    return render_template('/form_upload_1.html') #page to upload csv file

@app.route('/prediction',methods = ['POST'])
def upload_route_summary():
    if request.method == 'POST':

        # Create variable for uploaded file
        f = request.files['fileupload']

        #convert the csv file to dataframe
        df = pd.read_csv(f)
        ss = StandardScaler()
        df_ss  = ss.fit_transform(df)#scale the data

        df['buy_prob'] = [prob[1] for prob in model.predict_proba(df_ss)]#generate predict proba
        df['Customer ID']=np.arange(len(df)).astype(str)

        ## Generating random phone numbers

        from random import randint
        def random_with_N_digits(n):
            range_start = 10**(n-1)
            range_end = (10**n)-1
            return randint(range_start, range_end)

        df['phone number'] =1

        df['phone number'] = df['phone number'].apply(lambda x:f'{9}{random_with_N_digits(7)}')

        submission = df[['Customer ID','phone number' ,'buy_prob']]
        leads =submission.loc[df.buy_prob >0.5].sort_values(['buy_prob'], ascending= False).reset_index(drop= True) #slice the dataframe so that we show only the important columns and hides index

        pred_html = leads.to_html(col_space=100) #convert dataframe to html
#        pred_html =df.head(20).to_html(col_space=100)
#    return render_template("pred_html", output = output)

    return pred_html

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


"""Load data step (data prep pipeline and embedding pipeline)."""
import os
from typing import Tuple

import pandas as pd
from config import DATA_DIR
from utils.data_version_control import files_exist, git_checkout_folder, pull_data
from zenml import step
from zenml.logger import get_logger

logger = get_logger(__name__)

@step
def load_data(
    data_version: str,
    data_postfix: str,
    reference_data_version: str,
) -> Tuple[str, str, pd.DataFrame, pd.DataFrame]:
    """Load two CSVs from the "data/" directory. If no data exists, pull from the DVC storage bucket prior to loading.

    Args:
        data_version (str): Data version tag or commit hash for Git/DVC.
        data_postfix (str): Postfix to data 'raw' or 'validated'.
        reference_data_version (str): The reference data version for computing embedding drift.

    Returns:
        mind_data (pd.DataFrame): Data from the Mind website.
            Index:
                RangeIndex
            Columns:
                Name: uuid, dtype: object
                Name: text_scraped, dtype: object
                Name: timestamp, dtype: datetime64[ns]
                Name: url, dtype: object
        nhs_data (pd.DataFrame): Data from the NHS website.
            Index:
                RangeIndex
            Columns:
                Name: uuid, dtype: object
                Name: text_scraped, dtype: object
                Name: timestamp, dtype: datetime64[ns]
                Name: url, dtype: object
    """
    git_checkout_folder(tag_name=f"{data_version}_{data_postfix}", folder_name="data")
    pull_data()

    mind_file_path = os.path.join(DATA_DIR, f"mind_data_{data_postfix}.csv")
    nhs_file_path = os.path.join(DATA_DIR, f"nhs_data_{data_postfix}.csv")

    files_exist(
        [mind_file_path, nhs_file_path],
        error_message="Required CSV files do not exist in 'data' folder, ensure the previous pipeline has been run.",
    )

    mind_df = pd.read_csv(mind_file_path)
    nhs_df = pd.read_csv(nhs_file_path)

    return data_version, reference_data_version, mind_df, nhs_df


import time
from typing import Dict, List, Optional, Tuple

import numpy as np
from numba import njit

WALL = 2

class MazeBouncingBallPolicy:
    # Policy:
    #   1) Forward until you hit a wall
    #   2) Turn in random 360 direction
    #   3) Go to 1)

    def __init__(self):
        self.pos = None
        self.turns_remaining = 0

    def __call__(self, obs) -> Tuple[int, dict]:
        assert 'agent_pos' in obs, f'Need agent position'
        pos = obs['agent_pos']
        action = -1

        # print(f'{self.pos} => {pos} ({obs["agent_dir"]})')

        if self.turns_remaining == 0:
            if self.pos is None or not np.all(self.pos == pos):
                # Going forward
                action = 2
                self.pos = pos
            else:
                # Hit the wall - start turning
                if np.random.randint(2) == 0:
                    # self.turns_remaining = -np.random.randint(2, 5)  # Left
                    self.turns_remaining = -1  # TODO
                else:
                    # self.turns_remaining = np.random.randint(2, 5)  # Right
                    self.turns_remaining = 1  # TODO
                self.pos = None

        if self.turns_remaining > 0:
            # Turning right
            action = 1
            self.turns_remaining -= 1

        elif self.turns_remaining < 0:
            # Turning left
            action = 0
            self.turns_remaining += 1

        assert action >= 0
        return action, {}

class MazeDijkstraPolicy:
    # Policy:
    #   1) Pick a random spot on a map
    #   2) Go there using shortest path
    #   3) Occasionally perform a random action

    def __init__(self, step_size, turn_size, epsilon=0.10):
        self.step_size = step_size
        self.turn_size = turn_size
        self.epsilon = epsilon
        self.goal = None
        self.expected_pos = None

    def __call__(self, obs) -> Tuple[int, dict]:
        assert 'agent_pos' in obs, 'Need agent position'
        assert 'map_agent' in obs, 'Need map'

        x, y = obs['agent_pos']
        dx, dy = obs['agent_dir']
        d = np.arctan2(dy, dx) / np.pi * 180  # type: ignore
        map = obs['map_agent']
        # assert map[int(x), int(y)] >= 3, 'Agent should be here'

        if obs['reset']:
            self.goal = None  # new episode
            self.expected_pos = None
        if self.goal is None:
            self.goal = self.generate_goal(map)

        if self.expected_pos is not None:
            if not np.isclose(self.expected_pos[:2], [x, y], 1e-3).all():
                print('WARN: unexpected position - stuck? Generating new goal...')
                self.goal = self.generate_goal(map)

        while True:
            t = time.time()
            actions, path, nvis = find_shortest(map, (x, y, d), self.goal, self.step_size, self.turn_size)
            # print(f'Pos: {tuple(np.round([x,y,d], 2))}'
            #       f', Goal: {self.goal}'
            #       f', Len: {len(actions)}'
            #       f', Actions: {actions[:1]}'
            #       # f', Path: {path[:1]}'
            #       f', Visited: {nvis}'
            #       f', Time: {int((time.time()-t)*1000)}'
            #       )
            if len(actions) > 0:
                if np.random.rand() < self.epsilon:
                    self.expected_pos = None
                    return np.random.randint(3), {}  # random action
                else:
                    self.expected_pos = path[0]
                    return actions[0], {}  # best action
            else:
                self.goal = self.generate_goal(map)

    @staticmethod
    def generate_goal(map):
        while True:
            x = np.random.randint(map.shape[0])
            y = np.random.randint(map.shape[1])
            if map[x, y] != WALL:
                return x, y

@njit
def find_shortest(map, start, goal, step_size=1.0, turn_size=45.0):
    KPREC = 5
    RADIUS = 0.2
    x, y, d = start
    gx, gy = goal

    # Well ok, this is BFS not Dijkstra, technically speaking

    que = []
    que_ix = 0
    visited = {}
    parent = {}
    parent_action = {}

    p = (x, y, d)
    key = (round(x * KPREC) / KPREC, round(y * KPREC) / KPREC, round(d * KPREC) / KPREC)
    que.append(p)
    visited[key] = True
    goal_state = None

    while que_ix < len(que):
        p = que[que_ix]
        que_ix += 1
        x, y, d = p
        if int(x) == int(gx) and int(y) == int(gy):
            goal_state = p
            break
        for action in range(3):
            x1, y1, d1 = x, y, d
            if action == 0:  # turn left
                d1 = d - turn_size
                if d1 < -180.0:
                    d1 += 360.0
            if action == 1:  # turn right
                d1 = d + turn_size
                if d1 > 180.0:
                    d1 -= 360.0
            if action == 2:  # forward
                x1 = x + step_size * np.cos(d / 180 * np.pi)
                y1 = y + step_size * np.sin(d / 180 * np.pi)
                # Check wall collision at 4 corners
                for x2, y2 in [(x1 - RADIUS, y1 - RADIUS), (x1 + RADIUS, y1 - RADIUS), (x1 - RADIUS, y1 + RADIUS), (x1 + RADIUS, y1 + RADIUS)]:
                    if x2 < 0 or y2 < 0 or x2 >= map.shape[0] or y2 >= map.shape[1] or map[int(x2), int(y2)] == WALL:
                        x1, y1 = x, y  # wall
                        break
            p1 = (x1, y1, d1)
            key = (round(x1 * KPREC) / KPREC, round(y1 * KPREC) / KPREC, round(d1 * KPREC) / KPREC)
            if key not in visited:
                que.append(p1)
                parent[p1] = p
                parent_action[p1] = action
                visited[key] = True
                assert len(visited) < 100000, 'Runaway Dijkstra'

    path = []
    actions = []
    if goal_state is not None:
        p = goal_state
        while p in parent_action:
            path.append(p)
            actions.append(parent_action[p])
            p = parent[p]
        path.reverse()
        actions.reverse()
    else:
        print('WARN: no path found')

    return actions, path, len(visited)


import argparse
import logging
import os
import sys
from time import sleep

from mpi4py import MPI

sys.path.insert(0, os.path.abspath(os.path.join(os.getcwd(), "./../../../../")))
sys.path.insert(0, os.path.abspath(os.path.join(os.getcwd(), "./../../../../../")))

from fedml_core.distributed.test.test_rpc.dummy_algorithm.client_manager import RPCClientManager
from fedml_core.distributed.test.test_rpc.dummy_algorithm.server_manager import RPCServerManager

def add_args(parser):
    parser.add_argument("--rank", type=int, default=0)

    parser.add_argument("--backend", type=str, default="GRPC")

    parser.add_argument(
        "--enable_cuda_rpc",
        default=False,
        action="store_true",
        help="Enable cuda rpc (only for TRPC backend)",
    )

    parser.add_argument(
        "--gpu_mapping_file",
        type=str,
        default="gpu_mapping.yaml",
        help="the gpu utilization file for servers and clients. If there is no \
                        gpu_util_file, gpu will not be used.",
    )

    parser.add_argument(
        "--gpu_mapping_key", type=str, default="mapping_default", help="the key in gpu utilization file"
    )

    parser.add_argument(
        "--grpc_ipconfig_path",
        type=str,
        default="grpc_ipconfig.csv",
        help="config table containing ipv4 address of grpc server",
    )

    parser.add_argument(
        "--trpc_master_config_path",
        type=str,
        default="trpc_master_config.csv",
        help="config indicating ip address and port of the master (rank 0) node",
    )

    args = parser.parse_args()
    return args

def run_worker(args, rank, size):
    if rank == 0:
        server_manager = RPCServerManager(args, rank=rank, size=size, backend=args.backend)
        sleep(1)
        server_manager.send_model_params()
        server_manager.run()
    else:

        client_manager = RPCClientManager(args, rank=rank, size=size, backend=args.backend)
        client_manager.run()

if __name__ == "__main__":
    # parse python script input parameters
    parser = argparse.ArgumentParser()
    args = add_args(parser)

    rank = args.rank
    world_size = 2

    # customize the log format
    # logging.basicConfig(level=logging.INFO,
    logging.basicConfig(
        level=logging.DEBUG,
        format="rank - "
        + str(rank)
        + " - %(asctime)s.%(msecs)03d %(filename)s[line:%(lineno)d] %(levelname)s %(message)s",
        datefmt="%Y-%m-%d,%H:%M:%S",
    )

    logging.info(args)

    run_worker(args, rank, world_size)


#author: hanshiqiang365 （微信公众号：韩思工作室）

import numpy as np
import cv2
from matplotlib import pyplot as plt
from PIL import Image,ImageFont,ImageDraw
import time
import random

# 部分弹幕内容示例
barrages_all = [
    ('哈哈哈哈哈哈哈。萌翻了！', 1),
    ('秀', 2),
    ('小朋友们的演技都逆天了！！哭戏都演的超好啊！', 3),
    ('5189条.....', 12),
    ('真棒！', 5),
    ('每日三刷', 1),
    ('倾情演出', 7),
    ('《小戏骨》是湖南电视剧频道的一个“小孩学大剧”的综艺节目', 9),
    ('666', 4),
    ('与君初相识，犹如故人归。', 4),
    ('弹幕被清了好多', 21),
    ('翻拍经典的片子', 2),
    ('知心二叔么么哒', 17),
    ('哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈', 5),
    ('我没有', 12),
    ('38', 9),
    ('一股清流', 15),
    ('还是小白蛇好看、', 27),
    ('我是来看小白蛇的', 5),
    ('一星的制作，四星的表演', 2),
    ('似水年华', 49),
    ('回不去了', 60),
    ('法海，你不懂爱', 106),
    ('暂停成功', 218),
    ('开头见', 223),
    ('与君初相识，犹如故人归', 17),
    ('抱走猫酱', 92),
    ('突然害怕', 197),
    ('二十年生死两茫茫', 215),
    ('没弹幕', 18),
    ('白衣服的是我的，，', 155),
    ('这个我还是喜欢白衣服的，，', 117),
    ('白衣服是我的!', 177),
    ('娃娃神剧', 210),
    ('戏足自珠玑，情真催泪下', 40),
    ('美人如玉剑如虹', 173),
]

barrages_all.sort(key=lambda x:x[1])
colors = ['#600', '#060', '#006', '#066', '#606', '#660', '#666']

def get_fore(img):
    shape = img.shape[:]
    img = cv2.resize(frame,(int(img.shape[1] / 8), int(img.shape[0] / 8)), interpolation=cv2.INTER_CUBIC)
    mask = np.zeros(img.shape[:2],np.uint8)
    bgdModel = np.zeros((1,65),np.float64)
    fgdModel = np.zeros((1,65),np.float64)
    rect = (10, 10, img.shape[1]-10, img.shape[0]-10)
    try:
        cv2.grabCut(img,mask,rect,bgdModel,fgdModel,5,cv2.GC_INIT_WITH_RECT)
    except:
        pass
    mask = np.where((mask==2)|(mask==0),0,1).astype('uint8')
    mask = cv2.resize(mask,(shape[1], shape[0]))
    return mask

cv2.namedWindow('AI Barrage - developed by hanshiqiang365', cv2.WINDOW_NORMAL)
cap = cv2.VideoCapture('resources/babywhitesnake.mp4')

t = 0
ticks = 0
mask_history = []
barrages = barrages_all[:]
barrages_active = []

font = ImageFont.truetype('zhaozi.ttf', 18)

while cv2.waitKey(1) < 0:
    hasFrame, frame = cap.read()
    if not hasFrame:
        cv2.waitKey()
        break
    mask = get_fore(frame)

    mask_count = np.count_nonzero(mask)
    if len(mask_history) > 0:
        avg_mask = sum(mask_history) / len(mask_history)
        mask_ratio = mask_count / avg_mask
        if mask_ratio < 0.5 or mask_ratio > 1.5:
            mask = lask_mask
        else:
            lask_mask = mask
    else:
        lask_mask = mask
    mask_history.append(mask_count)
    if len(mask_history) > 20:
        mask_history.pop(0)

    ticks += 1

    if len(barrages) > 0 and barrages[0][1] * 20 < ticks:
        b = {
            'text': barrages.pop(0)[0],
            'height': int(random.random() * frame.shape[0]),
            'width': frame.shape[1],
            'color': random.choice(colors)
        }
        barrages_active.append(b)

    im = Image.fromarray(frame)
    draw = ImageDraw.Draw(im)
    for b in barrages_active:
        draw.text((b['width'], b['height']), b['text'], b['color'], font=font)
        b['width'] -= 5

    if len(barrages_active) > 0 and barrages_active[0]['width'] < -400:
        barrages_active.pop(0)
    frame_with_text = np.array(im)

    img = frame_with_text * (1-mask)[:,:,np.newaxis] + frame * mask[:,:,np.newaxis]
    cv2.imshow('AI Barrage - developed by hanshiqiang365', img)

    t2 = cv2.getTickCount()
    elapsed = ((t2 - t) / cv2.getTickFrequency())
    rest = max(0.075 - elapsed, 0)

    time.sleep(rest)
    t = cv2.getTickCount()


import traceback
import datetime
import pytest
import json
import requests
import common.common_util as common_util
import jsonpath
import re
from common.logger_util import write_log, write_error_log
from debugtalk import DebugTalk
import time

class RequestUtil(object):

    # 用来存储cookie信息
    cookie = {}
    sessions =requests.session()

    def __init__(self):
        # 初始化一个基础路径
        self.base_url = common_util.read_config_yaml('base', 'base_url')
        # 初始化cookies
        self.last_cookies = RequestUtil.cookie
        # 初始化请求头
        self.last_headers = None

    # 封装提取变量(json提取器,正则表达式提取器)
    def analysic_extract(self, casetest_info, res):
        text_result = res.text
        json_result = res.json()
        if jsonpath.jsonpath(casetest_info, '$..extract'):
            print("************%s" % casetest_info['extract'])
            for key, value in dict(casetest_info['extract']).items():
                if '(.+?)' in value or '(.*?)' in value:
                    write_log("analysic_extract进入正则提取判断")
                    if key == 'cookie':
                        obj = res.cookies
                    else:
                        extract_data = re.search(value, text_result)
                        write_log("--------------提取到的值是：%s" %extract_data.group(1))
                        obj = extract_data.group(1)
                    if obj:
                        data_dict = {key: obj}
                        common_util.write_extract_yaml(data_dict)
                        write_log("--------------------%s提取成功--------------------\n\n" % key)
                elif key == value:
                    write_log("进入json提取判断")
                    temp_data = jsonpath.jsonpath(json_result, '$..%s' % value)
                    if temp_data:
                        data_dict = {key: temp_data[0]}
                        common_util.write_extract_yaml(data_dict)
                        write_log("--------------------%s提取成功--------------------\n\n" % key)
                # 此判断适用于提取的键值在返回的数据中存在且返回的数据为json
                elif value:
                    write_log("进入通过key值提取数据场景")
                    temp_data = jsonpath.jsonpath(json_result, '$..%s' % key)
                    if temp_data:
                        data_dict = {key: temp_data[0]}
                        common_util.write_extract_yaml(data_dict)
                        write_log("--------------------%s提取成功--------------------\n\n" % key)
                else:
                    write_error_log("暂不支持该提取方式")

    # 封装提取变量(适用于返回的数据为非json格式)(json提取器,正则表达式提取器)
    def analysic_text_extract(self, casetest_info, res):
        text_result = res.text
        if jsonpath.jsonpath(casetest_info, '$..extract'):
            for key, value in dict(casetest_info['extract']).items():
                if '(.+?)' in value or '(.*?)' in value:
                    write_log("analysic_text_extract进入正则提取判断")
                    if key == 'cookie':
                        obj = res.cookies
                    else:
                        obj = re.search(value, text_result).group(1)
                    if obj:
                        data_dict = {key: obj}
                        common_util.write_extract_yaml(data_dict)
                        write_log("--------------------%s提取成功--------------------\n\n" % key)
                    else:
                        write_error_log("--------------------%s提取失败，在返回的数据中不存在--------------------\n\n" % key)
                else:
                    write_error_log("暂不支持该提取方式")

    # 封装的分析yaml测试用例文件的方法
    def analysis_yaml(self, testcase_info):
        """
        :param casetest_info: yaml测试用例数据
        :return: 无
        """
        try:
            # 判断：name,request,validate关键字是否存在
            testcase_info = dict(testcase_info)
            keys = testcase_info.keys()
            if 'name' in keys and 'request' in keys and 'validate' in keys:
                request_data = testcase_info["request"]
                request_keys = request_data.keys()
                if 'url' in request_keys and 'method' in request_keys:
                    headers=files=None
                    if jsonpath.jsonpath(request_data, '$..headers'):
                        headers = request_data["headers"]
                        del request_data["headers"]
                    if jsonpath.jsonpath(request_data, '$..files'):
                        for key, value in request_data["files"].items():
                            request_data["files"][key] = open(value, 'rb')
                        files = request_data["files"]
                        del request_data["files"]
                        # 收集日志
                    write_log("------------------------接口请求开始-------------------------")
                    write_log("接口名称：%s" % testcase_info['name'])
                    write_log("请求头：%s" % headers)
                    write_log("请求路径：%s" % testcase_info['request']['url'])
                    if jsonpath.jsonpath(testcase_info['request'], '$..data'):
                        write_log("接口替换前的请求数据：%s" % testcase_info['request']['data'])
                    if jsonpath.jsonpath(testcase_info['request'], '$..files'):
                        write_log("请求文件：%s" % testcase_info['request']['files'])
                    res = self.send_request(method=request_data.pop('method'), url=request_data.pop('url'),
                                            headers=headers, files=files, **request_data)
                    #　write_log("---------接口返回结果：%s" % res.text)
                    yq_result = testcase_info['validate']
                    status_code = res.status_code
                    # 断言返回结果
                    if jsonpath.jsonpath(testcase_info, '$..response_type') and testcase_info[
                        'response_type'] == 'text':
                        write_log("------------------返回的响应结果非字典类型，调用result_text_validatee方法断言-------------------")
                        self.result_text_validate(yq_result=yq_result, real_result=res.text, status_code=status_code)
                        # 提取变量
                        self.analysic_text_extract(testcase_info, res)
                    else:
                        write_log("------------------默认返回的响应结果是字典，调用result_validate方法断言-------------------")
                        # print('这是返回的数据' % res.json())
                        # 如果返回的响应结果是字典，则调用result_validate方法断言
                        self.result_validate(yq_result=yq_result, real_result=res.json(), status_code=status_code)
                        # 提取变量
                        self.analysic_extract(testcase_info, res)
                        return res.json()
                else:
                    print("request必须包含二级关键字：url、method!")
            else:
                write_error_log("测试用例一级关键字不符合规则")
        except Exception as e:
            write_error_log("分析yaml文件出错,异常信息：%s" % str(traceback.format_exc()))

    def send_request(self, method, url, headers=None, files=None, **kwargs):
        self.method = method.upper()
        url = self.base_url + url
        self.url = self.replace_value(url)
        if headers and isinstance(headers, dict):
            self.last_headers = self.replace_value(headers)
        # 对请求数据做参数替换
        for key, value in kwargs.items():
            if key in ['params', 'data', 'json']:
                kwargs[key] = self.replace_value(value)
        # 对请求数据做热加载处理
        for key, value in kwargs.items():
            if key in ['params', 'data', 'json']:
                kwargs[key] = self.replace_load(value)
        res = RequestUtil.sessions.request(self.method, self.url, headers=self.last_headers, files=files, **kwargs)
        return res

    def result_text_validate(self, yq_result, real_result, status_code):
        """
        :param yq_result: 预期结果
        :param real_result: 实际结果
        :param status_code: 状态码
        :return: 返回断言成功与否的标记
        """
        write_log("预期结果：%s" % yq_result)
        # write_log("实际结果：%s" % real_result)
        try:
            flag = 0
            if yq_result and isinstance(yq_result, list):
                for yq in yq_result:
                    if isinstance(yq, dict):
                        for key, value in yq.items():
                            if key == 'contains':
                                if value not in real_result:
                                    flag += 1
                                    write_error_log("contains断言失败, %s在返回结果中不存在！" % value)
                            else:
                                flag += 1
                                write_error_log("不支持的断言方式!")
                    else:
                        flag += 1
                        write_error_log("不支持的断言格式!")
            elif yq_result and isinstance(yq_result, dict):
                for key, value in yq_result.items():
                    if key == 'contains':
                        if value not in real_result:
                            flag += 1
                            write_error_log("contains断言失败, %s在返回结果中不存在！" % value)
                    else:
                        flag += 1
                        write_error_log("不支持的断言方式!")
            else:
                flag += 1
                write_error_log("不支持的断言格式!")
            assert flag == 0
            write_log("接口执行成功")
            write_log("------------------------接口请求结束-------------------------\n")
        except Exception as e:
            write_log("接口执行失败")
            write_error_log("断言出错,异常信息：%s" % str(traceback.format_exc()))
            write_log("------------------------接口请求结束-------------------------\n")

    def result_validate(self, yq_result, real_result, status_code):
        """
        :param yq_result: 预期结果
        :param real_result: 实际结果
        :param status_code: 状态码
        :return: 返回断言成功与否的标记
        """
        write_log("预期结果：%s" % yq_result)
        write_log("实际结果：%s" % real_result)
        try:
            flag = 0
            if yq_result and isinstance(yq_result, list):
                for yq in yq_result:
                    if isinstance(yq, dict):
                        for key, value in yq.items():
                            if key == 'equals':
                                if isinstance(value, dict):
                                    for assert_key, assert_value in value.items():
                                        if assert_key == 'status_code':
                                            if assert_value != status_code:
                                                flag += 1
                                                write_error_log("断言失败，status_code断言失败！")
                                        else:
                                            all_values = jsonpath.jsonpath(real_result, '$..%s' % assert_key)
                                            if not all_values or assert_value not in all_values:
                                                flag += 1
                                                write_error_log("断言失败，%s断言失败！" % assert_key)
                                else:
                                    flag += 1
                                    write_error_log("不支持的断言方式!")
                            elif key == 'contains':
                                # ensure_ascii=False 表示中文字符串不会转为unicode码
                                real_result_temp = json.dumps(real_result, ensure_ascii=False)
                                if value not in real_result_temp:
                                    flag += 1
                                    write_error_log("contains断言失败, %s在返回结果中不存在！" % value)
                            else:
                                flag += 1
                                write_error_log("不支持的断言方式!")
                    else:
                        flag += 1
                        write_error_log("不支持的断言格式!")
            else:
                flag += 1
                write_error_log("不支持的断言格式!")
            assert flag == 0
            write_log("接口执行成功")
            write_log("------------------------接口请求结束-------------------------\n")
        except Exception as e:
            write_log("接口执行失败")
            write_error_log("断言出错,异常信息：%s" % str(traceback.format_exc()))
            write_log("------------------------接口请求结束-------------------------\n")

    def get(self, url, headers, data, cookies):
        return requests.get(url=url, params=data, headers=headers, cookies=cookies)

    def post(self, url, data, params, headers, files, cookies):
        return requests.post(url=url, data=data, params=params, headers=headers, files=files, cookies=cookies)

    def put(self, url, data, headers, cookies):
        return requests.put(url=url, data=data, headers=headers, cookies=cookies)

    def dels(self, url, data, headers, cookies):
        return requests.delete(url=url, data=data, headers=headers, cookies=cookies)

    #处理热加载数据
    def replace_load(self, value):
        if value and isinstance(value, dict):
            str = json.dumps(value)
        else:
            str = value
        for i in range(0, str.count('${')):
            if '${' in str and '}' in str:
                index_start = str.index('${')
                index_end = str.index('}', index_start)
                old_value = str[index_start:index_end + 1]
                # print("old_value2= ", old_value)
                function_end_index = old_value.index('(')
                function_name = old_value[2:function_end_index]
                # print("function_name=", function_name)
                key_end = old_value.index(')', function_end_index)
                key_values = old_value[function_end_index + 1:key_end]
                # print("key_values=", key_values)
                value_list = key_values.split(',')
                # print("value_list=", value_list)
                new_value = getattr(DebugTalk(), function_name)(*value_list)
                str = str.replace(old_value, new_value)
        if value and isinstance(value, dict):
            value = json.loads(str)
        else:
            value = str
        return value

    # 处理关联取值
    def replace_value(self, value):
        # 获取爱兑分测试数据字段值
        aiduifen_config_keys = common_util.read_config_keys_yaml('test_data')
        if value and isinstance(value, dict):
            str = json.dumps(value)
        else:
            str = value
        for i in range(0, str.count('{{')):
            if '{{' in str and '}}' in str:
                index_start = str.index('{{')
                index_end = str.index('}}', index_start)
                old_value = str[index_start:index_end + 2]
                # print("old_value= ", old_value)
                key_value = old_value[2:-2]
                if key_value in aiduifen_config_keys:
                    new_value = common_util.read_config_yaml('test_data', 'appVerTitle')
                else:
                    new_value = common_util.read_extract_yaml(key_value)
                # print("new_value= ", new_value)
                str = str.replace(old_value, new_value)
                #　print("str=====", str)
        if value and isinstance(value, dict):
            value = json.loads(str)
        else:
            value = str
        return value

if __name__ == "__main__":
    url = "http://miniprogram-aiduifen-test.tongdui8.com/superAdmin/user-manage/give-adfun"
    params = {"t": "LUZfZGpmOVp0MglUDxN2A0AXGxcsKE4DFT87UidWTG4AKAk2JVF9Cg=="}
    data = {
        "uid": 143,
        "amount": 1,
        "reason": "test"
    }
    res = requests.post(url=url,params=params,data=data)
    print(res.json())


from collections import deque

# Given an m x n 2D binary grid grid which represents a map of '1's (land) and '0's (water),
# return the number of islands.

# An island is surrounded by water and is formed by connecting adjacent lands horizontally or vertically.
# You may assume all four edges of the grid are all surrounded by water.

# Example 1:

# Input: grid = [
#   ["1","1","1","1","0"],
#   ["1","1","0","1","0"],
#   ["1","1","0","0","0"],
#   ["0","0","0","0","0"]
# ]
# Output: 1

# Example 2:

# Input: grid = [
#   ["1","1","0","0","0"],
#   ["1","1","0","0","0"],
#   ["0","0","1","0","0"],
#   ["0","0","0","1","1"]
# ]
# Output: 3

def numIslands(grid):
    """
    :type grid: List[List[str]]
    :rtype: int
    Time - O(m * n)
    Space - O(mn)
    """
    if not grid:
        return 0

    rows = len(grid)
    cols = len(grid[0])

    islands = 0

    def is_island(grid, i, j):
        return (
            True
            if 0 <= i < len(grid) and 0 <= j < len(grid[0]) and grid[i][j] == "1"
            else False
        )

    # bfs, check neighbours
    for row in range(rows):
        for col in range(cols):
            if grid[row][col] == "1" and (row, col):
                islands += 1
                queue = deque([(row, col)])
                while queue:
                    i, j = queue.popleft()
                    grid[i][j] = "-1"
                    # check neighbours (left, right, down, top)
                    for dr, dc in ((-1, 0), (1, 0), (0, 1), (0, -1)):
                        r, c = i + dr, j + dc
                        if is_island(grid, r, c) and (r, c):
                            queue.append((r, c))
                            grid[r][c] = "-1"

    return islands

def numIslandsDFSRecursive(grid):
    if not grid:
        return 0

    rows = len(grid)
    cols = len(grid[0])

    islands = 0

    # dfs, check neighbours
    def search(grid, i, j):
        if 0 <= i < len(grid) and 0 <= j < len(grid[0]) and grid[i][j] == "1":
            grid[i][j] = "-1"  # ensure we don't check visited node
            search(grid, i - 1, j)
            search(grid, i + 1, j)
            search(grid, i, j + 1)
            search(grid, i, j - 1)
            return 1
        return 0

    for row in range(rows):
        for col in range(cols):
            islands += search(grid, row, col)

    return islands

if __name__ == "__main__":
    grid = [
        ["1", "1", "1", "1", "0"],
        ["1", "1", "0", "1", "0"],
        ["1", "1", "0", "0", "0"],
        ["0", "0", "0", "0", "0"],
    ]
    expected = 1
    # print(numIslands(grid) == 1)
    print(numIslandsDFSRecursive(grid) == 1)


# 볼록 선체
# 어느 한 부분도 오목하지 않은 상태
# 객체의 외각 영역을 찾는데 사용

import cv2
import numpy as np

img = cv2.imread("./img/hand.jpg")
img2 = img.copy()

gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

ret, th = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY_INV)

# 컨투어 찾기
contours, heiarchy = cv2.findContours(th, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

# 컨투어 그리기
cntr = contours[0]
cv2.drawContours(img, [cntr], -1, (0,255,0), 1)

# 볼록 선체 찾기(좌표 기준)와 그리기
# cv2.convexHull(입력 컨투어)
hull = cv2.convexHull(cntr)
cv2.drawContours(img2, [hull], -1, (0,255,0), 1)
# cv2.isContourConvex(볼록 선체 만족)   # True 볼록 선체 만족(오목 없음), False 불만족(오목 존재)
print(cv2.isContourConvex(cntr), cv2.isContourConvex(hull))

# 볼록 선체 찾기(인덱스 기준)
# cv2.convexHull(입력컨투어, 결과 좌표 형식 선택(True : 볼록 선체 좌표 반환, False : 입력 컨투어 중 볼록 선체에 해당하는 인덱스 반환))
hull2 = cv2.convexHull(cntr, returnPoints=False)
# cv2.convexityDefects(입력컨투어, 볼록 선체에 해당하는 컨투어 인덱스)
defects = cv2.convexityDefects(cntr, hull2)

# 볼록 선체 결함 순회
for i in range(defects.shape[0]):
    # 시작, 종료, 가장 먼 지점, 거리
    startP, endP, farthestP, distance = defects[i, 0]
    # 가장 먼 지점의 좌표 구하기
    farthest = tuple(cntr[farthestP][0])
    # 거리를 부동 소수점으로 변환
    dist = distance/256.0

    # 거리가 1보다 큰 경우
    if dist>1:
        # 빨간색 점으로 표시
        cv2.circle(img2, farthest, 3, (0,0,255), -1)

cv2.imshow("contour", img)
cv2.imshow("convex hull", img2)
cv2.waitKey(0)
cv2.destroyAllWindows()


import logging
import pickle
from datetime import datetime
from pathlib import Path
from typing import Literal, Optional, Union

import fire  # type: ignore
import numpy as np
from driver.legacy.models import Driver
from joblib.parallel import Parallel, delayed  # type: ignore

from active.sampling import Sampler
from active.simulation_utils import get_feedback, get_simulated_feedback, run_algo
from utils import append, load, make_reward_path, parse_replications, save_reward, update_inputs

def setup(criterion: str, query_type: str, outdir: Path, delta: Optional[float] = None):
    """ Normalizes flag strings, makes outdir, configures logging """
    assert delta is None or delta > 1.0, "Delta must be strcitly greater than 1"
    criterion = criterion.lower()
    query_type = query_type.lower()
    outpath = Path(outdir)
    outpath.mkdir(parents=True, exist_ok=True)

    now = datetime.now()

    logging.basicConfig(level="INFO", filename=outpath / f"{now}.log")

    assert criterion == "information" or criterion == "volume" or criterion == "random", (
        "There is no criterion called " + criterion
    )
    return criterion, query_type, outpath

def simulated(
    outdir: Path,
    criterion: Literal["information", "volume", "random"],
    termination_threshold: float,
    n_reward_samples: int,
    query_type: Literal["strict", "weak"] = "strict",
    equiv_size: Optional[float] = None,
    true_reward_path: Optional[Path] = None,
    continuous: bool = False,
    overwrite: bool = False,
    replicaitons: Optional[str] = None,
):
    """ Generates a test by eliciting from a human simulated by a ground truth reward. """
    if replicaitons is not None:
        replication_indices = parse_replications(replicaitons)
        if true_reward_path is not None:
            reward_dir, reward_name = make_reward_path(true_reward_path)
            Parallel(n_jobs=-2)(
                delayed(simulated)(
                    outdir=Path(outdir) / str(i),
                    criterion=criterion,
                    termination_threshold=termination_threshold,
                    n_reward_smaples=n_reward_samples,
                    query_type=query_type,
                    equiv_size=equiv_size,
                    true_reward_path=reward_dir / str(i) / reward_name,
                    continuous=continuous,
                    overwrite=overwrite,
                )
                for i in replication_indices
            )
        else:
            Parallel(n_jobs=-2)(
                delayed(simulated)(
                    outdir=Path(outdir) / str(i),
                    criterion=criterion,
                    termination_threshold=termination_threshold,
                    n_reward_smaples=n_reward_samples,
                    query_type=query_type,
                    equiv_size=equiv_size,
                    continuous=continuous,
                    overwrite=overwrite,
                )
                for i in replication_indices
            )
        exit()

    criterion, query_type, outdir = setup(criterion, query_type, outdir, delta=equiv_size)

    env = Driver()
    d = env.num_of_features

    if true_reward_path is not None:
        logging.info(f"Loading true reward from {true_reward_path}")
        true_reward = np.load(true_reward_path)
    else:
        logging.info("Randomly generating true reward")
        true_reward = np.random.normal(size=(4,))
        true_reward = true_reward / np.linalg.norm(true_reward)
        np.save(outdir / "true_reward.npy", true_reward)

    pickle.dump(
        {
            "criterion": criterion,
            "reward_iterations": n_reward_samples,
            "stop_thresh": termination_threshold,
            "query_type": query_type,
            "equiv_size": equiv_size,
            "continuous": continuous,
        },
        open(outdir / "flags.pkl", "wb"),
    )

    normals = load(outdir / "normals.npy", overwrite=overwrite)
    preferences = load(outdir / "preferences.npy", overwrite=overwrite)
    inputs = load(outdir / "inputs.npy", overwrite=overwrite)
    input_features = load(outdir / "input_features.npy", overwrite=overwrite)

    # If there is already data, feed it to the w_sampler to get the right posterior.
    w_sampler = Sampler(d)
    if inputs is not None and input_features is not None and preferences is not None:
        for (a_phi, b_phi), preference in zip(input_features, preferences):
            w_sampler.feed(a_phi, b_phi, [preference])

    score = np.inf
    try:
        while score >= termination_threshold:
            w_samples, delta_samples = w_sampler.sample_given_delta(
                sample_count=n_reward_samples, query_type=query_type, delta=equiv_size
            )

            input_A, input_B, score = run_algo(criterion, env, w_samples, delta_samples, continuous)
            logging.info(f"Score={score}")

            if score > termination_threshold:
                inputs = update_inputs(
                    a_inputs=input_A, b_inputs=input_B, inputs=inputs, outdir=outdir
                )
                phi_A, phi_B, preference = get_simulated_feedback(
                    simulation=env,
                    input_A=input_A,
                    input_B=input_B,
                    query_type=query_type,
                    true_reward=true_reward,
                    delta=equiv_size,
                )
                input_features = append(input_features, np.stack([phi_A, phi_B]))
                normals = append(normals, phi_A - phi_B)
                preferences = append(preferences, preference)
                np.save(outdir / "input_features.npy", input_features)
                np.save(outdir / "normals.npy", normals)
                np.save(outdir / "preferences.npy", preferences)

                w_sampler.feed(phi_A, phi_B, [preference])
    except KeyboardInterrupt:
        # Pass through to finally
        logging.warning("\nSaving results, please do not exit again.")
    finally:
        save_reward(query_type, w_sampler, n_reward_samples, outdir, true_delta=equiv_size)

def human(
    criterion: str,
    query_type: str,
    epsilon: float,
    n_reward_samples: int,
    equiv_size: float,
    outdir: Path = Path("questions"),
    continuous: bool = False,
    overwrite: bool = False,
):
    """ Generates a test by eliciting preferences from a human. """
    criterion, query_type, outdir = setup(criterion, query_type, outdir, delta=equiv_size)

    simulation_object = Driver()
    d = simulation_object.num_of_features

    pickle.dump(
        {
            "criterion": criterion,
            "query_type": query_type,
            "epsilon": epsilon,
            "reward_iterations": n_reward_samples,
            "delta": equiv_size,
            "continuous": continuous,
        },
        open(outdir / "flags.pkl", "wb"),
    )

    normals = load(outdir / "normals.npy", overwrite=overwrite)
    preferences = load(outdir / "preferences.npy", overwrite=overwrite)
    inputs = load(outdir / "inputs.npy", overwrite=overwrite)
    input_features = load(outdir / "input_features.npy", overwrite=overwrite)

    w_sampler = Sampler(d)
    if inputs is not None and input_features is not None and preferences is not None:
        for (a_phi, b_phi), preference in zip(input_features, preferences):
            w_sampler.feed(a_phi, b_phi, [preference])

    score = np.inf
    try:
        while score >= epsilon:
            w_samples, delta_samples = w_sampler.sample_given_delta(
                n_reward_samples, query_type, equiv_size
            )

            input_A, input_B, score = run_algo(
                criterion, simulation_object, w_samples, delta_samples, continuous
            )

            if score > epsilon:
                inputs = update_inputs(
                    a_inputs=input_A, b_inputs=input_B, inputs=inputs, outdir=outdir
                )
                phi_A, phi_B, preference = get_feedback(
                    simulation_object, input_A, input_B, query_type
                )
                input_features = append(input_features, np.stack([phi_A, phi_B]))
                normals = append(normals, phi_A - phi_B)
                preferences = append(preferences, preference)
                np.save(outdir / "input_features.npy", input_features)
                np.save(outdir / "normals.npy", normals)
                np.save(outdir / "preferences.npy", preferences)

                w_sampler.feed(phi_A, phi_B, [preference])
    except KeyboardInterrupt:
        # Pass through to finally
        logging.warning("\nSaving results, please do not exit again.")
    finally:
        save_reward(query_type, w_sampler, n_reward_samples, outdir, true_delta=equiv_size)

if __name__ == "__main__":
    fire.Fire()


import cv2
import pytesseract

img = cv2.imread('testImg/xx1.jpeg')

# 转换为灰度图像
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

# 进行边缘检测
edges = cv2.Canny(gray, 50, 150, apertureSize=3)

# 检测轮廓
contours, _ = cv2.findContours(edges, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)

# 遍历轮廓
for contour in contours:
    x, y, w, h = cv2.boundingRect(contour)
    area = w * h
    if area > 1000 and area < 5000:
        # 裁剪出车牌
        plate_img = img[y:y+h, x:x+w]
        # 进行 OCR 识别
        text = pytesseract.image_to_string(plate_img, lang='chi_sim')
        if 6<=len(text):
            print(text)
            # 在原图上绘制车牌区域
            cv2.rectangle(img, (x,y), (x+w,y+h), (0, 0, 255), 2)

# 显示结果
cv2.imshow('result', img)
cv2.waitKey(0)
cv2.destroyAllWindows()


from random import randint, sample
from scipy.stats import binom
import itertools
import numpy as np
import argparse

def polygon_area(npoints):
	# computes twice the area_list of a polygon with points given
	# using a vectorized shoelace formula
	points = npoints[1]
	if points.shape[0] < 3:
		return (npoints[0], 0)
	x = points[:, 0]
	y = points[:, 1]
	area_list = np.abs(np.dot(x, np.roll(y, 1)) -
		np.dot(y, np.roll(x, 1)))
	return (npoints[0], area_list)

def cross(o, a, b):
	# Computes cross product (a-o) x (b-o)
    return (a[0] - o[0]) * (b[1] - o[1]) - (a[1] - o[1]) * (b[0] - o[0])

def generate_hull(n, m=None):
	# Sample random points in grid, then take the convex hull
	if m is None:
		m = binom.rvs((n+1)**2, 1/(n+1)) # compute number of points to be included
	# sample m points uniformly across grid
	points = [divmod(p, n+1) for p in sorted(sample(range((n+1)**2), m))]
	if m <= 3:
		return (m, np.array(points))

	# Compute convex hull of the points chosen,
	# uses the monotone chain algorithm
	lower = points.copy() # preallocate array
	i = 0
	for p in points:
		while i >= 2 and cross(lower[i-2], lower[i-1], p) <= 0:
			i -= 1
		lower[i] = p
		i += 1

	upper = points.copy()
	j = 0
	for p in reversed(points):
		while j >= 2 and cross(upper[j-2], upper[j-1], p) <= 0:
			j -= 1
		upper[j] = p
		j += 1

    # Concatenation of the lower and upper hulls gives the convex hull.
    # Last point of each list is omitted because it is repeated at the beginning of the other list.
	return (len(points), np.array(lower[:i-1] + upper[:j-1]))

if __name__ == "__main__":
	parser = argparse.ArgumentParser()
	parser.add_argument('-N','--grid_size', type=int, default=100)
	parser.add_argument('-M','--samples', type=int, default=10000)
	parser.add_argument('--method', type=str, choices=['randomsize','uniformsize'],
						default='randomsize')
	args = parser.parse_args()
	N = args.grid_size
	M = args.samples

	print("Computing areas...")
	if args.method == 'randomsize':
		# Generate M random polygons, keeping track of the original number of points
		area_list = [polygon_area(generate_hull(N, x)) for x in np.random.binomial((N+1)**2, 1/(N+1), M)]
		print("Grouping...")
		list.sort(area_list)
	else:
		# Generate M polygons for each size from 3 to (N+1)**2
		area_list = [polygon_area(generate_hull(N, x//M + 3)) for x in range(((N+1)**2 - 2)*M)]

	# freeze a binomial distribution corresponding to the expected number of polygons
	# for a particular point count. The average will be computed separately for each
	# point count, and then the averages can be weighted by the number of occurances
	# expected of that count. This method reduces the variance.
	b = binom((N+1)**2, 1/(N+1))
	avg = 0
	print("Averaging...")
	for n, ptlist in itertools.groupby(area_list, lambda x: x[0]):
		if n < 3:
			continue
		n_arealist = [x[1] for x in ptlist]
		l = len(n_arealist)
		if l > 0:
			avg += b.pmf(n)*np.mean(n_arealist)/2 # /2 as previously computed twice the area
		print(n, l, b.pmf(n)*M, np.mean(n_arealist), np.var(n_arealist)/4)
	print("Done!")
	print(avg, np.var([x[1] for x in area_list])/4)